-
Notifications
You must be signed in to change notification settings - Fork 9
Description
Goal
Deliver the full Access Keys admin experience in LangRoute: typed data hooks, create (one-time reveal), list with client-side sorting and status badges, edit/revoke/delete with confirms — all aligned to the finalized BE contracts and error envelope.
🎯 Key Deliverables
-
End-to-end, production-quality Access Keys flows:
- Typed React Query hooks (CRUD) with centralized API types.
- Create flow with one-time key reveal (copy allowed only once).
- List view using the shared DataTable (client-side sorting, empty/loading/error states).
- Status badges (Expired > Revoked > Active) and locale-friendly dates.
- Edit (name/description/expiry), Revoke/Unrevoke (confirm), Delete (confirm).
-
Consistent error handling via the standard envelope:
{ "error": { "message": "...", "code": "..." }, "requestId": "…", "ts": "…" } -
DRY utilities where needed (date/status/sort comparators colocated with the first consumer).
🔗 Sub-Issues
- Access Keys — Data hooks (CRUD) + mutation keys + API types #65
- Access Keys — List view + Status badges + Sorting #66
- Access Keys — Create flow refactor + One-time Reveal #67
- Access Keys — Edit / Revoke / Delete #68
✅ Acceptance Criteria (for the epic)
-
API alignment: All FE requests match contracts from the brief:
GET /api/access-keys→ items includelastUsedAt|null,expiresAt|null,preview, timestamps as ISO strings.POST /api/access-keys→ returns fullkeyonce (Reveal dialog required).PATCH /api/access-keys/:id→ accepts any subset of{ name, description, revoked, expiresAt|null }, returns list-item shape.DELETE /api/access-keys/:id→204.
-
Create: One-time reveal modal shows full key with Show/Hide + Copy + “You won’t see this again.” No preview copy button anywhere else.
-
List: Columns = Name · Preview · Description · Status · Expires · Last used · Created · Actions. Default sort Created desc. Client-side column sorting works on the sortable columns.
-
Status logic:
- Expired if
expiresAt < now(takes precedence even if revoked). - Else Revoked if
revoked === true. - Else Active.
- Expired if
-
Edit/Revoke/Delete:
- Edit updates only dirty fields; clearing expiry sends
expiresAt: null. - Revoke/Unrevoke and Delete use confirm dialogs.
- List refreshes or updates optimistically.
- Edit updates only dirty fields; clearing expiry sends
-
UX quality bar:
- Inline Zod errors for client validation; server errors shown via toast using
error.message. - Loading skeletons and empty states present.
- Locale-friendly date rendering; “—” for nulls; absolute timestamp in tooltip.
- Accessible header buttons with
aria-sort, visible focus states.
- Inline Zod errors for client validation; server errors shown via toast using
📦 Dependencies & Order of Work
- Reusable DataTable with client-side sorting #63
- Access Keys — Data hooks (CRUD) + mutation keys + API types #65
- Access Keys — List view + Status badges + Sorting #66
- Access Keys — Create flow refactor + One-time Reveal #67
- Access Keys — Edit / Revoke / Delete #68
#65 can start in parallel with #63. #67 should target DataTable once #63 is merged (or use a feature branch base).
📌 Notes
-
Terminology: UI labels and code say Access Key. “Virtual key” may appear only in explanatory copy (not labels or identifiers).
-
Provider config: Current create sheet’s provider fields must be extracted and parked (reusable
ProviderConfigSection) but not rendered yet. -
DRY placement:
- Central API shapes live with Access Keys — Data hooks (CRUD) + mutation keys + API types #65.
- Date/status utilities land with Access Keys — List view + Status badges + Sorting #66 (first usage).
- Reusable ConfirmDialog is added in Access Keys — Edit / Revoke / Delete #68 and reused for Revoke/Delete (and future dialogs).
-
No new dependencies for this phase (DataTable is shadcn-based).
When all sub-issues (#65–#68) are closed and verified, this parent will be marked complete.