EXECUTIVE SUMMARY
Product success is rarely the result of code alone.
It depends on clear architecture, disciplined execution, and risk-aware decisions.

This document defines the operating system used to build and launch SaaS products with those principles in place from the start.

It reflects lessons from real builds — architectural choices that are costly to reverse, compliance gaps that surface late, and financial assumptions that require early scrutiny.

The playbook serves as a pre-flight checklist, architectural baseline, compliance reference, and investor-readiness framework.

Each product moves through this system before development begins. The result is more deliberate builds, fewer avoidable surprises, reduced legal and technical risk, and a foundation that stands up to investor review.

Infrastructure Context Layer
Separates intended architecture from observed runtime state. Required reading before any infrastructure action.

The Playbook defines intent — what this system is being built toward. The Context Layer defines reality — what is actually deployed and running. Neither replaces the other. The gap between them is intentional, and represents current build state.

All AI agents and contributors must read the Context Layer before making any infrastructure decision. It is the operational source of truth, not this document.

STACK_CONTEXT.md
Generated from system audit · not hand-authored
  • Operational source of truth — running containers, port bindings, network topology, active tunnels
  • Documents services not yet deployed alongside those that are
  • Must be regenerated after any service is added, removed, or reconfigured
  • Required reading for all AI agents before any infrastructure action
PORT_REGISTRY.md
Mandatory before any new service deployment
  • Flat registry of every claimed port — service name, runtime, bound address, owning compose file
  • Resolves conflicts before they reach production
  • Must be updated before any new service is deployed
Rule 1
Service Change Rule
No service may be added to this environment without first updating both STACK_CONTEXT.md and PORT_REGISTRY.md.
Rule 2
Agent Operating Rule
All AI agents must read STACK_CONTEXT.md before any action that affects services, ports, or compose files.
Rule 3
Separation of Layers
The Playbook defines intent. The Context Layer defines reality. Conflicts between them represent build state — they are expected and must be tracked, not collapsed.

Each pillar contains three layers. Work through them in order for each new product.

Layer 01
What It Is
The concept — why this pillar exists and what problem it solves.
Layer 02
Architecture Best Practices
How to build it correctly — standards, patterns, and decisions that cannot be undone cheaply.
Layer 03
Required Documentation
What must exist in writing before the pillar is considered complete.
⚠️ Pillars 1–6 plus 9 and 10 should be addressed before building features. Pillars 7 and 8 are completed per product as it matures. The Pre-Launch Checklist is a firm gate — each item should be green before launch.
EduReach — Live Build Progress
Tracked against this framework in real time · Loading…
🔒 Pre-Launch Gate Locked
Loading pillar status…
The 10 Pillars
1
Pillar 01 of 10
Product Identity
Not Started
What It Is

This pillar informs most technical decisions that follow. Treat it as a constraint document — if a feature does not serve the problem statement and target customer, it should not get built.

  • Use the Jobs-To-Be-Done framework
  • Outcomes first, features second — avoid feature-first thinking
  • Decisions should trace back to a user outcome
  • Treat this as a constraint document, not a wish list
  • Validate the problem exists before validating the solution
Architecture Best Practices
Constraint-First Thinking
Feature requests should trace back to a user outcome defined in the Product Brief. If they cannot, they should not get built.
Jobs-To-Be-Done Framework
Define what job the customer is hiring this product to do. This drives prioritization, positioning, and pricing.
Assumption Validation
Key assumptions about market and user should be validated or invalidated with real evidence — not opinion.
Required Documentation
2
Pillar 02 of 10
Technical Architecture Foundation
Not Started
What It Is

Core scaffolding most products share — auth, billing, database, infrastructure. Standardized across products, rarely rebuilt from scratch.

  • 12-Factor App Methodology — strict config separation, stateless processes
  • Auth via Auth0, Clerk, or Supabase — avoid building from scratch
  • RBAC enforced at API layer, not just UI
  • Zoho Subscriptions + Stripe as billing layer
  • Shared DB with tenant-scoped rows (org_id on every table)
  • Infrastructure as Code from day one
  • Secrets should not be in source code
