# Feature: Unified App - Pragmatic Monolith Consolidation ## Overview Consolidate the two separate frontend applications (Reports App and Data Entry App) into a single unified SPA with both modules accessible from one menu. This pragmatic monolith approach maintains module isolation while simplifying deployment and providing a unified user experience with a single build and single IIS site. **Status**: Implementation-Ready **Complexity**: Medium **Estimated Effort**: 2.5 days --- ## Problem Statement ### Current Issues - Two separate frontend deployments in IIS (`/roa2web/` and `/data-entry/`) - Complex deployment process (2 builds, 2 IIS configurations) - CSS conflicts when using shared components (white text on white background) - No unified navigation between modules - Duplicate setup and configuration code ### Benefits of Unification - Simplified deployment (single build, single IIS site) - Unified user experience with single menu - Shared component consistency - Module isolation preserved through error boundaries - Optimized bundle loading via lazy loading --- ## User Stories ### Primary Users - As a **user**, I want to access both Reports and Data Entry modules from a single menu so that I can navigate seamlessly between functionalities. - As a **developer**, I want simplified deployment with a single build process so that I can reduce deployment complexity and maintenance overhead. - As a **user**, I want the app to remain functional even if one module encounters an error so that my work is not interrupted. - As an **administrator**, I want a single IIS site configuration so that I can manage deployment more easily. --- ## Functional Requirements ### Core Requirements #### 1. Unified Navigation - Single top-level menu with sections for Reports and Data Entry modules - Menu structure: - **Rapoarte** (Reports) section with Dashboard, Invoices, Bank/Cash, Trial Balance - **Introduceri Date** (Data Entry) section with Receipts List, New Receipt - **Sistem** section with Telegram Bot, Cache Stats - Active route highlighting - Responsive slide menu (mobile + desktop) #### 2. Module Isolation - Error boundary per module (Reports, Data Entry) - Bug in one module does not crash the other - Independent lazy loading per module - Separate stores per module (no cross-contamination) #### 3. URL Structure ``` /login → Login page / → Redirect to /reports/dashboard /reports/dashboard → Dashboard (Reports module) /reports/invoices → Invoices view /reports/bank-cash → Bank/Cash register view /reports/trial-balance → Trial Balance view /reports/telegram → Telegram Bot management /reports/cache-stats → Cache statistics /data-entry → Receipts list (Data Entry module) /data-entry/create → Create new receipt /data-entry/:id → View receipt details /data-entry/:id/edit → Edit receipt ``` #### 4. Shared Components Integration - Use existing shared components from `shared/frontend/`: - `LoginView.vue` - Login page - `AppHeader.vue` - Top navigation bar - `SlideMenu.vue` - Sidebar menu - `CompanySelector.vue` - Company dropdown - `PeriodSelector.vue` - Accounting period selector - Maintain consistent styling and behavior across modules #### 5. Authentication & Authorization - Unified JWT authentication - Single login flow for both modules - Preserve existing auth store factory pattern - Session persistence across module navigation ### Secondary Requirements #### 1. Feature Flags - Ability to enable/disable modules via configuration - Feature flag configuration in `src/config/features.js` - UI hides disabled module menu items #### 2. Loading States - Module-level loading spinners - Skeleton screens for lazy-loaded routes - Progress indication during module switching #### 3. Analytics & Monitoring - Track module switching events - Error boundary triggers logged - Performance metrics per module --- ## Technical Requirements ### Project Structure ``` . ├── public/ │ └── favicon.ico ├── src/ │ ├── main.js # App entry point │ ├── App.vue # Root component with unified menu │ │ │ ├── router/ │ │ └── index.js # Unified router with lazy loading │ │ │ ├── modules/ │ │ ├── reports/ # ISOLATED REPORTS MODULE │ │ │ ├── ReportsLayout.vue # Error boundary wrapper │ │ │ ├── views/ # Reports views (migrated) │ │ │ │ ├── DashboardView.vue │ │ │ │ ├── InvoicesView.vue │ │ │ │ ├── BankCashRegisterView.vue │ │ │ │ ├── TrialBalanceView.vue │ │ │ │ ├── TelegramView.vue │ │ │ │ └── CacheStatsView.vue │ │ │ ├── stores/ # Module-specific stores │ │ │ │ ├── dashboard.js │ │ │ │ ├── invoices.js │ │ │ │ ├── treasury.js │ │ │ │ ├── trialBalance.js │ │ │ │ └── cacheStore.js │ │ │ └── services/ # Module API services │ │ │ └── api.js # Reports API client │ │ │ │ │ └── data-entry/ # ISOLATED DATA ENTRY MODULE │ │ ├── DataEntryLayout.vue # Error boundary wrapper │ │ ├── views/ # Data Entry views (migrated) │ │ │ └── receipts/ │ │ │ ├── ReceiptsListView.vue │ │ │ └── ReceiptCreateView.vue │ │ ├── components/ # Module-specific components │ │ │ └── ocr/ │ │ │ ├── OCRUploadZone.vue │ │ │ ├── OCRPreview.vue │ │ │ └── OCRConfidenceIndicator.vue │ │ ├── stores/ # Module-specific stores │ │ │ └── receiptsStore.js │ │ └── services/ # Module API services │ │ └── api.js # Data Entry API client │ │ │ ├── shared/ # SHARED COMPONENTS & LOGIC │ │ ├── components/ # Shared UI components │ │ │ ├── layout/ │ │ │ │ ├── AppHeader.vue │ │ │ │ └── SlideMenu.vue │ │ │ ├── LoginView.vue │ │ │ ├── CompanySelector.vue │ │ │ ├── PeriodSelector.vue │ │ │ └── ErrorBoundary.vue # NEW: Error boundary component │ │ ├── stores/ # Shared stores (factories) │ │ │ ├── auth.js # Auth store factory │ │ │ ├── companies.js # Companies store factory │ │ │ └── accountingPeriod.js # Period store factory │ │ └── styles/ # Shared CSS │ │ ├── login.css │ │ ├── layout/ │ │ │ ├── header.css │ │ │ └── navigation.css │ │ └── shared.css │ │ │ ├── config/ │ │ ├── menu.js # Unified menu configuration │ │ └── features.js # Feature flags │ │ │ └── assets/ │ └── css/ # Global CSS (from reports-app) │ ├── core/ # Design tokens │ ├── components/ # Reusable UI patterns │ ├── patterns/ # Interactive patterns │ ├── layout/ # Page structure │ ├── utilities/ # Utility classes │ └── vendor/ # PrimeVue overrides │ ├── vite.config.js # Unified Vite config (root) ├── package.json # Merged dependencies (root) ├── .env.example # Environment template (root) └── README.md # Unified app documentation (root) ``` ### Files to Create | File | Purpose | |------|---------| | `package.json` | Merged dependencies from both apps | | `vite.config.js` | Dual proxy config, lazy loading, base path `/` | | `src/main.js` | App initialization, PrimeVue setup, global components | | `src/App.vue` | Root component with unified menu | | `src/router/index.js` | Unified router with lazy loading | | `src/config/menu.js` | Menu configuration | | `src/config/features.js` | Feature flags | | `src/shared/components/ErrorBoundary.vue` | Error boundary component | | `src/modules/reports/ReportsLayout.vue` | Reports error boundary wrapper | | `src/modules/data-entry/DataEntryLayout.vue` | Data Entry error boundary wrapper | | `.env.example` | Environment variables template | | `README.md` | Documentation | ### Files to Migrate #### From `reports-app/frontend/` **Views** (→ `modules/reports/views/`): - DashboardView.vue - InvoicesView.vue - BankCashRegisterView.vue - TrialBalanceView.vue - TelegramView.vue - CacheStatsView.vue - ~~LoginView.vue~~ (use shared) **Stores** (→ `modules/reports/stores/`): - dashboard.js - invoices.js - treasury.js - trialBalance.js - cacheStore.js - ~~auth.js~~ (use shared) - ~~companies.js~~ (use shared) - ~~accountingPeriod.js~~ (use shared) **Services** (→ `modules/reports/services/`): - api.js (adapt for `/api/reports/` prefix) **CSS** (→ `assets/css/`): - Copy entire `src/assets/css/` directory structure - All design tokens, components, patterns, utilities #### From `data-entry-app/frontend/` **Views** (→ `modules/data-entry/views/receipts/`): - ReceiptsListView.vue - ReceiptCreateView.vue - ~~LoginView.vue~~ (use shared) **Components** (→ `modules/data-entry/components/`): - ocr/OCRUploadZone.vue - ocr/OCRPreview.vue - ocr/OCRConfidenceIndicator.vue **Stores** (→ `modules/data-entry/stores/`): - receiptsStore.js - ~~auth.js~~ (use shared) - ~~companies.js~~ (use shared) - ~~accountingPeriod.js~~ (use shared) **Services** (→ `modules/data-entry/services/`): - api.js (adapt for `/api/data-entry/` prefix) **CSS** (→ merge with `assets/css/`): - main.css (merge with reports-app main.css) - Any component-specific styles #### From `shared/frontend/` **Components** (→ `shared/components/`): - LoginView.vue - layout/AppHeader.vue - layout/SlideMenu.vue - CompanySelector.vue - PeriodSelector.vue **Stores** (→ `shared/stores/`): - auth.js (factory) - companies.js (factory) - accountingPeriod.js (factory) **Styles** (→ `shared/styles/`): - login.css - layout/header.css - layout/navigation.css ### Dependencies #### Unified package.json (root directory) Merge all dependencies from both apps: **From reports-app**: - axios: ^1.6.2 - chart.js: ^4.5.0 - date-fns: ^2.30.0 - jspdf: ^3.0.1 - jspdf-autotable: ^5.0.2 - pinia: ^2.1.7 - primeicons: ^6.0.1 - primevue: ^3.46.0 - qrcode.vue: ^3.6.0 - vue: ^3.4.0 - vue-chartjs: ^5.3.2 - vue-router: ^4.2.5 - xlsx: ^0.18.5 **From data-entry-app**: - All duplicates already covered - Additional: @primevue/themes: ^4.0.0 (optional, may remove) **DevDependencies**: - @playwright/test: ^1.54.2 - @vitejs/plugin-vue: ^5.0.0 - eslint: ^8.56.0 - eslint-plugin-vue: ^9.20.0 - prettier: ^3.1.1 - vite: ^5.0.10 ### API Routing #### Vite Dev Server Proxy ```javascript // vite.config.js server: { port: 3000, proxy: { '/api/reports': { target: 'http://localhost:8001', changeOrigin: true, rewrite: (path) => path.replace(/^\/api\/reports/, '/api') }, '/api/data-entry': { target: 'http://localhost:8003', changeOrigin: true, rewrite: (path) => path.replace(/^\/api\/data-entry/, '/api') }, '/uploads': { target: 'http://localhost:8003', changeOrigin: true } } } ``` #### IIS Production Proxy ```xml ``` ### Build Configuration #### Vite Config - Lazy Loading & Bundle Splitting ```javascript // vite.config.js export default defineConfig({ plugins: [vue(), htmlTimestampPlugin()], base: process.env.NODE_ENV === 'production' ? '/' : '/', resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), '@shared': fileURLToPath(new URL('./src/shared', import.meta.url)), '@reports': fileURLToPath(new URL('./src/modules/reports', import.meta.url)), '@data-entry': fileURLToPath(new URL('./src/modules/data-entry', import.meta.url)) }, dedupe: ['vue', 'vue-router', 'pinia', 'primevue'] }, build: { outDir: 'dist', sourcemap: true, rollupOptions: { output: { manualChunks: { // Core vendors 'vendor-core': ['vue', 'vue-router', 'pinia'], 'vendor-primevue': ['primevue/config', 'primevue/button', 'primevue/datatable'], 'vendor-utils': ['axios', 'date-fns'], // Charts (reports only) 'vendor-charts': ['chart.js', 'vue-chartjs'], // Excel/PDF exports 'vendor-export': ['xlsx', 'jspdf', 'jspdf-autotable'], // Module-specific chunks (lazy loaded) // Reports module loaded via dynamic import // Data Entry module loaded via dynamic import }, entryFileNames: `assets/[name].[hash].js`, chunkFileNames: `assets/[name].[hash].js`, assetFileNames: `assets/[name].[hash].[ext]` } } } }) ``` **Expected Build Output**: ``` dist/ ├── index.html ├── assets/ │ ├── vendor-core.[hash].js (~150KB) - Vue, Router, Pinia │ ├── vendor-primevue.[hash].js (~200KB) - PrimeVue components │ ├── vendor-utils.[hash].js (~80KB) - Axios, date-fns │ ├── vendor-charts.[hash].js (~150KB) - Chart.js (lazy) │ ├── vendor-export.[hash].js (~200KB) - XLSX, jsPDF (lazy) │ ├── reports.[hash].js (~150KB) - Reports module (lazy) │ ├── data-entry.[hash].js (~100KB) - Data Entry module (lazy) │ ├── main.[hash].js (~50KB) - App shell │ └── main.[hash].css (~80KB) - Global CSS ``` --- ## Design Decisions ### Approach: Pragmatic Monolith **Why NOT Micro-frontends (Module Federation / Single-SPA)?** | Micro-Frontend Criterion | ROA2WEB Reality | Justification | |-------------------------|-----------------|---------------| | 20+ developers on separate teams | 1 developer | Overkill - no team coordination needed | | Deploy multiple times per day | Weekly deploys | No benefit from independent deployments | | Millions of users, high scale | 1-5 concurrent users | No scaling justification | | Different frameworks per team | Vue 3 only | No technical diversity | | Independent release cycles | Single release cycle | Adds unnecessary complexity | **Pragmatic Monolith Benefits**: - Simple build process (single `npm run build`) - Shared dependencies (smaller bundle size) - Error boundaries provide 50-70% isolation (close to separate apps) - Lazy loading prevents loading unused modules - Feature flags allow disabling modules without redeploy ### Error Boundary Implementation **ErrorBoundary.vue Component**: ```vue ``` **Usage in Module Layouts**: ```vue ``` ### Lazy Loading Strategy **Router Configuration**: ```javascript const routes = [ { path: '/login', name: 'Login', component: LoginView, meta: { requiresAuth: false } }, { path: '/reports', component: () => import('@/modules/reports/ReportsLayout.vue'), children: [ { path: 'dashboard', name: 'Dashboard', component: () => import('@/modules/reports/views/DashboardView.vue'), meta: { requiresAuth: true, title: 'Dashboard - ROA Reports' } }, { path: 'invoices', name: 'Invoices', component: () => import('@/modules/reports/views/InvoicesView.vue'), meta: { requiresAuth: true, title: 'Facturi - ROA Reports' } }, // ... more routes ] }, { path: '/data-entry', component: () => import('@/modules/data-entry/DataEntryLayout.vue'), children: [ { path: '', name: 'ReceiptsList', component: () => import('@/modules/data-entry/views/receipts/ReceiptsListView.vue'), meta: { requiresAuth: true, title: 'Lista Bonuri' } }, // ... more routes ] }, { path: '/', redirect: '/reports/dashboard' } ] ``` ### Menu Configuration **config/menu.js**: ```javascript export const menuSections = [ { title: 'Rapoarte', items: [ { to: '/reports/dashboard', icon: 'pi pi-home', label: 'Dashboard' }, { to: '/reports/invoices', icon: 'pi pi-file', label: 'Facturi' }, { to: '/reports/bank-cash', icon: 'pi pi-money-bill', label: 'Casa și Banca' }, { to: '/reports/trial-balance', icon: 'pi pi-calculator', label: 'Balanță de Verificare' } ] }, { title: 'Introduceri Date', items: [ { to: '/data-entry', icon: 'pi pi-list', label: 'Lista Bonuri' }, { to: '/data-entry/create', icon: 'pi pi-plus', label: 'Bon Nou' } ] }, { title: 'Sistem', items: [ { to: '/reports/telegram', icon: 'pi pi-telegram', label: 'Telegram Bot' }, { to: '/reports/cache-stats', icon: 'pi pi-chart-bar', label: 'Statistici Cache' } ] } ] ``` ### Feature Flags **config/features.js**: ```javascript export const features = { reports: { enabled: true, modules: { dashboard: true, invoices: true, bankCash: true, trialBalance: true, telegram: true, cacheStats: true } }, dataEntry: { enabled: true, modules: { receipts: true, ocr: true } } } export function isFeatureEnabled(module, subModule = null) { if (!features[module]?.enabled) return false if (subModule && !features[module]?.modules?.[subModule]) return false return true } ``` ### CSS Architecture **Preserve Reports App CSS System**: - Use complete CSS structure from `reports-app/frontend/src/assets/css/` - Design tokens in `core/tokens.css` - Component patterns in `components/` - PrimeVue overrides in `vendor/primevue-overrides.css` **Merge Data Entry CSS**: - Extract unique data-entry styles - Integrate into existing pattern system - Ensure no conflicts with reports CSS **Shared Styles**: - Import from `src/shared/styles/` for LoginView, AppHeader, SlideMenu - Maintain consistency across modules --- ## Acceptance Criteria ### Functionality - [ ] User can log in and access both Reports and Data Entry modules from unified menu - [ ] All Reports views (Dashboard, Invoices, Bank/Cash, Trial Balance, Telegram, Cache Stats) work correctly - [ ] All Data Entry views (Receipts List, Create Receipt, Edit Receipt) work correctly - [ ] Navigation between modules preserves authentication and selected company/period - [ ] Error in Reports module does not crash Data Entry module (and vice versa) - [ ] Logout works correctly and clears all stores ### Performance - [ ] Initial page load < 2 seconds on 3G connection - [ ] Module switching (Reports ↔ Data Entry) < 500ms (already loaded) or < 1s (first load) - [ ] Build produces separate chunks for each module (reports.js, data-entry.js) - [ ] Total bundle size ≤ sum of current apps (no regression) - [ ] Lighthouse score ≥ 90 for Performance ### Build & Deployment - [ ] `npm run build` succeeds without errors - [ ] Build output contains expected chunks (vendor-core, reports, data-entry) - [ ] IIS deployment with single site works correctly - [ ] API proxy routes correctly to both backends (8001, 8003) - [ ] Production build works on Windows IIS - [ ] Cache busting works (new builds force reload) ### Error Handling - [ ] Error boundary catches component errors - [ ] Error boundary displays user-friendly message - [ ] User can retry or navigate away from error - [ ] Console logs error details for debugging - [ ] Error in one module doesn't affect the other ### Responsive Design - [ ] Works on mobile (375px width) - [ ] Works on tablet (768px width) - [ ] Works on desktop (1920px width) - [ ] Slide menu works on mobile - [ ] Company/Period selectors work on mobile ### Testing - [ ] E2E tests pass for login flow - [ ] E2E tests pass for Reports module navigation - [ ] E2E tests pass for Data Entry module navigation - [ ] E2E tests pass for module switching - [ ] E2E tests verify error boundary isolation --- ## Out of Scope The following are explicitly NOT included in this implementation: ### Backend Changes - No changes to `reports-app/backend/` (port 8001) - No changes to `data-entry-app/backend/` (port 8003) - Backends remain separate microservices ### Shared Database - Each backend keeps its own database (Oracle for Reports, SQLite for Data Entry) - No database consolidation ### API Consolidation - APIs remain at separate ports (8001, 8003) - No unified API gateway (using IIS/Vite proxy instead) ### Telegram Bot - Telegram bot remains in `reports-app/telegram-bot/` - No changes to bot architecture ### Advanced Features - No server-side rendering (SSR) - No progressive web app (PWA) features - No offline mode - No real-time updates (WebSockets) ### Future Enhancements - Module-level permissions (show/hide based on user role) - Module analytics dashboard - A/B testing framework - Module versioning - Micro-frontend migration (if team grows to 20+) --- ## Risks and Mitigations | Risk | Likelihood | Impact | Mitigation | |------|------------|--------|------------| | **CSS conflicts between modules** | Medium | Medium | Use CSS modules or scoped styles; test thoroughly; maintain design token system from reports-app | | **Large bundle size** | Medium | Medium | Implement aggressive code splitting; lazy load modules; use tree shaking; monitor with webpack-bundle-analyzer | | **Error boundary not catching all errors** | Low | High | Test error scenarios thoroughly; add global error handler; log errors to monitoring service | | **Deployment complexity on IIS** | Medium | High | Document IIS proxy configuration; create deployment scripts; test on staging first | | **Store contamination between modules** | Low | High | Keep stores module-scoped; use namespaced modules; test isolation | | **PrimeVue theme conflicts** | Low | Medium | Use single PrimeVue theme (saga-blue from reports-app); override in vendor CSS | | **Breaking existing E2E tests** | High | Medium | Update test selectors; test both modules independently; add new tests for unified navigation | | **Shared component changes breaking both modules** | Medium | High | Version shared components; add component tests; minimize changes to shared code | --- ## Implementation Plan ### Phase 1: Project Setup (0.5 days) **Tasks**: 1. Create directory structure in root (`.`) 2. Create `package.json` with merged dependencies 3. Create `vite.config.js` with dual proxy and lazy loading 4. Create `src/main.js` with PrimeVue setup 5. Create `.env.example` with environment variables 6. Copy `shared/frontend/` to `src/shared/` 7. Copy `reports-app/frontend/src/assets/css/` to `src/assets/css/` **Verification**: - `npm install` succeeds - `npm run dev` starts dev server on port 3000 - No build errors ### Phase 2: Module Migration (1 day) **Tasks**: 1. Create module structure (`modules/reports/`, `modules/data-entry/`) 2. Migrate Reports views to `modules/reports/views/` 3. Migrate Reports stores to `modules/reports/stores/` 4. Migrate Reports services, adapt API base URL to `/api/reports/` 5. Migrate Data Entry views to `modules/data-entry/views/` 6. Migrate Data Entry components to `modules/data-entry/components/` 7. Migrate Data Entry stores to `modules/data-entry/stores/` 8. Migrate Data Entry services, adapt API base URL to `/api/data-entry/` 9. Merge CSS from data-entry-app into main CSS system **Verification**: - All views render without errors - API calls route to correct backend - No import errors ### Phase 3: Routing & Navigation (0.5 days) **Tasks**: 1. Create unified router in `src/router/index.js` 2. Configure lazy loading for module layouts 3. Add authentication guard 4. Create `config/menu.js` with unified menu structure 5. Create `App.vue` with AppHeader and SlideMenu integration 6. Create `ReportsLayout.vue` with error boundary 7. Create `DataEntryLayout.vue` with error boundary 8. Create `ErrorBoundary.vue` component **Verification**: - Navigation works between all routes - Lazy loading chunks load correctly - Error boundary catches and displays errors - Menu highlights active route ### Phase 4: Error Boundaries & Resilience (0.25 days) **Tasks**: 1. Test error boundary with intentional errors 2. Verify module isolation (error in one doesn't crash other) 3. Add global error handler 4. Test feature flags (enable/disable modules) 5. Add loading states for lazy-loaded routes **Verification**: - Error boundary displays user-friendly message - User can retry or navigate away - Other module continues working - Feature flags hide disabled modules ### Phase 5: Build & Deployment (0.25 days) **Tasks**: 1. Run production build: `npm run build` 2. Verify bundle splitting (check `dist/assets/`) 3. Test production build locally: `npm run preview` 4. Create IIS web.config with URL rewrite rules 5. Deploy to staging IIS site 6. Test all routes and API calls on staging 7. Document deployment process **Verification**: - Build succeeds without errors - Separate chunks generated (vendor-core, reports, data-entry) - IIS deployment works - API proxy routes correctly - All features work in production --- ## Testing Strategy ### Unit Tests - Store actions and mutations - Service API methods - Utility functions - Error boundary component ### Integration Tests - Router navigation - Store integration with components - API service integration - Error boundary with child components ### E2E Tests (Playwright) **Critical Paths**: 1. **Login Flow** - Navigate to /login - Enter credentials - Verify redirect to /reports/dashboard 2. **Reports Module Navigation** - Navigate to each Reports view - Verify data loads - Test filters and actions 3. **Data Entry Module Navigation** - Navigate to receipts list - Navigate to create receipt - Verify form validation 4. **Module Switching** - Navigate from Reports to Data Entry - Verify state persistence (company, period) - Navigate back to Reports 5. **Error Isolation** - Trigger error in Reports module - Verify Data Entry still works - Retry error module 6. **Logout** - Logout from any module - Verify redirect to login - Verify stores cleared ### Performance Tests - Lighthouse audit (target: 90+ Performance) - Bundle size analysis (webpack-bundle-analyzer) - Load time measurement (initial load, module switching) --- ## Rollback Plan ### If Deployment Fails **Option 1: Keep Both Apps Running** (Zero Downtime) - Leave existing `/roa2web/` and `/data-entry/` sites running - Add new unified app at `/unified/` for testing - Switch over when stable **Option 2: Quick Rollback** (15 minutes) - Keep backup of current IIS configuration - Keep backup of current builds in `dist-backup/` - Restore IIS sites from backup - Restore builds from backup ### Git Strategy - Create feature branch: `feature/unified-app-pragmatic-monolith` - Tag last stable version before merge: `v1.0-pre-unified` - Can revert to tag if needed: `git reset --hard v1.0-pre-unified` ### Monitoring - Check IIS logs: `C:\inetpub\logs\LogFiles\` - Check application errors in browser console - Monitor backend logs (both 8001 and 8003) - Track user feedback in first 48 hours --- ## Documentation Updates ### Files to Create/Update 1. **README.md** (in root directory) - Project overview - Setup instructions - Development commands - Deployment guide - Architecture overview 2. **CLAUDE.md** (root) - Update architecture diagram - Update deployment instructions - Mark old apps as archived - Document new root structure 3. **DEPLOYMENT_GUIDE.md** - Update IIS configuration - Update build process - Update URL structure - Add rollback instructions 4. **docs/ARCHITECTURE_SCHEMA.md** - Update architecture diagrams - Document module structure - Add error boundary architecture 5. **deployment/windows/README.md** - Update deployment steps - Update IIS configuration - Update proxy rules --- ## Post-Implementation Tasks ### Archiving Old Apps After successful deployment and 1 week of stability: 1. Archive old frontends: ```bash mv reports-app/frontend reports-app/frontend-archived mv data-entry-app/frontend data-entry-app/frontend-archived ``` 2. Update start scripts to use root directory: ```bash # ./start-test.sh (update frontend path to root) # ./start-data-entry.sh (update frontend path to root) ``` 3. Update CI/CD pipelines (if any) 4. Document migration in CHANGELOG.md ### Monitoring & Optimization **First Week**: - Monitor error logs daily - Track bundle load times - Gather user feedback - Fix critical bugs **First Month**: - Optimize bundle sizes - Add performance monitoring - Consider further code splitting - Evaluate feature flag usage --- ## Dependencies on Other Work ### Prerequisites - None - can start immediately ### Blocking - No other work blocked by this ### Nice to Have (Not Required) - Updated E2E tests (can do after deployment) - Performance monitoring setup (can add later) - Analytics integration (can add later) --- ## Success Metrics ### Deployment Success - ✅ Single IIS site running instead of 2 - ✅ Single build command instead of 2 - ✅ Zero downtime during deployment ### User Experience - ✅ 100% feature parity with old apps - ✅ < 2s initial load time - ✅ < 500ms module switching (cached) - ✅ Zero user-reported bugs in first week ### Technical - ✅ Bundle size ≤ sum of old apps - ✅ Error isolation working (test scenarios) - ✅ All E2E tests passing - ✅ Lighthouse score ≥ 90 --- ## Open Questions 1. **PrimeVue Theme Standardization**: Use `saga-blue` (reports-app) or `lara-light-blue` (data-entry-app)? - **Recommendation**: Use `saga-blue` (reports-app is primary) 2. **Feature Flag Storage**: Config file or environment variables? - **Recommendation**: Config file for simplicity, env vars for production override 3. **Module Activation Strategy**: All modules active by default or opt-in? - **Recommendation**: All active by default (can disable via config) 4. **Monitoring Solution**: Console logs only or add Sentry/similar? - **Recommendation**: Console logs for MVP, add monitoring later 5. **Progressive Enhancement**: Load Reports first (most used) or parallel? - **Recommendation**: Load on-demand (lazy loading), whichever user navigates to first --- ## Estimated Complexity **Medium Complexity** - Justification: **Factors Increasing Complexity**: - Merging two apps with different structures - Ensuring error isolation between modules - CSS conflicts and PrimeVue theme differences - IIS proxy configuration complexity - Testing both modules thoroughly **Factors Decreasing Complexity**: - No backend changes required - Shared components already exist - Clear architectural pattern (pragmatic monolith) - Lazy loading well-supported by Vue Router - Both apps use same tech stack (Vue 3, PrimeVue) **Time Estimate**: 2.5 days (as per implementation plan) --- ## References ### Related Documents - `IMPLEMENTATION_PLAN_UNIFIED_APP.md` - Initial plan (this spec expands on it) - `CLAUDE.md` - Project documentation (update after implementation) - `docs/ONBOARDING_CSS.md` - CSS system guide - `docs/CSS_PATTERNS.md` - Available CSS patterns - `docs/ARCHITECTURE_SCHEMA.md` - Current architecture (update after) ### Key Files to Reference During Implementation - `reports-app/frontend/vite.config.js` - Proxy config, build settings (reference for new root `vite.config.js`) - `reports-app/frontend/src/router/index.js` - Router patterns (reference for new `src/router/index.js`) - `reports-app/frontend/src/App.vue` - AppHeader/SlideMenu integration (reference for new `src/App.vue`) - `data-entry-app/frontend/src/App.vue` - Alternative integration pattern - `shared/frontend/components/layout/AppHeader.vue` - Header API (copy to `src/shared/components/layout/`) - `shared/frontend/components/layout/SlideMenu.vue` - Menu API (copy to `src/shared/components/layout/`) --- ## Handover Notes This specification is **implementation-ready**. All technical decisions have been made. The implementation plan provides a clear path with verification steps at each phase. **Critical Files to Create First** (in root directory): 1. `package.json` - Merged dependencies 2. `vite.config.js` - Dual proxy config 3. `src/router/index.js` - Unified router with lazy loading 4. `src/shared/components/ErrorBoundary.vue` - Error isolation **After Implementation**: - Archive old frontends after 1 week of stability - Update all documentation (CLAUDE.md, DEPLOYMENT_GUIDE.md) - Consider adding monitoring/analytics - Optimize bundle sizes based on real usage --- **Specification Version**: 1.0 **Created**: 2025-12-22 **Status**: Ready for Implementation **Estimated Effort**: 2.5 days