summaryrefslogtreecommitdiff
path: root/docs/commercial-readiness.md
diff options
context:
space:
mode:
authorChia <Chia@93.nz>2026-08-05 14:48:00 +1200
committerChia <Chia@93.nz>2026-08-05 14:48:00 +1200
commitcd0dd91ab93653631904f2ea0e574ccde6d60339 (patch)
treec65417b880a3f4a35c504c44edae821bc2122f70 /docs/commercial-readiness.md
parent86b1f42e3c5601ff10621a9779cf0076590797a1 (diff)
add passkey, totp.
Diffstat (limited to '')
-rw-r--r--docs/commercial-readiness.md87
1 files changed, 87 insertions, 0 deletions
diff --git a/docs/commercial-readiness.md b/docs/commercial-readiness.md
new file mode 100644
index 0000000..b78ae2d
--- /dev/null
+++ b/docs/commercial-readiness.md
@@ -0,0 +1,87 @@
+# Commercial readiness gap analysis
+
+This document compares the current gateway and console with the customer-facing
+model catalog at `https://zenmux.ai/models?sort=newest`. It separates working
+capabilities from product gaps so an unfinished control is never presented as a
+commercial feature.
+
+## What works now
+
+- OpenAI Chat Completions and Anthropic Messages proxying, streaming, routing,
+ retry, authentication, persistent usage, prepaid billing, quotas, rate limits,
+ concurrent request limits, RBAC, audit logs, and a PostgreSQL-backed console.
+- Stripe-hosted Checkout with signed, idempotent Webhook crediting. The gateway
+ never accepts card details and never credits a success redirect.
+- PostgreSQL is the source of truth. Redis accelerates invalidation and shared
+ counters but is not required for startup, control-plane writes, billing, or
+ balance correctness.
+- Verified self-service registration, invitation acceptance, password reset,
+ persistent login throttles, per-device session revocation, encrypted email
+ outbox delivery, TOTP with recovery codes, and WebAuthn Passkeys.
+
+## Customer product gaps
+
+### P0 before a public commercial launch
+
+- Production transactional-email provider selection, domain authentication,
+ bounce/complaint handling, low-balance notifications, and monitoring for the
+ durable mail outbox. Local development currently uses Mailpit.
+- A public model catalog and detail page containing provider/developer, release
+ and retirement dates, input/output modalities, context and maximum output,
+ supported parameters and protocols, regional availability, and versioned price
+ dimensions.
+- Tenant and API-key model allowlists, budget alerts, low-balance notifications,
+ downloadable invoices/receipts, payment history, refunds/disputes operations,
+ and explicit tax handling after registrations are confirmed.
+- Operational separation of the public inference listener from the management
+ listener, HTTPS-only cookies behind a trusted proxy, backup/restore drills,
+ migration rollback policy, secret rotation, and alerting for usage settlement
+ or Webhook backlogs.
+- A durable settlement retry/outbox and reconciliation worker. Persistence and
+ balance settlement currently use bounded synchronous database calls after the
+ response; a database timeout is logged but is not queued for retry, so a long
+ outage can leave reservations pending or usage unbilled.
+
+### P1 for ZenMux-like breadth
+
+- OpenAI Responses, Embeddings, Images, Speech and Transcriptions; Gemini native
+ APIs; rerank and other media endpoints. The existing protocol field does not
+ make these APIs implemented.
+- Provider health measurements per model and route: availability, first-token
+ latency, throughput, error history, health-aware routing, and customer-visible
+ status history.
+- Provider comparison and price ranges, cache/search/image/audio pricing units,
+ lifecycle aliases and deprecation notices, searchable filters, release sorting,
+ SDK examples, and copyable endpoint snippets.
+- Usage exports, cost attribution, budgets, scheduled reports, organization
+ invites, custom roles, OIDC/SAML SSO, SCIM, and support impersonation with
+ approval and full audit evidence.
+
+## Environment boundary
+
+Versioned JSON configuration stores only environment variable names for external
+services. Local values live in `.env.debug`, which is ignored by Git and created
+with mode `0600`.
+
+| Integration value | Environment variable |
+| --- | --- |
+| HTTP listen address | `AIGW_SERVER_ADDRESS` |
+| PostgreSQL URLs | `AIGW_DATABASE_URL`, `AIGW_DATABASE_URL_DOCKER` |
+| Redis URLs | `AIGW_REDIS_URL`, `AIGW_REDIS_URL_DOCKER` |
+| Provider credential encryption | `AIGW_CREDENTIAL_KEY` |
+| Bootstrap administrator | `AIGW_ADMIN_TOKEN` |
+| Stripe application key | `AIGW_STRIPE_API_KEY` |
+| Stripe CLI development key | `AIGW_STRIPE_CLI_API_KEY` |
+| Stripe Webhook signing secret | `AIGW_STRIPE_WEBHOOK_SECRET` |
+| Stripe result URLs | `AIGW_STRIPE_SUCCESS_URL`, `AIGW_STRIPE_CANCEL_URL` |
+| Console public URL | `AIGW_PUBLIC_URL` |
+| SMTP endpoint/sender | `AIGW_SMTP_ADDRESS`, `AIGW_SMTP_FROM_ADDRESS` |
+| SMTP credentials | `AIGW_SMTP_USERNAME`, `AIGW_SMTP_PASSWORD` |
+| WebAuthn RP/origins | `AIGW_WEBAUTHN_RP_ID`, `AIGW_WEBAUTHN_ORIGINS` |
+| Static upstream endpoint/key | provider `base_url_env`, `api_key_env` |
+
+External service values are never embedded in versioned JSON. When mail is
+enabled, startup validates the sender and SMTP endpoint; username/password must
+either both be provided or both be empty. Production should use authenticated
+`starttls` or implicit `tls`; the checked-in local example uses unauthenticated
+Mailpit with `tls_mode: none`.