# iMakeFun — implementation baseline v2

This document supersedes conflicting URL, repository, plan and release-scope decisions in `architecture.md`. The exact updated request is retained in `product-requirements-v2.md`. Architecture describes the target; the delivery status below identifies running code.

## 1. Monorepo

```
apps/
  web/                 Next.js public website and /app client (planned)
  mobile/              React Native/Expo iPhone, iPad, Android (planned)
  admin/               Next.js admin client served at /admin (planned)
services/
  api/                 implemented NestJS API
  ai-gateway/          implemented typed adapter registry, no live adapter yet
  image-worker/        planned BullMQ image consumer
  video-worker/        planned BullMQ video consumer
  audio-worker/        planned BullMQ audio consumer
  render-worker/       planned isolated FFmpeg renderer
packages/
  ui/                  planned accessible UI primitives
  database/            SQL migrations, typed Kysely repositories and integration tests
  authentication/      implemented password/verification/recovery/session services
  billing/             implemented transactional credit repository
  storage/             server-only adapter contract
  ai-sdk/              typed provider requests, capabilities and outcomes
  validation/          implemented strict Zod request schemas
  shared/              application errors and route constants
  core/                retained original domain code and tests
infrastructure/
  docker/              API image, root compose.yaml
  deployment/          production topology and release gates
  monitoring/          signal and alert plan
  ci/                  CI documentation; workflow in .github/workflows
scripts/               checksum migration runner, runtime-role provisioning
```

The old `apps/api`, `apps/worker` and `infra` directories are migration notes only. Their replacements above are authoritative. Do not deploy duplicate services.

## 2. Database and ORM layer

PostgreSQL is the system of record. Kysely provides strictly typed queries; parameterized SQL expresses accounting locks and RLS precisely. This satisfies the requested ORM/query layer without maintaining a competing Prisma schema alongside reviewed SQL migrations. Migration 0001 is retained unchanged from the initial project; 0002 adds the platform entities and 0003 allows authenticated membership discovery. Schema migrations have checksums and an advisory lock. Runtime never uses migration-owner credentials.

The schema includes users, profiles, sessions, OAuth accounts, subscriptions, plans, payments, invoices, wallets/transactions, projects/members/versions, media and subtypes, films/scenes, characters/references, storyboards/frames, prompts, generations/jobs, providers/models, collections/items, favorites, publications, followers, comments, likes, teams/members, notifications, API keys, audit logs, reports, moderation cases, exports and webhooks. `credit_wallets`, `credit_transactions`, `teams`, and `team_members` are security-invoker views over the original accounting and workspace tables, avoiding two competing sources of truth.

Tenant-owned references use compound workspace keys. RLS isolates project/media/financial tables; identity tables are backend-only and queries must constrain user ownership. SQL privileges restrict the API role to implemented features. Platform schema is broader than currently exposed functionality; table existence does not imply a feature is complete. There are no fabricated prices, provider credentials, users or credit grants seeded at startup.

## 3. API endpoint map

Canonical API: **https://api.imakefun.com/v1/**. All applications use this API. See `api-endpoints.md` for exact implemented routes and the planned resource map. Browser requests use credentials plus a host-only API cookie; mutations require the exact configured web Origin, and authenticated mutations additionally require X-CSRF-Token. X-Workspace-Id is only a selector; membership is verified server-side.

## 4. Authentication

Implemented: registration, normalized email lookup, scrypt password hashing (N=32768, r=8, p=1), verified-email login, random 256-bit session tokens stored as hashes, single-use hashed verification/reset tokens, session list/revocation, logout, profile read/update, and reset revoking all active sessions. Reset tokens expire after 30 minutes, verification after 24 hours, sessions after 24 hours. Passwords require 12–128 characters. Verification/reset emails use a fragment token to avoid HTTP access logs; future web forms must POST the token and clear the fragment after processing.

Email dispatch is real SMTP. Local Compose uses Mailpit so messages can be inspected without external delivery. Delivery currently happens after database commit; a delivery outage requires the resend endpoint. Durable encrypted mail outbox/retries are a production launch requirement. Registration and recovery return generic responses for unknown/existing addresses; side-channel/rate-limit testing remains required.

