Skip to content

Task 21: Known Issues & Demo Limitations (P1.5.4)

Created: 2026-04-16 Status: Reference for demo day — do not action until post-demo signoff

Purpose

Catalog of known rough edges, sandbox constraints, and intentional POC-scope shortcuts so the demo can be framed honestly and the backlog is transparent. None of these block the MVP flow (create org → KYB → issuer enable → issue Past Employment credential → SES email → claim page + QR). Each row includes: severity, what a reviewer might see, and when it will be fixed.

1. SES Sandbox — Recipient Verification Required

Severity Blocking for anyone-beyond-us
What it looks like Sending to a non-verified email returns 554 Message rejected: Email address is not verified. The following identities failed the check in region AP-SOUTH-1.
Why New AWS accounts sit in SES sandbox by default. Senders and recipients must be verified in the SES Identities page for the region (ap-south-1) before mail leaves the relay.
Fix Request Production Access in the SES console after the POC demo. ~24 hr turnaround. Once granted, any recipient works.

2. CAO Tenant is Shared Across All POC Orgs

Severity Intentional POC scope
What it looks like All organizations created through our platform currently point at the same Velocity CIH tenant 69df3e9a1788f7af31e8edb1 with DID did:web:stagingregistrar.velocitynetwork.foundation:d:curo-rec.test.
Why v3.0 MVP, per the PDF, uses the existing Velocity Registrar dashboard to onboard staffing companies. For the POC we point every org at our CAO DID.
Fix Drop 1 Beta work (see GAP-09 / Task 09): staffing company registers its own org on the Velocity Registrar, gets a unique DID + keys.json, admin pastes those into the Create Organization form. Code already supports per-org DIDs (organizationDid on the DTO).

3. MVP Credential Scope — Past Employment Only

Severity Intentional PDF alignment
What it looks like The "Credential Type" dropdown in the manual-credential form shows only Past Employment Credential. Current / Email / Phone / Drivers License enum entries are defined but filtered out.
Why PDF p.1: "For the MVP, it is expected that only the past employment credential will be supported."
Fix Flip the allowlist in MVP_SUPPORTED_CREDENTIAL_TYPES in credential-template.entity.ts as Drop 1 Beta features come online. No template changes needed — all 5 template bodies already exist.

4. "Issuing Organization: Your Organization" Placeholder

Severity Cosmetic, P4
What it looks like Claim page and credential-offer email body show Issuing Organization: Your Organization instead of the real org name.
Why Hardcoded fallback at manual-credential.service.ts:237 and again at :879. The comment explicitly says // This should come from organization data.
Fix Load organization.name from the already-injected organizationRepository, pass through customVariables.organizationName and credentialOffer.payload.organizationName. ~5 min change. Folded into Task 20 Tier 1.

5. Email Template Zoom / Mobile Rendering

Severity Cosmetic, mobile only
What it looks like On Apple Mail (macOS / iOS) the credential-offer email renders "zoomed in" — button column stretches full-width. Gmail / Outlook Web render cleanly.
Why Template HTML lacks <meta name="viewport"> and the table layout isn't set to a fixed max-width. Mobile clients expand to viewport width instead of capping at a readable 600px.
Fix Add responsive meta + max-width: 600px container + media queries. 1 hr polish task. Tracks as part of Drop 1 Beta branding work (GAP-02).

6. Email Template Seeder Outputs Unrendered Placeholders

