# Mizan Roadmap ## v1 — Django + React ### Done - **@client decorator** — `context=`, `affects=`, `auth=`, `websocket=` - **ReactContext class** — type-safe context/affects references with linting - **Named contexts** — functions sharing a context name are grouped into one provider and one fetch - **Context bundling endpoint** — `GET /api/mizan/ctx//` returns all functions in one response - **Server-driven invalidation (JSON body)** — mutation responses carry `{"result": ..., "invalidate": [...]}` - **Scoped invalidation** — runtime supports `invalidate: [{context: "user", params: {user_id: 5}}]` - **Param elevation** — shared params become required provider props, non-shared become optional - **Schema export** — `x-mizan-functions` + `x-mizan-contexts` for codegen - **Auth guards** — `auth=True`, `auth='staff'`, `auth='superuser'`, `auth=callable` - **JWT + session auth** — auto-detected, CSRF handled - **Shapes** — Pydantic + django-readers for typed query projections - **WebSocket channels** — real-time bidirectional communication - **Codegen** — generates typed React providers, hooks, mutations from schema - **CDN-ready headers** — `Cache-Control`, `Vary`, deterministic JSON on context GETs, `no-store` on mutations ### Next: X-Mizan-Invalidate Header Second invalidation transport. For view responses (redirects, HTML), invalidation goes in an HTTP header instead of the JSON body. Both transports are first-class AFI spec. - Header format: `X-Mizan-Invalidate: user;user_id=5, notifications` - Comma-separated contexts, semicolon-separated params per context - Decorator auto-adds header to any HttpResponse with `affects=` - Edge reads this header to purge cached pages - Runtime also reads it on XHR/fetch responses (htmx path) ### Next: Return-Type Branching `@client` serves both RPC developers (React/SPA) and view developers (htmx/templates). Return type determines behavior: - **Data return** (dict, Shape, BaseModel) → RPC path. Generates typed hooks. Invalidation in JSON body. - **HttpResponse return** (render, redirect) → View path. No codegen. Invalidation in `X-Mizan-Invalidate` header. Same decorator. Same `affects=`. Same invalidation graph. Two paths. ### Next: affects_params Scoped invalidation with a lambda that extracts which params were affected: ```python @client(affects='user', affects_params=lambda req: {'user_id': req.user.pk}) def update_name(request, name: str) -> dict: ... ``` Produces `invalidate: [{context: "user", params: {user_id: 5}}]` in JSON body or `X-Mizan-Invalidate: user;user_id=5` in header. ### Next: Edge Manifest `mizan-generate --manifest` compiles the decorator registry + Django URL conf into static JSON for Edge: ```json { "contexts": { "user": { "endpoints": ["/api/mizan/ctx/user/"], "views": ["/profile/:user_id/"], "params": ["user_id"] } } } ``` Edge reads the manifest at deploy time. When it receives `X-Mizan-Invalidate: user;user_id=5`, it resolves URL patterns with params and purges `/profile/5/` and `/api/mizan/ctx/user/?user_id=5`. Generated alongside React code. Covers both RPC and view-path functions. ### Next: Codegen Rewrite Generated code uses the runtime directly (`mizanFetch`, `mizanCall`, `registerContext`) instead of the legacy `MizanProvider` pattern. Mutations have zero invalidation knowledge — the runtime reads the server response. ### Next: SSR Bridge Django renders React components server-side via a persistent Bun subprocess. - Bun worker: stdin/stdout JSON-RPC, `renderToString`, component registry - Django bridge: subprocess management, IPC, request synthesis - Template tag: `{% mizan_render "ProfilePage" user_profile=profile %}` - Hydration: `window.__MIZAN_SSR_DATA__` consumed by generated providers - Generated contexts check SSR data before first fetch --- ## Mizan Cloud (closed-source) ### Mizan Edge Cloudflare Workers for automatic edge caching. - Reads the Edge manifest to configure cache rules - Context GETs cached at edge, keyed by context name + params - Reads `X-Mizan-Invalidate` header from mutation responses to purge caches - Reads JSON `invalidate` key from RPC responses for the same purpose - Resolves URL patterns from manifest to purge view pages - Zero configuration — the manifest IS the cache policy ### Mizan Render SSR at the edge via Cloudflare Workers. - The Bun SSR bridge, running on Cloudflare instead of colocated with Django - Context data fetched from Django (or edge cache), rendered at the edge - HTML response streamed to the user from the nearest PoP ### Mizan Deploy One-command deployment for Django + React apps. - Container orchestration (AWS/Azure) - Edge + Render auto-configured - `mizan deploy` from the CLI - The Vercel experience for Django --- ## Protocol Spec (AFI) The protocol is the product. Two invalidation transports. Every endpoint CDN-ready. ### Context fetch ``` GET /api/mizan/ctx//?param=value 200 OK Cache-Control: public, max-age=0, stale-while-revalidate=300 Vary: Authorization, Cookie { "function_a": { ... }, "function_b": [ ... ] } ``` ### Mutation call (RPC path — JSON body transport) ``` POST /api/mizan/call/ Cache-Control: no-store { "result": { ... }, "invalidate": ["context_name"] } ``` ### Mutation call (View path — header transport) ``` POST /profile/update/ 302 Found Location: /profile/5/ Cache-Control: no-store X-Mizan-Invalidate: user;user_id=5, notifications ``` ### Scoped invalidation (JSON) ```json { "result": { ... }, "invalidate": [ "notifications", { "context": "user", "params": { "user_id": 5 } } ] } ``` ### Scoped invalidation (Header) ``` X-Mizan-Invalidate: user;user_id=5, notifications ``` ### Edge manifest ```json { "contexts": { "user": { "endpoints": ["/api/mizan/ctx/user/"], "views": ["/profile/:user_id/"], "params": ["user_id"] } } } ```