CSRF values are derived from the unexposed session token and can be retrieved from `/auth/csrf` after reload. No secrets are placed in frontend configuration. Google/Apple/Microsoft OIDC, MFA, device detail enrichment, account data export/deletion and mobile token rotation remain later authentication work. OAuth requires PKCE, state, nonce, exact redirect allowlists and verified account-linking; never link accounts only on an unverified email claim.

## 5. AI provider abstraction

`packages/ai-sdk` defines 13 operation types, capabilities, provider submission/inspection/cancellation and explicit unknown-outcome responses. `services/ai-gateway` provides a registry and capability check. No adapter is enabled by default and no AI endpoint returns fake output. Provider administration will select a registered adapter, immutable model revision, region, licensing policy, pricing and priority from the database. New provider protocols require a reviewed adapter, not a UI rewrite.

A worker must validate model resolution/duration/format, workspace entitlement and region before submission. Network ambiguity goes to reconciliation. Unknown outcomes must not trigger automatic paid fallback. Download URLs from providers pass an allowlisted, SSRF-protected fetcher and output moderation before publication.

## 6. Generation jobs

Durable flow: validate → moderate → quote → lock wallet → reserve → create generation + outbox → commit → dispatcher → BullMQ worker → provider → validate/store/moderate result → settle + complete + outbox → SSE/WebSocket. Workers persist attempts, provider request IDs and lease tokens. Cancellation is requested first and confirmed separately; user-visible status cannot imply cancellation of unconfirmed provider work.

The schema, domain state guards and atomic reservation/outbox repository are implemented. Redis is in local Compose. BullMQ dispatch/consumers, provider reconciliation, media finalization and real-time delivery are not implemented. Do not accept paid generation requests until those pieces are connected and tested.

## 7. Credits

Credits use PostgreSQL bigint and TypeScript bigint internally, decimal strings in JSON. `grant` serializes wallet access and deduplicates external event references. `reserveGeneration` atomically creates generation, hold and outbox under a request hash/idempotency key. `settleGeneration` debits once, releases the unused hold and writes terminal job/outbox state. These are internal repository operations in a caller-owned transaction, not public billing endpoints. The caller must verify price/moderation/entitlement before reservation and worker lease/output validity before settlement.

Available credits = balance − reserved. No grant on a browser success redirect. Pricing stays in model/plan versions; never charge a client-supplied amount. Expiring credit lots, refunds, chargebacks and admin adjustments require additional application services before commercial sale. Embedded PostgreSQL tests cover replay, rollback, over-budget rejection and ledger conservation; native PostgreSQL multi-connection race tests remain a release gate.

## 8. Payments

Updated plan names: Free, Creator, Pro, Studio, Business, Enterprise. Stripe and PayPal are both in requested Version 1. Neither integration is implemented yet. Their adapters must verify raw-body signatures, durably accept webhook events, deduplicate processor/event ID, tolerate out-of-order delivery, reconcile invoice/subscription state and grant credits once on settled payment. Hosted checkout/portal handles payment details. Apple Pay/Google Pay are payment methods when supported; they are distinct from mobile store purchase rules. Mobile digital credit/subscription purchases need a store-policy-specific billing implementation and receipt verification before release.

Prices, quotas, provider license rights, tax and merchant regions are launch decisions, not invented constants. Subscription state never bypasses license restrictions.

## 9. Storage

Private S3/R2 object storage holds bytes; PostgreSQL holds metadata. A server-only `StorageProvider` contract covers constrained uploads, HEAD/inspection, signed download and deletion. Upload flow requires an authorized project, available quota, opaque generated key, size/type/checksum checks, quarantine scan and moderation before ready state. Large files use multipart upload. Storage adapters and upload endpoints remain to be implemented. Do not expose R2_PUBLIC_URL for private assets or treat possession of a filename as authorization.

## 10. Web routes and SEO

Canonical public root: **https://www.imakefun.com**. Route manifest is in `packages/shared/src/routes.ts`; it covers all requested public and private routes. Root homepage uses the requested headline “Create images, videos and films with AI.” and Start Creating / Explore AI Tools actions when implemented. Website, creator app and admin must call the same API.

Public pages need unique title/description, canonical URL, semantic H1, Open Graph/X text metadata, sitemap and robots. No social image is generated by this code. `/app`, `/admin`, authentication screens, verification/reset links and API responses are noindex. Authenticated data must never enter public Next.js caches. Public creator media uses an approved publication projection, never direct RLS bypass from a public controller.

