Skip to content

Monorepo Reorganization Implementation Plan

Status: ✅ COMPLETED — 2026-02-08 Branch: feat/monorepo-reorganizationCommit: All 5 phases implemented in a single branch and committed together Worklog: 2026-02-08_monorepo-reorganization_complete.md


Implementation Summary

All 5 phases were completed on 2026-02-08 in a single feature branch (feat/monorepo-reorganization) rather than 5 separate PRs as originally planned. This was faster and reduced merge overhead since the phases were tightly coupled.

Results:

  • 299 files changed (5,906 insertions, 5,866 deletions)
  • 381 tests passing (379 web app + 2 shared package)
  • 85%+ code coverage maintained
  • Build succeeds (~9s)
  • All git history preserved via git mv

Deviations from Plan

  1. Single branch instead of 5 PRs — All phases implemented on feat/monorepo-reorganization since local validation was sufficient and phases had tight dependencies.
  2. No apps/web/package.json created — The web app continues to use the root package.json for dependencies and scripts, with --config flags pointing to apps/web/ configs. This is simpler and avoids workspace hoisting complexity.
  3. Additional config fixes discovered during implementation:
    • Vite needed root: __dirname and envDir: path.resolve(__dirname, '../..') in apps/web/vite.config.mjs
    • Vitest needed root: dirname in apps/web/vitest.config.js
    • ~12 scripts in tooling/scripts/ needed __dirname path depth updates (.., '..''..', '..', '..') since they moved one level deeper
    • Import paths in scripts referencing apps/web/src/ needed updating from ../apps/web/src/ to ../../apps/web/src/
    • .eslintrc.json override paths needed apps/web/src/ prefix

What Was Updated

CategoryFiles Updated
Root configspackage.json, .eslintrc.json, .gitignore, firebase.json, vitest.workflows.config.js
App configsapps/web/vite.config.mjs, apps/web/vitest.config.js, apps/admin/vite.config.mjs
GitHub Actionsdeploy-dev.yml, deploy-prod.yml, deploy-preview.yml, ci.yml
Tooling scripts~12 scripts with path updates
Storybooktooling/.storybook/main.js (stories pattern)
DocumentationCLAUDE.md, .github/copilot-instructions.md, README.md
New filespackages/shared/ (4 files + 1 test)

Follow-up Work

Immediate (before merging to dev)

  • [ ] Deploy to dev environment and verify all 4 URLs work
  • [ ] Verify Firebase Functions deploy successfully
  • [ ] Run npm run validate end-to-end

After Issue #147 (Advanced Encryption Features)

  • [ ] Migrate encryption constants from apps/web/src/lib/encryption.js to packages/shared/encryption/
  • [ ] Migrate auth role constants from apps/web/src/lib/auth.js to use @lantern/shared/auth
  • [ ] Migrate devLog patterns to packages/shared/utils with conditional exports
  • [ ] Update services/functions/firebase/ to import from @lantern/shared/auth

Future Services Expansion

  • [ ] services/api/auth — Authentication API service
  • [ ] services/bots/slack — Slack integration bot
  • [ ] apps/mobile — React Native mobile app

Original Plan (Preserved for Reference)

Click to expand the original implementation plan

Context

