diff --git a/spec/65_adr_001_monolithic_spa_architecture.md b/spec/65_adr_001_monolithic_spa_architecture.md new file mode 100644 index 00000000..ea1c4ace --- /dev/null +++ b/spec/65_adr_001_monolithic_spa_architecture.md @@ -0,0 +1,431 @@ +# ADR-001: Monolithic SPA Architecture for OMS·WMS·ERP Platform + +**Status**: ACCEPTED (2026-07-26) +**Date**: 2026-07-26 +**Deciders**: Product Manager, Technical Lead, Architecture Team +**Related Decisions**: [Strategic Execution Framework (Spec 61)](spec/61_strategic_execution_framework.yaml), [OpenAPI (Spec 63)](spec/63_oms_wms_erp_api_openapi.yaml), [Database Schema (Spec 64)](spec/64_oms_wms_erp_database_schema.sql) + +--- + +## Context + +OMS·WMS·ERP commercialization requires unified platform architecture decision to balance: + +1. **Time-to-Market**: 18-week Phase 0-11 roadmap (4.5 months) +2. **Team Capacity**: 13 FTE (4 frontend devs, 2 backend, 1 UX, 2 QA, infrastructure) +3. **Maintenance Burden**: Long-term operational cost +4. **Scalability**: Peak load (100 concurrent users during peak hours, future 1000+) +5. **Team Skill Set**: Experienced Vue 2 team, transitioning to Vue 3 + TypeScript +6. **Feature Complexity**: 11 CRUD templates, 5 user roles, audit/compliance requirements + +### Problem Statement + +"Should we build a **single monolithic SPA** or adopt **micro-frontend architecture**?" + +**Tradeoff Matrix**: + +| Factor | Monolithic | Micro-Frontend | +|--------|-----------|---| +| **Time-to-Market** | ✅ Fast (single build, shared state) | ❌ Slower (coordination, build complexity) | +| **Team Efficiency** | ✅ Shared code/patterns | ❌ Potential duplication | +| **Deployment Risk** | ⚠️ Full redeploy | ✅ Independent deploys (but coordination complexity) | +| **Complexity (Initial)** | ✅ Simple (one codebase) | ❌ Complex (module federation, routing) | +| **State Management** | ✅ Centralized (Pinia) | ⚠️ Distributed (synchronization overhead) | +| **Learning Curve** | ✅ Single pattern | ❌ Multiple architectural patterns | +| **Future Modularity** | ⚠️ Refactoring cost | ✅ Already isolated | + +--- + +## Decision + +**ADOPT: Monolithic SPA Architecture** + +### Rationale + +1. **Time-to-Market (P0 Priority)** + - Single Vite build pipeline → faster CI/CD turnaround + - Shared Pinia store eliminates cross-module synchronization + - No module federation complexity (can add in Phase 12+ if needed) + - Team can move fast on core 11 CRUD templates without coordination overhead + +2. **Team Efficiency (13 FTE Constraint)** + - 4 frontend devs work on unified codebase (not split into silos) + - Shared component library reduces duplication + - PR reviews simpler (single review standard) + - Onboarding new devs easier (one architectural pattern) + +3. **Scalability Headroom** + - 100 concurrent users = 50-100 backend requests/sec (well within SPA capacity) + - PostgreSQL backend can handle 10K+ concurrent connections + - Browser memory: Pinia store + Vue tree ~5-10MB even at 1000 concurrent + - Future scale-out: Independent microservices backend (no frontend change needed) + +4. **Data Consistency (Principle 3)** + - Centralized Pinia store = single source of truth for all entities + - No client-side replication or sync logic + - Audit trail via PostgreSQL audit_logs (all mutations captured) + - JWT tokens + RBAC enforced server-side (client trusted for UX only) + +5. **Cost Efficiency** + - Single deployment pipeline = lower ops cost + - Monolithic codebase = faster debugging and troubleshooting + - No microservices orchestration overhead (Kubernetes, service mesh) + +### Architectural Layers (7-Layer Model) + +``` +┌─────────────────────────────────────────────────────┐ +│ 1. Presentation Layer (Vue 3 SPA) │ +│ - 4-layer component hierarchy │ +│ - Tabler UI + Bootstrap 5 + Storybook │ +│ - Responsive + WCAG 2.1 AA │ +├─────────────────────────────────────────────────────┤ +│ 2. State Management (Pinia) │ +│ - Entity stores (orders, inventory, products) │ +│ - UI state (modals, notifications, routing) │ +│ - Auth store (user, roles, permissions) │ +├─────────────────────────────────────────────────────┤ +│ 3. API Client Layer (Axios + Auto-Generated) │ +│ - Type-safe: OpenAPI → TypeScript SDK │ +│ - Interceptors: JWT refresh, error handling │ +│ - Offline support: Request queue (Phase 12+) │ +├─────────────────────────────────────────────────────┤ +│ 4. Domain Layer (Business Logic) │ +│ - Computed properties (qty_available, totals) │ +│ - Validation rules (duplicate checks, constraints) │ +│ - Formatters (currency, date, status labels) │ +├─────────────────────────────────────────────────────┤ +│ 5. Repository Layer (Data Access Patterns) │ +│ - Cache strategies (LRU, TTL) │ +│ - Optimistic updates (e.g., reorder lines) │ +│ - Pagination (lazy load, infinite scroll) │ +├─────────────────────────────────────────────────────┤ +│ 6. Infrastructure (Routing, Navigation, Config) │ +│ - Vue Router (lazy-loaded per route) │ +│ - Global error boundaries │ +│ - Feature flags (Phase 12+) │ +├─────────────────────────────────────────────────────┤ +│ 7. External Services (Backend APIs + 3P) │ +│ - REST APIs (OpenAPI 3.0) │ +│ - JWT authentication │ +│ - Real-time updates (WebSocket Phase 12+) │ +└─────────────────────────────────────────────────────┘ +``` + +### 4-Layer Component Hierarchy + +``` +Layer 1: Primitive Components + ├─ ButtonBase, InputBase, SelectBase, TextBase + └─ Reusable, no business logic, full a11y + +Layer 2: Typed Field Components + ├─ TextField, DateField, CurrencyField, StatusField + └─ Domain-aware validation, formatting, labels + +Layer 3: Domain Field Components + ├─ OrderLineField, InventoryField, VoucherLineField + └─ Business rules, inline lookups, multi-field composition + +Layer 4: Business Composite Components + ├─ OrderForm, InventoryTransferWizard, VoucherEditor + └─ Full workflows, state orchestration, audit trail +``` + +### 11 CRUD Templates Standardization + +All 11 entity CRUD flows follow **uniform pattern** (List → Create → Read → Edit → Delete): + +| Entity | API Endpoints | UI Components | Test Coverage | +|--------|--------------|---------------|---| +| **Order** | 6 (GET, POST, PUT, DELETE + list, detail) | OrderList, OrderDetail, OrderForm | 30 E2E scenarios | +| **OrderLine** | Nested CRUD (in order context) | LineEditor (inline in form) | 10 E2E | +| **Inventory** | 6 | InventoryList, TransferWizard | 15 E2E | +| **StockTransfer** | 6 | TransferForm, ApprovalMatrix | 12 E2E | +| **Product** | 6 | ProductList, ProductForm | 10 E2E | +| **Supplier** | 6 | SupplierList, SupplierForm | 8 E2E | +| **Customer** | 6 | CustomerList, CustomerForm | 8 E2E | +| **GLAccount** | 6 | AccountList, AccountForm | 8 E2E | +| **Voucher** | 6 | VoucherEditor (line-by-line) | 15 E2E | +| **User** | 6 | UserList, UserForm, PermissionMatrix | 12 E2E | +| **Warehouse** | 6 | WarehouseList, WarehouseForm | 8 E2E | + +**Total E2E Coverage**: 116 test scenarios (Phase 4 milestone) + +--- + +## Consequences + +### ✅ Positive + +1. **Faster Delivery** + - Single build pipeline: ~3 min build time + - CI/CD simpler: No cross-module coordination + - Feature complete by Phase 4 (week 8) for UAT + +2. **Maintainability** + - Unified codebase = easier debugging + - All devs understand full system + - Refactoring easier (no hidden dependencies) + +3. **Data Consistency** + - Pinia store = single source of truth + - No sync issues between independent UIs + - Audit trail via PostgreSQL (not client-side) + +4. **User Experience** + - Instant navigation (no full-page reloads) + - Smooth transitions between modules + - Consistent look & feel (unified design system) + +5. **Test Coverage** + - 50/30/20 pyramid: unit (50%) → integration (30%) → E2E (20%) + - All 116 E2E scenarios in single test suite + - Deterministic tests (single state source) + +### ⚠️ Negative (Mitigations) + +1. **Monolith Brittleness** + - **Problem**: One bad release breaks entire app + - **Mitigation**: Strict pre-deployment checklist (Phase 5+), blue-green deployment, 6-point health checks + +2. **Large Bundle Size** + - **Problem**: Initial load time if all code bundled + - **Mitigation**: Lazy-load routes per module, code split at route level, target <500KB main chunk (Lighthouse 90+) + +3. **Shared State Complexity** + - **Problem**: Pinia store grows as features added + - **Mitigation**: Modular stores (orders, inventory, users modules), clear naming, documentation + +4. **Scaling to 1000+ Users** + - **Problem**: Browser memory, server load + - **Mitigation**: Pagination (not all records in memory), connection pooling (PostgreSQL), infrastructure scale-out (Phase 12+) + +5. **Future Microfront-End Transition** + - **Problem**: If modularity needed later, refactoring cost + - **Mitigation**: Component library + API contracts locked down early, can extract UI module → separate SPA in Phase 13+ + +--- + +## Alternatives Considered + +### 1. Micro-Frontend Architecture (Module Federation) + +**Approach**: Each CRUD entity (Order, Inventory, etc.) as independent webpack Module Federation remote + +**Pros**: +- Independent deployments per module +- Teams can work in parallel without merge conflicts +- Better long-term modularity + +**Cons**: +- ❌ Shared state synchronization complexity (events, bus, sync failures) +- ❌ Build time: 9-12 min (multiple builds + federation setup) +- ❌ 18-week timeline NOT feasible (needs 20+ weeks for coordination overhead) +- ❌ Learning curve (few devs experienced in Module Federation) +- ❌ CI/CD complexity (version matrix: Order v1-v3 × Inventory v2-v5) + +**Decision**: REJECTED — Too risky for 18-week timeline with 4 frontend devs + +### 2. Headless Backend + Separate Frontends (Web + Mobile) + +**Approach**: Unified .NET backend + Vue SPA (web) + React Native (mobile) + +**Pros**: +- Native mobile experience +- Backend shared code reuse + +**Cons**: +- ❌ Scope creep (mobile adds 4-6 weeks) +- ❌ Double maintenance (Vue + React Native) +- ❌ Mobile not in Phase 0-11 scope (can add in Phase 13+) + +**Decision**: REJECTED — Out of scope. Mobile deferred to Phase 13+ + +### 3. Low-Code Platform (OutSystems, Mendix) + +**Approach**: Rapid CRUD generation, visual development + +**Pros**: +- Fastest CRUD generation +- Less boilerplate code + +**Cons**: +- ❌ Vendor lock-in +- ❌ Limited customization for complex workflows (approval matrix, audit trail) +- ❌ Higher TCO (licensing) +- ❌ Team skill atrophy (no real engineering) + +**Decision**: REJECTED — Does not meet control + compliance requirements + +### 4. Separate Microservices UIs (One SPA per domain: OMS, WMS, ERP) + +**Approach**: 3 independent SPAs (micro-frontends without Module Federation) + +**Pros**: +- Clear domain separation +- Smaller bundles per SPA + +**Cons**: +- ❌ Cross-domain navigation complex (not SPA-like experience) +- ❌ Duplicate components (auth, common UI) +- ❌ Harder to reorder across domains (OMS order → WMS allocation → ERP GL) +- ❌ 3 CI/CD pipelines vs 1 + +**Decision**: REJECTED — Poor user experience for cross-domain workflows + +--- + +## Implementation Plan (Phases 1-4) + +### Phase 1: Dev Environment & CI/CD (Week 1-2) + +- [ ] Vite SPA scaffold + TypeScript strict mode +- [ ] Pinia stores structure (orders, inventory, users modules) +- [ ] Axios API client + OpenAPI SDK auto-generation +- [ ] ESLint + Prettier + pre-commit hooks +- [ ] GitHub Actions CI/CD (lint → test → build) +- [ ] Storybook setup (6.0+, TypeScript support) + +**Exit Criteria**: All devs can build locally, CI green, Storybook runs + +### Phase 2: Primitive & Composite Layers (Week 3-4) + +- [ ] Layer 1: 30 Primitive components (Button, Input, Select, etc.) +- [ ] Layer 2: 12 Typed Field components (TextField, DateField, etc.) +- [ ] Storybook documentation for all components +- [ ] WCAG 2.1 AA accessibility audit (axe-core) +- [ ] Unit tests: 70%+ coverage + +**Exit Criteria**: Storybook published, all primitives tested, accessibility passed + +### Phase 3: Smart Components & State (Week 5-6) + +- [ ] Layer 3: 12 Domain Field components +- [ ] Layer 4: 4 Business Composite components (Order, Inventory, Voucher, User) +- [ ] Pinia stores + API integration +- [ ] Integration tests (Vitest + MSW mocks) +- [ ] Real-time data binding + +**Exit Criteria**: State management tested, API mocks working, 50 integration tests pass + +### Phase 4: CRUD Templates & E2E (Week 7-8) + +- [ ] 11 full CRUD forms (List, Create, Read, Edit, Delete) +- [ ] Approval workflows (supervisor sign-off for high-value orders) +- [ ] Pagination + lazy loading +- [ ] 116 E2E test scenarios (Playwright) +- [ ] Responsive design (mobile, tablet, desktop) + +**Exit Criteria**: All 11 CRUD screens tested, 116 E2E scenarios pass, Lighthouse 90+ + +--- + +## Related Decisions + +- **ADR-002** (TBD): Authentication & Authorization (JWT + RBAC) +- **ADR-003** (TBD): State Management Strategy (Pinia module organization) +- **ADR-004** (TBD): Component Library Versioning (npm @quantengine/ui) +- **Strategic Execution Framework** (Spec 61): 30 principles applied +- **OpenAPI Specification** (Spec 63): 30 REST endpoints defined +- **Database Schema** (Spec 64): PostgreSQL 3NF design + +--- + +## Validation Checklist (Phase 0 → Phase 1) + +Before proceeding to Phase 1 development: + +- [ ] All stakeholders agree on monolithic SPA approach +- [ ] Component taxonomy approved (4-layer hierarchy) +- [ ] 11 CRUD templates mapped to API endpoints +- [ ] OpenAPI spec validated by backend team +- [ ] Database schema approved by DBA +- [ ] Vite scaffold created with TypeScript strict mode +- [ ] CI/CD pipeline (GitHub Actions) functional +- [ ] Team training: Vue 3 Composition API + Pinia + TypeScript +- [ ] Design system finalized (Tabler + custom components) + +--- + +## Appendix A: Bundle Size Strategy + +**Target**: Main chunk <500KB (gzip), total <1MB + +**Strategy**: + +1. **Route-level code splitting**: Lazy-load each CRUD module (orders, inventory, etc.) +2. **Dynamic imports**: `import('./orders/OrderForm.vue')` +3. **Library externalization**: Vue, Pinia, Axios in separate chunks +4. **Tree-shaking**: Remove unused Tabler components at build time +5. **Compression**: Gzip (server) + Brotli (CDN) + +**Monitoring**: Bundle analyzer in CI (Phase 5+) + +--- + +## Appendix B: Performance Targets + +| Metric | Target | Rationale | +|--------|--------|-----------| +| **First Contentful Paint (FCP)** | <2s | Initial render speed | +| **Time to Interactive (TTI)** | <3s | User can interact | +| **Largest Contentful Paint (LCP)** | <2.5s | Main content visible | +| **Cumulative Layout Shift (CLS)** | <0.1 | Visual stability | +| **API response time (P95)** | <250ms | Backend performance | +| **Database query (P95)** | <100ms | Query optimization | +| **Concurrent users (initial)** | 100 | Phase 0-8 capacity | +| **Concurrent users (future)** | 1000+ | Phase 12+ infrastructure scale | + +--- + +## Appendix C: Team Structure (13 FTE) + +``` +Product Manager (1) +├─ Requirements gathering, stakeholder communication +│ +Technical Lead / Architect (1) +├─ Architecture decisions, code review +│ +Frontend Development Team (4) +├─ Lead FE Dev (1): Component library, design system +├─ Senior FE Dev (1): State management, API integration +├─ Mid-Level FE Dev (2): CRUD templates, E2E tests +│ +Backend Development Team (2) +├─ API development (.NET) +├─ Database optimization +│ +UX/UI Designer (1) +├─ Figma designs, accessibility audit +│ +QA Team (2) +├─ Automation (Playwright) +├─ Manual testing + UAT coordination +│ +DevOps/SRE (1) +├─ CI/CD pipeline, monitoring, deployment +│ +Security Specialist (0.5 contractor) +├─ Security audit, OWASP validation +│ +Technical Writer (0.5) +├─ API docs, user guides, wiki +``` + +--- + +## Sign-Off + +- **Product Manager**: _________________ Date: _______ +- **Technical Lead**: _________________ Date: _______ +- **Backend Lead**: _________________ Date: _______ +- **Frontend Lead**: _________________ Date: _______ +- **QA Lead**: _________________ Date: _______ + +--- + +**Document Version**: 1.0 +**Last Updated**: 2026-07-26 +**Next Review**: Phase 1 completion (2026-08-09)