# System Plan ## Summary Build `nproxy`, a B2C web product for image generation through external model APIs. The first model is `nano_banana`. Users register with `email + password`, pay a monthly crypto subscription, receive a monthly request limit, and use a chat-style interface for `text-to-image` and `image-to-image` generation. The service hides provider-key failures behind a routed key pool. A user request is attempted against one provider key at a time. Retryable failures move execution to the next eligible key. The user sees an error only after all eligible keys have been exhausted or the request fails for a terminal user-caused reason. ## Confirmed product decisions - One B2C website. - One monthly subscription plan. - Crypto checkout through a payment processor. - Manual renewal. - Text-to-image and image-to-image. - User-facing synchronous experience implemented with polling over background execution. - Approximate quota buckets only: `100/80/60/40/20/0`. - Storage in S3-compatible object storage. - One VPS deployment with Docker Compose. - Web admin plus Telegram admin bot. - Telegram admin onboarding through pairing on the server console. - Multiple provider API keys with round-robin routing, cooldown, balance tracking, optional per-key proxy, and transparent failover. ## Core product surfaces ### Public web - landing page - register / login / password reset - dashboard with subscription state and approximate quota - chat UI - billing / checkout pages ### Admin surfaces - web admin for users, subscriptions, payments, generations, provider keys, proxies, and health - Telegram bot for alerts and low-friction admin actions - CLI for server-side operational commands, including Telegram pairing ## Main backend domains - auth - billing - subscriptions - quota ledger - conversations and generations - provider routing - provider key pool health - asset storage - admin audit - notifications ## Billing rules - One active plan. - Access ends immediately when `currentPeriodEnd` is reached. Warnings may be sent beforehand, but there is no grace period after expiry. - Each user has an individual billing cycle based on successful activation timestamp. - Limit resets on each successful cycle activation. - One successful generation consumes one request. - Failed generations do not consume quota. ## Quota display contract Backend tracks exact usage. Normal users see only an approximate bucket: - `81-100%` remaining -> `100%` - `61-80%` remaining -> `80%` - `41-60%` remaining -> `60%` - `21-40%` remaining -> `40%` - `1-20%` remaining -> `20%` - `0%` remaining -> `0%` ## Generation controls - mode: `text_to_image` or `image_to_image` - resolution preset - batch size - image strength for `image_to_image` ## Key pool behavior - Start from the next `active` key by round robin. - Use the key-specific proxy first if configured. - If the proxy path fails with a transport error, retry the same key directly. - Retry on the next key only for retryable failures: network, timeout, provider `5xx`. - Do not retry on the next key for validation, policy, or other user-caused `4xx` errors. - Move a key to `cooldown` on retryable failures. - Default cooldown is `5 minutes`. - After more than `10` consecutive retryable failures across cooldown recoveries, move the key to `manual_review`. - Move a key to `out_of_funds` when the provider balance API or provider response shows insufficient funds. - `out_of_funds` and `manual_review` keys return to service only through a manual admin action. ## Telegram pairing 1. A Telegram user opens the bot. 2. If the user is not in the allowlist, the bot generates a short pairing code and stores a pending pairing record. 3. The bot tells the user to run `nproxy pair ` on the server. 4. The server-side CLI confirms the target user and adds the Telegram ID to the allowlist. 5. The pairing record is marked complete and the user gains bot access. ## Deployment target Single VPS with Docker Compose, expected services: - `web` - `worker` - `bot` - `postgres` - `caddy` or `nginx` - optional `minio` when object storage is self-hosted ## Optional extensions These are not current commitments. Consider them only if user demand, operational need, and product scale justify the added complexity: - more image providers - more billing methods - more subscription plans - internal balance wallet - recurring billing if the payment processor supports it natively