Architecture Best Practices
Subscription & Billing
Zoho Subscriptions is the billing layer. Zoho Subscriptions webhooks are the source of truth for subscription state — your DB should reflect what Zoho tells you, not the other way around.
Vendor Lock-In Policy
For every major infrastructure decision, document the switching cost and lock-in risk. If lock-in is accepted, document why and the exit strategy.
Technical Debt Policy
Tracked in a dedicated backlog. A percentage of each sprint is reserved for debt reduction. Debt should not accumulate undocumented.
Disaster Recovery
Backups daily minimum, tested quarterly. A documented recovery procedure has been executed end-to-end at least once. RTO and RPO defined.
Required Documentation
Tooling
1 — Framework Generator Prompt v0.3

Copy-paste into Claude. Replace all tokens before pasting. The prompt enforces plan-first execution — Claude outputs a numbered plan and waits for "proceed" before writing any file. Clicking Mark as Used sets Environment Setup Guide and Runbook to Draft in the tracker and moves Pillar 2 to In Progress.

You are a senior backend engineer scaffolding a new multi-tenant SaaS product.
Prompt version: v0.3

── TOKENS (replace all before pasting) ──────────────────────────────
PRODUCT_NAME:      {{PRODUCT_NAME}}
AUTH_PROVIDER:     {{AUTH_PROVIDER}}       # Auth0 | Clerk | Supabase
DB_NAME:           {{DB_NAME}}
PORT:              {{PORT}}
FRAMEWORK:         {{FRAMEWORK}}           # flask | fastapi
TENANT_ISOLATION:  {{TENANT_ISOLATION}}    # rls | app-layer
─────────────────────────────────────────────────────────────────────

─── PLAN FIRST ───────────────────────────────────────────────────────
Before writing any files, output a numbered list of every file
you will create and its purpose. Wait for the user to reply
"proceed" before generating any code.
─────────────────────────────────────────────────────────────────────

Scaffold the following when proceeding:

1. Project structure
   {{PRODUCT_NAME}}/
   ├── app/
   │   ├── __init__.py
   │   ├── config.py              # 12-Factor: all config from env vars; no hardcoded values
   │   ├── auth.py                # {{AUTH_PROVIDER}} middleware — verify token, attach user to request
   │   ├── context.py             # resolve_org_context() → {user_id, org_id, role} from token + DB
   │   ├── routes/
   │   │   ├── health.py          # GET /api/health → {"status":"ok","env":"...","ts":"..."}
   │   │   ├── me.py              # GET /api/me → {user_id, org_id, role, org_name}
   │   │   ├── billing.py         # POST /api/webhooks/zoho — HMAC verify, dispatch to stubs
   │   │   └── __init__.py
   │   ├── models/
   │   │   ├── base.py            # SQLAlchemy base; id (UUID PK) + org_id (UUID NOT NULL) + timestamps
   │   │   ├── org.py             # Org(id, name, slug, plan, created_at)
   │   │   ├── user.py            # User(id, email, auth_provider_id, created_at)
   │   │   └── membership.py      # Membership(id, org_id FK, user_id FK, role)
   │   └── middleware/
   │       └── rbac.py            # @require_role('admin'|'member') — API layer only, not UI
   ├── migrations/
   │   ├── env.py                 # Alembic: include_schemas=True; target_metadata from Base
   │   └── versions/              # empty — ready for first migration
   ├── scripts/
   │   ├── backup.sh              # pg_dump -Fc + timestamp; exit non-zero on failure; 30-day retention
   │   ├── restore.sh             # "type YES" confirmation gate; pg_restore --clean --if-exists
   │   └── workdrive_upload.sh    # stub: upload latest dump to Zoho WorkDrive (wire MCP when ready)
   ├── docker-compose.yml         # dev: ${BIND_HOST:-127.0.0.1}:${PORT}:${PORT}; dev volumes mounted
   ├── docker-compose.staging.yml # staging overlay: same image tag; no dev volumes; .env.staging
   ├── .env.example               # all required vars with placeholder values — no real secrets
   ├── .env.staging.example       # staging-specific vars, all placeholders
   ├── .gitignore                 # blocks .env*, backups/, *.pgdump, __pycache__
   ├── README.md                  # project name, token list, quickstart, link to RUNBOOK.md
   ├── RUNBOOK.md                 # start/stop, migrations, backup/restore, deploy, rollback
   ├── requirements.txt
   └── alembic.ini

