# Assessment, Effort Estimates, and Recommendation

_____

This article provides an honest assessment of both approaches, effort estimates for the re-architecture, and a recommendation.

## Architecture Comparison at a Glance

```mermaid
flowchart TD
    subgraph risk["Risk Comparison"]
        direction TB
        R1["Per-app model<br/>Bug affects 1 group"]
        R2["Single instance<br/>Bug affects ALL 500 groups"]
        R1 -.-|"vs"| R2
    end

    subgraph isolation["Data Isolation"]
        direction TB
        I1["Per-app model<br/>Physical isolation<br/>Separate databases"]
        I2["Single instance<br/>Logical isolation<br/>useDb switching"]
        I1 -.-|"vs"| I2
    end

    subgraph cost["Cost at 500 Groups"]
        direction TB
        C1["Per-app model<br/>No Fly.io charges<br/>600/month MongoDB"]
        C2["Single instance<br/>50-80/month Fly.io<br/>600/month MongoDB"]
        C1 -.-|"vs"| C2
    end

    style risk fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143
    style isolation fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143
    style cost fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143
```

## Arguments for Single-Instance Multi-Tenant

- **Ramblers Head Office preference**: reduces their perceived complexity for national rollout
- **Operational simplicity at scale**: managing 500 Fly.io apps is genuinely harder than managing 1–4
- **Transparent billing**: a single app with clear, predictable costs avoids any ambiguity around free-tier usage at scale. A large organisation like Ramblers would likely prefer a clean billing relationship with infrastructure providers
- **Easier onboarding**: adding a new group = database seed + DNS record, not full Fly.io app provisioning
- **Central visibility**: single log stream, single metrics dashboard, single deployment

## Arguments for Keeping the Current Model

- **Data isolation is inherent**: no risk of cross-group data leakage — it's physically impossible today. Multi-tenancy introduces the risk of a missing `groupCode` filter or a stale `useDb()` call. **At 500 groups this risk is amplified.**
- **Blast radius**: a bug or outage takes down ALL 500 groups simultaneously. **A single point of failure at national scale is a serious operational risk.**
- **Resource isolation**: one group's heavy traffic doesn't starve others
- **Zero Fly.io compute cost today**: each app falls under the $5/month free allowance. However, **this advantage may not scale to 500 apps** — Fly.io could reasonably view 500 free-tier apps operated by a single organisation as an unintended use of their pricing model.
- **The current model already works**: single Docker image, automated deployment, proven at scale
- **Security posture**: separate databases and auth secrets per group is stronger. A multi-tenant data leak across 500 groups could be catastrophic
- **Custom domains already work**: users are completely unaware of the shared codebase

## Recommendation

**The current architecture can scale to 500 groups** with investment in deployment automation (which is already largely in place). The per-group deployment model provides stronger isolation, lower blast radius, and simpler application code.

If Ramblers Head Office insists on a single instance, **Option B** (database-per-group with `useDb()` switching) is the lowest-risk path because it preserves the current data isolation model and minimises code changes.

The key distinction to communicate to Ramblers Head Office:

| What they want | Current status |
|----------------|---------------|
| Single codebase | Already true — one repo, one team |
| Single build artifact | Already true — one Docker image |
| Automated group provisioning | Already true — CLI tool creates new groups |
| Single running instance | Not currently, but technically feasible |

The question is whether "single running instance" is a hard requirement or whether "single codebase with automated provisioning" meets their actual need.

## Estimated Effort

Estimates are given for two delivery modes: **AI-assisted** (developer prompting Claude Code or similar) and **manual** (developer working unassisted).

| Component | AI-assisted | Manual | Risk |
|-----------|------------|--------|------|
| Tenant resolution middleware | 2–4 hours | 2–3 days | Medium |
| Database switching (`useDb()`) | 4–8 hours | 3–5 days | High — needs load testing |
| Auth consolidation + group-scoped tokens | 1–2 hours | 1–2 days | Medium |
| S3 consolidation to single bucket | 3–6 hours | 2–3 days | Medium |
| Background job scheduler (group-aware) | 4–8 hours | 3–5 days | Medium |
| API route audit (`req.db` everywhere) | 2–4 hours | 3–5 days | High — AI excels here |
| Super-admin and provisioning UI | 1–2 days | 5–8 days | Medium |
| Migration tooling (13 sites → single) | 3–6 hours | 2–3 days | Medium |
| Load testing at 500-group concurrency | 1–2 days | 3–5 days | High |
| **Total** | **~5–8 days** | **~5–7 weeks** | |

### Why the AI-Assisted Speedup?

The speedup is most dramatic for:
- **Route auditing**: AI can systematically scan every Express route handler and flag those not using `req.db` — tedious for humans, trivial for AI
- **Middleware and boilerplate**: tenant resolution, auth changes, and S3 path rewriting are well-understood patterns
- **Migration scripts**: database-to-database data movement is mechanical and well-suited to AI generation

The speedup is smallest for:
- **Load testing**: test execution and monitoring takes real time regardless
- **Super-admin UI**: involves UX decisions and iterative refinement
- **Integration testing**: verifying behaviour across 500 groups requires real infrastructure

## Next Steps

- Present current architecture to Ramblers Head Office, emphasising single codebase + single artifact + automated provisioning
- Clarify whether "single instance" is a hard requirement or whether the actual need is simpler onboarding/management
- If required, prototype tenant resolution middleware + `useDb()` database switching
- Load test `mongoose.useDb()` under concurrent multi-group traffic (simulate 500 databases)
- Assess MongoDB Atlas pricing at M30+ tier for 500 databases
- Assess Fly.io multi-domain TLS certificate management at 500+ domains
