summaryrefslogtreecommitdiff
path: root/docs/commercial-readiness.md
blob: b78ae2dab3bb5927f00176135dc34dfa14622b1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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`.