2. Config (config.py) — required env vars
   DATABASE_URL              # postgresql+psycopg2://user:pass@host/db
   SECRET_KEY                # no default — must be set explicitly
   {{AUTH_PROVIDER}}_DOMAIN
   {{AUTH_PROVIDER}}_CLIENT_ID
   {{AUTH_PROVIDER}}_CLIENT_SECRET
   ZOHO_WEBHOOK_SECRET       # HMAC verification key
   BIND_HOST                 # default 127.0.0.1; set 0.0.0.0 for LAN/Tailscale exposure
   CORS_ALLOWED_ORIGINS      # comma-separated list of allowed origins
   CORS_ALLOW_CREDENTIALS    # true | false
   FRONTEND_ORIGIN           # convenience alias; auto-added to CORS_ALLOWED_ORIGINS
   ENV                       # dev | staging | production
   WORKDRIVE_FOLDER_ID       # Zoho WorkDrive folder for backup uploads (optional)

3. Multi-tenant primitives
   · Org, User, Membership models as defined above
   · org_id UUID NOT NULL + index on every application table
   · resolve_org_context(request): token subject → User → Membership → {user_id, org_id, role}
     Raise 403 if no active membership found
   · GET /api/me: call resolve_org_context(); return context + org_name; require auth
   · Tenant isolation — controlled by TENANT_ISOLATION env var:
     "rls"        → ALTER TABLE ... ENABLE ROW LEVEL SECURITY; CREATE POLICY using
                    current_setting('app.current_org')::UUID; set via DB session var
     "app-layer"  → no RLS; every query filters by org_id explicitly; include test stubs
                    asserting cross-tenant queries return zero rows

4. Zoho billing seam (billing.py)
   · POST /api/webhooks/zoho
   · Step 1: verify HMAC-SHA256(payload, ZOHO_WEBHOOK_SECRET) — return 401 on mismatch
   · Step 2: parse event_type from payload body
   · Step 3: dispatch to stub handlers:
       subscription_activated(payload)
       subscription_cancelled(payload)
       subscription_renewed(payload)
       payment_failed(payload)
   · Principle: Zoho is source of truth — DB reflects what Zoho sends, not the reverse
   · Each stub must log event_type and payload keys before returning 200

5. Backup, restore, and offsite upload
   backup.sh:
     · set -euo pipefail; pg_dump -Fc; timestamped filename; exit non-zero on failure
     · 30-day local retention (find ... -mtime +30 -delete)
     · On success, exec scripts/workdrive_upload.sh "$FILE"
   restore.sh:
     · Takes backup file path as $1; abort with usage if missing
     · Print target DB + file; prompt "Type YES to continue"
     · pg_restore -U $DB_USER -d $DB_NAME --clean --if-exists
   workdrive_upload.sh:
     · Reads WORKDRIVE_FOLDER_ID from env
     · Stub: echo upload intent + curl skeleton to Zoho WorkDrive Files API
     · Comment: # TODO: wire Zoho MCP tool here when available

6. Environment separation
   docker-compose.yml         dev; ${BIND_HOST:-127.0.0.1} binds; source-mounted app volume
   docker-compose.staging.yml staging overlay; no app volume mount; uses .env.staging;
                               same pinned image tag; add healthcheck config
   .env.example               dev vars only; all placeholders
   .env.staging.example       staging vars; ENV=staging; separate DB_NAME and SECRET_KEY slots
   Rule: staging and production env files must never be used locally without explicit intent

