Add Accredible as a supported badge source - #5
Open
jeff-grann wants to merge 3 commits into
Open
Conversation
Adds an Accredible connector alongside the existing Canvas/Credly/Parchment sources, so Accredible badges can be pulled directly into Badge Publisher instead of going through a manual JSON paste step. - src/lib/utils/accredible.ts: region config (US/EU/Sandbox), types for the /v1/issuer/all_groups response, and badgeclassFromAccredibleGroup(), which maps a group into Badge Publisher's BadgeClassCTDLExtended shape. - src/lib/stores/badgeSourceStore.ts: 'accredible' BadgeSourceTypeOptions entry, accredible* stores, fetchAccredibleGroups() (paginated fetch via the existing StagingApi/Proxy route, Token-header auth matching Accredible's own export script), and wiring into badgeSetupComplete / normalizedBadges / resetBadgeData. - src/lib/partials/AccredibleConfig.svelte: config panel (environment, API key, terms, load-badges) modeled on ParchmentConfig/CredlyConfig. - src/lib/partials/BadgeSourceConfig.svelte: Accredible radio option and panel wiring. Key behavior: alignment/skill entries without a resolvable targetUrl are dropped rather than passed through with only targetName, because badgeClassBasicSchema (src/lib/utils/badges.ts) requires targetUrl on every alignment entry and rejects the whole achievement otherwise. Verified against a 316-achievement sample from Accredible's own export script: 255/316 (81%) failed import for exactly this reason before this fix. Known open item: badge image retrieval. Accredible's Groups endpoint (per their own export script) does not return a design/image URL, and Accredible's API reference (docs.accredible.com) could not be reached while building this to confirm the right endpoint. extractImageFromGroup() checks a few plausible field names defensively, and ACCREDIBLE_GROUP_IMAGE_ENDPOINT_UNCONFIRMED in accredible.ts is a placeholder for a second per-group lookup call once Accredible confirms the actual endpoint. Until then, image will typically be blank, same as it is today via the manual JSON path. Verified with 'npm run check' (svelte-check): 42 errors on this branch vs. 44 on main, none attributable to the new/changed files. 'npm run build' fails identically on main due to a pre-existing missing env var (PUBLIC_PARCHMENT_SG_ENABLED) unrelated to this change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F4KiQrHVeCQqSbFHNDUkKV
Real fixes to the Accredible badge source:
- Add Accredible API regions to the proxy origin whitelist; without them
every Accredible fetch was rejected with a 400.
- Normalize `earning_criteria`, which Accredible returns as a structured
array (not a string); passing it to markdownToTxt() threw and silently
dropped the whole credential from the import.
- Resolve the badge image from the group Design (design_id -> GET
/v1/designs/{id} -> rasterized_content_url), deduped by design_id and
best-effort so a lookup failure never breaks the fetch.
- Make importCheckedSourceBadges convert per-badge so one malformed badge
can no longer wipe the entire drafts list; failures are logged and skipped.
- Surface a clear error on a non-JSON (Keycloak) login response instead of
spinning forever; abort submit on failed form validation.
Dev-only scaffolding (ships disabled):
- PUBLIC_DEV_BYPASS_PUBLISHER_LOGIN flag adds a "Skip login (dev)" button
that injects a fake publisher session for local testing against
Keycloak-migrated Publisher environments. Defaults off in tracked env files.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The group payload carries no image, only design-id references, and the
design's rasterized image is a blank template. Two fixes so the imported
badge matches what Accredible renders:
- Select the badge-specific design. A group exposes several design ids;
badgeDesignIdForGroup() prefers badge_design_id, then primary_design_id,
then design_id (certificate_design_id last). Using design_id alone often
resolved the wrong design or none, yielding a placeholder.
- Merge the group's name into the render. POST /v1/designs/{id}/preview with
group.course_name / group.name returns the populated badge as { link };
fall back to the blank rasterized image only if that fails. Image
resolution is now per-group (cached by design+name) since the render
depends on the name.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Accredible as a supported badge source in the Open Badge Publisher, alongside the existing Credly / Canvas / Parchment sources. An issuer connects with their Accredible API key, pulls their badge achievements (groups), and publishes them to the Credential Registry — importing earning criteria, alignments, and the rendered badge image end-to-end.
Accredible provided Credential Engine with a sandbox account and a script to access an issuer's badge achievements, which were used to build and verify this integration against live sandbox data.
Demo (end-to-end flow)
https://drive.google.com/file/d/1M7dPgtd39EFZgxT21l2df8UFmmXQ98La/view?usp=drive_link
What's included
/v1/issuer/all_groups(added to the proxy origin allowlist).earning_criteriaarray), and learning-outcome alignments.badge_design_idand renders it with the group name merged in via/v1/designs/{id}/preview, falling back to the design's rasterized image.Follow-ups (out of scope for this PR)
learning_outcomes(strings) and framework-referencedframework_skills(by id) — so writing a Credential Registry backlink onto the group is not cleanly supported the way it is for Canvas/Parchment. Tracked in Accredible write-back: add Credential Registry alignment to source group ("Update Alignments") jeff-grann/Open-Badge-Publisher#1🤖 Generated with Claude Code