The Lantern app currently uses a flat monorepo structure that has grown organically. As the codebase expands and we prepare for mobile development (Issue #246), we need a more scalable structure that:

  1. Separates concerns - Clear distinction between apps, backend services, and shared code
  2. Enables code sharing - Shared utilities for auth, encryption, and common helpers
  3. Supports future growth - Structure allows adding new apps (mobile), APIs, and bots
  4. Preserves git history - All file movements use git mv
  5. Minimizes deployment risk - Phased approach with testing at each step

This reorganization is a prerequisite for Issue #147 (advanced encryption features) which will need shared crypto utilities across web, admin, and backend services.

Target Structure

lantern_app/ ├── apps/ │ ├── web/ # Main Lantern PWA (current src/) │ │ ├── src/ │ │ ├── public/ │ │ ├── vite.config.mjs │ │ ├── vitest.config.js │ │ └── package.json │ └── admin/ # Admin portal (current admin/) │ ├── src/ │ ├── vite.config.mjs │ └── package.json ├── services/ │ ├── functions/ │ │ └── firebase/ # Cloud Functions (current firebase-functions/) │ ├── api/ │ │ └── docs/ # Docs API (current cloud-run-docs-api/) │ └── bots/ │ └── discord/ # Discord bot (current discord-bot/) ├── packages/ │ └── shared/ # Shared utilities (NEW) │ ├── auth/ # Shared auth constants & types │ ├── encryption/ # Shared crypto utilities (for Issue #147) │ └── utils/ # Common helpers (devLog patterns, etc.) ├── tooling/ # Build tools (NEW) │ ├── .storybook/ # Component library config │ └── scripts/ # Build utilities ├── docs/ # VitePress documentation (unchanged) ├── .github/ # CI/CD workflows (unchanged location) └── [root configs] # firebase.json, package.json, etc. Key benefits of this structure:

Scalable services: Can add services/api/auth, services/bots/slack later Clear categorization: functions vs APIs vs bots Shared code foundation: packages/shared/ ready for Issue #147 Clean tooling separation: Build tools don't clutter root Implementation Strategy: 5 Phased PRs Each phase is independently testable and can be rolled back without affecting other phases.

Timeline: 12-15 hours over 5 days (2-3 hours per phase) Risk Level: HIGH - affects all deployment pipelines Approach: Sequential PRs with 4-6 hour monitoring windows between merges

Phase 1: Apps Directory Migration (PR #1) Goal: Move main PWA and admin portal to apps/ directory Risk: MEDIUM - affects primary deployment pipelines Time: 3-4 hours Branch: feat/monorepo-phase1-apps

File Movements

cd /home/mechelle/repos/lantern_app

Create apps structure

mkdir -p apps/web apps/admin

Move main PWA to apps/web

git mv src apps/web/src git mv public apps/web/public git mv vite.config.mjs apps/web/vite.config.mjs git mv tailwind.config.cjs apps/web/tailwind.config.cjs git mv postcss.config.cjs apps/web/postcss.config.cjs git mv vitest.config.js apps/web/vitest.config.js git mv test.setup.js apps/web/test.setup.js

Move admin to apps/admin

git mv admin/* apps/admin/ rmdir admin Config File Updates

  1. Create apps/web/package.json

{ "name": "@lantern/web", "version": "0.1.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "test": "vitest", "test:coverage": "vitest run --coverage", "lint": "eslint src --ext .js,.jsx", "format": "prettier --write "src//*.{js,jsx,css}"" } } 2. Update apps/web/vite.config.mjs Change alias: { '@': path.resolve(__dirname, './src') } → no change needed (still points to ./src) Update version.json path reference if needed 3. Update apps/web/vitest.config.js Coverage exclude paths: change '.storybook/' → '../../.storybook/' Coverage exclude paths: change 'docs/' → '../../docs/**' 4. Update apps/admin/vite.config.mjs

envDir: path.resolve(__dirname, '../..'), // was '..' 5. Update apps/admin/package.json

{ "name": "@lantern/admin", // ... update any path references } 6. Update Root package.json Workspaces:

"workspaces": [ "apps/admin", "cloud-run-docs-api", "discord-bot", "firebase-functions" ] Scripts (update ~20 scripts):

"scripts": { "predev": "node scripts/generate-version.mjs", "dev": "vite --config apps/web/vite.config.mjs", "prebuild": "node scripts/generate-version.mjs", "build": "vite build --config apps/web/vite.config.mjs", "build:app": "node scripts/generate-version.mjs && vite build --config apps/web/vite.config.mjs", "preview": "vite preview --config apps/web/vite.config.mjs", "test": "vitest --config apps/web/vitest.config.js", "test:coverage": "vitest run --coverage --config apps/web/vitest.config.js", "admin:dev": "npm run dev -w apps/admin", "admin:build": "npm run build-storybook && npm run docs:build && npm run build -w apps/admin && node scripts/bundle-storybook-admin.mjs && node scripts/bundle-docs-admin.mjs", "admin:preview": "npm run preview -w apps/admin", "admin:deploy:preview": "npx wrangler pages deploy apps/admin/dist --project-name=lantern-admin-preview --branch=preview", "admin:deploy:dev": "npx wrangler pages deploy apps/admin/dist --project-name=lantern-admin-dev --branch=dev", "admin:deploy:prod": "npx wrangler pages deploy apps/admin/dist --project-name=lantern-admin-prod --branch=main", "lint:fix": "eslint apps/web/src --ext .js,.jsx --fix", "format": "prettier --write "apps/web/src//*.{js,jsx,css}"", "format:check": "prettier --check "apps/web/src//*.{js,jsx,css}"", "validate": "npm run validate:headers && npm run test:workflows:validate && npm run test:coverage && npm run format:check && npm run lint && npm run audit && npm run validate -w apps/admin && npm run validate -w discord-bot && npm run validate -w firebase-functions" } 7. Update scripts/generate-version.mjs

const versionPath = path.join(process.cwd(), 'apps', 'web', 'public', 'version.json') 8. Update scripts/bundle-storybook-admin.mjs

const adminDistDir = path.join(rootDir, 'apps', 'admin', 'dist', 'storybook') 9. Update scripts/bundle-docs-admin.mjs

const adminDistDir = path.join(rootDir, 'apps', 'admin', 'dist', 'docs') 10. Update GitHub Actions Workflows Files to update: .github/workflows/deploy-dev.yml, .github/workflows/deploy-prod.yml, .github/workflows/deploy-preview.yml

Changes for each workflow:

Build verification for main app:

  • name: Verify build output run: | if [ ! -d "apps/web/dist" ]; then echo "❌ Build failed: apps/web/dist directory does not exist" exit 1 fi if [ ! -f "apps/web/dist/index.html" ]; then echo "❌ Build failed: apps/web/dist/index.html does not exist" exit 1 fi if [ ! -f "apps/web/dist/_headers" ]; then echo "❌ Build failed: apps/web/dist/_headers does not exist" exit 1 fi echo "✅ Build succeeded" Deploy command for main app:
yaml
command: pages deploy apps/web/dist --project-name=lantern-app-dev --branch=${{ github.event.workflow_run.head_branch }}

Build verification for admin:

  • name: Verify build output run: | if [ ! -d "apps/admin/dist" ]; then echo "❌ Build failed: apps/admin/dist does not exist" exit 1 fi if [ ! -f "apps/admin/dist/index.html" ]; then echo "❌ Build failed: apps/admin/dist/index.html does not exist" exit 1 fi if [ ! -f "apps/admin/dist/_headers" ]; then echo "❌ Build failed: apps/admin/dist/_headers does not exist" exit 1 fi echo "✅ Build succeeded" Deploy command for admin:
yaml
command: pages deploy apps/admin/dist --project-name=lantern-admin-dev --branch=${{ github.event.workflow_run.head_branch }}

Testing Checklist Local validation:

npm ci npm run build:app ls -la apps/web/dist/ npm run admin:build ls -la apps/admin/dist/ npm run test:coverage npm run validate Post-merge validation (wait 4-6 hours):

https://dev.ourlantern.app loads ✅ https://admin.dev.ourlantern.app loads ✅ Auth flows work on both apps ✅ No console errors ✅ Real-time updates work Rollback Plan

git revert -m 1 <merge-commit-sha> git push origin dev Phase 2: Services Directory Migration (PR #2) Goal: Move backend services to categorized services/ structure Risk: MEDIUM - affects Firebase Functions and Cloud Run deployments Time: 2-3 hours Branch: feat/monorepo-phase2-services

File Movements

Create services structure with categories

mkdir -p services/functions services/api services/bots

Move Firebase Functions

git mv firebase-functions services/functions/firebase

Move Docs API

git mv cloud-run-docs-api services/api/docs

Move Discord Bot

git mv discord-bot services/bots/discord Config File Updates

  1. Update Root package.json Workspaces:

"workspaces": [ "apps/admin", "services/api/docs", "services/bots/discord", "services/functions/firebase" ] Scripts:

"scripts": { "start": "npm start -w services/bots/discord", "docs-api:dev": "npm run dev -w services/api/docs", "docs-api:start": "npm run start -w services/api/docs", "docs-api:deploy:dev": "npm run deploy:dev -w services/api/docs", "docs-api:deploy:prod": "npm run deploy:prod -w services/api/docs", "validate": "npm run validate:headers && npm run test:workflows:validate && npm run test:coverage && npm run format:check && npm run lint && npm run audit && npm run validate -w apps/admin && npm run validate -w services/bots/discord && npm run validate -w services/functions/firebase" } 2. Update firebase.json

{ "functions": { "source": "services/functions/firebase" } } 3. Update services/functions/firebase/package.json

{ "name": "@lantern/functions-firebase", // Update any relative path references if needed } 4. Update services/api/docs/package.json

{ "name": "@lantern/api-docs", "scripts": { "dev": "node --env-file=../../../.env.local --watch src/index.js" } } 5. Update services/bots/discord/package.json

{ "name": "@lantern/bot-discord" } 6. Update .github/workflows/ci.yml Discord bot audit command:

  • name: Audit discord-bot run: cd services/bots/discord && npm audit --audit-level=moderate Testing Checklist Local validation:

npm ci firebase emulators:start --only functions # Test Firebase Functions work npm run start -w services/bots/discord # Test Discord bot starts npm run docs-api:dev # Test docs API starts npm run validate Post-merge validation:

✅ Firebase Functions deploy successfully ✅ Cloud Functions respond to requests ✅ Discord bot receives events ✅ Docs API accessible Phase 3: Tooling Directory Migration (PR #3) Goal: Move Storybook and scripts to tooling/ directory Risk: LOW - mostly build-time tools Time: 2 hours Branch: feat/monorepo-phase3-tooling

File Movements

mkdir -p tooling git mv .storybook tooling/.storybook git mv scripts tooling/scripts Config File Updates

  1. Update tooling/.storybook/main.js Stories pattern:

"stories": [ "../../apps/web/src//*.mdx", "../../apps/web/src//*.stories.@(js|jsx|mjs|ts|tsx)" ], "staticDirs": ["static"] 2. Update Root package.json All script references (~40 scripts need updating):

"scripts": { "predev": "node tooling/scripts/generate-version.mjs", "prebuild": "node tooling/scripts/generate-version.mjs", "build:app": "node tooling/scripts/generate-version.mjs && vite build --config apps/web/vite.config.mjs", "audit": "node tooling/scripts/audit-production.js --level=moderate", "storybook": "storybook dev -p 6006 --config-dir tooling/.storybook", "build-storybook": "STORYBOOK=true storybook build --config-dir tooling/.storybook && cp tooling/.storybook/static/_headers storybook-static/_headers && cp tooling/.storybook/static/_redirects storybook-static/_redirects", "test:workflows:validate": "node tooling/scripts/validate-triage-consistency.js && bash .github/workflows/validate-triage-config.sh", "lint": "bash tooling/scripts/lint.js", "lint:docs": "node tooling/scripts/lint.docs.js", "lint:docs:strict": "node tooling/scripts/lint.docs.js --strict", "lint:conventions": "node tooling/scripts/lint.lint-conventions.js", "lint:console": "bash tooling/scripts/lint.find-console-logs.sh", "lint:venue-config": "node tooling/scripts/lint.venue-config.js", "lint:venue-config:static": "node tooling/scripts/lint.venue-config.js --no-firestore", "lint:workspace-cache": "node tooling/scripts/lint.workspace-cache.js", "admin:build": "npm run build-storybook && npm run docs:build && npm run build -w apps/admin && node tooling/scripts/bundle-storybook-admin.mjs && node tooling/scripts/bundle-docs-admin.mjs", "validate:headers": "node tooling/scripts/validate-headers.js" } 3. Update apps/web/vitest.config.js Coverage exclusions:

exclude: [ 'node_modules/', 'src//*.stories.jsx', 'dist/', '../../tooling/.storybook/', '../../docs/', '../../tooling/scripts/**', ] 4. Update tooling/scripts/validate-headers.js Path exclusions:

if ( relativePath.includes('node_modules') || relativePath.includes('dist') || relativePath.includes('coverage') || relativePath.includes('tooling/.storybook') || relativePath.includes('storybook-static') ) { return true } Testing Checklist

npm run build-storybook ls -la storybook-static/ npm run lint npm run admin:build npm run validate Phase 4: Create Shared Packages (PR #4) Goal: Create packages/shared/ with initial structure Risk: LOW - additive only, no breaking changes Time: 2-3 hours Branch: feat/monorepo-phase4-shared-packages

Directory Structure

mkdir -p packages/shared/auth mkdir -p packages/shared/encryption mkdir -p packages/shared/utils

  1. Create packages/shared/package.json

{ "name": "@lantern/shared", "version": "0.1.0", "private": true, "type": "module", "exports": { "./auth": "./auth/index.js", "./encryption": "./encryption/index.js", "./utils": "./utils/index.js" } } 2. Create packages/shared/auth/index.js Initial exports (role constants, auth types):

/**

  • Shared authentication constants and types
  • Used across web, admin, and backend services */

export const USER_ROLES = { USER: 'user', MERCHANT: 'merchant', ADMIN: 'admin' }

export const AUTH_ERRORS = { INVALID_CREDENTIALS: 'auth/invalid-credentials', USER_NOT_FOUND: 'auth/user-not-found', ADMIN_PASSWORD_REQUIRED: 'auth/admin-password-required', INSUFFICIENT_PERMISSIONS: 'auth/insufficient-permissions' }

export const ROLE_HIERARCHY = { [USER_ROLES.USER]: 0, [USER_ROLES.MERCHANT]: 1, [USER_ROLES.ADMIN]: 2 }

/**

  • Check if role has sufficient permissions
  • @param {string} userRole - Current user's role
  • @param {string} requiredRole - Minimum required role
  • @returns {boolean} */ export function hasRequiredRole(userRole, requiredRole) { return ROLE_HIERARCHY[userRole] >= ROLE_HIERARCHY[requiredRole] }
  1. Create packages/shared/encryption/index.js Placeholder for Issue #147:

/**

  • Shared encryption utilities
  • This package is created as part of monorepo reorganization (Issue #246)
  • to prepare for Issue #147 (Advanced Encryption Features).
  • Future contents:
    • Recovery code generation/validation
    • Tiered encryption utilities
    • Shared crypto constants */

export const ENCRYPTION_CONFIG = { PBKDF2_ITERATIONS: 600_000, ALGORITHM: 'AES-GCM', KEY_LENGTH: 256, IV_LENGTH: 12, SALT_LENGTH: 16 }

// Placeholder - will be populated in Issue #147 export function generateRecoveryCodes() { throw new Error('Not implemented - awaiting Issue #147') } 4. Create packages/shared/utils/index.js Environment detection utilities:

/**

  • Shared utility functions */

/**

  • Detect if running in development environment

  • Works in both browser and Node.js contexts */ export function isDevelopment() { // Browser environment if (typeof window !== 'undefined') { return ( window.location.hostname === 'localhost' || window.location.hostname.includes('127.0.0.1') || window.location.hostname.endsWith('.local') ) }

    // Node.js environment if (typeof process !== 'undefined') { return ( process.env.NODE_ENV === 'development' || process.env.GCLOUD_PROJECT?.includes('-dev') ) }

    return false }

/**

  • Detect Firebase project environment

  • @returns {'development' | 'production' | 'unknown'} */ export function getFirebaseEnvironment() { // Browser if (typeof window !== 'undefined' && window.location) { if (window.location.hostname.includes('dev.ourlantern.app')) { return 'development' } if (window.location.hostname === 'ourlantern.app') { return 'production' } }

    // Node.js if (typeof process !== 'undefined') { const project = process.env.GCLOUD_PROJECT || process.env.VITE_FIREBASE_PROJECT_ID if (project?.includes('-dev')) return 'development' if (project?.includes('-prod')) return 'production' }

    return 'unknown' }

/**

  • DevLog interface - implemented differently in browser vs Node.js
  • This is a type definition/contract, actual implementations stay separate */ export const DevLogInterface = { log: (message, ...args) => {}, warn: (message, ...args) => {}, error: (message, ...args) => {} }
  1. Update Root package.json Add to workspaces:

"workspaces": [ "apps/admin", "services/api/docs", "services/bots/discord", "services/functions/firebase", "packages/shared" ] 6. Create Tests for Shared Package Create packages/shared/tests/auth.test.js:

import { describe, it, expect } from 'vitest' import { USER_ROLES, hasRequiredRole } from '../auth/index.js'

describe('Shared Auth Utilities', () => { it('should define user roles', () => { expect(USER_ROLES.USER).toBe('user') expect(USER_ROLES.MERCHANT).toBe('merchant') expect(USER_ROLES.ADMIN).toBe('admin') })

it('should check role hierarchy correctly', () => { expect(hasRequiredRole(USER_ROLES.ADMIN, USER_ROLES.USER)).toBe(true) expect(hasRequiredRole(USER_ROLES.USER, USER_ROLES.ADMIN)).toBe(false) expect(hasRequiredRole(USER_ROLES.MERCHANT, USER_ROLES.MERCHANT)).toBe(true) }) }) Testing Checklist

npm ci npm run test -w packages/shared # Run shared package tests npm run validate Note: This phase creates the structure but does NOT migrate existing code yet. Migration happens incrementally in future PRs as needed.

Phase 5: Output Directory Standardization (PR #5) Goal: Move Storybook output to tooling/storybook-static Risk: LOW Time: 1-2 hours Branch: feat/monorepo-phase5-outputs

Config Updates (no file movements)

  1. Update Root package.json Storybook build script:

"build-storybook": "STORYBOOK=true storybook build --config-dir tooling/.storybook --output-dir tooling/storybook-static && cp tooling/.storybook/static/_headers tooling/storybook-static/_headers && cp tooling/.storybook/static/_redirects tooling/storybook-static/_redirects" 2. Update tooling/scripts/bundle-storybook-admin.mjs

const storybookDir = path.join(rootDir, 'tooling', 'storybook-static') 3. Update GitHub Actions Workflows Files: .github/workflows/deploy-dev.yml, .github/workflows/deploy-prod.yml, .github/workflows/deploy-preview.yml

Storybook verification:

  • name: Verify build output run: | if [ ! -d "tooling/storybook-static" ]; then echo "❌ Build failed: tooling/storybook-static does not exist" exit 1 fi if [ ! -f "tooling/storybook-static/index.html" ]; then echo "❌ Build failed: tooling/storybook-static/index.html does not exist" exit 1 fi echo "✅ Build succeeded" Storybook deploy:
yaml
command: pages deploy tooling/storybook-static --project-name=lantern-storybook-dev --branch=${{ github.event.workflow_run.head_branch }}
  1. Update .github/workflows/ci.yml Artifact upload:
  • name: Upload Storybook artifact uses: actions/upload-artifact@v4 with: name: storybook-static path: tooling/storybook-static/ retention-days: 7 Testing Checklist

npm run build-storybook ls -la tooling/storybook-static/ npm run admin:build ls -la apps/admin/dist/storybook/ npm run validate Post-Migration Cleanup

  1. Update .gitignore Add entries for old output directories (now moved):

Old output directories (migrated to new structure)

/dist /storybook-static /admin/dist 2. Update Documentation Files to update:

CLAUDE.md - Monorepo structure section docs/engineering/guides/DIRECTORY_DEFINITIONS.md - Add new directories docs/engineering/guides/ADMIN_PORTAL_SETUP.md - Update paths Create worklog:

docs/worklog/2026-02-08_monorepo-reorganization_complete.md 3. Verify Old Directories Removed

ls -la | grep -E '^d' | grep -v apps | grep -v services | grep -v packages Should NOT see: admin/, firebase-functions/, cloud-run-docs-api/, discord-bot/, scripts/, .storybook/

Risk Management Critical Safeguards 5 phased PRs - Each phase independently testable and reversible Git history preserved - All moves use git mv Preview deployments - Test before merging to dev 4-6 hour monitoring - Wait between merges to detect issues Fast rollback - Single git revert per phase Rollback Triggers Build verification fails in CI Deployment succeeds but returns 404/500 Auth flow breaks Any service inaccessible after 10 minutes Firebase Functions fail to deploy Test coverage drops below 75% Emergency Rollback

Revert the problematic merge

git revert -m 1 <merge-commit-sha> git push origin dev

Manual Firebase hotfix if only Functions affected

git checkout HEAD~1 firebase.json firebase deploy --only functions --project lantern-app-dev Timeline Day 1 (Monday): Phase 1 - Apps migration

Morning: Implement + test locally (2 hours) Afternoon: PR review + merge + monitor (2 hours) Monitoring: Watch dev deployments for 4-6 hours Day 2 (Tuesday): Phase 2 - Services migration

Morning: Implement + test (1.5 hours) Afternoon: PR review + merge + monitor (1.5 hours) Monitoring: Verify Firebase Functions work Day 3 (Wednesday): Phase 3 - Tooling migration

Morning: Implement + test (1 hour) Afternoon: PR review + merge + monitor (1 hour) Monitoring: Verify Storybook builds Day 4 (Thursday): Phase 4 - Shared packages

Morning: Create packages/shared structure (1.5 hours) Afternoon: PR review + merge (1.5 hours) Day 5 (Friday): Phase 5 + Documentation

Morning: Output standardization (1 hour) Afternoon: Documentation updates + cleanup (2 hours) Total Time: 12-15 hours over 5 days

Critical Files Summary Phase 1: Apps Migration /home/mechelle/repos/lantern_app/package.json - Workspace + script updates /home/mechelle/repos/lantern_app/.github/workflows/deploy-dev.yml - 8 path changes /home/mechelle/repos/lantern_app/.github/workflows/deploy-prod.yml - 8 path changes /home/mechelle/repos/lantern_app/.github/workflows/deploy-preview.yml - 8 path changes /home/mechelle/repos/lantern_app/tooling/scripts/generate-version.mjs - Output path /home/mechelle/repos/lantern_app/tooling/scripts/bundle-storybook-admin.mjs - Admin path /home/mechelle/repos/lantern_app/tooling/scripts/bundle-docs-admin.mjs - Admin path Phase 2: Services Migration /home/mechelle/repos/lantern_app/package.json - Workspace updates /home/mechelle/repos/lantern_app/firebase.json - Functions source path /home/mechelle/repos/lantern_app/.github/workflows/ci.yml - Discord bot audit path Phase 3: Tooling Migration /home/mechelle/repos/lantern_app/package.json - ~40 script path updates /home/mechelle/repos/lantern_app/tooling/.storybook/main.js - Stories pattern /home/mechelle/repos/lantern_app/apps/web/vitest.config.js - Coverage exclusions Phase 4: Shared Packages /home/mechelle/repos/lantern_app/package.json - Add workspace Create 4 new files in packages/shared/ Phase 5: Output Standardization /home/mechelle/repos/lantern_app/.github/workflows/deploy-*.yml - 3 workflow files /home/mechelle/repos/lantern_app/tooling/scripts/bundle-storybook-admin.mjs - Source path Success Criteria Technical Success ✅ All builds pass (npm run validate) ✅ All 4 production URLs working ✅ All tests passing with 75%+ coverage ✅ Firebase Functions operational ✅ Discord bot receiving events ✅ CI/CD green across all workflows ✅ No console errors on deployed apps Structural Success ✅ Clean directory structure matches target ✅ Git history preserved for all moved files ✅ packages/shared/ ready for Issue #147 ✅ Workspaces configured correctly ✅ Import paths working Documentation Success ✅ CLAUDE.md updated ✅ DIRECTORY_DEFINITIONS.md updated ✅ Worklog created ✅ Team onboarded to new structure Future Work (Not in This Plan) After Issue #147 (Advanced Encryption Features):

Migrate encryption utilities to packages/shared/encryption Migrate auth logic to packages/shared/auth Migrate devLog to packages/shared/utils with conditional exports Future Services Expansion:

services/api/auth - Authentication API service services/bots/slack - Slack integration bot apps/mobile - React Native mobile app Notes This plan is a living document - adjust as needed Each phase builds on the previous Security and deployment stability are paramount Monitor dev environment closely between phases Document any deviations or issues encountered User approved the plan Excellent! The plan has been approved. Let me create a todo list to track our progress through the 5 phases of the monorepo reorganization.

Update Todos

Phase 1: Move main app and admin to apps/ directory

Phase 1: Update all config files for apps/ structure

Phase 1: Update GitHub Actions workflows for apps/ paths

Phase 1: Test and validate apps migration locally

Phase 2: Move services to categorized services/ structure

Phase 3: Move .storybook and scripts to tooling/

Phase 4: Create packages/shared/ with auth, encryption, utils

Phase 5: Standardize output directories

Built with VitePress