7. Network and CORS
   · CORS middleware reads CORS_ALLOWED_ORIGINS (split on comma) + FRONTEND_ORIGIN
   · CORS_ALLOW_CREDENTIALS controls credentials header
   · docker-compose port binding: "${BIND_HOST:-127.0.0.1}:${PORT}:${PORT}"
   · No hardcoded bind addresses anywhere in compose files

   Document these reachability modes in README.md:
   Mode 1 — Local only (default, safe):
     BIND_HOST=127.0.0.1 — reachable only from localhost
   Mode 2 — LAN / Tailscale:
     BIND_HOST=0.0.0.0 — reachable on LAN or Tailscale network
     Set CORS_ALLOWED_ORIGINS to include Tailscale hostname
     Note: confirm firewall rules before enabling
   Mode 3 — Reverse proxy / tunnel:
     Keep BIND_HOST=127.0.0.1; expose via Tailscale Funnel or Cloudflare Tunnel
     CORS_ALLOWED_ORIGINS = public domain only

8. Git hygiene
   .gitignore must cover:
     .env, .env.*, !.env.example, !.env.staging.example
     __pycache__/, *.pyc, *.egg-info/, .venv/
     /backups/, /data/, /uploads/, *.pgdump, *.sql
   README.md must include:
     · One-line product description
     · Full token list (all {{TOKENS}} used in this prompt)
     · Quickstart: clone → copy .env.example → fill secrets → docker-compose up
     · Link to RUNBOOK.md
   RUNBOOK.md must include:
     · Start / stop service
     · Run / rollback migrations (alembic upgrade head / downgrade -1)
     · Create backup and test restore (scripts/backup.sh / scripts/restore.sh)
     · Deploy to staging (docker-compose -f docker-compose.staging.yml up -d)
     · Rollback procedure

9. Constraints (enforced across all generated files)
   · No secrets in any tracked file — .env.example and .env.staging.example only
   · Auth via middleware only — no per-route token parsing
   · org_id filter applied at the repository/service layer in every query
   · Zoho HMAC verified before any webhook payload is processed
   · backup.sh exits non-zero on pg_dump failure
   · All compose port bindings use ${BIND_HOST} — no hardcoded addresses

10. After scaffolding, print this verification checklist:

    ── Environment ──────────────────────────────────────────────────
    [ ] cp .env.example .env && fill in all required values
    [ ] docker-compose up -d && docker-compose ps  → all containers Up
    [ ] docker exec backend alembic upgrade head   → no errors
    [ ] curl http://${BIND_HOST}:${PORT}/api/health → {"status":"ok"}

    ── Multi-tenant ─────────────────────────────────────────────────
    [ ] Seed: create test Org + User + Membership via psql or seed script
    [ ] GET /api/me with valid token → {user_id, org_id, role, org_name}
    [ ] Cross-tenant isolation:
        SET app.current_org = '<org-a-id>';
        SELECT COUNT(*) FROM <table> WHERE org_id != '<org-a-id>';
        # Expected: 0

    ── Billing seam ─────────────────────────────────────────────────
    [ ] POST /api/webhooks/zoho with bad signature  → 401
    [ ] POST /api/webhooks/zoho with valid signature → 200, event logged

    ── Reachability ─────────────────────────────────────────────────
    [ ] Mode 1: BIND_HOST=127.0.0.1 — curl from localhost succeeds
    [ ] Mode 2: BIND_HOST=0.0.0.0  — curl from LAN device succeeds
    [ ] Mode 3: tunnel configured  — curl via Tailscale/Cloudflare hostname succeeds

    ── Git hygiene ──────────────────────────────────────────────────
    [ ] git grep -rn "password\|secret\|api_key" -- "*.py" "*.yml" | grep -v ".env.example"
        # Expected: no output
    [ ] git status does not show .env (gitignore working)
    [ ] README.md and RUNBOOK.md present and non-empty
2 — STACK_CONTEXT.md Template

Generated from system audit — not hand-authored. Regenerate after any service change. All AI agents must read this before any infrastructure action.

# STACK_CONTEXT.md
# Generated: {{DATE}} — system audit, not hand-authored.
# Regenerate after any service is added, removed, or reconfigured.
# Required reading for all AI agents before infrastructure actions.

## Host
Host:       {{HOSTNAME}}
LAN IP:     {{LAN_IP}}
Tailscale:  {{TAILSCALE_IP}} / {{TAILSCALE_HOSTNAME}}

## Running Services
| Container | Image | Port Binding | Status |
|-----------|-------|-------------|--------|
| {{name}}  | {{image}} | 0.0.0.0:{{port}} | Up Nh |

