Skip to content

feat(admin): GET /admin/users/:id/credentials with on-chain verification (#410) - #460

Open
ZacLou wants to merge 1 commit into
ChainLearnOfficial:mainfrom
ZacLou:feat/admin-user-credentials-410
Open

feat(admin): GET /admin/users/:id/credentials with on-chain verification (#410)#460
ZacLou wants to merge 1 commit into
ChainLearnOfficial:mainfrom
ZacLou:feat/admin-user-credentials-410

Conversation

@ZacLou

@ZacLou ZacLou commented Sep 4, 2026

Copy link
Copy Markdown

What

Adds GET /api/v1/admin/users/:id/credentials (#410): all credentials for a user, each with its mint transaction verified live against Stellar Horizon, so admins see real on-chain state instead of trusting a stored hash.

Implementation

  • CredentialService.getAdminUserCredentials(userId) — joins credentials → courses for titles (same shape as the user-facing list()), then resolves per-row verification:
    • mintTxHash == null{kind: "none", status: "unknown"}
    • pending_indexer_confirmation placeholder (bad-seq recovery path) → pending without a Horizon lookup, same convention as reward.getTransactions
    • otherwise stellarClient.getHorizonTransaction(hash)confirmed / pending / failed with ledger + confirmation count
  • Admin route GET /:id/credentials on admin-users.routes (authGuard + adminGuard), Fastify swagger schema matching the module's existing routes.
  • Cached 30s under a separate credentials:admin-list:<userId> key — deliberately not shared with the user-facing credentials:list: key (different consumer, different TTL).

Notes

  • verification.ledger / verification.confirmations come straight from the Horizon verifier already used by rewards transactions, so no new Stellar client code.
  • Superseded-by-mistake rows can't appear here — credentials has a unique (userId, courseId) index and mint() is the only writer.

Closes #410

Testing

  • New tests/unit/admin/admin-user-credentials.test.ts (4 cases): on-chain resolution paths, the pending-placeholder mapping, cache hit short-circuit, and the 30s TTL. All 4 pass (vitest run).
  • Repo-wide tsc --noEmit is unchanged by this PR (main currently carries its own pre-existing errors; this branch adds no new ones — verified by diffing against a clean worktree of 4765abb).

@ZacLou
ZacLou force-pushed the feat/admin-user-credentials-410 branch from c6b0ea1 to 9d07678 Compare September 4, 2026 06:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7. Add GET /api/v1/admin/users/:id/credentials endpoint

1 participant