Severity Functional bug, low priority
What it looks like Subjects in the email_logs table show literal strings like Your {{credentialTypeName}} is Ready to Claim — not the compiled version.
Why InitializeEmailTemplatesService seeds stock templates at org creation. The service stores the raw template text on the email_logs row, while the actual delivered email is compiled correctly by Handlebars. So the delivered email is fine; the audit log row just looks weird.
Fix Either store the compiled subject on email_logs (cleaner) or remove the seeder + author production-ready templates in the Email Templates admin UI (what we'll actually do). Tracked under Task 20 Tier 2.
Severity Data hygiene
What it looks like The Credentials Dashboard shows in the Deep Link / QR columns for older offers; the claim page for those falls back to a synthetic velocity-network-testnet://... URL.
Why Before we patched the CIH response-shape parser + dropped the VerifiableCredential type wrapper + fixed the stale issuer service, refreshIssueLinks never returned a real URL. New credentials issued from 2026-04-16 13:11 onward store the real redirectUrl.
Fix For the demo, either issue fresh credentials (preferred — cleaner history) or accept on older rows. Optionally run a one-off backfill script: find offers with null deep_link_url + non-null credential_manifest_id, call refreshIssueLinks, persist. Not worth engineering for the POC.

8. Superadmin Cannot Issue Credentials for Arbitrary Orgs

Severity Expected POC scope
What it looks like Logged in as admin@curo.com (role platform_admin, home org "curo"), calling POST /api/v1/issuer/manual-credentials for an employee of Test Kompany returns 404 "Employee not found or does not belong to your organization".
Why Manual-credential controller resolves organizationId from req.user.organizationId — the caller's own org. Superadmin acts as admin of its own (Curo) org, not all orgs.
Fix Intentional: issuance is a staffing-company-admin action, not a superadmin action. If a superadmin needs to issue on behalf of a client (support case), the proper flow is to log in via Auth0 org switching or use the impersonation API (GAP-17 / future work). For the POC demo, log in as the respective org admin.

9. Host Port Mapping Must Match Env

Severity Config footgun
What it looks like Email claim links 404 if FRONTEND_URL doesn't match the host port the frontend is exposed on. Click-tracking returns ERR_CONNECTION_REFUSED if API_BASE_URL points at the wrong port.
Why docker-compose.local.yml maps frontend container port 3000 → host 3001, and backend 8000 → host 8000. .env.development must use host ports, not container ports.
Fix Already set correctly for our setup (FRONTEND_URL=http://localhost:3001, API_BASE_URL=http://localhost:8000). For other environments: CI/CD will template these from deployment config.

10. Organization Detail Page Still Shows Old Orgs with tenant_status=FAILED

Severity Data hygiene
What it looks like E2E Flow Test 1776284410 and a couple of earlier test orgs show FAILED tenant status — their KYB was auto-approved (pre-P1.3.1 bypass code) but tenant creation crashed on placeholder DIDs.
Why Dev data from before the auto-approval bypass was removed.
Fix One-off DELETE on those orgs before demo day, or just navigate around them. Not indicative of current code behavior.

11. KYB Review Is Currently a Status Flip, Not a Document Review

Severity Intentional POC scope
What it looks like SuperAdmin → Update KYB Status → pick approved from dropdown → done. No document upload, no reviewer notes UI, no compliance checklist.
Why PDF p.3: "There will be basic information gathered for the Know Your Business (KYB) checks, as mirrored on the Velocity Network. This will initially take place directly via the Velocity Registrar for the MVP but should be executed via a web form on the platform by the full Beta release." POC treats KYB as a status machine only; full KYB flow is Drop 1 Beta work (GAP-??).
Fix Drop 1: KYB document upload + reviewer notes + audit trail.

12. Ethereal Fallback Kicks In When SMTP Config Missing

Severity Dev-only behavior
What it looks like If someone runs the backend without SMTP_USER set, email.service.ts falls back to nodemailer.createTestAccount() and uses Ethereal. Candidates never receive anything; preview URLs only appear in backend logs.
Why Intentional safety net for local dev. Prevents accidentally wiring production SMTP into a laptop build.
Fix Production deploy must set SMTP_HOST / SMTP_USER / SMTP_PASS / SMTP_FROM — any valid value disables the Ethereal fallback. Noted under Task 20 Tier 2 (remove Ethereal once templates are finalized).
Severity Expected (this is staging)
What it looks like QR codes resolve to https://stagingcih.velocitycareerlabs.io/app-redirect?deeplink=velocity-network-testnet://... — a testnet URL, not mainnet.
Why Our VNF_CIH_API_URL points at stagingcih.velocitycareerlabs.io. Deep links are minted relative to the configured CIH host.
Fix Production: flip the env to prodcih.velocitycareerlabs.io (or whatever Velocity gives us) and mint tenant + issuer service on prod. Must coordinate with Velocity for production credentials.

Demo Talking Points

Frame these up front during the demo so reviewers know what's real vs parked:

  1. "We're on Velocity staging; everything except production SMTP provider (SES sandbox) and a bulk org registration flow is the real path."
  2. "MVP is past-employment only — the PDF is explicit about that. Four other credential types are already template-ready for Drop 1."
  3. "KYB here is a status machine. Document upload + reviewer workflow lands in Drop 1 Beta — that's 1-2 weeks of work."
  4. "Every org's credential is signed by our CAO DID in this demo. At Beta, each staffing company brings their own Velocity DID via the Registrar dashboard."
  5. "Email delivery is live AWS SES; only verified recipient emails work today because we're still in SES sandbox. Production Access request pending."

References

  • Task 10 — Gap Analysis (GAP-01 through GAP-18) lists the Drop 1 / Drop 2 work behind several of these.
  • Task 16 — Existing Flow Audit documents the KYB bypass history that Task 21 #8 references.
  • Task 18 — Master Execution Plan is the source of truth for priority/sequencing.
  • Task 20 — Code Cleanup Audit bundles items #4, #6, #12 into post-demo housekeeping.