drop-monorepo-refactor-plan Plan: Drop Monorepo Refactor (src/ → apps/+packages/) MC: #10051 Owner: John (orchestrator) + CodeCraft + Proveo + Skillforge Estimated total: ~15h CodeCraft + 2h validation + 1h docs = ~18h fleet time Strategy: 4-PR staged migration (NOT atomic) per Petter's research Research: /tmp/drop-monorepo-research-10051.md (347 lines, Petter Graff) Research Summary Drop monorepo currently uses npm workspaces under src/ (3 registered: src/shared , src/drop-api , src/drop-app ; src/drop-mobile is on separate release cycle, NOT in workspace config but referenced in 3 mobile workflows). Migrating to apps/ + packages/ requires touching 80+ hardcoded paths across 8 GitHub Actions workflows, 2 root Dockerfiles, buildspec.yml (just merged in PR #3), 2 docker-compose files, and root package.json lint-staged. Top 3 production risks Dockerfile.drop-app:59,67 — WORKDIR /app/src/drop-app baked into Next.js standalone runner stage. Silent build success / runtime fail on App Runner cold start. ci.yml:49-53 paths-filter must update atomically with rename. Wrong order = silent CI skip = unreviewed code reaches main. Dockerfile.api uses raw source-copy to /shared/ (not workspace symlinks) — structurally inconsistent with Dockerfile.drop-app . Audit separately. Why multi-PR (NOT atomic) Each PR is reviewable, revertable, testable independently CI workflow update (PR 3) is highest-risk single change → its own PR Pre-Finanstilsynet: every CI/security-gate change deserves explicit review 4 conflict-able PRs > 1 monster PR with 80+ touched paths Objective Restructure Drop monorepo to industry-standard Turborepo/pnpm convention ( apps/ for deployables, packages/ for shared libs) WITHOUT introducing behavior changes, downtime, or production deploys breaking. Land in 4 staged PRs over 2-3 days, with staging validation before prod merge. Team Orchestration Team Members ID Name Role Agent Type B1 codecraft-pkg PR 1: workspace config + packages/ rename codecraft B2 codecraft-apps PR 2: apps/ rename + Dockerfiles + buildspec codecraft B3 codecraft-ci PR 3: 8 GitHub workflow files update codecraft B4 codecraft-cleanup PR 4: delete old src/ + final validation codecraft V1 proveo-staging Staging validation pre-PR-4 merge proveo V2 proveo-prod Production validation post-PR-4 merge proveo V3 securion-fintech Pre-Finanstilsynet security audit securion D1 skillforge-docs BookStack page + memory entries skillforge R1 gemini-reviewer Review every PR before merge gemini-reviewer Step-by-Step Tasks Phase 1 — Internal packages rename (low risk, isolated) Task 1: PR 1 — Rename src/shared → packages/shared Owner: B1 (codecraft) BlockedBy: none (research deliverable already done) Branch: feat/monorepo-pr1-packages-shared Scope: git mv src/shared packages/shared (preserves history) Root package.json workspaces array: "src/shared" → "packages/shared" npm install regenerate lockfile (in Linux container per ZAKON LOCKFILE PORTABILITY) Verify apps/drop-app/node_modules/@drop/shared symlink resolves (post-PR-2; for PR 1 verify root node_modules/@drop/shared resolves) Update lint-staged glob if src/shared/ referenced Acceptance: npm install --ignore-scripts --no-audit exit 0 cd src/drop-app && npx tsc --noEmit exit 0 (shared resolves via root workspace) cd src/drop-api && npx tsc --noEmit exit 0 CI Quality Gate REQUIRED green on PR No file outside packages/shared/ and package.json + package-lock.json modified Task 2: Gemini review PR 1 Owner: R1 BlockedBy: 1 Acceptance: VERDICT: APPROVE Task 3: Squash merge PR 1 to main Owner: John BlockedBy: 2 Post-merge: verify main CI green Phase 2 — Apps rename + Docker (highest production risk) Task 4: PR 2 — Rename src/drop-* → apps/drop-* + Dockerfile + buildspec updates Owner: B2 (codecraft) BlockedBy: 3 (PR 1 merged) Branch: feat/monorepo-pr2-apps-docker Scope: git mv src/drop-app apps/drop-app , src/drop-api apps/drop-api , src/drop-mobile apps/drop-mobile Update root package.json workspaces: "src/drop-api" → "apps/drop-api" , "src/drop-app" → "apps/drop-app" Update lint-staged globs (3 patterns) + cd src/drop-* commands Update Dockerfile.drop-app : ALL src/drop-app → apps/drop-app , src/shared → packages/shared . CRITICAL: both WORKDIR /app/src/drop-app lines (59 + 67) → /app/apps/drop-app Update Dockerfile.api : src/drop-api → apps/drop-api , src/shared → packages/shared AND /monorepo/src/shared/ → /monorepo/packages/shared/ (the absolute-path hack) Update buildspec.yml : 7 occurrences of src/drop-app → apps/drop-app , src/shared → packages/shared Update docker-compose.yml + docker-compose.dev.yml build contexts + bind mounts Verify next.config.ts outputFileTracingRoot: ../../ still resolves to repo root from apps/drop-app/ (it does — same depth) Local Docker build MANDATORY (ZAKON LOCAL DOCKER BUILD): docker buildx build --platform linux/amd64 -f Dockerfile.drop-app . exit 0 Acceptance: npm install --ignore-scripts --no-audit exit 0 cd apps/drop-app && npx eslint . 0 errors cd apps/drop-app && npx tsc --noEmit exit 0 docker buildx build --platform linux/amd64 -f Dockerfile.drop-app . exit 0 (LOCAL evidence required) docker buildx build --platform linux/amd64 -f Dockerfile.api . exit 0 CI Quality Gate REQUIRED green on PR No CI workflow file modified in this PR (saved for PR 3) No src/ directory deleted yet (saved for PR 4) Task 5: Gemini review PR 2 Owner: R1 BlockedBy: 4 Acceptance: VERDICT: APPROVE Special review focus: Dockerfile WORKDIR lines, Dockerfile.api absolute path, lockfile linux-x64 variants Task 6: Squash merge PR 2 to main — CAUTION Owner: John BlockedBy: 5 Note: This DOES trigger deploy.yml auto-deploy. Production App Runner will build with new paths. Monitor aws apprunner describe-service until RUNNING status. If deploy fails, immediate rollback via CF CNAME flip + previous SHA redeploy per DEPLOY-MAP.md. Pre-merge mandatory: external curl -sI https://app.getdrop.no shows current production health Post-merge mandatory: external curl -sI https://app.getdrop.no shows healthy within 10min of CF CNAME flip Phase 3 — CI workflows update (silent skip risk) Task 7: PR 3 — Update 8 GitHub Actions workflows Owner: B3 (codecraft) BlockedBy: 6 (PR 2 merged + production verified RUNNING) Branch: feat/monorepo-pr3-ci-workflows Scope: ci.yml : paths-filter (5 lines), working-directory, cache-dependency-path, cd commands, artifact paths deploy.yml : docker build context path deploy-staging.yml : paths, working-directory, cache-dependency-path, playwright report path hotfix.yml : working-directory x2, cache-dependency-path deploy-aws.yml : working-directory, docker build context mobile-ci.yml : paths-filter, working-directory x3, cache-dependency-path, artifact path mobile-deploy.yml : paths-filter, working-directory, git add path mobile-release.yml : working-directory, cache-dependency-path, VERSION_FILE path, git add path Acceptance: All 8 workflow files modified, no other code changes CI Quality Gate REQUIRED green on PR gh workflow view "CI — Quality Gate" runs against new paths mobile-ci.yml triggers on apps/drop-mobile/** paths-filter when mobile code changed (test by including 1-line mobile change in PR) Task 8: Gemini review PR 3 Owner: R1 BlockedBy: 7 Acceptance: VERDICT: APPROVE Special review focus: paths-filter glob accuracy (silent CI skip is the danger) Task 9: Squash merge PR 3 Owner: John BlockedBy: 8 Note: deploy-staging.yml manual workflow_dispatch test BEFORE merge, against PR HEAD SHA, to confirm staging path resolution Phase 4 — Cleanup + production validation Task 10: PR 4 — Delete legacy src/ directory + ALAI memory updates Owner: B4 (codecraft) BlockedBy: 9 (PR 3 merged + main CI green) Branch: feat/monorepo-pr4-cleanup Scope: git rm -r src/ (now empty after PR 1 + PR 2 moves) Update BUILD-BLUEPRINT.md repo structure section + build commands Update DEPLOY-MAP.md paths Update RUNBOOK.md if any path references Update project/architecture/*.md references Update ~/.claude/projects/-Users-makinja/memory/MEMORY-products.md Drop entry Update any ~/.claude/projects/-Users-makinja/memory/project_drop_*.md referring to old paths Acceptance: find . -path "./src" -type d empty grep -r "src/drop-" --include="*.md" --include="*.yml" --include="*.json" 0 hits in repo (excluding old git history) CI Quality Gate REQUIRED green on PR Task 11: Proveo validation — STAGING (pre-merge) Owner: V1 (proveo) BlockedBy: 10 (PR 4 ready, but NOT merged yet) Action: trigger deploy-staging.yml workflow_dispatch against PR 4 head SHA Acceptance: Staging App Runner reaches RUNNING state within 15min curl -s https://staging.getdrop.no/api/health | jq .status == "ok" Playwright smoke test (login + dashboard + send-money flow) passes No new Sentry errors in staging post-deploy Evidence written to /tmp/proveo-monorepo-staging-10051.json Task 12: Gemini review PR 4 Owner: R1 BlockedBy: 11 Acceptance: VERDICT: APPROVE Task 13: Securion fintech security audit (pre-prod merge) Owner: V3 (securion / Parisa Tabriz) BlockedBy: 11 Scope: monorepo path rename security implications — secrets accidentally exposed via different paths, .gitignore coverage, JWT/auth boundary integrity, OWASP Top 10 quick check Acceptance: No secret leaks introduced by path changes Auth middleware paths still correct No new attack surface introduced Report at /tmp/securion-monorepo-10051.md Task 14: Squash merge PR 4 to main Owner: John BlockedBy: 12, 13 Triggers: deploy.yml auto-deploy to production Pre-merge mandatory: external curl baseline, gh run list main shows green Post-merge mandatory: monitor App Runner deploy Task 15: Proveo validation — PRODUCTION Owner: V2 (proveo) BlockedBy: 14 Action: post-deploy verification per DEPLOY-MAP.md ZAKON PI2 protocol Acceptance: curl -s https://app.getdrop.no/api/health | jq .status == "ok" Playwright screenshot of dashboard (live data load) No CI deploy.yml errors No Sentry error spike in 30min post-deploy App Runner blue/green flip verified Evidence at /tmp/proveo-monorepo-prod-10051.json + screenshot Task 16: Skillforge documentation Owner: D1 (skillforge) BlockedBy: 15 Scope: BookStack page "Drop Monorepo Architecture" — apps/+packages/ structure, deploy paths, conventions Memory entry project_drop_monorepo_refactor_2026-XX-XX.md with lessons learned + path migration patterns Update ~/system/rules/zakon-local-docker-build.md if monorepo-specific gotchas surfaced Acceptance: BookStack page exists and synced Memory entry created MEMORY.md index updated Risk Register Risk Probability Impact Mitigation Dockerfile WORKDIR baked path miss (E1) MED HIGH (prod cold start fail) Mandatory local Docker build in PR 2 paths-filter wrong = silent CI skip (E4) LOW CRITICAL (unreviewed code in main) PR 3 has explicit paths-filter glob review by R1 Lockfile platform variants missing (E6) MED MED (CodeBuild fail) Regenerate in Linux container per ZAKON LOCKFILE PORTABILITY @drop/shared symlink resolution fails (E5) MED HIGH (build fail) PR 1 isolated test before PR 2 starts Sentry source maps un-symbolicate (E8) LOW LOW (debug noise only) Verify post-deploy Sentry dashboard Dockerfile.api absolute path break (E3) MED HIGH (drop-api fail) Local docker build evidence MANDATORY in PR 2 AWS App Runner deploy fails post-merge LOW CRITICAL (prod outage) CF CNAME rollback < 10s + previous SHA redeploy backend/ legacy dir confusion (E9) LOW LOW Document as legacy, do not rename in this MC Mobile workflow paths-filter coupling (E7) LOW MED Tested in PR 3 with 1-line mobile change Rollback Plan (per PR) PR Rollback action PR 1 git revert — pure rename, no behavior change. < 5min recovery. PR 2 git revert + ECR previous-SHA redeploy via apprunner start-deployment + CF CNAME flip. < 15min recovery. PR 3 git revert — workflows revert. CI may briefly run against wrong paths during revert window (acceptable). < 5min. PR 4 git revert — restores src/ from history. Same as PR 2 if production-affecting deploy triggers. Validation Checkpoints (cumulative across phases) After EACH PR merge to main: gh run list --branch main --limit 1 last run = SUCCESS for "CI — Quality Gate" curl -sI https://app.getdrop.no returns HTTP 200 aws apprunner describe-service --service-arn Status: RUNNING No new Sentry errors in 15min after deploy git log --oneline main shows clean linear history (squash merges) After PR 4 (final cleanup): 6. find /Users/makinja/ALAI/products/Drop -type d -name "src" returns 0 results 7. Repo size reduced (lockfile + node_modules can re-regenerate in fresh clone) 8. Skillforge BookStack page accessible at https://docs.alai.no Estimate of Total Time Phase CodeCraft hours Calendar days PR 1 (packages/) 1.5h Day 1 PR 2 (apps/ + Docker) 5h Day 1-2 PR 3 (CI workflows) 2.5h Day 2 PR 4 (cleanup) 2h Day 2-3 Proveo + Securion validation 2h Day 2-3 Skillforge docs 1h Day 3 Total ~14h 3 days Add 30% buffer for failure recovery iterations = ~18h fleet, 3 calendar days . Required Follow-ups backend/ legacy directory at repo root — confirm dead code in separate MC, then either rename or delete. NOT in scope of this MC. mobile-release.yml cross-references src/drop-app/src/config/app-versions.json from within mobile workflow — clarify ownership boundary in followup. Migration to true Turborepo (turbo.json) or pnpm — separate MC. This refactor only renames paths, does NOT change tooling. Sentry post-deploy verification — if source maps un-symbolicate, separate MC for Sentry config update. Per ZAKON PLAN compliance Validation task — Tasks 11 (Proveo staging) + 15 (Proveo prod) — end-to-end Playwright + curl + Sentry monitoring (NOT dry-run) Documentation task — Task 16 (Skillforge) — BookStack page + memory entry Approval Plan ready for CEO review. To execute: /build-plan ~/system/specs/drop-monorepo-refactor-plan.md Or dispatch first phase manually: /mehanik "Drop monorepo PR 1: packages/shared rename + workspace config" /Users/makinja/ALAI/products/Drop