## Port Map
| Port | Service | Runtime | Bound To | Compose File |
|------|---------|---------|----------|-------------|
| {{port}} | {{service}} | Docker / native | 0.0.0.0 / 127.0.0.1 | {{file}} |

## Not Yet Deployed
| Service | Planned Port | Status |
|---------|-------------|--------|
| {{service}} | {{port}} | Not deployed |

## Connectivity
Tailscale:          active / inactive
Cloudflare Tunnel:  active / inactive

## Assumptions
- ASSUMPTION: ...
3 — PORT_REGISTRY.md Template

Update before deploying any new service. Resolve conflicts here — before they reach production.

# PORT_REGISTRY.md
# RULE: Update this file before deploying any new service.
# RULE: Resolve port conflicts here — before they reach production.
# Last updated: {{DATE}}

| Port | Service | Runtime | Bound To | Compose File | Status |
|------|---------|---------|----------|-------------|--------|
| 5000 | backend  | Docker | 0.0.0.0 | docker-compose.yml | active  |
| 5432 | postgres | Docker | 0.0.0.0 | docker-compose.yml | active  |
| 8080 | frontend | Docker | 0.0.0.0 | docker-compose.yml | active  |
| {{port}} | {{service}} | — | — | — | planned |

## Conflict Log
| Date | Port | Conflict | Resolution |
|------|------|----------|-----------|
| {{date}} | {{port}} | {{description}} | {{resolution}} |
4 — Ops Script Templates

Git-tracked under scripts/. All use set -euo pipefail. Configured via env vars — no hardcoded values.

── backup.sh ──────────────────────────────────────────────────────
#!/usr/bin/env bash
set -euo pipefail
DB_CONTAINER="${DB_CONTAINER:-db}"
DB_NAME="${DB_NAME:-app}"
DB_USER="${DB_USER:-app}"
BACKUP_DIR="${BACKUP_DIR:-./backups}"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.pgdump"
mkdir -p "$BACKUP_DIR"
echo "→ Dumping ${DB_NAME}…"
docker exec "$DB_CONTAINER" pg_dump -U "$DB_USER" -Fc "$DB_NAME" > "$FILE"
echo "✓ Backup: $(du -sh "$FILE" | cut -f1)"
find "$BACKUP_DIR" -name "*.pgdump" -mtime +30 -delete   # 30-day retention

── restore.sh ─────────────────────────────────────────────────────
#!/usr/bin/env bash
set -euo pipefail
BACKUP_FILE="${1:?Usage: restore.sh <backup.pgdump>}"
DB_CONTAINER="${DB_CONTAINER:-db}"
DB_NAME="${DB_NAME:-app}"
DB_USER="${DB_USER:-app}"
echo "⚠  This will OVERWRITE ${DB_NAME}. File: ${BACKUP_FILE}"
printf "   Type YES to continue: "; read -r CONFIRM
[[ "$CONFIRM" == "YES" ]] || { echo "Aborted."; exit 1; }
docker exec -i "$DB_CONTAINER" pg_restore \
  -U "$DB_USER" -d "$DB_NAME" --clean --if-exists < "$BACKUP_FILE"
echo "✓ Restore complete."

── health-check.sh ────────────────────────────────────────────────
#!/usr/bin/env bash
set -euo pipefail
PORT="${PORT:-5000}"
echo "── Containers ──────────────────────────────────────────"
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
echo "── Migration state ─────────────────────────────────────"
docker exec backend alembic current 2>/dev/null || echo "  (unreachable)"
echo "── Health endpoint ─────────────────────────────────────"
curl -sf "http://127.0.0.1:${PORT}/api/health" | python3 -m json.tool \
  || echo "  ✗ Health check failed"
5 — Multi-Tenant Baseline Schema Blueprint

org_id on every application table — indexed, NOT NULL. RLS enabled before any customer data enters production. Run the validation query as the app DB user, not the postgres superuser.

-- Every application table follows this baseline.
-- Replace 'resources' with your entity name.

CREATE TABLE resources (
    id          UUID        PRIMARY KEY DEFAULT gen_random_uuid(),
    org_id      UUID        NOT NULL,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT now()
    -- add domain columns here
);

