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,106 @@
# 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