docs/architecture/user-billing-admin.md
User, Billing, And Admin
This slice covers Cognito registration, profile/tank data, tank-level target ranges, Stripe, free Pro grants, admin configuration, admin costs, and support tooling.
Signup, Profile, And Billing
sequenceDiagram
participant User
participant UI as Landing / Profile UI
participant Cognito as Amazon Cognito
participant SES as Amazon SES no-reply@reefamatic.com
participant Pre as user-cognito-pre-register
participant Post as user-cognito-post-register
participant API as REST API Gateway
participant Profile as user-get/save-user-profile
participant Ranges as user-target-ranges
participant Checkout as user-billing-checkout
participant Portal as user-billing-portal
participant Webhook as user-billing-webhook
participant Stripe as Stripe
participant UserTable as env-user
participant TankTable as env-user-tank
participant Friend as env-friend-access-grant
User->>UI: Select Free Trial, Basic, or Pro
UI->>Cognito: Create account
Cognito->>SES: Send verification code
Cognito->>Pre: Pre-registration checks
Cognito->>Post: Post-confirmation
Post->>Friend: Check email grant
Post->>UserTable: Create user, tier, trial/friend state
Post->>TankTable: Create/default tank profile
User->>UI: Open profile or complete checkout
UI->>API: POST /user or /user/save
API->>Profile: Invoke
Profile->>UserTable: Read/write profile
Profile->>TankTable: Read/write tank
UI->>API: POST /user/target-ranges
API->>Ranges: List/save/reset versioned tank target ranges
UI->>API: POST /user/billing/checkout
API->>Checkout: Invoke
Checkout->>UserTable: Read Stripe customer, pending checkout, and subscription state
alt Existing open checkout session
Checkout->>Stripe: Retrieve checkout session
Checkout-->>UI: Reuse checkout URL
else Existing active Stripe subscription
Checkout->>Stripe: Create billing portal session
Checkout-->>UI: Portal URL
else New paid subscription
Checkout->>Stripe: Create checkout session with idempotency key
Checkout->>UserTable: Store Stripe customer and pending checkout session state
end
Stripe->>API: POST /user/billing/webhook
API->>Webhook: Verify and process event
Webhook->>UserTable: Store subscription tier/status/price ids and clear pending checkout state
UI->>API: POST /user/billing/portal
API->>Portal: Invoke
Portal->>Stripe: Create billing portal sessionAdmin Console
flowchart LR
subgraph UI["Admin UI"]
ADMIN["Admin page"]
USERS["Users with nested tanks"]
COSTS["Usage + Costs"]
CONFIG["Runtime config"]
ERRORS["Application errors"]
FRIENDS["Friend Pro access"]
FEEDBACK["RaM draft feedback"]
VERSION["Version + release notes"]
end
subgraph API["REST API Gateway"]
OVERVIEW["POST /user/admin/overview"]
COSTAPI["POST /user/admin/costs"]
CFGGET["POST /user/admin/config"]
CFGSAVE["POST /user/admin/config/save"]
ERRLIST["POST /user/admin/errors"]
ERRCLEAR["POST /user/admin/errors/clear"]
FRIENDAPI["POST /user/billing/friend-access"]
end
subgraph Lambdas["Lambdas"]
L_OVERVIEW["user-admin-overview-get"]
L_COSTS["user-admin-costs-get"]
L_CFGGET["user-admin-config-get"]
L_CFGSAVE["user-admin-config-save"]
L_ERRLIST["user-admin-errors-list"]
L_ERRCLEAR["user-admin-errors-clear"]
L_FRIEND["user-billing-friend-access"]
end
subgraph Data["DynamoDB + AWS"]
USER["env-user"]
TANK["env-user-tank"]
TESTH["env-test-history"]
DOSEH["env-dose-history"]
PROGH["env-program-history"]
APPERR["env-app-error"]
USAGE["env-usage-event"]
APPCFG["env-app-config"]
FRIEND["env-friend-access-grant"]
DRAFTFB["env-program-draft-feedback"]
WS["env-websocket-connections"]
CE["AWS Cost Explorer"]
end
ADMIN --> USERS
ADMIN --> COSTS
ADMIN --> CONFIG
ADMIN --> ERRORS
ADMIN --> FRIENDS
ADMIN --> FEEDBACK
USERS --> OVERVIEW --> L_OVERVIEW
FEEDBACK --> OVERVIEW
COSTS --> COSTAPI --> L_COSTS
CONFIG --> CFGGET --> L_CFGGET
CONFIG --> CFGSAVE --> L_CFGSAVE
ERRORS --> ERRLIST --> L_ERRLIST
ERRORS --> ERRCLEAR --> L_ERRCLEAR
FRIENDS --> FRIENDAPI --> L_FRIEND
L_OVERVIEW --> USER
L_OVERVIEW --> TANK
L_OVERVIEW --> TESTH
L_OVERVIEW --> DOSEH
L_OVERVIEW --> PROGH
L_OVERVIEW --> APPERR
L_OVERVIEW --> USAGE
L_OVERVIEW --> DRAFTFB
L_OVERVIEW --> WS
L_COSTS --> CE
L_COSTS --> USAGE
L_CFGGET --> APPCFG
L_CFGSAVE --> APPCFG
L_ERRLIST --> APPERR
L_ERRCLEAR --> APPERR
L_FRIEND --> FRIEND
L_FRIEND --> USERNotes
- Free Trial accounts get a 7-day app trial, 3 total uploads, and Pro functionality during the trial.
- Paid subscriptions use recurring Stripe monthly or annual prices.
- Checkout creation is backend guarded to avoid duplicate subscriptions. The checkout lambda reuses an open pending Checkout Session, redirects existing subscribers to the billing portal, uses Stripe idempotency keys for customer/session creation, and clears pending checkout metadata when webhook subscription state arrives.
- Promotion code
RAM_2026applies 50% off for the first year. - Friend access grants Pro-level access without admin permissions.
- Canceled or inactive Stripe subscriptions retain user/tank/history data but remove effective app access.
- Admin costs combine AWS Cost Explorer actuals with RaM per-PDF usage-event attribution.