CREATE INDEX idx_resources_org_id ON resources (org_id);

-- Row-Level Security — enable before any customer data enters
ALTER TABLE resources ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON resources
    USING (org_id = current_setting('app.current_org')::UUID);

-- alembic/env.py — required additions
-- from app.models.base import Base
-- target_metadata = Base.metadata
-- include_schemas = True

-- Validation (run as app DB user — not postgres superuser)
SET app.current_org = 'aaaaaaaa-0000-0000-0000-000000000000';
SELECT COUNT(*) FROM resources;
-- Expected: 0  (org has no data — confirms RLS is enforced)
6 — Verification Commands

Run in order. All six must pass before marking Pillar 2 in progress.

# 1 — Running containers
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

# 2 — Migration state (must show a head revision — not "None")
docker exec backend alembic current

# 3 — Health endpoint (expect {"status": "ok"})
curl -s http://127.0.0.1:$PORT/api/health | python3 -m json.tool

# 4 — Zoho webhook reachable (expect 200 or 400 — not 404)
curl -s -o /dev/null -w "%{http_code}" \
  -X POST http://127.0.0.1:$PORT/api/webhooks/zoho

# 5 — RLS active (run as app DB user — not postgres superuser)
docker exec -it db psql -U $DB_USER -d $DB_NAME -c \
  "SET app.current_org = 'aaaaaaaa-0000-0000-0000-000000000000';
   SELECT COUNT(*) FROM resources;"
# Expected: 0 rows — confirms tenant isolation is enforced

# 6 — No secrets in tracked files
git grep -rn "password\|secret\|api_key\|token" -- "*.py" "*.yml" "*.env" \
  | grep -v ".env.example"
# Expected: no output
7 — Completion Criteria

The Playbook enforces discipline without punishing early-stage execution. Priority tiers prevent premature overbuild — not every criterion carries the same cost of delay. Tier 1 items protect architecture: their absence forces structural teardowns at the worst possible time. Tier 2 items protect customers: they must exist before production exposure or first revenue. Tier 3 items protect scale: they are not optional, but their absence does not block safe early iteration. Completion of Tier 1 enables safe feature development.

Tier 1 — Blocker
Must exist before feature development begins. Absence forces schema rewrites, auth redesigns, or tenant isolation rebuilds.
  • Migrations configured → Pre-Launch: CI/CD pipeline operational
  • Auth provider wired → Pre-Launch: Authentication implemented via established provider
  • RBAC enforced at API layer → Pre-Launch: RBAC implemented and tested at API layer
Tier 2 — Required Before First Paying Customer
Must exist before charging customers or exposing production usage. Legal, billing, and data handling risk.
  • Zoho webhook endpoint reachable → Pre-Launch: Zoho Subscriptions webhooks connected to application and tested
  • Dev/Staging separation confirmed → Pre-Launch: All environments separated — Dev, Staging, Production
  • Secrets not in source code → Pre-Launch: No secrets in source code
Tier 3 — Maturity
Must exist before scale or external operational dependency. Absence increases operational fragility — not a launch blocker.
  • Backups configured and restore tested → Pre-Launch: Backups configured and tested
3
Pillar 03 of 10
Core Product UI/UX Shell
Not Started
What It Is

Standard screens most products ship before feature work begins:

  • Public landing page — problem, solution, pricing, CTA
  • Auth screens — sign up, login, forgot password, MFA
  • Onboarding flow — first-run to first value
  • Main application dashboard
  • Settings and profile management
  • Billing and subscription management page
  • Admin dashboard — users, usage, account controls
Architecture Best Practices
Component Architecture
Build on Radix UI, shadcn, Material UI, or Chakra. UI elements should be composable components. Separate UI from business logic.
Onboarding
One of the most important UX flows in the product. Design to reach one specific aha moment as quickly as possible. Use a progress indicator.
Core Web Vitals
Optimize LCP, CLS, and FID from the start. Lighthouse audits in CI pipeline. Lazy load routes and heavy components.
Required Documentation
4
Pillar 04 of 10
Admin and Operations Dashboard
Not Started
What It Is

