8fc88ffc14
Build & Push / Pipeline Tests (push) Failing after 59s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Failing after 51s
Test / API Unit Tests (push) Has been skipped
Test / Homepage Unit Tests (push) Has been skipped
Test / Carplace Unit Tests (push) Has been skipped
Test / Admin Unit Tests (push) Has been skipped
Test / Dashboard Unit Tests (push) Has been skipped
Test / API Integration Tests (push) Has been skipped
47 lines
2.8 KiB
Markdown
47 lines
2.8 KiB
Markdown
# Phase 4 — Extraction gates & candidates
|
|
|
|
**Status:** Planning / measurement only (ADR-003)
|
|
**Date:** 2026-08-12
|
|
**Prerequisite:** Phase 3 exit evidence (soak, pen-test, canary, key rotation) should be underway before any extraction design review.
|
|
|
|
## Rule
|
|
|
|
Extract a bounded context into its **own deployable** only if measurement shows the monolith cannot meet SLOs or blast-radius requirements **and** ownership is staffed. Otherwise scale the existing `api` + `api-worker` topology.
|
|
|
|
## Candidates (from diligence / readiness plan)
|
|
|
|
| Candidate | Today | Extract when… | Prefer first |
|
|
|-----------|--------|---------------|--------------|
|
|
| **Notification worker** | Already a separate **process** (`apps/api` worker / Compose `api-worker`) sharing the API package | Worker CPU/memory or release cadence is blocked by API deploys; or need multi-language worker fleet with independent scaling | Scale `api-worker` replicas; keep shared package |
|
|
| **Payments / webhooks** | Modules inside API (`payments`, `billing`, `subscriptions`, webhook routes) | Webhook lag or payment CPU dominates API p95; or PCI/provider isolation requires a smaller trust boundary | Dedicated webhook ingress + queue inside monolith; idempotent consumers |
|
|
| **Media processing** | Upload + storage drivers in API; local/S3 | Image/PDF processing blocks request threads or storage I/O saturates API | Async job on `api-worker`; object storage (MinIO/S3) already preferred |
|
|
|
|
## Hard gates (all required per candidate)
|
|
|
|
Copy to an evidence note before any extract ADR:
|
|
|
|
| # | Gate | Evidence |
|
|
|---|------|----------|
|
|
| G1 | Phase 3 soak baseline exists | Dated `test:soak` / k6 + `/metrics` snapshot |
|
|
| G2 | Bottleneck attributed | Profile or metrics: p95, queue lag, CPU by route/job — not anecdote |
|
|
| G3 | Blast radius / compliance need | Written threat or compliance reason (e.g. webhook storm, media malware scan) |
|
|
| G4 | Ownership | Named eng + on-call for the new service |
|
|
| G5 | Contract | OpenAPI or event schema + consumer contract tests |
|
|
| G6 | Dual-run | Shadow or dual-publish ≥ 1 release cycle with zero silent divergence |
|
|
| G7 | Rollback | Documented cutback to monolith path in < 30 minutes |
|
|
|
|
If any gate fails → **do not extract**; file an in-monolith improvement instead.
|
|
|
|
## In-monolith improvements (do these before/instead of extract)
|
|
|
|
1. Keep payment/webhook handlers thin; push side effects through outbox/jobs.
|
|
2. Run N `api-worker` replicas with DB leases (already Phase 1).
|
|
3. Move heavy media work to worker jobs + S3; never resize on the request path.
|
|
4. Publish domain events internally (same DB outbox) so a future service can subscribe without a big-bang rewrite.
|
|
|
|
## Explicit non-goals for Phase 4
|
|
|
|
- Rewriting the monorepo into many services
|
|
- Separate databases per module “for purity”
|
|
- Per-tenant container orchestration (still ADR-001)
|