Appearance
User Account Service (UAS) Docs
Target host: doc.g3nretailstack.com (VitePress → S3/CloudFront with post-deploy invalidation). Service is implemented and deployed; this doc mirrors the live handlers.
Overview
- Class: Core microservice. Direct Lambda for most ops; public API Gateway only for
/uas/stat. - Data: DynamoDB
uas_mainsingle-table; GSIs for email uniqueness, account ref, payment ordering. Events to EventBridgeuas-events; change logs to S3 via Firehose. - Runtime: Node.js 24, ARM64; argon2 native module pinned at 0.40.3 and bundled via CDK command hooks (
npm_config_platform=linux npm_config_arch=arm64 npm install argon2@0.40.3) so Lambdas ship with the correct binary. Responses/events carry build metadata and stats.orgcodeis opaque passthrough only.cccodeis validated/canonicalized on the public/uas/statAPI Gateway surface (body/header mismatch → 400); direct Lambda actions treatcccodeas passthrough only. Bearersession_guidtokens are treated as secrets and are not emitted in responsestatsor tenant events/audits.
Surfaces
- Public API:
POST https://api.g3nretailstack.com/uas/stat→ user snapshot. Payload{ email, passcode, include_payment_history?, actor? }(email inputs canonicalized: trim + lowercase; optional passthrough accepted:orgcode,cccode;cccodemay also be provided viax-cccodeheader and must match^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$; body/header mismatch → 400). - Direct Lambda (CLI/SDK): actions
userCreate,userGet/userSnapshot,userStatusSet, email (emailAdd/list/setPrimary/issueToken/confirmToken/doom), passcode (passcodeSet/reset), payment methods (pmCreate/list/setStatus/promote/demote/doom/vacateToken). - CLI (in-repo
cli/bin/g3n.js): mirrors direct actions with--profilerequired. - Optimistic concurrency: for any state-changing action on an existing user record, caller must provide
expected_revisionmatching the current recordrevision(fromstat/userGet). Missing →428 expected-revision-required; mismatch →409 conflictwitherror.details.{provided_revision,current_revision,current_record}.
Response envelope
json
{
"success": true,
"data": {},
"build": { "build_major": "MONDAY", "build_minor": "<epoch>", "build_id": "MONDAY-<epoch>" },
"revision": "...",
"stats": {
"call": "...",
"service": "uas",
"request_id": "...",
"timestamp_utc": "...",
"latency_ms": 12,
"ddb_calls": 3,
"actor": "...",
"user_guid": "...",
"orgcode": "...",
"cccode": "..."
}
}Domain rules (summary)
- User FSM: unverified→verified/suspended; doomed is terminal; primary email must be verified for verified status.
- Emails: last token wins; primary cannot be doomed; doomed TTL 31d.
- Passcodes: Argon2id, 8+ chars upper/lower/number/special; no reuse within 90d.
- Payment methods: statuses pending/active/suspended/doomed; uniqueness on processor+token_type+token; ordering active>pending>suspended>doomed; status_history required.
- Eventing: emit success/failure events; change logs to versioned S3 (1y).
Publishing notes
- Build static docs with VitePress (
npm run docs:build) → S3 bucket behind CloudFrontdoc.g3nretailstack.com; invalidate CloudFront after publish. - Keep external-facing protocol doc synced at
uservice/uas/mcp/PROTOCOL.mdformcp.g3nretailstack.com. - Contract test hook:
npm run test:uasexercises the deployed Lambdas directly (seeQA.mdfor latest run).