Internal control panel for operating the business:

  • All accounts and users with status
  • Revenue overview — MRR, churn, trial conversions (from Zoho)
  • Feature flag management — enable/disable per account without a deploy
  • Manual account adjustments via Zoho Subscriptions, reflected via webhook
  • Support ticket visibility via Zoho Desk integration
  • Audit logs — append-only, who did what, when
Architecture Best Practices
Same Security Rigor
Admin routes protected by auth and explicit role checks at the API layer. Build on the same API the product uses — avoid a parallel codebase.
Feature Flags
Via LaunchDarkly, Unleash, or Flagsmith from day one. Enables testing, rollouts, and account-specific overrides without deploys.
Append-Only Audit Logs
Stored separately from application data. They are legal evidence — should not be modified or deleted.
Required Documentation
5
Pillar 05 of 10
Analytics and Product Intelligence
Not Started
What It Is

The measurement layer — what users are doing, whether the product is working, whether the business is healthy. Built in from day one, not bolted on later.

  • Consistent naming: noun_verb (subscription_upgraded, search_performed)
  • Segment as CDP event router — instrument once, route anywhere
  • MRR, churn, LTV, CAC from Zoho data — not just estimated
  • Alerts for anomalies — learn from monitoring, not customer complaints
Architecture Best Practices
Event Taxonomy First
Define event taxonomy before writing tracking code. Retroactive instrumentation is expensive and incomplete.
Zoho Analytics as BI Layer
Pulls natively from Zoho Subscriptions, CRM, and Books. Numbers should be trustworthy when an investor asks.
Alerting Architecture
Automated alerts for error spikes, signup drops, sudden churn. Aim to know about problems before customers report them.
Required Documentation
6
Pillar 06 of 10
Legal and Compliance Foundation
Not Started
What It Is

Foundational in 2026. Should exist before the first paying customer. Covers privacy, data protection, legal agreements, security standards, AI governance, and accessibility compliance.

  • Privacy by Design — legal basis for every data point before collection
  • CMP for cookie consent — required for EU/UK and increasingly US states
  • Under GDPR: 72 hours to notify regulators of a breach
  • IP assignment signed before any contributor touches code
  • Open source license audit — GPL in a commercial product may require open-sourcing your code
  • AI governance — disclose where and how AI is used
Architecture Best Practices
Cascading Deletion
Build cascading deletion across all systems from the start. A user's right to erasure should not be an afterthought in a distributed system.
Data Minimization
Only collect what is actually needed. Each additional field adds liability — it should be protected, disclosed, and eventually deleted.
EduReach Note
Faculty directory data contains PII and must be handled with a documented legal basis. Evaluate ToS, robots.txt, and PII obligations before scraping any source.
Required Documentation
7
Pillar 07 of 10
Go-To-Market and Tier Structure
Not Started
What It Is

Completed per product as it matures. Defines how the product reaches its market, at what price, and through which channels. Pricing should be validated by real customer conversations before launch.

  • Pricing validated by minimum three willingness-to-pay conversations
  • No single customer should exceed 20% of revenue (concentration risk)
  • ICP defined with specificity — not "SMBs" but the exact buyer profile
  • Feature gate matrix aligned to Zoho Subscriptions tier configuration
Architecture Best Practices
Tier Limits in Config
Tier limits stored in config or database — not hardcoded. Pricing changes should not require code deploys.
Customer Concentration Risk
Track revenue concentration from day one. A single customer exceeding 20% of MRR creates concentration risk.
Required Documentation
8
Pillar 08 of 10
Investor and Pitch Readiness
Not Started
What It Is

Completed per product when relevant. The investor-facing layer — everything needed to navigate due diligence with fewer surprises. Most other pillars feed into this one.

  • One-pager that can be understood in 60 seconds
  • Financial model with MRR projections and unit economics
  • Cap table and entity structure clean and documented
  • Data room organized before it is needed
Architecture Best Practices
Due Diligence Readiness
Most other pillars in this framework support investor due diligence. When a serious investor asks for documentation, it should exist — not be created under deadline pressure.
Data Room Structure
Organize the data room before it is needed. Disorganized data rooms can signal operational immaturity to sophisticated investors.
Required Documentation
9
Pillar 09 of 10
Financial Foundation and Unit Economics
Not Started
What It Is

