# 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`.