Files
carmanagement/docs/design/PRODUCTION_READINESS_IMPLEMENTED.md
T
root 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
fix production issues
2026-08-12 16:48:41 -04:00

107 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Production readiness — what was implemented
**Date:** 2026-08-12
**Code root:** monorepo `apps/*`, `packages/*`
**Plan:** `docs/ops/RentalDriveGo_Production_Readiness_Plan.md`
This document is the design-facing summary of work already landed. It is not a backlog.
---
## Architecture decision (unchanged)
Keep a **modular Express monolith** plus a dedicated **job worker process**. Do not split payments/webhooks/media into microservices until measurement gates pass (ADR-003).
```
[Traefik] → [API × N] → PostgreSQL
↓ ↑
[Redis] [api-worker]
[local disk | S3/MinIO]
```
---
## Phase 0 — Security & envelope
| Area | Design outcome | Primary paths |
|------|----------------|---------------|
| Team API secrets | Safe presenters; no `passwordHash` / raw reset tokens in responses | `apps/api/src/services/teamService.ts` |
| Invite tokens | Stored as SHA-256 hashes | `teamService.ts` |
| Admin presenters | Scrub reset/verification secrets | `admin.presenter.ts` |
| Per-tenant Docker | Feature **fail-closed**; UI out-of-scope | `containerService.ts`, ADR-001 |
| Login redirects | Relative same-origin allowlist only | dashboard `SignInForm` |
| Payment return URLs | Authenticated checkout allowlists | `paymentRedirects.ts` |
| Admin slugs | Validated / slugified | admin schemas/repo |
| Employee email | `@@unique([companyId, email])`; ambiguous login fails closed | Prisma + auth repo |
| Reset / email verify tokens | Hash-only lookup (no raw dual-match) | employee/admin repos |
| Env templates | Scrubbed of real-looking secrets | `.env.example`, docker env samples |
| CI hygiene | `security:static` + production `npm audit` gate | `.gitea/workflows/test.yml` |
---
## Phase 1 — Replica-safe shared state
| Area | Design outcome | Primary paths |
|------|----------------|---------------|
| Job plane | Dedicated `api-worker`; API embeds jobs only if `ENABLE_EMBEDDED_JOBS=true` | `apps/api/src/workers/` |
| Notification outbox | DB leases (`lockedAt` / `lockedBy` / `attempts` / `availableAt`) | `notificationService` + migration |
| Realtime | Redis publish on IN_APP delivery | worker / notification service |
| Rate limits | Shared Redis store | `redisRateLimitStore.ts` |
| Carplace idempotency | Redis-backed store | `idempotencyStore.ts` |
| Files | `FILE_STORAGE_DRIVER=local\|s3` (+ MinIO compose profile) | `lib/storage`, `objectStorage` |
| Readiness | `GET /ready` checks DB, Redis, storage | `app.ts` |
| Shutdown | SIGTERM drains API and worker | `index.ts`, `workers/index.ts` |
---
## Phase 2 — Operational control (code baselines)
| Area | Design outcome | Primary paths |
|------|----------------|---------------|
| Metrics / logs | Structured JSON access logs; Prometheus text at `GET /metrics` | `opsMetrics.ts`, `app.ts` |
| Worker metrics | Optional `WORKER_METRICS_PORT` exposes `/metrics` + `/health` | `workers/index.ts` |
| Plan catalog | Single source in `@rentaldrivego/types` | `packages/types/src/planCatalog.ts` |
| Homepage pricing | Imports catalog (no hard-coded MAD amounts) | `apps/homepage/.../pricing-config.ts` |
| OpenAPI gate | Coverage script + CI step | `scripts/check-openapi-coverage.mjs` |
| Backup smoke | Artifact checker + RPO/RTO checklist | `scripts/backup-restore-*` |
| Privacy / SoT docs | Baseline maps | `docs/PRIVACY_DATA_MAP.md`, `docs/BILLING_NOTIFICATION_SOURCE_OF_TRUTH.md` |
**Still evidence-only:** staging alert fire, dated restore drill, provider reconciliation sample, privacy owners.
---
## Phase 3 — Scale & assurance (code / runbooks)
| Area | Design outcome | Primary paths |
|------|----------------|---------------|
| Cross-tenant suite | Vehicles, customers, reservations, offers, team, payments negatives | `cross-tenant-isolation.test.ts` |
| S11 | `reviewToken` omitted from API JSON | reservation presenter, review service |
| S12 | Public booking token: GET does not burn; payment **consumes** once | `site.service.ts` / `site.repo.ts` |
| S13 | Fresh admin 2FA max-age (default 30 minutes) | `requireFreshAdmin2FA` |
| Soak / chaos | Node soak probe + optional k6; failure-injection helper | `scripts/load/`, `scripts/chaos/` |
| Canary / keys / pen-test | Runbooks and scope pack | `docs/ops/`, `docs/security/pen-test-scope.md` |
| Postgres RLS | Explicitly deferred | ADR-002 |
**Still evidence-only:** soak/chaos drill records, pen-test report, canary + key-rotation drills.
---
## Phase 4 — Extract only if measured
| Area | Design outcome |
|------|----------------|
| Default | Stay on monolith + `api-worker` |
| Gates | G1G7 in `docs/ops/phase4-extraction-gates.md` |
| Candidates | Notifications worker deployable, payments/webhooks, media — **blocked** until measurement |
| Code change | None required for “phase complete”; ADR-003 + templates only |
---
## Explicit non-goals (still)
- Claiming production ready without §13 evidence
- Shipping per-tenant container orchestration
- Microservices rewrite without gate evidence
- Marketing KYC / OCR authenticity beyond license date checks