The financial discipline layer. Most founders scale before they understand their unit economics. This pillar surfaces the financial questions that determine whether the business is viable before capital is deployed.

  • CAC from Zoho CRM deal data and Zoho Books marketing expense
  • LTV from Zoho Subscriptions cohort data
  • LTV:CAC ratio target at least 3:1
  • Payback period target under 12 months
  • Runway calculated weekly, reviewed weekly
  • All equity on vesting schedule — 4 years, 1-year cliff
Architecture Best Practices
Zoho One Financial Stack
Zoho Subscriptions → Zoho Books → Zoho CRM → Zoho Analytics. These talk natively. Avoid building custom integrations for data flows Zoho One handles automatically.
Revenue Recognition
Zoho Books handles revenue recognition natively. Annual prepaid contracts should not be recognized on day one. Have an accountant verify the setup before first revenue.
Banking and Treasury
Maintain operating expenses in FDIC-insured accounts. Avoid keeping more than $250,000 in any single bank. Connect bank to Zoho Books for automatic reconciliation.
Required Documentation
10
Pillar 10 of 10
Risk Register
Not Started
What It Is

A living document of key known risks to the business — technical, legal, financial, market, and operational — with a mitigation plan for each. A clear signal of investor-grade operational thinking.

  • Each risk rated: likelihood (1-5) × impact (1-5) = risk score
  • Risks scoring 15+ are treated as critical and require active mitigation
  • Reviewed monthly — not a document that sits on a shelf
  • Five categories: Technical, Legal, Financial, Market, Operational
Risk Categories
Technical Risks
Key dependency discontinuation, security breach, scalability failure, technical debt blocking features, single point of failure.
Legal & Financial Risks
Privacy law violations, IP disputes, runway exhaustion before PMF, CAC exceeding LTV, unexpected tax liability.
Market & Operational Risks
Competitor ships first, market smaller than estimated, key person dependency, support volume exceeding capacity.
Required Documentation
Master Documentation Registry
Every required document, its owner, and review frequency
Document Owner Review Frequency
Product BriefFounderPer major pivot
Competitive AnalysisFounderQuarterly
Assumptions LogFounderMonthly
Architecture Decision RecordsLead DevPer decision
System Architecture DiagramLead DevQuarterly
Entity Relationship DiagramLead DevPer schema change
API DocumentationLead DevPer release
Dependency RegisterLead DevPer new dependency
Vendor Lock-In Risk LogLead DevQuarterly
Technical Debt BacklogLead DevSprint planning
Disaster Recovery PlanLead DevAnnually + after incidents
Zoho One Integration MapDevPer integration change
Zoho One Configuration DocumentFounder / DevPer configuration change
Privacy PolicyLegal / FounderPer data practice change
Terms of ServiceLegal / FounderAnnually
Cookie PolicyLegal / FounderPer change
DPA TemplateLegal / FounderAnnually
Data Map and Article 30 RecordFounderQuarterly
Incident Response PlanFounder / DevAnnually + after incidents
Vendor Security ChecklistFounderPer new vendor
AI Usage PolicyFounderPer AI feature added
IP Assignment AgreementsFounderPer new contributor
Open Source License AuditLead DevPer new dependency
Worker Classification RegisterFounderPer new hire or contractor
Unit Economics ModelFounderMonthly
Runway DashboardFounderWeekly
Cap TableFounderPer equity event
Co-Founder AgreementFounder / LegalPer major change
Risk RegisterFounderMonthly
Risk Review NotesFounderMonthly
Event Tracking PlanProduct / DevPer feature release
Metrics DefinitionsFounderPer metric added
Analytics Dashboard InventoryFounderQuarterly
Design System DocumentDesigner / DevPer design change
Feature Flag RegisterDevPer flag added or removed
Internal Operations ManualFounder / DevPer process change
Audit Log SchemaDevPer change
Pricing Tiers and Feature Gate MatrixFounderPer pricing change
ICP DefinitionFounderQuarterly
Pitch DeckFounderPer fundraise
Financial ModelFounderMonthly