Skip to content

Conversation

gerardopar
Copy link
Collaborator

@gerardopar gerardopar commented Sep 26, 2025

Overview

🎟 Relevant Jira Issues

LC-1309
LC-1310

CLIENT SIDE PR

📚 What is the context and goal of this PR?

This PR introduces full Evidence support into our BoostCredential workflow and updates our VC context to version 1.03. The goal is to make LearnCard-issued credentials more interoperable with external verifiable credentials while still supporting our enhanced metadata needs.

  1. Extended JSON-LD Context (v1.03)

    • Added a new EvidenceFile type extending the standard Evidence class.
    • Moves all file metadata (fileName, fileSize, fileType) into EvidenceFile to avoid redefining Evidence.
  2. Evidence Integration

    • Added support for including evidence arrays in generated credentials.
    • Each evidence entry now supports dual typing: ["Evidence", "EvidenceFile"].
    • Ensures that existing audience, genre, and other OBv3-compliant fields remain compatible.
  3. Implementation Improvements

    • Updated BoostCredential construction logic to dynamically map evidence data with extended types.
    • Standardized context references and added type safety for future Zod validation updates.
    • Verified compatibility with JSON-LD playground and ingestion pipeline.

🥴 TL; RL:

💡 Feature Breakdown (screenshots & videos encouraged!)

🛠 Important tradeoffs made:

🔍 Types of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Chore (refactor, documentation update, etc)

💳 Does This Create Any New Technical Debt? ( If yes, please describe and add JIRA TODOs )

  • No
  • Yes

Testing

🔬 How Can Someone QA This?

  1. Generate a new BoostCredential with at least one evidence object with fileName, fileType, and fileSize.
  2. Validate the generated VC on JSON-LD Playground to confirm expanded context resolution.
  3. Verify rendering and metadata extraction on the frontend

📱 🖥 Which devices would you like help testing on?

🧪 Code Coverage

Documentation

📜 Gitbook

📊 Storybook

✅ PR Checklist

  • Related to a Jira issue (create one if not)
  • My code follows style guidelines (eslint / prettier)
  • I have manually tested common end-2-end cases
  • I have reviewed my code
  • I have commented my code, particularly where ambiguous
  • New and existing unit tests pass locally with my changes
  • I have made corresponding changes to gitbook documentation

🚀 Ready to squash-and-merge?:

  • Code is backwards compatible
  • There is not a "Do Not Merge" label on this PR
  • I have thoughtfully considered the security implications of this change.
  • This change does not expose new public facing endpoints that do not have authentication

✨ PR Description

Purpose: Add evidence support to Open Badge credentials with enhanced type validation and template functionality.

Main changes:

  • Updated EvidenceValidator with standardized type patterns and required fields
  • Added evidence field to credential templates with automatic type handling
  • Created new context file (boosts/1.0.3.json) for evidence file metadata support
  • Fixed type definitions to use z.array(z.string()) instead of z.string().array()

Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using. We'd love your feedback! 🚀

Copy link

changeset-bot bot commented Sep 26, 2025

🦋 Changeset detected

Latest commit: 2a3cf53

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 39 packages
Name Type
@learncard/types Patch
@learncard/vc-templates-plugin Patch
@learncard/chapi-example Patch
@learncard/snap-example-dapp Patch
@learncard/create-http-bridge Patch
@learncard/cli Patch
@learncard/core Patch
@learncard/helpers Patch
@learncard/init Patch
@learncard/react Patch
@learncard/network-brain-client Patch
@learncard/learn-cloud-client Patch
@learncard/simple-signing-client Patch
@learncard/ceramic-plugin Patch
@learncard/chapi-plugin Patch
@learncard/claimable-boosts-plugin Patch
@learncard/did-web-plugin Patch
@learncard/didkey-plugin Patch
@learncard/didkit-plugin Patch
@learncard/encryption-plugin Patch
@learncard/idx-plugin Patch
@learncard/network-plugin Patch
@learncard/learn-card-plugin Patch
@learncard/learn-cloud-plugin Patch
@learncard/open-badge-v2-plugin Patch
@learncard/vc-api-plugin Patch
@learncard/vc-plugin Patch
@learncard/vpqr-plugin Patch
learn-card-discord-bot Patch
@learncard/meta-mask-snap Patch
@learncard/network-brain-service Patch
@learncard/learn-cloud-service Patch
@learncard/simple-signing-service Patch
@learncard/snap-chapi-example Patch
@learncard/expiration-plugin Patch
@learncard/crypto-plugin Patch
@learncard/dynamic-loader-plugin Patch
@learncard/ethereum-plugin Patch
@learncard/simple-signing-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

