fix production issues
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

This commit is contained in:
root
2026-08-12 16:48:41 -04:00
parent 53de25120a
commit 8fc88ffc14
117 changed files with 4717 additions and 1443 deletions
@@ -0,0 +1,492 @@
# RentalDriveGo — Plan to Reach Production Ready
**Purpose of this document:** This is the **execution plan to take the current codebase to production ready**. It is not a feature roadmap and not an architecture rewrite. Success is measured only by the definition in §1 and the checkpoint in §13.
**Status:** Phases 04 **application code / runbooks complete** (12 Aug 2026). Remaining work is **ops evidence** (CI smoke, restore/alert drills, pen-test, soak) — not missing features. Phase 4 correctly does **not** extract microservices (ADR-003).
**Code root:** `D:\1\management`
**Last re-verified against source:** 12 Aug 2026 (Phases 04 code pass)
**Inputs:** Live repo state + *Technical Architecture & Investor Due Diligence* (v1.0, 9 Aug 2026) + prior hardening reports under `docs/`
**Architecture decision:** Keep the modular monolith. Do not split services until Phase 3 load/ownership evidence justifies it.
### How this plan works
```mermaid
flowchart TD
now[Current_beta_pre_scale] --> sec[Close_security_P0]
sec --> p0[Finish_Phase0_evidence]
p0 --> p1[Phase1_replica_safe]
p1 --> p2[Phase2_operate_recover]
p2 --> p3[Phase3_prove_under_load]
p3 --> prod[Production_ready_gate]
```
| Stage | Outcome |
|-------|---------|
| Security P0 + Phase 0 close | Safe enough to run a controlled environment; envelope proven |
| Phase 1 | Safe to run **two API replicas** + worker |
| Phase 2 | Operable: observe, backup/restore, commercial/privacy baselines |
| Phase 3 + §13 checklist | **Production ready** — claims allowed only after exit evidence |
---
## 1. Definition of “production ready” (the finish line)
The project is **production ready** only when all of the following are true and evidenced:
1. Install, generate, lint, type-check, test, and build from a clean checkout
2. Deploy a known topology (API, frontends, PostgreSQL, Redis, storage, worker)
3. Run **two API replicas** without duplicate bookings, duplicate cron side effects, or missing files
4. Deliver notifications that were written to the outbox (email + realtime) without multi-replica double-send
5. Detect failure, restore data within agreed RPO/RTO, and show no unresolved critical/high dependency vulnerabilities outside a dated exception
6. Ship with Critical/High application-security findings closed (§3)
7. §13 diligence checkpoint items are checked off with retained evidence
Until then, the accurate label remains **capable beta / pre-scale**, not production SaaS.
**Out of scope for this plan:** new marketplace features, KYC/OCR, per-tenant Docker isolation, microservices rewrite, marketing-only work.
### Why this path
> The core product and data architecture exist; the next milestone is to convert that breadth into a reproducible, secure, observable, horizontally safe production system.
---
## 2. Current state (re-verified after project update)
### 2.1 Progress since the original diligence snapshot
| Area | Previous gap | Status now | Evidence |
|------|--------------|------------|----------|
| Turbo pipeline | Missing | **Done** | `turbo.json` (build/dev/lint/type-check/db:*) |
| Shared TS base | Missing | **Done** | `tsconfig.base.json` |
| Scripts / ops helpers | Missing | **Done** | `scripts/` (env, docker-prod-*, admin, `security-static-check.mjs`, backup guides) |
| Compose / Docker | Missing | **Done** | `docker-compose.dev.yml`, `docker-compose.production.yml`, `Dockerfile.dev` / `.production` / `.test`, `production/` mirror |
| `.gitignore` | Missing | **Done** | Root `.gitignore` |
| Static security script | Missing | **Done** | `scripts/security-static-check.mjs` + `npm run security:static` |
| CI | No workflows | **Partial** | `.gitea/workflows/` (`test.yml`, `build-and-deploy.yml`) + `.gitlab-ci.yml`; **no** `.github/workflows` |
| Notification outbox consumer | Missing | **Partial** | `processNotificationOutbox()` in `notificationService.ts`; cron every minute in `apps/api/src/index.ts` — still **inside the API process**; email/IN_APP delivery + DLQ; **no** `redis.publish` for realtime |
| Prior hardening passes | — | **Documented** | `SECURITY_HARDENING_APPLIED_REPORT.md`, leftover report, `docs/SECURITY_HARDENING_*` (June 2026) — API-key hash-only, Socket.IO actor verify, cookie session work, etc. |
### 2.2 What remains strong
| Area | Evidence |
|------|----------|
| Product surfaces | `apps/homepage`, `dashboard`, `admin`, `carplace`, `api` |
| Domain depth | Prisma: fleet, reservations, billing, payments, notifications, collections, admin |
| API shape | Express modular monolith |
| Auth / tenancy | JWT actors, HttpOnly cookies, admin 2FA, company middleware, subscription gates |
| Payments foundation | Stripe / PayPal / AmanPay; webhook signature verify; `WebhookEvent` |
| Upload validation | Magic bytes + MIME + size limits |
| Deploy intent | Compose + Traefik configs, backup/restore scripts present |
### 2.3 What still blocks a production claim
| Priority | Gap | Repo evidence (current) |
|----------|-----|-------------------------|
| **P0** | App security Critical/High still open | Team API spreads `passwordHash` / reset tokens; plaintext invite tokens; open redirect; unrestricted payment return URLs on authenticated checkout; admin presenter scrub incomplete; container Docker-socket design still in tree — see **§3** |
| **P0** | Ghost / dangerous container feature | `containerService.ts` + `apps/admin/.../containers/page.tsx` still present |
| **P0** | Dependency SCA not freshly proven | Diligence (9 Aug): 21 prod vulns; must re-run on CI/clean runner |
| **P0** | Phase 0 exit not fully evidenced | Envelope files exist, but clean-runner green CI + container removal + SCA gate not closed |
| **P1** | Outbox not multi-replica safe | Processor runs via `node-cron` in every API process; no lease/lock; no Redis realtime publish |
| **P1** | Process-local coordination | In-memory `express-rate-limit`; Carplace `idempotencyCache` `Map`; all crons in API `index.ts` |
| **P1** | Local file storage | `FILE_STORAGE_ROOT` disk — no S3/MinIO adapter found |
| **P1** | Ops blind spots | Only `GET /health`; no `/ready`; no `SIGTERM` graceful shutdown |
| **P1** | Catalog drift | Homepage pricing vs shared plan/entitlement constants (unchanged risk) |
```mermaid
flowchart LR
subgraph done [Restored_envelope]
Turbo[turbo_tsconfig]
Compose[compose_Dockerfiles]
Scripts[scripts_security_static]
Gitignore[gitignore]
end
subgraph open [Still_open]
Sec[App_security_Critical_High]
Containers[containerService_UI]
Shared[Redis_rate_limit_idempotency]
Worker[Separate_worker_lease]
Ready[ready_shutdown_object_store]
end
done --> open
```
---
## 3. Security assessment (re-checked 12 Aug 2026 after update)
**Scope:** Static re-verification of findings from the earlier application review against current source.
**Not in this pass:** Live pen-test, production secrets rotation, successful live `npm audit` (registry TLS may still block local runs).
### 3.1 Controls that remain solid
| Control | Evidence |
|---------|----------|
| Tenant scoping on core CRUD | Company routes use session `companyId` |
| JWT from env + HS256 pinned | `security/tokens.ts` |
| Session cookies HttpOnly / Secure / SameSite | `sessionCookies.ts` |
| Hashed company API keys (legacy plaintext removed) | Hardening reports + schema |
| Upload magic-byte validation | `http/upload` |
| Payment webhook signatures | Stripe / PayPal / AmanPay paths |
| Forwarded-header scrubbing by default | `sanitizeForwardedHeaders` unless `TRUSTED_FORWARD_HEADERS=true` |
| Site payment redirect allowlist | `assertAllowedPaymentRedirect` in `site.service.ts` |
### 3.2 Findings status after project update
| Sev | ID | Status | Location | Finding |
|-----|----|--------|----------|---------|
| Critical | S1 | **FIXED (Phase 0)** | `teamService.ts` | Team list/invite use safe presenter; no hash/token leakage |
| Critical | S2 | **FIXED (Phase 0)** | `containerService.ts` + admin containers page + ADR-001 | Feature disabled / fail-closed; UI shows out-of-scope |
| High | S3 | **FIXED (Phase 0)** | `teamService.ts` invite | Invite token stored as SHA-256 hash |
| High | S4 | **FIXED (Phase 0)** | Prisma `Employee` + auth repo | `@@unique([companyId, email])`; login fails closed on ambiguity |
| High | S5 | **FIXED (Phase 0)** | `SignInForm.tsx` | Safe relative-path redirect only |
| High | S6 | **FIXED (Phase 0)** | `paymentRedirects.ts` + payment/subscription services | Authenticated checkout allowlists return URLs |
| High | S7 | **FIXED (Phase 0)** | `admin.schemas` / `admin.repo` | Slug regex + slugify on update |
| High | S8 | **FIXED (Phase 0)** | `admin.presenter.ts` | Strips reset/verification secrets |
| High | S9 | **FIXED (docs + default scrub)** | `forwardedHeaders.ts` + `docs/ops/proxy-trust.md` | Default scrub; TRUSTED_FORWARD_HEADERS documented |
| Medium | S10 | **FIXED (Phase 0)** | employee/admin reset repos | Hash-only reset token lookup |
| Medium | S11 | **FIXED (Phase 3)** | reservation/review presenters | `reviewToken` omitted from API JSON |
| Medium | S12 | **FIXED** | `site.repo` / `site.service` | Public booking token unused-only on payment consume |
| Medium | S13 | **FIXED** | `requireFreshAdmin2FA` | Max-age TTL (`ADMIN_FRESH_2FA_MAX_AGE_MS`, default 30m) |
| Medium | S14 | **FIXED** | `.gitignore` | Present |
| Medium | S15 | **FIXED** | `scripts/security-static-check.mjs` | Present; CI wired; local pass after env scrub |
### 3.3 Dependency / SCA status
| Check | Result |
|-------|--------|
| Diligence SCA (9 Aug 2026) | 21 production findings: 1 critical, 14 high, 5 moderate, 1 low |
| Local re-audit | May fail on TLS to registry — **do not treat as clean** |
| Required | CI/clean-runner `npm audit --omit=dev` (or OSV) with fail-on critical/high |
### 3.4 Security remediations (ordered)
**P0 — before any production traffic**
1. **S1:** Explicit safe select/presenter for team APIs — never return hashes/tokens
2. **S3:** Hash invite tokens at rest; remove raw dual-match after migration (**S10**)
3. **S8:** Expand admin presenter denylist
4. **S2:** Remove/disable `containerService` + admin containers UI from GA
5. **S14/S15:** Already fixed — keep in CI
6. Re-run and clear dependency critical/high
**P1 — before multi-user GA**
7. **S4:** `@@unique([companyId, email])` + fail-closed login
8. **S5:** Allowlist relative same-origin post-login redirects
9. **S6:** Apply payment redirect allowlist to authenticated checkout/subscription
10. **S7:** Slugify/validate admin slug updates
11. **S9:** Document proxy trust; never enable trusted forwards without edge scrubbing
12. **S11S13:** Hide review tokens; single-use public access; align fresh 2FA on money mutations
### 3.5 Security exit criteria
- [ ] No API response includes password hashes, TOTP secrets, or raw reset/invite tokens
- [ ] Invite/reset tokens hashed at rest; legacy raw match removed
- [ ] Container/Docker-socket feature absent from production scope
- [ ] Login redirect and payment return URLs allowlisted on all checkout paths
- [ ] Employee email uniqueness (or fail-closed login) enforced
- [ ] CI runs `security:static` + SCA; no unresolved critical/high outside dated exception
- [ ] Independent pen-test after deploy envelope proven (Phase 3)
---
## 4. Guiding principles
1. **Evidence over claims** — Phase exit criteria must be demonstrable.
2. **Close Critical/High security before scale work** — Envelope restore is largely done; app-sec P0 is now the front of the queue.
3. **Shared state before more replicas** — Redis/DB/object storage before scaling API.
4. **One worker plane** — Notifications and scheduled jobs must not run identically on every API replica.
5. **Disable incomplete privileged features** — Especially Docker-socket container management.
6. **One commercial source of truth** — Marketing, checkout, and enforcement share typed entitlements.
7. **Extract services last** — Only after measurement.
---
## 5. Phase 0 — Evidence recovery
**Goal:** Reproducible build/deploy envelope + security hygiene baseline.
**Update:** Core files are **restored**. Remaining work is **prove + close security/container/SCA**.
### 5.1 Build orchestration — DONE
| Deliverable | Status |
|-------------|--------|
| `turbo.json` | Present |
| `tsconfig.base.json` | Present |
| `scripts/` (env, docker-prod, admin, security-static) | Present |
### 5.2 Runtime topology — DONE (files present)
| Deliverable | Status |
|-------------|--------|
| `docker-compose.dev.yml` / `.production.yml` | Present |
| `Dockerfile.dev` / `.production` / `.test` | Present |
| Env examples | Present (`.env.example`, docker env samples) |
| Backup/restore scripts | Present under `scripts/` |
**Still required as evidence:** recorded smoke that Compose boots API + Postgres + Redis and `/health` succeeds on a clean machine.
### 5.3 Continuous integration — PARTIAL
| Deliverable | Status |
|-------------|--------|
| Gitea workflows | Present (`.gitea/workflows/test.yml`, `build-and-deploy.yml`) |
| GitLab CI | Present (`.gitlab-ci.yml`) |
| GitHub Actions | Not present (optional if Gitea/GitLab is the system of record) |
| Proven green run + SCA fail gate | **Not evidenced in this review** |
### 5.4 Ghost container control plane — NOT DONE
| Action | Status |
|--------|--------|
| Remove admin containers UI | **Still present** |
| Quarantine/delete `containerService.ts` | **Still present** |
| ADR: out of GA | Missing |
### 5.5 Dependency hygiene — NOT EVIDENCED
Must re-run SCA on CI and clear critical/high.
### Phase 0 exit criteria (updated checkboxes)
- [x] `turbo.json` + `tsconfig.base.json` + `scripts/` present in tree
- [x] Compose + Dockerfiles present in tree
- [x] `.gitignore` + `security:static` present
- [x] Team API no longer returns password hashes / reset tokens; invite tokens hashed at rest (**S1/S3**)
- [x] Admin presenter scrubs reset/verification secrets (**S8**)
- [x] Container orchestration disabled + ADR (`docs/ADR-001-disable-per-tenant-containers.md`) (**S2**)
- [x] Login redirect allowlisted; authenticated payment return URLs allowlisted; admin slug validated; employee `(companyId, email)` unique (**S4S7**)
- [x] Env example/dev templates scrubbed of real-looking secrets; `security:static` passes locally
- [x] Gitea CI includes `security:static` + `npm audit --omit=dev --audit-level=high`
- [ ] Fresh clone: `npm ci` → generate → lint → type-check → test → build with no local repair (needs recorded evidence on a clean runner)
- [ ] CI green on default branch with SCA policy (push/run evidence)
- [ ] Compose smoke: API + Postgres + Redis; `/health` ok (recorded)
- [ ] No unresolved critical/high vulns outside dated exceptions (await CI audit result)
---
## 6. Phase 1 — Correctness and shared state
**Goal:** Two API replicas + one dedicated worker are correct under retries and failover.
**Status (12 Aug 2026):** Core code landed. Still needs `npm ci`, migrate, and a two-replica Compose smoke for exit evidence.
### 6.1 Notification outbox — DONE in code
| Piece | Status |
|-------|--------|
| Process isolation | `apps/api/src/workers/index.ts` + Compose `api-worker`; API jobs only if `ENABLE_EMBEDDED_JOBS=true` |
| Leasing | `lockedAt` / `lockedBy` / `attempts` / `availableAt` + claim via `updateMany` |
| Realtime | `redis.publish('notifications:' + userId, …)` on IN_APP delivery |
| Metrics | Phase 2 `/metrics` + outbox counters (scrape/alerts still open) |
### 6.2 Shared rate limiting — DONE in code
Redis store in `redisRateLimitStore.ts` (memory when `NODE_ENV=test` or `RATE_LIMIT_STORE=memory`).
### 6.3 Durable booking idempotency — DONE in code
`idempotencyStore.ts` (Redis; memory in test) used by Carplace `/reservations`.
### 6.4 Externalize scheduled work — DONE in code
Cron moved to `workers/jobs.ts` with Redis leader lock. API no longer starts cron by default.
### 6.5 Object storage — DONE in code (optional)
`FILE_STORAGE_DRIVER=local|s3` + `@aws-sdk/client-s3` + MinIO Compose profile `storage`. Default remains local disk.
### 6.6 Readiness and graceful shutdown — DONE in code
| Item | Status |
|------|--------|
| `GET /health` | Liveness |
| `GET /ready` | DB + Redis + storage probes |
| `SIGTERM` drain | API + worker close HTTP/Socket/Redis/Prisma |
### Phase 1 exit criteria
- [x] Worker entrypoint + outbox lease + Redis publish implemented
- [x] Redis rate limits + durable Carplace idempotency implemented
- [x] Cron externalized with leader lock; `/ready` + graceful shutdown implemented
- [x] S3/MinIO adapter + Compose worker/MinIO services present
- [ ] Two API replicas + one worker: recorded concurrency/retry smoke (needs runner)
- [ ] Outbox no double-send under two API replicas (API without embedded jobs)
- [ ] Files readable across replicas when `FILE_STORAGE_DRIVER=s3` (optional smoke)
---
## 7. Phase 2 — Operational control
**Code baselines landed (2026-08):** metrics/logs endpoint, plan catalog + tests, OpenAPI coverage gate, backup smoke check, privacy + billing/notification source-of-truth docs. Remaining work is **evidence** (drills, owners, alerts).
| Item | Status | Location |
|------|--------|----------|
| Structured JSON access logs + `/metrics` (latency, status, outbox) | **In code** | `apps/api/src/lib/opsMetrics.ts`, `app.ts`, worker |
| Readiness `/ready` | **In code** (Phase 1) | DB / Redis / storage |
| Plan/entitlement catalog + contract tests | **In code** | `packages/types/src/planCatalog.ts`, homepage pricing import |
| OpenAPI completeness gate | **In code** | `npm run openapi:coverage``scripts/check-openapi-coverage.mjs` |
| Backup artifact smoke check + RPO/RTO checklist | **In code / docs** | `scripts/backup-restore-smoke-check.sh`, `scripts/backup-restore-guide.md` |
| Privacy data map | **Doc baseline** | `docs/PRIVACY_DATA_MAP.md` (owners / DSAR still open) |
| Billing & notification SoT | **Doc baseline** | `docs/BILLING_NOTIFICATION_SOURCE_OF_TRUTH.md` |
| Staging alert + restore drill evidence | **Open** | Ops exercise |
| Provider reconciliation sample | **Open** | Finance / eng |
### Phase 2 exit criteria
- [ ] Staging incident detectable and recoverable via runbooks (metrics scraped + alert fired once)
- [ ] Restore exercise meets RPO/RTO (dated drill using backup smoke check)
- [ ] Provider reconciliation sample exists
- [x] Plan catalog single-sourced with tests
- [x] Privacy data map drafted (assign legal/ops owners before GA)
- [x] OpenAPI coverage script in CI
- [x] Billing/notification source-of-truth documented
---
## 8. Phase 3 — Scale and assurance
**Goal:** Prove the system holds under load/failure, tenant isolation, independent security testing, and operable release/secret drills. Keep the modular monolith until measurement says otherwise (ADR-002 defers RLS).
**Code / runbook baselines landed (2026-08):**
| Item | Status | Location |
|------|--------|----------|
| Cross-tenant negative suite | **In code** | `apps/api/src/tests/integration/cross-tenant-isolation.test.ts` |
| S11 reviewToken scrubbed from API payloads | **FIXED** | reservation presenter + review service presenters |
| Soak / load probe (+ optional k6) | **In code** | `scripts/load/soak-probe.mjs`, `booking-smoke.k6.js``npm run test:soak` |
| Failure injection helper | **In code** | `scripts/chaos/failure-injection.sh` |
| Canary / rollback runbook | **Doc** | `docs/ops/canary-rollback.md` |
| Key rotation drill | **Doc** | `docs/ops/key-rotation-drill.md` |
| Pen-test scope pack | **Doc** | `docs/security/pen-test-scope.md` |
| Postgres RLS | **Deferred** | `docs/ADR-002-defer-postgres-rls.md` |
### Phase 3 exit criteria
- [ ] Soak + failure-injection drill completed on staging with dated metrics evidence
- [x] Cross-tenant suite green in CI (`cross-tenant-isolation`) — **code landed**; CI run is evidence
- [ ] Independent pen-test report in `security-reports/`; Critical/High closed or accepted
- [ ] Canary promote **or** rollback drill recorded once
- [ ] Key rotation drill recorded on staging
- [x] App-level isolation suite started; RLS deferred per ADR-002
- [x] S11 review tokens not returned in reservation/review JSON
- [x] S12 single-use public payment token consume
- [x] S13 fresh admin 2FA TTL
### Phase 4 (months 36) — extract only if measured
**Default:** stay on the modular monolith + `api-worker` (ADR-003). Phase 4 is **not** a microservices rewrite.
| Item | Status | Location |
|------|--------|----------|
| Extraction policy ADR | **Accepted** | `docs/ADR-003-defer-service-extraction.md` |
| Gates G1G7 + candidates | **Doc** | `docs/ops/phase4-extraction-gates.md` |
| Measurement template | **Doc** | `docs/ops/phase4-measurement-template.md` |
| Module seam map | **Doc** | `docs/ops/phase4-module-boundaries.md` |
| Actual service split | **Blocked** until a candidate passes G1G7 | — |
#### Phase 4 exit criteria (for *deciding*, not for “having microservices”)
- [x] Extraction gates and candidates documented
- [x] In-monolith-first alternatives listed (scale workers, async media, thin webhooks)
- [ ] At least one soak/profile attribution packaged with the measurement template (needs Phase 3 evidence)
- [ ] Explicit decision recorded per candidate: **do not extract** (default) or approved extract ADR
Candidates if gates ever pass: payments/webhooks, notification worker as independent deployable, media processing.
---
## 9. Risk register → plan mapping
| ID | Risk | Status | Addressed by |
|----|------|--------|--------------|
| R1 | Unreproducible package | **Mostly mitigated** (files restored; prove CI smoke) | Phase 0 evidence |
| R2 | Dependency vulnerabilities | **Open** (CI policy; clear on runner) | Phase 0.5 / CI SCA |
| R3 | Privileged container feature | **Mitigated in code** (ADR-001) | Phase 0.4 + **S2** |
| R4 | Outbox not dispatched | **Mitigated in code** (worker + leases) | Phase 1.1 |
| R5 | Process-local rate limit / idempotency | **Mitigated in code** (Redis stores) | Phase 1.21.3 |
| R6 | Embedded schedules | **Mitigated in code** (worker + lock) | Phase 1.4 |
| R7 | Local file persistence | **Mitigated in code** (S3 driver) | Phase 1.5 |
| R8 | Ops blind spots | **Partial** (metrics/logs in code; alerts/drills open) | Phase 1.6 + Phase 2 |
| R9R14 | Privacy, catalog, OpenAPI, legacy overlap, FE drift, flaky tests | **Partial / later** (catalog, OpenAPI gate, privacy map, SoT docs) | Phase 23 |
| **S1S8** | App security Critical/High | **Fixed in code** (S9 documented) | §3 P0/P1 |
| **S10S15** | Medium app security | **Fixed in code** (S11S13 included) | Hardening + Phase 3 |
| **S16S21** | Medium/Low (undefined IDs) | **Track in pen-test** | Phase 3 evidence |
---
## 10. Suggested ownership and evidence log
| Field | Example |
|-------|---------|
| Phase | 0 / Security P0 |
| Date | YYYY-MM-DD |
| Commit / tag | `prod-ready-phase0` |
| Commands | `npm ci && npm run type-check && npm run security:static && npm audit --omit=dev` |
| Artifacts | CI URL, Compose smoke logs, audit report |
| Exceptions | CVE-xxxx until DATE by OWNER |
| Sign-off | Eng lead |
---
## 11. Explicit non-goals (until gates pass)
- Claiming production ready / HA / horizontally scaled before security P0 + Phase 1 exit evidence
- Shipping per-tenant container orchestration
- Guaranteeing SMS/push without provider paths + worker proof
- Marketing KYC / license authenticity beyond date/expiry validation
- Splitting the monolith for its own sake
---
## 12. Next backlog (when implementation resumes)
**Immediate (security + Phase 0 close)**
1. Fix team API secret leakage (**S1**); hash invite tokens (**S3**); scrub admin presenter (**S8**)
2. Remove/disable `containerService` + admin containers UI (**S2**)
3. Allowlist login redirect (**S5**) and authenticated payment return URLs (**S6**); slugify admin slugs (**S7**); employee email uniqueness (**S4**)
4. Record clean-runner CI green + production SCA clear/critical policy
5. Record Compose smoke evidence
**Then Phase 1**
6. Move outbox + cron to dedicated worker with leases; add Redis publish for realtime
7. Redis rate-limit store; durable Carplace idempotency
8. Object storage (MinIO/S3); `/ready` + graceful shutdown
**Then Phase 23**
9. Observability, restore drill, catalog convergence, privacy map (Phase 2 evidence still open)
10. Soak/failure drills, cross-tenant CI green, pen-test report, canary + key-rotation evidence (Phase 3)
**Then Phase 4 (only if measured)**
11. Fill `docs/ops/phase4-measurement-template.md` from Phase 3 soak data; default decision remains **do not extract** (ADR-003)
---
## 13. Diligence checkpoint (definition of done)
1. Clean checkout builds/tests on documented Node/npm with no local repair
2. Production SCA has no unresolved critical/high outside formal exception
3. Two API replicas pass booking/payment/job/notification/file correctness with shared coordination
4. Authoritative API contract + auth test matrix
5. Restore exercise meets RPO/RTO
6. Logs/metrics/alerts/runbooks demonstrated in a failure exercise
7. Privacy controls cover classification, encryption plan, retention, privileged reads/exports, incident response
8. Plan catalog / checkout / entitlements single-sourced
9. Independent security testing closes critical/high or records explicit acceptance
10. **§3 Critical/High application findings closed**
---
## 14. Thesis and kickoff
**This plan is how RentalDriveGo gets to production ready.** The monorepo envelope is largely restored; the remaining path is: close Critical/High app security → finish Phase 0 evidence → replica-safe Phase 1 → operate/recover Phase 2 → prove Phase 3 → pass §13.
**When implementation starts**, execute §12 in order. Do not skip security P0 for feature work. Do not claim production ready until §1 and §13 are evidenced.
---
*End of production-readiness plan. Code root: `D:\1\management`. Companion diligence: `RentalDriveGo_Technical_Architecture_and_Investor_Due_Diligence.docx`. Re-verified: 12 Aug 2026.*