Dynamic Proposal System
Making sprint.zebradesign.io generate proposals for any client.
Dynamic Proposal System
Priority: Could Have
Make sprint.zebradesign.io generate proposals for any client without code changes. Currently the Research Tech proposal is hardcoded — every new client requires editing the codebase and redeploying.
Why This Matters
The current onboarding flow at sprint.zebradesign.io works, but it's a template with Research Tech's specific content baked into the code. For the next client, you'd need to:
- Edit page content in the codebase
- Change pricing, scope descriptions, and assumptions
- Update the slug and routing
- Redeploy
This isn't terrible for 1-2 clients. But it creates unnecessary friction and makes the "afternoon of booking" build longer than it needs to be.
What Exists Today
Research Tech pages (hardcoded):
/onboarding/research-tech-1→ Proposal review/onboarding/research-tech-1/engagement→ Engagement summary/onboarding/research-tech-1/agreements→ Terms acceptance/onboarding/research-tech-1/about→ Client information/onboarding/research-tech-1/confirmed→ Confirmation/onboarding/research-tech-1/invoice→ Invoice and payment
Supabase data model (from architecture-decision.md):
Tables already exist for clients, proposals, and invoices with fields for slug, scope, terms, assumptions, callouts, amounts, and status. The data model supports dynamic proposals — the frontend just doesn't use it dynamically yet.
What to Build
Option A: Admin Interface (Full Solution)
- Admin page to create/edit proposals
- Form fields mapping to existing Supabase schema
- Preview before publishing
- Generate unique client link
- ~1-2 day build
Option B: Database-Driven Templates (Lighter)
- Keep the existing page structure
- Pull content from Supabase instead of hardcoded values
- Create new proposals by inserting rows directly in Supabase dashboard
- No admin UI — just database entries
- ~0.5 day build
Recommendation
Option B for the next client. The admin interface is nice but isn't needed until client volume justifies it. Inserting a row in Supabase and having the pages render dynamically gets 80% of the value in 20% of the time.
Move to Option A when doing 3+ proposals per quarter.
Client-Specific Adaptation
Per client, populate these fields in Supabase:
slug— Client identifier (e.g., "acme-sprint-1")title— Proposal titlescope— What this sprint covers (markdown)terms— Sprint terms (reuse template, edit per client)assumptions— Project-specific assumptionscallouts— Important highlights for this engagementtotal_amount/currency— Pricing
How It Connects
- Deferred feature:
next-client.mditem #10 (Dynamic Proposal Generation) - Architecture:
architecture-decision.md— data model already supports this - Current state:
booking-app.md→ V1 Scope section - Version roadmap: Falls between V1 (live) and V2 (client dashboard) in the roadmap
This is Could Have because manually editing code for the next 2-3 clients is acceptable. The dynamic system becomes important at scale — not at client #2.