Appearance
User Account Service (UAS)
UAS — User Account Service
Identity: users, emails, passcodes, and payment methods. Public stat lives on API Gateway; all other operations are direct Lambda (CLI wraps them).
Surface map (contract-only)
- Public API (API Gateway):
POST https://api.g3nretailstack.com/uas/stat→ user snapshot (requiresemail+passcode; nouser_id-only mode). Optionalcccodemay be provided in body orx-cccodeheader and is validated/canonicalized; mismatch → 400. - Direct Lambda actions:
userCreate,userSnapshot(userGet),userStatusSet,userConfigSet, email (emailAdd/list/setPrimary/issueToken/confirmToken/doom), passcode (passcodeSet/reset), payment methods (pmCreate/list/setStatus/promote/demote/doom/vacateToken). - CLI:
cli/bin/g3n.js(g3n uas ...), requires--profile; optional--region; JSON output by default. Calls the same Lambdas. - Pagination: list calls (
emailList,pmList) default to limit 8, clamp 1–256, return opaquenext_token. - Email canonicalization: email inputs are trimmed + lowercased; duplicates are case-insensitive and stored emails are canonical.
- MCP: unauthenticated protocol doc at https://mcp.g3nretailstack.com/uas/PROTOCOL.md (mirrored to /uas/PROTOCOL.md here).
- OpenAPI:
https://doc.g3nretailstack.com/uas/openapi.yaml - Optimistic concurrency (revision): any state-changing action on an existing user requires
expected_revision(userevisionreturned bystat/userGet). Missing →428 expected-revision-required; mismatch →409 conflictwitherror.details.{provided_revision,current_revision,current_record}.
Responses share { success, data?, error?, build, stats? } with build_id + UTC timestamp shown in every footer. Stats include call, service, request_id, timestamp_utc, latency_ms, and passthrough context when provided (direct Lambdas forward orgcode/cccode verbatim; /stat validates cccode).
Record lifecycles and operations
User + status FSM (unverified → verified ↔ suspended → doomed)
- Create (
userCreate): issue a user with email + passcode; returnsuser_idandaccount_ref. Use to onboard new identities. Errors:duplicate-email,validation-error. - Snapshot (
userSnapshot/userGet): fetch current user/emails/payment methods; optionally include payment history. - Status (
userStatusSet):{ user_id, status, expected_revision, reason?, actor? }. Allowed transitions: unverified→verified, unverified→doomed, verified↔suspended, suspended→doomed, verified→doomed. Verified requires verified primary email + passcode set. Errors:invalid-transition,not-found. - Session cap (
userConfigSet):{ user_id, max_active_sessions: number|null, expected_revision, reason?, actor? }(32–8192 when set; null clears). Errors:validation-errorfor out-of-range values. - Use case: create → verify email → set verified → set per-user session cap if needed → consume via USM for sessions.
Example (direct Lambda payload):
json
{ "email": "user@example.com", "passcode": "Abcd!234", "caption": "Retail staff iPad", "actor": "ops-user" }Response: { "success": true, "data": { "user_id": "u123", "account_ref": "..." }, "build": {...}, "stats": {...} }
Emails (unverified ↔ verified → doomed; primary required)
- Add/list (
emailAdd/emailList):emailAddrequires{ expected_revision }; list is paginated. Duplicate emails across users are rejected. - Verify (
emailIssueToken→emailConfirmToken): both require{ expected_revision }. Issue verification token (last token wins, 48h validity). Confirm marks email verified; if primary is verified, user can be verified. Errors:invalid-token,token-expired,duplicate-email,validation-error. - Primary (
emailSetPrimary): requires{ expected_revision }. One primary email per user; primary cannot be doomed. If primary becomes unverified, user status cannot be verified. - Doom (
emailDoom): requires{ expected_revision }. Terminal; doomed emails cannot be primary. Errors:invalid-transition,not-found. - Use case: add secondary email → set primary → issue/confirm token → rotate primary as needed (re-verify new primary).
Example (confirm token):
json
{ "user_id": "u123", "token": "base64token", "expected_revision": "rev-123", "actor": "ops-user", "reason": "email-verify" }Response: { "success": true, "data": { "email": "user@example.com", "status": "verified" }, "build": {...}, "stats": {...} }
Passcodes (set/reset)
- Set/reset (
passcodeSet/passcodeReset):{ user_id, passcode, expected_revision, reason?, actor? }. Enforces policy (length ≥8 with upper/lower/number/special) and reuse guard. Errors:passcode-policy-failed,passcode-reuse,validation-error. - Use case: set during onboarding; rotate on compromise; reset after verification.
Payment methods (pending → active ↔ suspended → doomed)
- Create/list (
pmCreate/pmList):pmCreaterequires{ expected_revision }; uniqueness on processor+token_type+token; list is paginated and ordered (active, pending, suspended, doomed). Errors:payment-uniqueness-conflict,validation-error. - Status (
pmSetStatus,pmPromote,pmDemote,pmDoom): require{ expected_revision }. Manage lifecycle. Doomed removes token and is terminal. - Default ordering: first active; else first pending; else first suspended; never doomed.
- Vacate token (
pmVacateToken): requires{ expected_revision }. Nulls stored token for a doomed/retired PM. Errors:not-found,invalid-transition. - Use case: add PM → promote to active → demote/suspend as needed → doom or vacate when revoked.
Example (promote):
json
{ "user_id": "u123", "pm_id": "pm_abc", "expected_revision": "rev-123", "reason": "set-default", "actor": "ops-user" }Response: { "success": true, "data": { "pm_id": "pm_abc", "status": "active" }, "build": {...}, "stats": {...} }
Error tags (representative)
duplicate-email,invalid-token,token-expired,invalid-transition,passcode-policy-failed,passcode-reuse,payment-uniqueness-conflict,not-found,validation-error,unauthorized,internal-error.
See Surfaces for per-operation request/response examples, accepted/rejected transitions, and CLI usage. For protocol-level detail, consult the MCP doc.