📊 Project Completion Progress

78%
22%
Complete 38 of 49 weeks · 78%
Remaining 11 weeks · 22%

Remaining work breakdown

  • Sprint 17 Part B — modal + QC unmapped tab + dashboard widget · 1 week
  • Sprint 18 — AI Bridge integration (DrFone inference, vLLM via WireGuard) · 2 weeks
  • Sprint 19 — Repairs Pro data migration scripts + production dry-run · 1.5 weeks
  • Sprint 20 — Security hardening + accessibility audit · 1.5 weeks
  • UAT + cut-over · 2 weeks
  • Hyper-care · 3 weeks

📋 Phase 1 — Operational Blueprint 10/10

  • Business context & actor roster locked
  • End-to-end device flow (10 stages + branch states)
  • 14 master-data entities defined
  • 10 workflows locked (#9 Client Portal deferred to v2)
  • 20 critical business rules locked
  • Battery health thresholds (<80 / 80–84 / ≥85)
  • Batch ID format spec (YYMMDD-CLIENT-COURIER-AWB5-QTY)
  • SLP dispatch_rule = BATCH_LOCKED
  • Aging flags (>14d repair, >21d warehouse)
  • Free-zone tax = 0% VAT, USD primary / AED reference

🏗️ Phase 2 — Technical Blueprint 13/13

  • #1 System Architecture (modular monolith)
  • #2 Tech Stack (Next.js 15, NestJS 11, Prisma 6, PG16, Redis 7)
  • #3 Data Model (Prisma schema + RLS policies)
  • #4 API Spec (OpenAPI 3.1 conventions)
  • #5 Auth & Security Model
  • #6 Project Structure (pnpm + Turborepo monorepo)
  • #7 File Storage Strategy (MinIO + B2 backup)
  • #8 Background Jobs (BullMQ queue design)
  • #9 DevOps & Deployment
  • #10 Repairs Pro Migration Plan
  • #11 Acceptance Criteria (Gherkin)
  • #12 Sprint Roadmap
  • #13 Amendments Appendix (17 items)

📐 Amendments 17/17 locked

A1withTenant wrapper mandatory — no bare Prisma calls
A2Late-append blocked when invoice.status = sent
A3Generalised numbering_sequences + sequence_definitions
A4expected_batches.session_count column
A5daily_metrics_snapshots table
A6Duplicate completed repair-code assertion (defence-in-depth post-Mig 0003)
A7FX rate snapshot read order
A8Magic-link auth stubs (501)
A9BullMQ concurrency=1 (per-org upgrade → backlog B-001)
A10'migrated' source enum on device_repair_codes
A11finalizeDispatch idempotency (FOR UPDATE + early return)
A12INSERT + UPDATE same Prisma transaction, callback form only
A13sequence_definitions seed table (global, no RLS)
A14Prisma $transaction callback form only (no array form)
A15ESLint: no-bare-prisma, no-withtenant-in-iteration, no-async-array-mapretired S17 B1; plugin never built; deferred to B-006
A16FORCE ROW LEVEL SECURITY on all 26 tenant tables
A17withTenant must SET LOCAL ROLE ram_app — superusers bypass all RLS; role switch enforces isolation regardless of connection privilege

🏃 Sprint Execution — S0 → S17

Sprint Scope Status Verification
S0Foundations (monorepo, Docker, CI skeleton)✓ CompleteUnit tests
S1Tenancy & Auth (JWT + RLS)✓ CompleteIntegration ✓
S2Master Data CRUD✓ CompleteUnit tests
S3Asset Receiving✓ CompleteUnit tests
S4QC Workbench (triage, BER review)✓ CompleteUnit tests
S5Inventory & Parts Issue✓ CompleteUnit tests
S6Worksheets & Team Build✓ CompleteUnit tests
S7Outbound Dispatch✓ CompleteUnit tests
S8Invoicing & Pricing✓ CompleteUnit tests
S9Reports & Owner Dashboard✓ CompleteUnit tests
S10TypeScript polish (19 errors resolved)✓ Completetsc clean
S11Stub pages (Repairs, Technicians, Settings)✓ CompleteUnit tests
S12Devices page + pagination retrofit✓ CompleteUnit tests
S13drfone-parse BullMQ processor✓ CompleteUnit tests
S14bulk-upload processor + Team page✓ CompleteUnit tests
S15Infra catch-up (PG16, Redis, RLS idempotent)✓ CompleteIntegration ✓
S16Idempotent RLS + BullMQ e2e + CI tracked✓ CompleteE2E verified
S17 B1DrfoneCodeMapping + unmapped queue + reports count + CI all-green✓ CompleteCI verified (4 jobs)
Verification key:   Unit tests = code compiles + all jest unit tests pass  ·  Integration ✓ = exercised against live Postgres + Redis with RLS enforced  ·  E2E verified = full job → BullMQ worker → Prisma write chain validated  ·  Live-run verified = exercised against real external dependency (none yet — AI Bridge in Sprint 18 will be first)

🚀 Sprint 17 B1 Achievements 13/13

  • Migration 0004 — repair_codes catalogue table + 24 canonical codes seeded
  • drfone_code_mappings table + RLS + FORCE + UNIQUE(org_id, drfone_code)
  • device_repair_codes.repair_code_id FK (nullable) added
  • Source enum extended: drfone_mapped, drfone_unmapped
  • Legacy backfill for existing drfone / drfone_auto rows
  • DrfoneCodeMappingService — TenantContext for CRUD, explicit orgId for BullMQ worker (Rule #18)
  • DrfoneMappingsController — 7 routes including resolve endpoint
  • GET /initial-qc/unmapped-queue endpoint
  • GET /reports/drfone-unmapped-count endpoint
  • 30 demo mappings seeded for demo org
  • 426/426 unit tests passing — 26 spec files, tsc EXIT 0 (428→411: integration + e2e in dedicated CI jobs; +15 Part B Item 3 repair-codes tests)
  • e2e Test 3 (unmapped path) added to drfone-parse.e2e.spec.ts and passing
  • CI all 4 jobs green (run 12) — lint, unit, integration, build · e2e job wired as job 5

🧪 Test Coverage Snapshot

426/426
Unit tests passing
26 spec files
14/14
Integration tests
4 suites · live PG + Redis
5/5
E2E tests passing
bulk-upload 2/2 · drfone 3/3
EXIT 0
TypeScript clean
apps/api + apps/web
  • RLS isolation verified — zero rows returned without valid tenant context
  • reserveNumber: 20 concurrent callers → sequential 1–20, no gaps, no duplicates
  • First-call race: 5 concurrent callers on absent row → 1–5, no duplicates (DELETE approach)
  • drfone-parse e2e: mapped path (source=drfone_mapped, repair_code_id non-null) ✓
  • drfone-parse e2e: unmapped path (source=drfone_unmapped, repair_code_id null) ✓
  • drfone-parse e2e: idempotency (second run, same XML → same row count) ✓

📦 Backlog

IDItemStatusBlocking trigger
B-001 BullMQ per-org concurrency upgrade Deferred Before second paying tenant
B-002 reserveNumber first-call TOCTOU race ✓ Resolved S16-1b
B-003 Shared-packages tsconfig missing Deferred Second engineer onboarding
B-004 Migration 0004 backfill performance (production scale) Deferred Sprint 19 production migration
B-005 Remove --passWithNoTests from e2e CI step Deferred After 3 confirmed green e2e CI runs showing specs discovered
B-006 Build eslint-plugin-ram-custom as workspace package Deferred Second engineer onboarding (same trigger as B-003)

🚦 Outstanding Operational Items

  • Manual push of 12 queued commits via PAT with workflows scope (8be515ea7a39c1)
  • CI run 13 — first 5-job topology (lint · unit · integration · e2e · build); verify e2e shows ≥5 specs; unit job should show 426 tests
  • QC Workbench "Unmapped Codes" tab — UI not yet built (Sprint 17 Part B)
  • VPS order: 32 GB IONOS instance + domain registration

🎯 Remaining to Project Completion

  • Sprint 17 Part B — Item 3 ✓ (repair_codes CRUD) · Item 5 ✓ (e2e CI job) · Item 2 pending (confirmation modal) · Item 1 pending (QC unmapped tab) · Item 4 pending (dashboard widget)
  • Sprint 18 — AI Bridge integration (DrfoneCodeMapping inference layer, vLLM via WireGuard)
  • Sprint 19 — Repairs Pro data migration scripts + production dry-run
  • Sprint 20 — Security hardening + accessibility audit
  • UAT — Data migration, staff training, production cut-over
  • Hyper-care — Post-launch support window
Source of truth: docs/STATUS.md in saigates/ram-app-v2.0  ·  Update this page by editing docs/index.html