netlify bot commented Sep 26, 2025

Deploy Preview for learncarddocs canceled.

Name Link
🔨 Latest commit 2a3cf53
🔍 Latest deploy log https://app.netlify.com/projects/learncarddocs/deploys/68dffc9cb1a4380008ba0c16

Copy link
Contributor

@gitstream-cm gitstream-cm bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✨ PR Review

The PR implements Evidence support for Open Badges v3 with proper JSON-LD context updates, but there are critical issues with validator consistency and evidence field handling that could break existing functionality.

3 issues detected:

🐞 Bug - Evidence field was removed from achievement credential validator despite the PR adding evidence support

Details: The evidence field has been removed from UnsignedAchievementCredentialValidator while the PR is specifically adding evidence support. This contradicts the core functionality being implemented and will prevent proper validation of evidence in achievement credentials.
File: packages/learn-card-types/src/obv3.ts

🐞 Bug - Potential runtime error when filtering undefined e.type array

Details: The evidence type manipulation logic assumes e.type exists as an array but uses optional chaining, suggesting it might be undefined. The filter operation on a potentially undefined value could cause runtime errors during credential generation.
File: packages/plugins/vc-templates/src/templates.ts (156-162)

🧹 Maintainability - Inconsistent union syntax compared to other optional array fields

Details: The evidence field uses z.union() while other similar optional array fields in the same validator use the .or() method pattern. This inconsistency makes the codebase harder to maintain and understand.
File: packages/learn-card-types/src/vc.ts (163-163)

Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using. We'd love your feedback! 🚀

Comment on lines +156 to +162
type: e.type?.includes('EvidenceFile')
? e.type
: [
'Evidence',
'EvidenceFile',
...(e.type?.filter(t => t !== 'Evidence') || []),
],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐞 Bug - Unsafe Type Manipulation: Add proper null/undefined checks before the filter operation and ensure e.type is always initialized as an array.

Suggested change
type: e.type?.includes('EvidenceFile')
? e.type
: [
'Evidence',
'EvidenceFile',
...(e.type?.filter(t => t !== 'Evidence') || []),
],
type: Array.isArray(e.type)
? e.type.includes('EvidenceFile')
? e.type
: [
'Evidence',
'EvidenceFile',
...e.type.filter(t => t !== 'Evidence'),
]
: ['Evidence', 'EvidenceFile'],

