Commit graph

15 commits

Author SHA1 Message Date
Grok Bot
74e9183c5c feat(billing): Usage & Billing API for the peergos-flutter app
/portal/api/billing/{summary,usage,estimate,invoices,invoices/:id/pay[/confirm],
payment-methods[/setup-intent|/checkout-session|/:id|/:id/default],po} behind the
portal session; staff routes for storage samples and purchase orders.
Additive tables storage_samples and purchase_orders (CREATE TABLE IF NOT EXISTS).
Card routes 503 without a real Stripe key; nothing charges without customer
confirmation. 9 new tests; full suite 283/283.
2026-10-06 13:26:03 -04:00
Grok Bot
0e41be62ca chore: commit live drift from ns1:/opt/verae/zappier-edge (send-invoices job, overdue email HTML, portal #billing deep link)
These files were running on ns1 but never committed. Copied verbatim so the
next deploy from git does not regress them.
2026-10-06 13:22:22 -04:00
Grok Bot
0895f6bdda docs: add storage billing decisions D7-D12 (hybrid prepaid, Free tier signup, restart OK pre-launch, alerts only, non-payment restriction, pricing.ts authoritative)
Docs only; no runtime code changes.
2026-10-06 13:19:37 -04:00
b1dc6e5093 Merge pull request 'docs: storage overage markup is 25% (x1.25); mark 2026-10-06 storage billing decisions' (#1) from docs/storage-billing-consistency into overdue-negative-balance-only 2026-10-06 08:19:09 -09:00
Grok Bot
cdb4298414 docs: storage overage markup is 25% (x1.25); note 2026-10-06 storage billing decisions
Docs and comments only, no behavior change:
- src/pricing.ts: fix two comments that said +20% / AWS x1.20 (the code is 2500 bps = x1.25)
- tests/peergos-billing.test.ts: fix test title and arithmetic comment (2875 millicents -> 29c, which the test already asserts)
- docs/PEERGOS-BILLING.md: hosted overage AWS x1.25; clarify that the 1.5/0.75 multipliers are timestamp-only; flag the cust-platform default as contradicting D3; add a decisions D1-D6 section
- docs/ACCOUNTING.md, docs/CUSTOMER-PORTAL.md: mark prepaid drawdown as current behavior and note the planned Stripe subscription collection (D1)
2026-10-06 13:04:41 -04:00
1ac4e5539e fix(overdue): payment-request job targets ONLY negative effective balances
- listOverdueCustomers requires effective < 0; zero/positive never listed
- --threshold-cents / OVERDUE_THRESHOLD_CENTS clamped to <= 0 (can only narrow)
- sendPaymentRequests skips any non-negative row (defense in depth)
- tests + docs/NEGATIVE-BALANCE.md updated; dry run remains default
2026-10-05 14:15:38 -04:00
3d40fdeb09 fix: charge /v1/timestamp only after successful stamp
Defer meter recording for single stamps so upstream failures (402/5xx)
do not bill customers. commitMeteredUsage on 2xx/mock; abandonMeteredUsage
zeros X-Verae-Credits-Spend on failure. Batch path unchanged.
2026-10-05 14:08:34 -04:00
ac8b801c7f Merge remote-tracking branch 'origin/admin-customer-password-email-2fa' into negative-balance-stamping
# Conflicts:
#	src/admin.ts
#	src/app.ts
#	src/portal.ts
2026-10-05 14:04:39 -04:00
7abb9d6c36 feat: never gate stamps on prepaid balance; overdue-balance job; $50 signup credit
- Document that 402 QUOTA_EXCEEDED (51/50) is the verae-zapier-middleware shared
  tenant free-plan quota, not a customer balance gate; edge passes it through
  fail-closed (no mock certs).
- tests/negative-balance.test.ts locks in: negative balance_cents still stamps.
- src/jobs/overdue-balances.ts: effective balance = prepaid - unpaid issued
  invoices - unbilled usage; dry-run by default, --send uses existing mailer
  (SMTP_FROM). systemd unit/timer stubs in deploy/systemd.
- src/billing/signup-credit.ts: SIGNUP_CREDIT_CENTS (default 5000) granted on
  new portal signup and admin create via credit ledger + ledgerAdjust;
  idempotent, no double grant on claim; admin create 409 on existing id.
- docs/NEGATIVE-BALANCE.md
2026-10-05 14:03:30 -04:00
e64a9322ac sync: pick up fail-closed Verae cert fix already deployed live (from fail-closed-verae-certs @1107272: src/app.ts, src/upstream.ts, tests) 2026-10-05 14:01:45 -04:00
2f524deea0 feat(auth): password change + reset with emailed 6-digit codes for portal and admin
Customer portal:
- POST /portal/api/password/change (session): currentPassword -> emailed code;
  then {code,newPassword,totpCode?}. TOTP required when enabled. Aliases
  /password/change/start|confirm. Revokes all sessions, returns a new token,
  sends a 'password was changed' notice. Security tab UI replaces the
  'handled by support' card. Capabilities: passwordChange, loginIdentifier=email.

Admin console:
- admin_users gains email (unique, case-insensitive), totp_secret, totp_enabled
  (additive migration). ADMIN_USER_EMAILS backfill env (never overwrites).
- Login by email or legacy username; optional TOTP enforced at login.
- POST /admin/api/password/forgot|reset (no enumeration, emailed code, TOTP if on).
- /admin/api/account: password change (current pw -> code -> new pw), verified
  email change (code to new address), TOTP setup/enable/disable, revoke-others.
- POST /users takes {email,password}; email becomes the username.
  PUT /users/:username/email for other admins. Deactivate revokes sessions.
- UI: Forgot password on sign-in, TOTP prompt, Users -> My account, Set email.

Email-as-username: admin customer create validates/lower-cases email (portal
sign-in name, dup -> 409) and the UI asks for it; portal labels updated.

Shared: src/email-codes.ts, src/admin-sessions.ts, src/admin-account.ts.
Docs: docs/PASSWORD-2FA.md. Tests: tests/password-change-2fa.test.ts.
2026-10-05 14:00:47 -04:00
1107272d38 fix: fail-closed Verae timestamp certificates
Sync live /opt/verae/zappier-edge tree, then stop inventing mock-cert-*
receipts in production.

- When ZAPPIER_UPSTREAM is set and upstream is missing/non-2xx, return
  upstream status (or 502) with error=upstream_timestamp_failed
- Dev-only mock-cert-* behind ALLOW_MOCK_CERTS=true when upstream unset
- Tests for fail-closed single/batch paths; mock tests set ALLOW_MOCK_CERTS
2026-10-05 13:52:37 -04:00
5b37842fee sync: import live /opt/verae/zappier-edge state (2026-10-05) into git 2026-10-05 13:50:26 -04:00
237540c621 docs: bring README.md in line with Standard Readme 2026-09-22 09:58:31 -04:00
0c014036d6 Initial import of zappier-edge from zapier monorepo 2026-09-11 19:53:10 -04:00