## 11. Admin routes

`/admin/` plus users, profiles, subscriptions, payments, credits, providers, models, jobs, storage, reports, moderation, publications, templates, support, api-usage, errors, audit, revenue and costs. Admin route names exist as a manifest only. No default admin is created. Admin authorization requires platform roles distinct from workspace roles, MFA/step-up, audited actions, reasoned financial adjustments and separate privileged service methods.

## 12. Mobile architecture

React Native + Expo + TypeScript, one app for iPhone/iPad/Android using shared request contracts and `https://api.imakefun.com/v1`. Responsive tablet review and project browsing; advanced multitrack film editing initially remains desktop.

Use Expo AuthSession for OIDC authorization code + PKCE and SecureStore for rotating refresh tokens; keep short-lived access tokens in memory. Do not embed provider keys or reuse browser cookies as a native authentication shortcut. Deep/universal links must bind to the app and verified domain. Pause/resume uploads safely; persist only draft metadata locally, clear account-scoped caches on logout, and use push notifications for completed jobs after opt-in. Do not background-poll continuously. Native authentication endpoints, purchase receipts, push delivery and actual screens are not implemented in this phase. `apps/mobile/README.md` specifies the implementation order.

## 13. Docker and local environment

`compose.yaml` starts PostgreSQL, Redis, SMTP inbox, a one-shot migration/provisioning job and the API. API image uses a non-root runtime user. The API DB role has no ownership, superuser or RLS-bypass permissions. Local ports bind to 127.0.0.1. Generate local passwords in `.env`; never reuse production keys.

Docker is not installed in the current authoring environment, so the image/Compose runtime has not been executed here. CI builds the image; a full native PostgreSQL/Redis/SMTP smoke test remains required. Tests use PGlite's PostgreSQL engine, real SQL migrations and a restricted runtime role, not an in-memory JavaScript database fake.

## 14. Environment specification

`.env.example` distinguishes active API configuration from future integrations. Active: APP_URL, API_URL, NODE_ENV, PORT, DATABASE_URL, SMTP settings, MAIL_FROM. Migration-only: DATABASE_ADMIN_URL, APP_DB_PASSWORD. Local Compose: POSTGRES_PASSWORD. Future: REDIS_URL, OIDC, R2, Stripe, PayPal, AI provider keys. Public NEXT_PUBLIC_/EXPO_PUBLIC_ values contain only API origins.

Production refuses non-HTTPS origins and missing SMTP identity configuration. Store secrets in the deployment secret manager with rotation/audit. No JWT secrets are required by the current opaque-session implementation; add signing keys only with a reviewed native access-token design. Deployed systems must validate required integration configuration before enabling each capability.

## 15. Production deployment

DNS: www → public web origin, api → API ingress, media → signed CDN; apex redirects to www preserving path/query. Obtain provider-issued DNS targets and verify certificates before cutover. No DNS changes have been made.

Use managed containers, managed PostgreSQL with backups/PITR, managed Redis, private object storage, CDN/WAF, SMTP and secret manager. Web/API scale independently of provider/CPU/GPU workers. Configure exact-origin CORS, distributed rate limits and trusted proxy handling at ingress. The current local process limiter is only a backstop; horizontal production scaling needs a shared limiter. Add OpenTelemetry, error reporting without prompts/secrets, queue age alerts, credit/processor reconciliation and restore drills. Release migrations with expand/contract compatibility and canary application traffic. Kubernetes is deferred until operations/scale warrant it.

## Current delivery and next modules

Implemented and tested: strict TypeScript build, request schemas, PostgreSQL migrations, email/password lifecycle, revocable browser sessions, profile read/update, tenant-scoped project create/list/rename/archive, optimistic writes, transactional credit repository and provider interfaces. Docker, CI, routes, endpoint map and environment scaffolding are present.

Next in the requested order: finish authentication production hardening (OIDC/MFA/privacy operations and durable email), cloud uploads/media, credentialed provider adapters, generation workers/realtime, billing adapters, public/creator web UI, admin UI and native app. These are not represented as completed by empty folders or contracts. The requested Version 1 remains larger than the initial MVP suggested in the earlier architecture; the new Version 1 list is authoritative.