status: CredentialStatusValidator.or(CredentialStatusValidator.array()).optional(),
termsOfUse: TermsOfUseValidator.or(TermsOfUseValidator.array()).optional(),
evidence: VC2EvidenceValidator.or(VC2EvidenceValidator.array()).optional(),
evidence: z.union([VC2EvidenceValidator, z.array(VC2EvidenceValidator)]).optional(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Maintainability - Inconsistent Union Syntax: Use consistent syntax by changing to VC2EvidenceValidator.or(VC2EvidenceValidator.array()).optional() to match the pattern used for other similar fields.

Suggested change
evidence: z.union([VC2EvidenceValidator, z.array(VC2EvidenceValidator)]).optional(),
evidence: VC2EvidenceValidator.or(VC2EvidenceValidator.array()).optional(),

Copy link
Contributor

gitstream-cm bot commented Sep 26, 2025

🥷 Code experts: TaylorBeeston

TaylorBeeston, gerardopar have most 👩‍💻 activity in the files.
gerardopar, TaylorBeeston have most 🧠 knowledge in the files.

See details

packages/learn-card-types/src/obv3.ts

Activity based on git-commit:

TaylorBeeston gerardopar
OCT
SEP
AUG
JUL
JUN
MAY

Knowledge based on git-blame:
TaylorBeeston: 100%

packages/learn-card-types/src/vc.ts

Activity based on git-commit:

TaylorBeeston gerardopar
OCT
SEP
AUG
JUL
JUN
MAY

Knowledge based on git-blame:
TaylorBeeston: 100%

packages/plugins/vc-templates/src/templates.ts

Activity based on git-commit:

TaylorBeeston gerardopar
OCT
SEP 7 additions & 7 deletions
AUG
JUL 191 additions & 563 deletions 558 additions & 534 deletions
JUN
MAY

Knowledge based on git-blame:
TaylorBeeston: 75%
gerardopar: 25%

packages/plugins/vc-templates/src/types.ts

Activity based on git-commit:

TaylorBeeston gerardopar
OCT
SEP 6 additions & 0 deletions
AUG
JUL 4 additions & 1 deletions 3 additions & 0 deletions
JUN
MAY

Knowledge based on git-blame:
gerardopar: 60%
TaylorBeeston: 33%

✨ Comment /gs review for LinearB AI review. Learn how to automate it here.

@gerardopar gerardopar changed the title feat: LC-1310 - Add Evidence Support feat: [LC-1309][LC-1310] - Add Evidence Support Sep 26, 2025
Copy link
Contributor

@gitstream-cm gitstream-cm bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✨ PR Review

The PR successfully implements evidence support for Open Badges v3 compliance by updating validators, templates, and type definitions. The evidence field has been properly moved from achievement-specific to VC-level validation, which is architecturally correct.

2 issues detected:

🐞 Bug - Optional chaining suggests e.type might be undefined, but subsequent operations assume it's an array

Details: The evidence type manipulation logic uses optional chaining for e.type?.includes() and e.type?.filter() but doesn't handle the case where e.type is undefined. This could cause runtime errors when processing evidence arrays during credential generation.
File: packages/plugins/vc-templates/src/templates.ts (156-161)

🧹 Maintainability - Mixing z.union() and .or() patterns for similar field types creates inconsistent code style

Details: The evidence field uses z.union() while other similar optional array fields in the same validator use the .or() method pattern. This inconsistency makes the codebase harder to understand and maintain.
File: packages/learn-card-types/src/vc.ts (163-163)

Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using. We'd love your feedback! 🚀

Comment on lines +156 to +161
type: e.type?.includes('EvidenceFile')
? e.type
: [
'Evidence',
'EvidenceFile',
...(e.type?.filter(t => t !== 'Evidence') || []),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐞 Bug - Potential Runtime Error: Add proper null/undefined checks or provide default values. For example: (e.type || []).includes('EvidenceFile') and ensure e.type is always an array before filtering.

Suggested change
type: e.type?.includes('EvidenceFile')
? e.type
: [
'Evidence',
'EvidenceFile',
...(e.type?.filter(t => t !== 'Evidence') || []),
type: (e.type || []).includes('EvidenceFile')
? e.type
: [
'Evidence',
'EvidenceFile',
...(e.type || []).filter(t => t !== 'Evidence'),

status: CredentialStatusValidator.or(CredentialStatusValidator.array()).optional(),
termsOfUse: TermsOfUseValidator.or(TermsOfUseValidator.array()).optional(),
evidence: VC2EvidenceValidator.or(VC2EvidenceValidator.array()).optional(),
evidence: z.union([VC2EvidenceValidator, z.array(VC2EvidenceValidator)]).optional(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Maintainability - Inconsistent Validation Pattern: Change to use the consistent .or() pattern: evidence: VC2EvidenceValidator.or(VC2EvidenceValidator.array()).optional()

Suggested change
evidence: z.union([VC2EvidenceValidator, z.array(VC2EvidenceValidator)]).optional(),
evidence: VC2EvidenceValidator.or(VC2EvidenceValidator.array()).optional(),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant