feat(modernization): full architecture blueprint with hardening follow-up
Implement phased modernization infrastructure for transitioning from multi-page legacy routing to SPA portal-shell architecture, plus post-delivery hardening fixes for policy loading, fallback consistency, and governance drift detection. Key changes: - Add route contract enrichment with scope/visibility/compatibility policies - Canonical 302 redirects from legacy direct-entry to /portal-shell/ routes - Asset readiness enforcement and runtime fallback retirement for in-scope routes - Shared feature-flag helpers (env > config > default) replacing duplicated _to_bool - Defensive copy for lru_cached policy payloads preventing mutation corruption - Unified retired-fallback response helper across app and blueprint routes - Frontend/backend route-contract cross-validation in governance gates - Shell CSS token fallback values for routes rendered outside shell scope - Local-safe .env.example defaults with production recommendation comments - Legacy contract fallback warning logging and single-hop redirect optimization Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-11
|
||||
@@ -0,0 +1,146 @@
|
||||
## Context
|
||||
|
||||
The project has completed the no-iframe shell migration and fluid shell Phase 1, but frontend modernization remains fragmented across routing governance, styling ownership, and quality enforcement.
|
||||
|
||||
Current state:
|
||||
- Shell contract currently governs a subset of report routes, and route governance is implemented through `frontend/src/portal-shell/routeContracts.js` + `nativeModuleRegistry.js`.
|
||||
- Multiple page families still ship page-global CSS patterns (`:root`, `body`, page-level max-width wrappers), creating style ownership ambiguity and cross-page leakage risk.
|
||||
- Existing specs still preserve fallback-era assumptions in several areas (runtime fallback continuity and coexistence-oriented style policy).
|
||||
|
||||
Scope decisions for this change:
|
||||
- In scope: admin surfaces `/admin/pages`, `/admin/performance`.
|
||||
- Out of scope (follow-up change): `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`.
|
||||
|
||||
Stakeholders:
|
||||
- Frontend platform owners (shell/routing/design system)
|
||||
- Report page module owners
|
||||
- Backend maintainers for route serving and release gates
|
||||
- QA/operations for release readiness and rollback governance
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Define a shell-first canonical frontend architecture for in-scope routes with explicit route governance.
|
||||
- Converge style architecture from permissive coexistence to enforceable isolation + token semantics.
|
||||
- Modernize in-scope page content (charts, filters, interactions) with contract-first parity validation to prevent architecture drift during migration.
|
||||
- Replace runtime fallback dependency for in-scope modules with build/deploy readiness gates.
|
||||
- Add modernization-grade quality gates (behavioral, visual, accessibility, performance).
|
||||
- Provide phased migration and rollback-safe program governance.
|
||||
|
||||
**Non-Goals:**
|
||||
- Implementing code changes in this artifact phase.
|
||||
- Rewriting excluded routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) in this change.
|
||||
- Replacing backend business APIs or changing report data semantics.
|
||||
- Introducing mandatory framework rewrites for all pages in one release window.
|
||||
|
||||
## Decisions
|
||||
|
||||
### D1. Route Scope Matrix with Explicit Inclusion/Exclusion
|
||||
|
||||
**Decision:** Define an explicit route matrix for modernization enforcement.
|
||||
|
||||
- Included: in-scope shell-governed report routes + `/admin/pages`, `/admin/performance`.
|
||||
- Excluded for follow-up: `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`.
|
||||
|
||||
**Rationale:** Prevent uncontrolled scope creep while still addressing governance gaps for admin functionality.
|
||||
|
||||
**Alternatives considered:**
|
||||
- Modernize all routes at once: rejected due to high blast radius and schedule risk.
|
||||
- Only modernize report routes, defer admin pages: rejected because admin navigation governance remains inconsistent.
|
||||
|
||||
### D2. Canonical Shell Routing Policy for In-Scope Report Routes
|
||||
|
||||
**Decision:** In-scope report routes MUST have a canonical shell entry path and contract metadata. Direct route entry remains available only through explicit compatibility policy.
|
||||
|
||||
**Rationale:** Removes ambiguity between direct route behavior and shell-governed behavior; improves observability and testability.
|
||||
|
||||
**Alternatives considered:**
|
||||
- Keep dual-mode indefinitely (direct vs shell): rejected due to long-term drift risk.
|
||||
|
||||
### D3. Admin Surfaces Become First-Class Contracted Navigation Targets
|
||||
|
||||
**Decision:** `/admin/pages` and `/admin/performance` are governed as explicit shell navigation targets with visibility and access policy, while retaining server authority for auth/session.
|
||||
|
||||
**Rationale:** Admin actions are part of platform governance and must be consistently modeled in route and visibility contracts.
|
||||
|
||||
### D4. Style Convergence Policy: Isolation + Token Enforcement
|
||||
|
||||
**Decision:** Move from "Tailwind and legacy CSS coexistence" to "controlled convergence":
|
||||
- In-scope modules MUST avoid page-global selectors (`:root`, `body`) for page-local concerns.
|
||||
- Shared semantics MUST be token-driven through `frontend/src/styles/tailwind.css` and shared UI layers.
|
||||
- Legacy CSS usage in in-scope routes requires explicit exception policy.
|
||||
|
||||
**Rationale:** Reduces style collisions and maintenance overhead from fragmented style ownership.
|
||||
|
||||
### D5. Asset Readiness Over Runtime Fallback for In-Scope Modules
|
||||
|
||||
**Decision:** In-scope modules require build/deploy readiness guarantees; runtime fallback is no longer primary resilience strategy for these routes.
|
||||
|
||||
**Rationale:** Runtime fallback hides release failures and delays detection. Fail-fast at build/release is safer for correctness and easier to operate.
|
||||
|
||||
### D6. Modernization Quality Gates as Release Contract
|
||||
|
||||
**Decision:** Define mandatory route-level acceptance gates:
|
||||
- Functional behavior parity
|
||||
- Visual regression checks for critical states
|
||||
- Accessibility checks (keyboard semantics, reduced-motion compatibility, landmark/label quality)
|
||||
- Performance budgets (bundle and runtime thresholds)
|
||||
|
||||
**Rationale:** Architecture convergence without quality gates causes unstable rollouts and regressions.
|
||||
|
||||
### D7. Contract-First Page-Content Migration for Charts and Filters
|
||||
|
||||
**Decision:** In-scope chart/filter/page-content migration MUST follow a contract-first flow with reversible rollout:
|
||||
- Freeze per-route content contracts before refactor (filter input semantics, query payload structure, chart data shape, interaction events, empty/error states).
|
||||
- Implement a parity harness using golden fixtures and critical-state comparisons before switching default rendering.
|
||||
- Cut over with route-scoped feature flags and immediate rollback controls (no irreversible flip in one step).
|
||||
- Progress route-by-route only after manual acceptance sign-off is completed for the current route.
|
||||
- Remove legacy content implementation only after parity checks and manual acceptance sign-off are completed.
|
||||
|
||||
**Rationale:** Prior migration failures were caused by implementation-first rewrites without strict parity and rollback controls, leading to layout/interaction drift and hard-to-debug regressions.
|
||||
|
||||
### D8. Mandatory "BUG Revalidation During Migration" Gate
|
||||
|
||||
**Decision:** Each route modernization MUST include explicit BUG revalidation before sign-off:
|
||||
- Create a route-level known-bug baseline (within migrated scope: chart, filter, and page interaction behavior) before implementation.
|
||||
- During manual acceptance, replay known-bug checks on the modernized route.
|
||||
- If a known legacy bug is reproduced in the modernized implementation, route sign-off MUST fail and cutover/legacy-retirement MUST be blocked until fixed.
|
||||
|
||||
**Rationale:** Parity-only migration can accidentally preserve old defects. The modernization objective is not only structural migration, but also preventing legacy defect carry-over into the new architecture.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- **[Scope ambiguity]** Route inclusion can drift during execution. → Mitigation: publish a frozen in-scope/out-of-scope matrix in specs and tasks.
|
||||
- **[Admin integration complexity]** Admin routes have different auth/session behavior than report modules. → Mitigation: keep backend auth authority unchanged; only modernize navigation contract layer in this change.
|
||||
- **[Temporary dual standards]** Excluded routes still use legacy conventions. → Mitigation: explicit follow-up change linkage and governance deadline.
|
||||
- **[Release friction increase]** Fail-fast asset readiness can block releases more often initially. → Mitigation: phased enforcement with warning mode then blocking mode.
|
||||
- **[Style migration churn]** Token/isolation enforcement may require broad CSS refactor in in-scope pages. → Mitigation: staged rollout by route family and exception registry.
|
||||
- **[Content migration instability]** Chart/filter rewrites can regress data semantics or interaction flows. → Mitigation: contract freeze + golden fixture parity + page-by-page manual acceptance + feature-flagged cutover with rollback.
|
||||
- **[Legacy bug carry-over]** Modernized routes can pass parity yet still replicate known legacy defects. → Mitigation: mandatory per-route bug baseline and replay checks as blocking sign-off criteria.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Publish and freeze modernization scope matrix (included/excluded routes).
|
||||
2. Define delta specs for route governance, style enforcement, quality gates, and asset readiness retirement policy.
|
||||
3. Derive implementation tasks in phased waves (governance first, then style convergence, then gate enforcement).
|
||||
4. Publish page-content contracts and golden fixtures for in-scope routes before chart/filter cutover.
|
||||
5. Record route-level known-bug baselines for migrated scope and attach them to acceptance checklists.
|
||||
6. Execute page-by-page manual acceptance sign-off (including bug replay checks) and only then move to the next route.
|
||||
7. Enable non-blocking observability checks first (dry-run mode), then switch to blocking gates.
|
||||
8. Roll out per route family with rollback criteria and runbook updates.
|
||||
9. Open follow-up modernization change for excluded routes.
|
||||
|
||||
## Rollback Strategy
|
||||
|
||||
- Maintain reversible config switches for new quality gates during initial adoption.
|
||||
- If blocking gates cause production-impacting false positives, revert gate mode to warning while preserving telemetry.
|
||||
- Keep route-level rollback path documented for each in-scope family.
|
||||
- Keep per-route manual acceptance records so rollback decisions can reference concrete pass/fail evidence.
|
||||
- Keep per-route bug baseline and bug-replay results so cutover and rollback decisions can prove legacy bug non-carry-over.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should admin pages remain backend-rendered targets with shell-managed links only, or move to shell-native view composition in a later phase?
|
||||
- Which visual regression toolchain should be standardized (existing snapshot evidence extension vs dedicated UI visual diff pipeline)?
|
||||
- What are initial enforceable performance thresholds for route bundles and shell startup latency?
|
||||
- Should parity harness for charts use DOM-level snapshots only, or also include canonicalized data-level assertions as a blocking gate?
|
||||
@@ -0,0 +1,46 @@
|
||||
## Why
|
||||
|
||||
The project has completed the critical iframe-to-Vue migration and Phase 1 shell fluidization, but the frontend architecture is still only partially modernized. Several routes remain outside shell contract governance, style ownership is still fragmented across page-local global CSS (`:root`, `body`, page-level `max-width`), and fallback-era patterns remain in docs and runtime expectations.
|
||||
|
||||
A full modernization blueprint is needed now to converge the system into a single, predictable frontend architecture before more feature work increases divergence and maintenance cost.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Establish a shell-first architecture baseline where in-scope routes are contract-governed and module-registered with deterministic route visibility and ownership metadata.
|
||||
- **BREAKING**: Retire legacy runtime fallback expectations for primary report routes in favor of build-readiness and deploy gating (fail-fast in CI/release instead of runtime degraded UX).
|
||||
- **BREAKING**: Adopt canonical shell routing policy for report pages (legacy direct-entry routes become explicit compatibility redirects with sunset policy).
|
||||
- Standardize style architecture: remove page-level global CSS side effects, enforce scoped styling boundaries, and converge to token-first Tailwind design primitives.
|
||||
- Define contract-first page-content modernization for in-scope routes (charts, filters, and page interactions) with parity checkpoints before cutover.
|
||||
- Use page-by-page manual acceptance sign-off as the required readiness gate for content migration progression.
|
||||
- Enforce mandatory "BUG revalidation during migration" for each route so known legacy bugs in migrated scope SHALL NOT be carried into the new architecture.
|
||||
- Introduce modernization quality gates covering interaction behavior, visual regressions, accessibility, and performance budgets.
|
||||
- Define phased execution and rollback-safe governance for “full modernization” as a program (not a single code patch), including explicit completion criteria and deprecation milestones.
|
||||
- Include admin surfaces in this change scope: `/admin/pages` and `/admin/performance` SHALL be first-class shell-governed routes with explicit contract metadata and visibility policy.
|
||||
- Defer the following routes to a subsequent change (out of scope for this change): `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `frontend-platform-modernization-governance`: Defines target frontend architecture, phased milestones, modernization guardrails, and deprecation policy.
|
||||
- `unified-shell-route-coverage`: Ensures in-scope routes (including admin pages/performance) are covered by shell route contracts, loader registry, and navigation visibility rules with CI blocking on gaps.
|
||||
- `style-isolation-and-token-enforcement`: Enforces CSS scope boundaries and token-first style semantics; eliminates page-global style leakage patterns.
|
||||
- `page-content-modernization-safety`: Governs chart/filter/page-content migration with contract baselines, parity verification, legacy bug carry-over prevention, and reversible rollout controls.
|
||||
- `frontend-quality-gate-modernization`: Adds behavioral, visual, accessibility, and performance acceptance gates for route-level changes.
|
||||
- `asset-readiness-and-fallback-retirement`: Defines build/deploy guarantees and controlled retirement of runtime fallback-era behavior.
|
||||
|
||||
### Modified Capabilities
|
||||
- `spa-shell-navigation`: Extend from current native route-view baseline to full route coverage, canonical shell routing, and contract completeness enforcement.
|
||||
- `tailwind-design-system`: Shift from coexistence-with-legacy to convergence-and-enforcement with explicit legacy CSS deprecation rules.
|
||||
- `full-vite-page-modularization`: Tighten from “fallback continuity” to “asset readiness governance” with stronger release-time guarantees.
|
||||
- `vue-vite-page-architecture`: Update route serving expectations to shell-first canonical model with explicit compatibility redirects and sunset criteria.
|
||||
|
||||
## Impact
|
||||
|
||||
- **Frontend shell and routing**: `frontend/src/portal-shell/` (`App.vue`, `router.js`, `routeContracts.js`, `nativeModuleRegistry.js`, navigation metadata handling).
|
||||
- **Frontend page style system**: `frontend/src/*/style.css`, `frontend/src/*/styles.css`, `frontend/src/styles/tailwind.css`, shared UI/style modules.
|
||||
- **Frontend page-content modules**: chart, filter, and page interaction modules under `frontend/src/**` used by in-scope routes, including compatibility adapters where needed.
|
||||
- **Backend route serving and compatibility**: Flask route handlers that serve page entries and legacy direct-entry paths, plus deploy-time asset-readiness checks.
|
||||
- **Quality system**: `frontend/tests/`, Python integration tests, and potential new CI checks for visual/a11y/performance budgets.
|
||||
- **Documentation and operations**: migration/runbook docs, architecture maps, and release governance docs aligned to modernization milestones.
|
||||
- **Dependencies/tooling**: likely introduction of additional frontend QA tooling in dev workflow (subject to design artifact decisions).
|
||||
- **Scope boundary note**: this change explicitly excludes `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`; those routes are planned for a follow-up modernization change.
|
||||
@@ -0,0 +1,25 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: In-scope frontend assets SHALL be release-ready before deployment
|
||||
In-scope routes SHALL rely on build/deploy readiness guarantees instead of runtime fallback behavior as the primary resilience mechanism.
|
||||
|
||||
#### Scenario: Build-readiness enforcement
|
||||
- **WHEN** release artifacts are prepared for deployment
|
||||
- **THEN** in-scope route assets SHALL be validated for presence and loadability
|
||||
- **THEN** missing required in-scope assets SHALL fail the release gate
|
||||
|
||||
### Requirement: Runtime fallback retirement SHALL follow a governed phase policy
|
||||
Runtime fallback behavior for in-scope modernization routes SHALL be retired under explicit governance milestones.
|
||||
|
||||
#### Scenario: Fallback retirement in phase scope
|
||||
- **WHEN** a route is marked in-scope for fallback retirement
|
||||
- **THEN** runtime fallback behavior for that route SHALL be removed or disabled by policy
|
||||
- **THEN** reliability for that route SHALL be guaranteed by release-time readiness gates
|
||||
|
||||
### Requirement: Deferred routes SHALL keep existing fallback posture in this phase
|
||||
Routes deferred from this modernization phase SHALL retain their existing fallback posture until handled by a follow-up change.
|
||||
|
||||
#### Scenario: Deferred fallback continuity
|
||||
- **WHEN** `/tables`, `/excel-query`, `/query-tool`, or `/mid-section-defect` is evaluated in this phase
|
||||
- **THEN** fallback retirement SHALL NOT be required for phase completion
|
||||
- **THEN** fallback retirement decisions for those routes SHALL be addressed in a follow-up modernization change
|
||||
@@ -0,0 +1,26 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Frontend modernization scope SHALL be explicitly governed
|
||||
The modernization program SHALL define an explicit in-scope and out-of-scope route matrix for each phase, and SHALL treat that matrix as a release-governed contract artifact.
|
||||
|
||||
#### Scenario: Scope matrix publication
|
||||
- **WHEN** a modernization phase is created
|
||||
- **THEN** the phase SHALL publish an explicit in-scope route list and out-of-scope route list
|
||||
- **THEN** the matrix SHALL include `/admin/pages` and `/admin/performance` in scope for this phase
|
||||
- **THEN** the matrix SHALL mark `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` as deferred routes for a follow-up phase
|
||||
|
||||
#### Scenario: Scope drift prevention
|
||||
- **WHEN** implementation tasks are derived from the phase specs
|
||||
- **THEN** tasks targeting routes outside the in-scope matrix SHALL be rejected for this phase
|
||||
|
||||
### Requirement: Modernization phases SHALL define completion and deprecation milestones
|
||||
Each modernization phase SHALL define measurable completion criteria and deprecation milestones for legacy-era patterns.
|
||||
|
||||
#### Scenario: Phase completion criteria
|
||||
- **WHEN** a phase reaches release review
|
||||
- **THEN** it SHALL provide objective completion criteria for route governance, style governance, and quality gates
|
||||
- **THEN** it SHALL identify any remaining deferred routes and their next-phase linkage
|
||||
|
||||
#### Scenario: Legacy deprecation milestones
|
||||
- **WHEN** legacy fallback or legacy style exceptions remain in phase scope
|
||||
- **THEN** the phase SHALL define a dated milestone or release gate to remove those exceptions
|
||||
@@ -0,0 +1,25 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Modernization releases SHALL pass multi-dimensional frontend quality gates
|
||||
In-scope modernization releases SHALL pass functional, visual, accessibility, and performance gates before promotion.
|
||||
|
||||
#### Scenario: Gate bundle at release candidate
|
||||
- **WHEN** a release candidate includes in-scope modernization changes
|
||||
- **THEN** it SHALL execute functional behavior parity checks for affected routes
|
||||
- **THEN** it SHALL execute critical-state visual regression checks for affected routes
|
||||
- **THEN** it SHALL execute accessibility checks for keyboard and reduced-motion behavior
|
||||
- **THEN** it SHALL execute performance budget checks for defined shell/route thresholds
|
||||
|
||||
### Requirement: Gate failures SHALL block release promotion
|
||||
Blocking quality gates SHALL prevent release promotion for in-scope modernization changes.
|
||||
|
||||
#### Scenario: Blocking gate failure
|
||||
- **WHEN** any mandatory modernization quality gate fails
|
||||
- **THEN** release promotion SHALL be blocked until the failure is resolved or explicitly waived per governance policy
|
||||
|
||||
### Requirement: Deferred routes SHALL be excluded from this phase gate baseline
|
||||
The route baseline for this modernization phase SHALL exclude deferred routes.
|
||||
|
||||
#### Scenario: Deferred route baseline exclusion
|
||||
- **WHEN** gate baseline is computed for this phase
|
||||
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be excluded from mandatory modernization gate coverage
|
||||
@@ -0,0 +1,24 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Major Pages SHALL be Managed by Vite Modules
|
||||
The system SHALL provide Vite-managed module entries for all in-scope modernization routes under shell-first governance, including admin surfaces `/admin/pages` and `/admin/performance` as governed targets. Deferred routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) are excluded from this phase's required module-governance completeness.
|
||||
|
||||
#### Scenario: In-scope module governance completeness
|
||||
- **WHEN** modernization route coverage is validated for this phase
|
||||
- **THEN** every in-scope route SHALL have deterministic module-governance metadata and ownership mapping
|
||||
|
||||
#### Scenario: Deferred route exclusion in this phase
|
||||
- **WHEN** completeness validation executes for this phase
|
||||
- **THEN** deferred routes SHALL be excluded from mandatory pass criteria
|
||||
|
||||
### Requirement: Build Pipeline SHALL Produce Backend-Served Assets
|
||||
Vite build output for in-scope modernization routes MUST be emitted into backend static paths and validated at release time. Missing required in-scope assets SHALL fail release gates instead of relying on runtime fallback behavior.
|
||||
|
||||
#### Scenario: Build artifact readiness for in-scope routes
|
||||
- **WHEN** frontend build is executed for release
|
||||
- **THEN** required in-scope route artifacts SHALL be present in configured backend static dist paths
|
||||
- **THEN** missing required artifacts SHALL fail readiness checks
|
||||
|
||||
#### Scenario: Deferred route fallback posture unchanged in this phase
|
||||
- **WHEN** deferred routes are evaluated in this phase
|
||||
- **THEN** existing fallback posture SHALL not block this phase's completion
|
||||
@@ -0,0 +1,54 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: In-scope page-content modernization SHALL be contract-first
|
||||
Before chart/filter/page interaction refactors are cut over, each in-scope route SHALL define a contract baseline that captures data and interaction semantics.
|
||||
|
||||
#### Scenario: Route contract baseline defined
|
||||
- **WHEN** an in-scope route is selected for chart/filter modernization
|
||||
- **THEN** the route SHALL define filter input semantics, query payload expectations, and chart data-shape contracts
|
||||
- **THEN** the route SHALL define critical state expectations for loading, empty, error, and success interactions
|
||||
|
||||
### Requirement: Cutover SHALL require parity evidence against baseline behavior
|
||||
In-scope chart/filter modernization cutover SHALL require parity evidence against baseline fixtures and critical interaction flows.
|
||||
|
||||
#### Scenario: Parity gate before default switch
|
||||
- **WHEN** a route is proposed for defaulting to a modernized chart/filter implementation
|
||||
- **THEN** golden fixture parity checks SHALL pass for defined critical states
|
||||
- **THEN** interaction parity checks SHALL pass for filter apply/reset and chart selection/drill behaviors
|
||||
|
||||
### Requirement: Route-level content cutover SHALL be reversible
|
||||
Modernized chart/filter content rollouts SHALL use reversible controls that allow immediate rollback without reverting unrelated shell architecture work.
|
||||
|
||||
#### Scenario: Controlled rollout and rollback
|
||||
- **WHEN** a modernized route is enabled for users
|
||||
- **THEN** the route SHALL be controlled by route-scoped feature flag or equivalent switch
|
||||
- **THEN** rollback procedure SHALL be documented and executable within one release cycle
|
||||
|
||||
### Requirement: Page-content modernization progression SHALL require manual route acceptance
|
||||
In-scope chart/filter/page-content migration SHALL progress one route at a time with explicit manual acceptance records.
|
||||
|
||||
#### Scenario: Route-by-route manual acceptance gate
|
||||
- **WHEN** an in-scope route completes modernization implementation and parity checks
|
||||
- **THEN** that route SHALL be manually accepted using a defined checklist covering filter flows, chart interactions, empty/error behavior, and visual correctness
|
||||
- **THEN** the next route SHALL NOT begin cutover until manual acceptance for the current route is signed off
|
||||
|
||||
### Requirement: Known legacy bugs in migrated scope SHALL NOT be carried into modernized routes
|
||||
Modernized route acceptance SHALL include explicit revalidation of known legacy defects in migrated scope, and reproduced defects SHALL block sign-off.
|
||||
|
||||
#### Scenario: Route-level legacy bug baseline and replay
|
||||
- **WHEN** an in-scope route enters chart/filter/page-content modernization
|
||||
- **THEN** a route-level known-bug baseline (within migrated scope) SHALL be recorded before implementation
|
||||
- **THEN** manual acceptance SHALL replay those known-bug checks on the modernized route
|
||||
|
||||
#### Scenario: Legacy bug carry-over is blocked
|
||||
- **WHEN** manual acceptance finds that a known legacy bug is still reproducible in the modernized route
|
||||
- **THEN** route sign-off SHALL fail
|
||||
- **THEN** route cutover completion and legacy code retirement SHALL be blocked until the bug is fixed
|
||||
|
||||
### Requirement: Legacy content path retirement SHALL require parity and manual acceptance
|
||||
Legacy chart/filter implementations SHALL be removed only after parity checks and manual acceptance criteria are satisfied.
|
||||
|
||||
#### Scenario: Legacy removal approval
|
||||
- **WHEN** legacy chart/filter code is planned for removal on an in-scope route
|
||||
- **THEN** the route SHALL provide parity pass evidence and manual acceptance sign-off records
|
||||
- **THEN** unresolved parity failures or manual acceptance defects SHALL block legacy removal
|
||||
@@ -0,0 +1,28 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Portal SHALL provide a SPA shell driven by Vue Router
|
||||
The portal frontend SHALL use a single SPA shell entry and Vue Router to render in-scope page modules without iframe embedding. In-scope routes for this phase SHALL include the governed report routes and admin surfaces `/admin/pages` and `/admin/performance`, while deferred routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) are explicitly excluded from this phase contract.
|
||||
|
||||
#### Scenario: In-scope route renders through shell governance
|
||||
- **WHEN** a user navigates to an in-scope shell-governed route
|
||||
- **THEN** the route SHALL resolve through Vue Router with shell contract metadata
|
||||
- **THEN** the shell SHALL render the corresponding module/target without iframe fallback
|
||||
|
||||
#### Scenario: Admin route appears as governed target
|
||||
- **WHEN** an admin user opens shell navigation
|
||||
- **THEN** `/admin/pages` and `/admin/performance` SHALL be exposed as governed navigation targets per access policy
|
||||
|
||||
#### Scenario: Deferred route is excluded from this phase route-governance requirement
|
||||
- **WHEN** phase-level shell-governance compliance is evaluated
|
||||
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be treated as deferred and excluded from pass/fail criteria for this phase
|
||||
|
||||
### Requirement: Existing route contracts SHALL remain stable in SPA mode
|
||||
Migration to the shell-first SPA model SHALL preserve route/query compatibility for in-scope routes while introducing canonical shell routing policy and explicit compatibility handling.
|
||||
|
||||
#### Scenario: Canonical shell path behavior for in-scope routes
|
||||
- **WHEN** a user opens an in-scope report route via canonical shell path
|
||||
- **THEN** route behavior and query semantics SHALL remain compatible with established baseline behavior
|
||||
|
||||
#### Scenario: Compatibility policy for direct route entry
|
||||
- **WHEN** a user opens an in-scope report route via direct non-canonical entry
|
||||
- **THEN** the system SHALL apply explicit compatibility policy (preserve behavior or compatibility redirect) without breaking route semantics
|
||||
@@ -0,0 +1,25 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: In-scope pages SHALL enforce style isolation boundaries
|
||||
In-scope modernization pages SHALL avoid page-global selectors for page-local concerns and SHALL keep style concerns scoped to route-level containers or shared design-system layers.
|
||||
|
||||
#### Scenario: Global selector control
|
||||
- **WHEN** style governance checks analyze in-scope page styles
|
||||
- **THEN** page-local style changes SHALL NOT introduce new `:root` or `body` rules for route-local presentation concerns
|
||||
- **THEN** shared cross-route concerns SHALL be authored in designated shared style layers
|
||||
|
||||
### Requirement: In-scope shared semantics SHALL be token-first
|
||||
Shared UI semantics in in-scope routes SHALL be implemented with token-backed Tailwind/shared-style primitives before page-local overrides are allowed.
|
||||
|
||||
#### Scenario: Token-first UI pattern adoption
|
||||
- **WHEN** an in-scope route introduces or updates shared UI semantics (layout shell, card, filter, action, status)
|
||||
- **THEN** the route SHALL consume token-backed shared primitives
|
||||
- **THEN** page-local hard-coded visual values SHALL require explicit exception justification
|
||||
|
||||
### Requirement: Legacy style exceptions SHALL be tracked and sunset
|
||||
Legacy CSS exceptions for in-scope routes SHALL be tracked with ownership and removal milestones.
|
||||
|
||||
#### Scenario: Exception registry requirement
|
||||
- **WHEN** an in-scope route cannot yet remove legacy style behavior
|
||||
- **THEN** the route SHALL be registered with an exception owner and planned removal milestone
|
||||
- **THEN** unresolved exceptions past milestone SHALL fail modernization governance review
|
||||
@@ -0,0 +1,24 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Frontend styles SHALL be governed by Tailwind design tokens
|
||||
The frontend SHALL enforce a token-governed style system for in-scope routes. Shared visual semantics SHALL be expressed through token-backed Tailwind/shared layers, and ad-hoc page-local hard-coded values for shared semantics SHALL require explicit exception governance.
|
||||
|
||||
#### Scenario: Shared token usage across in-scope modules
|
||||
- **WHEN** two in-scope modules render equivalent UI semantics (e.g., card, filter chip, primary action, status indicator)
|
||||
- **THEN** they SHALL use the same token-backed style semantics
|
||||
- **THEN** visual output SHALL remain consistent across those modules
|
||||
|
||||
#### Scenario: Token governance review
|
||||
- **WHEN** an in-scope route introduces new shared UI styling
|
||||
- **THEN** the styling SHALL map to shared tokens/layers or be recorded in an approved exception registry
|
||||
|
||||
### Requirement: Tailwind migration SHALL support coexistence with legacy CSS
|
||||
Tailwind migration SHALL support controlled coexistence only as a transition state for this phase. In-scope routes SHALL move toward isolation-first style ownership and SHALL NOT introduce new page-global CSS side effects for route-local concerns.
|
||||
|
||||
#### Scenario: In-scope global selector control
|
||||
- **WHEN** in-scope route styles are reviewed
|
||||
- **THEN** new route-local styling SHALL NOT introduce page-global selectors (`:root`, `body`) for local presentation behavior
|
||||
|
||||
#### Scenario: Deferred route coexistence allowance
|
||||
- **WHEN** deferred routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) are evaluated during this phase
|
||||
- **THEN** existing coexistence posture SHALL be allowed and handled by a follow-up modernization change
|
||||
@@ -0,0 +1,29 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: In-scope routes SHALL be shell-contract governed
|
||||
All in-scope modernization routes SHALL be represented in shell route contracts, loader registration policy, and navigation visibility governance.
|
||||
|
||||
#### Scenario: In-scope coverage validation
|
||||
- **WHEN** shell route contract validation is executed
|
||||
- **THEN** every in-scope route SHALL have route metadata, ownership metadata, and visibility policy metadata
|
||||
- **THEN** missing in-scope route contracts SHALL fail validation
|
||||
|
||||
#### Scenario: Admin route inclusion
|
||||
- **WHEN** shell navigation is built for admin users
|
||||
- **THEN** `/admin/pages` and `/admin/performance` SHALL be represented as governed navigation targets according to visibility/access policy
|
||||
|
||||
### Requirement: Out-of-scope routes SHALL not block this phase
|
||||
Routes explicitly marked as out-of-scope for this modernization phase SHALL be excluded from required shell-coverage gates in this phase.
|
||||
|
||||
#### Scenario: Deferred route exclusion
|
||||
- **WHEN** modernization gates execute for this phase
|
||||
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be treated as deferred routes
|
||||
- **THEN** deferred route absence from new shell-governance gates SHALL NOT fail this phase
|
||||
|
||||
### Requirement: Route coverage governance SHALL be CI-enforced
|
||||
Route coverage and contract completeness checks for in-scope routes SHALL run as CI gates.
|
||||
|
||||
#### Scenario: CI gate failure on in-scope gap
|
||||
- **WHEN** CI detects an in-scope route without required contract metadata
|
||||
- **THEN** the modernization gate SHALL fail
|
||||
- **THEN** release promotion SHALL be blocked until resolved
|
||||
@@ -0,0 +1,20 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Pure Vite pages SHALL be served as static HTML
|
||||
The system SHALL serve in-scope pure Vite pages through backend static HTML delivery under a shell-first canonical routing policy. Direct-entry compatibility for in-scope routes SHALL be explicit and governed. Admin targets `/admin/pages` and `/admin/performance` SHALL be represented as governed shell navigation targets, while maintaining backend auth/session authority.
|
||||
|
||||
#### Scenario: In-scope canonical shell entry
|
||||
- **WHEN** a user navigates to an in-scope canonical shell route
|
||||
- **THEN** the shell SHALL render the target route via governed route contracts and static asset delivery
|
||||
|
||||
#### Scenario: Direct-entry compatibility policy for in-scope routes
|
||||
- **WHEN** a user opens an in-scope route through direct non-canonical entry
|
||||
- **THEN** the system SHALL apply explicit compatibility behavior without breaking established query semantics
|
||||
|
||||
#### Scenario: Admin targets in shell governance
|
||||
- **WHEN** shell navigation is rendered for an authorized admin user
|
||||
- **THEN** `/admin/pages` and `/admin/performance` SHALL be reachable through governed admin navigation targets
|
||||
|
||||
#### Scenario: Deferred routes excluded from this phase architecture criteria
|
||||
- **WHEN** this phase architecture compliance is evaluated
|
||||
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be excluded and handled in a follow-up change
|
||||
@@ -0,0 +1,78 @@
|
||||
## 1. Program Governance Baseline
|
||||
|
||||
- [x] 1.1 Publish a frozen in-scope/out-of-scope route matrix for this phase (include `/admin/pages`, `/admin/performance`; exclude `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`)
|
||||
- [x] 1.2 Add modernization governance documentation for phase completion criteria and legacy deprecation milestones
|
||||
- [x] 1.3 Create an exception registry format for temporary route/style exceptions (owner + milestone)
|
||||
|
||||
## 2. Shell Route Contract Expansion (In Scope)
|
||||
|
||||
- [x] 2.1 Extend shell route contract metadata to cover all in-scope routes for this phase
|
||||
- [x] 2.2 Add governed navigation target definitions for `/admin/pages` and `/admin/performance`
|
||||
- [x] 2.3 Ensure route visibility/access policy metadata is validated for in-scope routes
|
||||
- [x] 2.4 Add CI contract checks that fail on missing in-scope route metadata
|
||||
|
||||
## 3. Canonical Routing and Compatibility Policy
|
||||
|
||||
- [x] 3.1 Define canonical shell entry behavior for in-scope report routes
|
||||
- [x] 3.2 Implement explicit compatibility policy for direct non-canonical route entry
|
||||
- [x] 3.3 Verify query-semantics compatibility for in-scope routes under canonical/compatibility paths
|
||||
|
||||
## 4. Admin Surface Modernization Integration
|
||||
|
||||
- [x] 4.1 Integrate `/admin/pages` and `/admin/performance` into shell-governed navigation flow
|
||||
- [x] 4.2 Preserve backend auth/session authority while modernizing shell navigation governance
|
||||
- [x] 4.3 Add admin visibility/access behavior tests for shell-governed admin targets
|
||||
|
||||
## 5. Style Isolation and Token Enforcement
|
||||
|
||||
- [x] 5.1 Inventory in-scope route styles for page-global selector usage (`:root`, `body`) and classify required refactors
|
||||
- [x] 5.2 Refactor in-scope route-local styles to scoped/container-based ownership
|
||||
- [x] 5.3 Move shared visual semantics to token-backed Tailwind/shared layers
|
||||
- [x] 5.4 Add style-governance lint/check rules for in-scope routes and exception handling
|
||||
|
||||
## 6. Page-Content Modernization Safety (Charts/Filters/Interactions)
|
||||
|
||||
- [x] 6.1 Define route-level content contracts for in-scope pages (filter input semantics, query payload structure, chart data shape, state transitions)
|
||||
- [x] 6.2 Build golden fixtures and parity assertions for chart/filter critical states before cutover
|
||||
- [x] 6.3 Add interaction parity checks for critical flows (filter apply/reset, chart drill/selection, empty/error states)
|
||||
- [x] 6.4 Add route-scoped feature flags and immediate rollback controls for content cutover
|
||||
- [x] 6.5 Define a per-route manual acceptance checklist for chart/filter/page-content migration
|
||||
- [x] 6.6 Require manual acceptance sign-off for each route before moving to the next route
|
||||
- [x] 6.7 Require parity pass + manual acceptance sign-off before legacy content path retirement
|
||||
- [x] 6.8 Create route-level known-bug baselines for migrated scope before implementation begins
|
||||
- [x] 6.9 Add mandatory "BUG revalidation during migration" checklist items to manual acceptance for each route
|
||||
- [x] 6.10 Block route sign-off and legacy retirement if known legacy bugs are reproduced in the modernized route
|
||||
|
||||
## 7. Asset Readiness and Fallback Retirement (In Scope)
|
||||
|
||||
- [x] 7.1 Define required in-scope asset readiness checks for build/release pipeline
|
||||
- [x] 7.2 Enforce fail-fast release behavior when required in-scope assets are missing
|
||||
- [x] 7.3 Retire runtime fallback posture for in-scope routes per governance milestones
|
||||
- [x] 7.4 Keep deferred route fallback posture unchanged in this phase and document follow-up linkage
|
||||
|
||||
## 8. Frontend Quality Gate Modernization
|
||||
|
||||
- [x] 8.1 Define mandatory functional parity checks for in-scope modernization routes
|
||||
- [x] 8.2 Define visual regression checkpoints for critical states in in-scope routes
|
||||
- [x] 8.3 Define accessibility checks (keyboard flows, aria semantics, reduced-motion behavior)
|
||||
- [x] 8.4 Define performance budgets and measurement points for shell/route behavior
|
||||
- [x] 8.5 Configure gate severity policy (warn mode rollout -> blocking mode promotion)
|
||||
|
||||
## 9. Test and CI Wiring
|
||||
|
||||
- [x] 9.1 Extend frontend test suite for new route governance/admin scenarios
|
||||
- [x] 9.2 Extend backend/integration tests for canonical routing and compatibility behavior
|
||||
- [x] 9.3 Add CI jobs for route-governance completeness, quality-gate execution, and asset readiness checks
|
||||
- [x] 9.4 Ensure deferred routes are excluded from this phase blocking criteria
|
||||
|
||||
## 10. Migration and Rollback Runbook
|
||||
|
||||
- [x] 10.1 Update runbook with phased rollout steps and hold points for modernization gates
|
||||
- [x] 10.2 Document rollback controls for gate false positives and route-level reversion
|
||||
- [x] 10.3 Add operational observability checkpoints for route governance and gate outcomes
|
||||
|
||||
## 11. Follow-up Change Preparation (Deferred Routes)
|
||||
|
||||
- [x] 11.1 Create a linked follow-up modernization change for `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`
|
||||
- [x] 11.2 Transfer deferred-route requirements and acceptance criteria into the follow-up change
|
||||
- [x] 11.3 Record explicit handoff from this phase to the deferred-route phase
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-12
|
||||
@@ -0,0 +1,108 @@
|
||||
## Context
|
||||
|
||||
Phase 1 modernization was completed and archived, but post-delivery review identified several hardening gaps across policy loading, fallback behavior consistency, feature-flag ergonomics, and route-governance drift detection. The gaps are cross-cutting: backend route hosts, frontend contract metadata, CI governance checks, and operator onboarding defaults.
|
||||
|
||||
Current risks include:
|
||||
- shared mutable cached policy payloads via `lru_cache` return values,
|
||||
- inconsistent retired-fallback 503 response surfaces between app routes and blueprint routes,
|
||||
- local bootstrap failures caused by strict `.env.example` defaults,
|
||||
- duplicated boolean feature-flag parsing with slightly different precedence logic,
|
||||
- missing frontend/backend route-inventory cross-validation.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- Make modernization policy loading deterministic, mutation-safe, and explicitly documented.
|
||||
- Standardize retired-fallback error response behavior across all in-scope route hosts.
|
||||
- Keep `.env.example` local-safe while documenting production hardening expectations.
|
||||
- Centralize feature-flag resolution semantics in shared helpers.
|
||||
- Enforce route-contract parity across backend artifacts and frontend shell contracts.
|
||||
- Improve operational observability for legacy contract fallback loading.
|
||||
|
||||
**Non-Goals:**
|
||||
- No new route migrations in this change.
|
||||
- No redesign of shell navigation UX.
|
||||
- No deferred-route modernization implementation (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`).
|
||||
- No runtime hot-reload framework for all policy artifacts.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: Introduce shared feature-flag helpers for bool parsing and env/config precedence
|
||||
- Choice: Add shared helpers (for example `parse_bool`, `resolve_bool_flag`) used by app/policy/runtime modules.
|
||||
- Rationale: eliminates duplicated parsing and precedence drift.
|
||||
- Alternative considered: keep local `_to_bool` and alignment-by-convention.
|
||||
- Why not alternative: high regression risk from future divergence and incomplete audits.
|
||||
|
||||
### Decision 2: Protect cached policy payloads from cross-caller mutation
|
||||
- Choice: keep internal cache, but return defensive copies to callers; document refresh semantics and expose explicit cache-clear helper for tests/controlled refresh points.
|
||||
- Rationale: avoids shared-reference corruption without changing call sites.
|
||||
- Alternative considered: return `MappingProxyType`.
|
||||
- Why not alternative: nested list/dict payloads still remain mutable unless deeply frozen.
|
||||
|
||||
### Decision 3: Unify retired-fallback response generation
|
||||
- Choice: move to a shared fallback-retirement response helper callable from both app-level and blueprint-level routes.
|
||||
- Rationale: consistent status/template/body contract and easier testing.
|
||||
- Alternative considered: leave blueprint-specific inline HTML responses.
|
||||
- Why not alternative: inconsistent user/operator behavior and duplicated logic.
|
||||
|
||||
### Decision 4: Rebalance `.env.example` for safe local onboarding
|
||||
- Choice: set strict modernization toggles to local-safe defaults and annotate production-recommended values inline.
|
||||
- Rationale: avoid false-negative startup failures in local/test environments while preserving explicit production guidance.
|
||||
- Alternative considered: keep strict defaults and require all local users to override manually.
|
||||
- Why not alternative: unnecessary onboarding friction and frequent bootstrap failures.
|
||||
|
||||
### Decision 5: Add governance parity checks across frontend and backend route contracts
|
||||
- Choice: extend governance checks/tests to compare backend route contract artifacts with frontend route inventory/scope metadata.
|
||||
- Rationale: catches silent drift before release.
|
||||
- Alternative considered: rely only on backend JSON consistency.
|
||||
- Why not alternative: frontend contract drift can still break runtime behavior silently.
|
||||
|
||||
### Decision 6: Emit explicit warning when legacy contract source is used
|
||||
- Choice: log warning when loader falls back from primary contract artifact to legacy path.
|
||||
- Rationale: improves observability during migration tail.
|
||||
- Alternative considered: silent fallback.
|
||||
- Why not alternative: hard to detect stale-source dependency in production.
|
||||
|
||||
### Decision 7: Reduce unnecessary redirect hops in `/hold-detail` missing-reason flow
|
||||
- Choice: when SPA shell mode is enabled, redirect directly to canonical shell overview path.
|
||||
- Rationale: reduces redirect chain complexity and improves deterministic route tracing.
|
||||
- Alternative considered: keep current two-hop behavior.
|
||||
- Why not alternative: no benefit, adds trace/debug noise.
|
||||
|
||||
### Decision 8: Add token fallbacks for shell-dependent route styles
|
||||
- Choice: where route-local CSS consumes shell variables, include fallback values in `var(--token, fallback)` form.
|
||||
- Rationale: prevents degraded rendering when route is rendered outside shell variable scope.
|
||||
- Alternative considered: assume shell-only render path.
|
||||
- Why not alternative: fallback/compatibility entry paths still exist in this phase.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Risk] Shared helper refactor may alter existing truthy/falsey behavior in edge env values.
|
||||
- Mitigation: add unit tests covering canonical and malformed env values before replacing call sites.
|
||||
- [Risk] Contract parity gate can fail current CI if artifacts are already drifted.
|
||||
- Mitigation: land parity test with synchronized artifacts in same change.
|
||||
- [Risk] Defensive-copy strategy adds minor per-call overhead.
|
||||
- Mitigation: policy payloads are small and low-frequency; prioritize correctness over micro-optimization.
|
||||
- [Risk] `.env.example` default changes may be interpreted as weaker production stance.
|
||||
- Mitigation: add explicit production recommendation comments next to each local-safe default.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Add shared feature-flag helpers and migrate existing bool parsing call sites.
|
||||
2. Refactor modernization policy cache-return behavior to mutation-safe contract and document refresh semantics.
|
||||
3. Introduce shared retired-fallback response helper and migrate hold-overview/hold-history/hold-detail route handlers.
|
||||
4. Update `.env.example` defaults and production guidance comments.
|
||||
5. Extend governance script/tests for frontend/backend route-contract parity.
|
||||
6. Add warning log on legacy contract-source fallback.
|
||||
7. Update `/hold-detail` missing-reason redirect to single-hop canonical target under SPA mode.
|
||||
8. Add fallback values for QC-GATE shell-derived CSS variables.
|
||||
9. Run targeted unit/integration/e2e + governance checks.
|
||||
|
||||
Rollback strategy:
|
||||
- Changes are config/code-level and can be reverted by standard git rollback.
|
||||
- If parity gate causes unexpected release blocking, gate can temporarily run in warning mode while drift is fixed in same release window.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should policy cache refresh be strictly restart-based, or do we want an operator-triggered cache-clear hook in production later?
|
||||
- Do we want a single centralized governance artifact as source-of-truth long-term, with generated frontend/backend contract outputs?
|
||||
@@ -0,0 +1,34 @@
|
||||
## Why
|
||||
|
||||
Recent code review on the Phase 1 modernization delivery found several high-risk consistency gaps: mutable cached policy payloads, inconsistent fallback-retirement error behavior, aggressive `.env.example` defaults, and route-governance drift risks between backend JSON and frontend contract definitions. These issues can cause environment-dependent startup failures, silent policy drift, and hard-to-debug runtime behavior.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Harden modernization policy loaders to prevent shared mutable cache corruption and make refresh semantics explicit/documented.
|
||||
- Unify in-scope fallback-retirement response behavior across app-level routes and blueprint routes.
|
||||
- Make `.env.example` safe for local onboarding while still documenting production-recommended hardening values.
|
||||
- Consolidate feature-flag boolean resolution (`env > config > default`) into a shared helper and remove duplicated `_to_bool` implementations.
|
||||
- Add route-contract cross-validation between backend contract artifacts and frontend `routeContracts.js` inventory.
|
||||
- Add explicit warning telemetry when legacy shell-contract artifact fallback is used.
|
||||
- Document and test intentional canonical-redirect scope asymmetry (report routes vs admin external targets).
|
||||
- Reduce avoidable redirect chain length for `/hold-detail` missing-reason flow in SPA mode.
|
||||
- Add shell-token fallback values for QC-GATE page CSS variables to prevent rendering degradation outside shell context.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- None.
|
||||
|
||||
### Modified Capabilities
|
||||
- `asset-readiness-and-fallback-retirement`: unify fallback-retirement failure surfaces and safe local defaults for readiness-related flags.
|
||||
- `frontend-platform-modernization-governance`: add governance requirements for contract-source consistency and legacy artifact fallback observability.
|
||||
- `spa-shell-navigation`: document and enforce canonical redirect scope rules, including missing-reason redirect behavior.
|
||||
- `unified-shell-route-coverage`: require frontend/backend route-contract set consistency checks.
|
||||
- `style-isolation-and-token-enforcement`: require token fallback behavior for route-local styles that may render outside shell variable scope.
|
||||
- `maintainability-type-and-constant-hygiene`: require shared feature-flag and boolean parsing helpers for policy/runtime modules.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected backend modules: `src/mes_dashboard/core/modernization_policy.py`, `src/mes_dashboard/core/runtime_contract.py`, `src/mes_dashboard/app.py`, hold-related routes.
|
||||
- Affected frontend modules: `frontend/src/portal-shell/routeContracts.js`, `frontend/src/qc-gate/style.css`.
|
||||
- Affected governance and tests: modernization gate script/tests, route-contract consistency tests, redirect/fallback behavior tests, `.env.example` documentation.
|
||||
@@ -0,0 +1,12 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Fallback-retirement failure response SHALL be consistent across route hosts
|
||||
When in-scope runtime fallback retirement is enabled and route assets are unavailable, app-level and blueprint-level route handlers SHALL return a consistent retired-fallback response surface.
|
||||
|
||||
#### Scenario: App-level in-scope route enters retired fallback state
|
||||
- **WHEN** an in-scope app-level route cannot serve required dist assets and fallback retirement is enabled
|
||||
- **THEN** the route SHALL return the standardized retired-fallback response contract
|
||||
|
||||
#### Scenario: Blueprint-level in-scope route enters retired fallback state
|
||||
- **WHEN** an in-scope blueprint-level route cannot serve required dist assets and fallback retirement is enabled
|
||||
- **THEN** the route SHALL return the same standardized retired-fallback response contract used by app-level routes
|
||||
@@ -0,0 +1,19 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Operator-facing environment defaults SHALL be onboarding-safe
|
||||
`.env.example` SHALL prioritize local onboarding safety while clearly documenting production hardening recommendations for modernization controls.
|
||||
|
||||
#### Scenario: Local bootstrap from `.env.example`
|
||||
- **WHEN** a developer initializes `.env` from `.env.example` in a local non-production environment
|
||||
- **THEN** startup-critical modernization flags SHALL default to onboarding-safe values that do not fail boot solely because dist readiness gates are strict by default
|
||||
|
||||
#### Scenario: Production recommendation visibility
|
||||
- **WHEN** operators review `.env.example` for deployment configuration
|
||||
- **THEN** production-recommended values for shell-first and modernization-hardening flags SHALL be explicitly documented in adjacent comments
|
||||
|
||||
### Requirement: Policy cache refresh model SHALL be explicit in governance docs
|
||||
Governance-owned policy artifacts that are loaded with in-process caching SHALL document runtime refresh behavior and operator expectations.
|
||||
|
||||
#### Scenario: Cached policy artifact behavior documentation
|
||||
- **WHEN** maintainers read modernization governance artifacts
|
||||
- **THEN** they SHALL find explicit guidance on whether policy JSON updates require process restart, cache clear, or automatic reload
|
||||
@@ -0,0 +1,19 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Feature-flag resolution SHALL use shared helper semantics
|
||||
Environment/config/default feature-flag resolution logic SHALL be implemented through shared helper utilities instead of duplicated per-module parsing.
|
||||
|
||||
#### Scenario: Feature-flag evaluation in app and policy modules
|
||||
- **WHEN** modules resolve boolean feature flags from environment variables and Flask config
|
||||
- **THEN** they SHALL use a shared helper that enforces consistent precedence and truthy/falsey parsing behavior
|
||||
|
||||
### Requirement: Cached policy payloads SHALL protect against shared mutable-state corruption
|
||||
Policy loader functions that cache JSON payloads in-process SHALL prevent downstream callers from mutating the shared cached object reference.
|
||||
|
||||
#### Scenario: Cached policy payload consumed by multiple callers
|
||||
- **WHEN** multiple callers read cached policy payloads during process lifetime
|
||||
- **THEN** one caller's accidental mutation SHALL NOT alter another caller's observed policy state through shared reference side effects
|
||||
|
||||
#### Scenario: Policy cache behavior documentation
|
||||
- **WHEN** maintainers inspect cached policy loader code
|
||||
- **THEN** they SHALL find explicit comments describing refresh/invalidation behavior expectations
|
||||
@@ -0,0 +1,20 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Canonical redirect scope boundaries SHALL be explicit and intentional
|
||||
Canonical shell direct-entry redirects SHALL apply only to governed in-scope report routes and SHALL explicitly exclude admin external targets with documented rationale.
|
||||
|
||||
#### Scenario: In-scope report route direct entry
|
||||
- **WHEN** SPA shell mode is enabled and a user enters an in-scope report route directly
|
||||
- **THEN** the system SHALL redirect to the canonical `/portal-shell/...` route while preserving query semantics
|
||||
|
||||
#### Scenario: Admin external target direct entry
|
||||
- **WHEN** SPA shell mode is enabled and a user enters `/admin/pages` or `/admin/performance` directly
|
||||
- **THEN** the system SHALL NOT apply report-route canonical redirect policy
|
||||
- **THEN** the exclusion rationale SHALL be documented in code-level comments or governance docs
|
||||
|
||||
### Requirement: Missing-required-parameter redirects SHALL avoid avoidable multi-hop chains
|
||||
Routes with server-side required query parameters SHALL minimize redirect hops under SPA shell mode.
|
||||
|
||||
#### Scenario: Hold detail missing reason in SPA shell mode
|
||||
- **WHEN** a user opens `/hold-detail` without `reason` while SPA shell mode is enabled
|
||||
- **THEN** the route SHALL resolve via a single-hop redirect to the canonical overview shell path
|
||||
@@ -0,0 +1,12 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Route-local token usage SHALL include fallback values outside shell scope
|
||||
Route-level styles that reference shell-provided token variables SHALL define fallback values to preserve rendering correctness when rendered outside shell variable scope.
|
||||
|
||||
#### Scenario: Route rendered outside portal shell variable scope
|
||||
- **WHEN** a route-local stylesheet references shell token variables and the page is rendered without shell-level CSS variables
|
||||
- **THEN** visual-critical properties (for example header gradients) SHALL still resolve through explicit fallback token values
|
||||
|
||||
#### Scenario: Style governance check for unresolved shell variables
|
||||
- **WHEN** style-governance validation inspects in-scope route styles
|
||||
- **THEN** unresolved shell-variable references without fallback SHALL be flagged as governance failures or approved exceptions
|
||||
@@ -0,0 +1,19 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Frontend and backend route-contract inventories SHALL be cross-validated
|
||||
Route-governance checks SHALL verify that frontend shell route contracts and backend route contract artifacts describe the same governed route set and scope classes.
|
||||
|
||||
#### Scenario: Cross-source contract parity gate
|
||||
- **WHEN** modernization governance checks run in CI
|
||||
- **THEN** mismatches between backend route contract JSON and frontend `routeContracts.js` route inventory SHALL fail the gate
|
||||
|
||||
#### Scenario: Scope classification drift detection
|
||||
- **WHEN** a route has inconsistent scope classification between frontend and backend contract sources
|
||||
- **THEN** governance checks SHALL report the specific route and conflicting scope values
|
||||
|
||||
### Requirement: Legacy contract-source fallback SHALL emit operational warning
|
||||
When contract loading falls back from the primary modernization contract artifact to a legacy artifact path, the service SHALL emit explicit warning telemetry.
|
||||
|
||||
#### Scenario: Legacy contract fallback path selected
|
||||
- **WHEN** the primary contract artifact is unavailable and a legacy contract file is loaded
|
||||
- **THEN** the system SHALL log a warning that includes the selected legacy source path
|
||||
@@ -0,0 +1,50 @@
|
||||
## 1. Shared Flag and Policy Helper Hardening
|
||||
|
||||
- [x] 1.1 Introduce shared boolean parsing and feature-flag resolution helpers (`env > config > default`) in a common core utility module.
|
||||
- [x] 1.2 Replace duplicated `_to_bool` / inline bool parsing in `app.py`, `modernization_policy.py`, and `runtime_contract.py` with shared helpers.
|
||||
- [x] 1.3 Refactor modernization policy cached JSON loaders to prevent shared mutable-state corruption (defensive return strategy + clear cache helper for controlled refresh/testing).
|
||||
- [x] 1.4 Add inline documentation comments describing policy cache refresh behavior and operator expectations.
|
||||
|
||||
## 2. Fallback and Redirect Behavior Consistency
|
||||
|
||||
- [x] 2.1 Implement a shared retired-fallback response helper usable by both app-level and blueprint-level route handlers.
|
||||
- [x] 2.2 Migrate hold-related blueprint routes (`hold-overview`, `hold-history`, `hold-detail`) to the shared retired-fallback response contract.
|
||||
- [x] 2.3 Update `/hold-detail` missing-`reason` logic to single-hop redirect to canonical shell overview when SPA shell mode is enabled.
|
||||
- [x] 2.4 Document canonical redirect scope boundaries (report routes only, admin external targets excluded) in policy code comments.
|
||||
|
||||
## 3. Environment and Governance Documentation Safety
|
||||
|
||||
- [x] 3.1 Update `.env.example` modernization/runtime hardening flags to onboarding-safe defaults for local environments.
|
||||
- [x] 3.2 Add explicit production-recommended values and rationale comments next to each adjusted flag in `.env.example`.
|
||||
- [x] 3.3 Update modernization governance docs to clarify policy artifact cache refresh/invalidation model.
|
||||
|
||||
## 4. Route Contract Drift Detection and Observability
|
||||
|
||||
- [x] 4.1 Extend modernization governance checks to cross-validate backend route contract artifacts against frontend `routeContracts.js` route inventory and scope classifications.
|
||||
- [x] 4.2 Add/extend tests that fail on frontend-backend route set drift and scope mismatch.
|
||||
- [x] 4.3 Emit explicit warning logs when shell contract loading falls back to a legacy contract artifact path.
|
||||
- [x] 4.4 Add test coverage verifying legacy contract fallback warning behavior.
|
||||
|
||||
## 5. Style Token Fallback Resilience
|
||||
|
||||
- [x] 5.1 Update QC-GATE route-local CSS variables that depend on shell tokens to include fallback values.
|
||||
- [x] 5.2 Add style-governance check or test assertion that shell-derived route styles include fallback values unless explicitly exempted.
|
||||
|
||||
## 6. Test Coverage and Regression Validation
|
||||
|
||||
- [x] 6.1 Add redirect compatibility tests for non-ASCII query parameters through canonical redirect flows.
|
||||
- [x] 6.2 Add explicit test for `/hold-detail` missing-`reason` redirect chain behavior under SPA enabled mode.
|
||||
- [x] 6.3 Narrow broad `os.path.exists` patches in route/template tests to targeted path-specific behavior where feasible.
|
||||
- [x] 6.4 Run relevant unit/integration/frontend/e2e governance test suites and record pass criteria for this hardening change.
|
||||
|
||||
## Validation Record
|
||||
|
||||
- `pytest -q tests/test_feature_flags.py tests/test_modernization_policy_hardening.py tests/test_asset_readiness_policy.py tests/test_hold_routes.py tests/test_portal_shell_routes.py tests/test_full_modernization_gates.py tests/test_template_integration.py` → `84 passed`
|
||||
- `pytest -q tests/test_hold_overview_routes.py tests/test_hold_history_routes.py` → `34 passed`
|
||||
- `pytest -q tests/test_wip_routes.py` → `27 passed`
|
||||
- `pytest -q tests/test_runtime_contract.py tests/test_runtime_hardening.py -k "runtime_contract or runtime"` → `10 passed`
|
||||
- `pytest -q tests/test_wip_hold_pages_integration.py` → `3 passed`
|
||||
- `npm --prefix frontend test` → `64 passed`
|
||||
- `python scripts/check_full_modernization_gates.py --mode block` → `[OK] modernization gates passed`
|
||||
- `E2E_BASE_URL=http://127.0.0.1:8091 pytest -q tests/e2e/test_wip_hold_pages_e2e.py -k "hold_detail_without_reason_redirects_to_overview" --run-e2e` → `1 passed`
|
||||
- `STRESS_TEST_URL=http://127.0.0.1:8091 STRESS_CONCURRENT_USERS=2 STRESS_REQUESTS_PER_USER=3 pytest -q tests/stress/test_api_load.py -k "hold_detail_lots_concurrent_load"` → `1 passed`
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-12
|
||||
@@ -0,0 +1,60 @@
|
||||
## Context
|
||||
|
||||
This follow-up change consumes the explicit handoff from `full-modernization-architecture-blueprint` phase 1. Deferred routes were intentionally excluded to control blast radius, but they now represent the remaining architecture gap.
|
||||
|
||||
Current deferred-route risks:
|
||||
- Shell contract incompleteness and mixed navigation behavior.
|
||||
- Legacy runtime fallback dependency.
|
||||
- Content modernization parity not yet formalized.
|
||||
- Potential legacy bug carry-over if migration is done implementation-first.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals**
|
||||
- Complete shell-governed route coverage for deferred routes.
|
||||
- Adopt canonical shell routing and explicit compatibility policy.
|
||||
- Execute contract-first content modernization with parity and rollback controls.
|
||||
- Enforce mandatory manual acceptance and BUG revalidation before sign-off.
|
||||
|
||||
**Non-Goals**
|
||||
- Reworking already in-scope phase-1 routes again.
|
||||
- Changing backend business data semantics beyond compatibility safeguards.
|
||||
- Bundling unrelated admin/report features into this follow-up.
|
||||
|
||||
## Decisions
|
||||
|
||||
### D1. Deferred routes are promoted to in-scope as a single governed wave
|
||||
- `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect` are all in-scope for this change.
|
||||
|
||||
### D2. Canonical policy matches phase 1
|
||||
- Canonical shell path is `/portal-shell/<route>`.
|
||||
- Direct entry behavior remains explicit compatibility (redirect or compatibility render) with preserved query semantics.
|
||||
|
||||
### D3. Content migration remains route-by-route, not big-bang
|
||||
- Only one deferred route can be in cutover state at a time.
|
||||
- Next route is blocked until current route has parity pass + manual sign-off + bug replay pass.
|
||||
|
||||
### D4. Legacy bug carry-over prevention is a hard gate
|
||||
- Known bug baseline must be recorded before implementation.
|
||||
- Reproduced known bugs on modernized path block sign-off and legacy retirement.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- Deferred routes may have heavier legacy coupling than phase-1 routes.
|
||||
- Route-by-route cutover increases total elapsed time but reduces rollback blast radius.
|
||||
- Asset-readiness enforcement can block releases earlier; rollout plan must phase warn->block.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Freeze deferred-route scope matrix for this follow-up change.
|
||||
2. Extend shell route contracts and metadata coverage to full completeness.
|
||||
3. Define route content contracts + golden fixtures + interaction parity checks.
|
||||
4. Execute per-route migration with feature-flagged cutover and manual acceptance.
|
||||
5. Retire deferred-route runtime fallback posture after acceptance and readiness gates pass.
|
||||
6. Update runbook/rollback docs and close handoff linkage.
|
||||
|
||||
## Rollback Strategy
|
||||
|
||||
- Keep route-scoped cutover flags for immediate per-route rollback.
|
||||
- Allow temporary gate downgrade (`block` -> `warn`) only with explicit waiver and expiry.
|
||||
- Preserve route-level evidence (parity, manual sign-off, bug replay) to support rollback decisions.
|
||||
@@ -0,0 +1,33 @@
|
||||
## Why
|
||||
|
||||
`full-modernization-architecture-blueprint` intentionally deferred these routes:
|
||||
|
||||
- `/tables`
|
||||
- `/excel-query`
|
||||
- `/query-tool`
|
||||
- `/mid-section-defect`
|
||||
|
||||
Those routes still run on legacy posture (direct-entry-first + fallback continuity + mixed style ownership). A dedicated follow-up change is required to finish modernization without reopening scope in phase 1.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Promote all deferred routes to first-class in-scope shell-governed targets.
|
||||
- Apply canonical shell routing policy and explicit direct-entry compatibility behavior for each deferred route.
|
||||
- Modernize deferred route page-content flow (filters/charts/interactions) with contract-first parity gates.
|
||||
- Apply the same mandatory manual acceptance + BUG revalidation blocking policy used in phase 1.
|
||||
- Move deferred routes from fallback-era runtime posture to asset-readiness + governed retirement posture.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Modified Capabilities
|
||||
- `unified-shell-route-coverage`: deferred routes become in-scope and CI-blocking for route contract completeness.
|
||||
- `spa-shell-navigation`: deferred routes adopt canonical shell entry policy and governed compatibility behavior.
|
||||
- `page-content-modernization-safety`: deferred routes require contract baselines, parity evidence, manual sign-off, and known-bug revalidation.
|
||||
- `asset-readiness-and-fallback-retirement`: deferred routes adopt release-time asset checks and governed fallback retirement milestones.
|
||||
|
||||
## Impact
|
||||
|
||||
- Frontend route modules for `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`.
|
||||
- Shell contract and navigation governance in `frontend/src/portal-shell/**`.
|
||||
- Backend route handlers serving deferred routes and compatibility behavior.
|
||||
- Quality gate artifacts, runbook updates, and rollout/rollback policy for deferred-route cutover.
|
||||
@@ -0,0 +1,18 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Deferred-route assets SHALL be release-ready before promotion
|
||||
Deferred routes SHALL adopt release-time asset-readiness checks and SHALL fail promotion when required assets are missing.
|
||||
|
||||
#### Scenario: Deferred-route readiness validation
|
||||
- **WHEN** release artifacts are prepared for follow-up phase promotion
|
||||
- **THEN** required assets for `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be validated
|
||||
- **THEN** missing required assets SHALL fail release gating
|
||||
|
||||
### Requirement: Deferred-route runtime fallback SHALL be retired by governed policy
|
||||
Deferred routes SHALL not remain on runtime fallback posture after follow-up modernization completion criteria are met.
|
||||
|
||||
#### Scenario: Deferred-route fallback retirement
|
||||
- **WHEN** a deferred route passes readiness + parity + manual acceptance gates
|
||||
- **THEN** runtime fallback posture for that route SHALL be retired according to milestone policy
|
||||
- **THEN** rollback control SHALL remain available via explicit route-level governance switch
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Deferred-route content modernization SHALL remain contract-first
|
||||
Before deferred routes are cut over to modernized implementations, each route SHALL define filter/query/data-state contracts and critical interaction expectations.
|
||||
|
||||
#### Scenario: Deferred-route contract baseline defined
|
||||
- **WHEN** `/tables`, `/excel-query`, `/query-tool`, or `/mid-section-defect` enters modernization
|
||||
- **THEN** a route-level baseline SHALL capture filter input semantics, query payload shape, and critical state expectations
|
||||
|
||||
### Requirement: Deferred-route cutover SHALL require parity + manual acceptance
|
||||
Deferred routes SHALL NOT complete cutover without parity evidence and explicit manual sign-off.
|
||||
|
||||
#### Scenario: Parity and sign-off before route progression
|
||||
- **WHEN** a deferred route reports implementation complete
|
||||
- **THEN** golden fixture parity checks and interaction parity checks SHALL pass
|
||||
- **THEN** manual acceptance checklist sign-off SHALL be recorded
|
||||
- **THEN** next deferred route cutover SHALL be blocked until sign-off is complete
|
||||
|
||||
### Requirement: Legacy bug carry-over SHALL be blocked for deferred routes
|
||||
Known legacy bugs in deferred-route migrated scope SHALL be replayed during acceptance and SHALL block sign-off if reproduced.
|
||||
|
||||
#### Scenario: Deferred-route bug replay gate
|
||||
- **WHEN** deferred-route manual acceptance executes
|
||||
- **THEN** known-bug replay checks SHALL run
|
||||
- **THEN** reproduced known bugs SHALL fail route sign-off and block legacy retirement
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Deferred routes SHALL become shell-contract governed in this follow-up phase
|
||||
All routes deferred by phase 1 (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) SHALL be represented as in-scope shell contracts with complete ownership and visibility metadata.
|
||||
|
||||
#### Scenario: Deferred route contract promotion
|
||||
- **WHEN** follow-up route coverage validation is executed
|
||||
- **THEN** each deferred route SHALL have route metadata, owner metadata, and visibility/access policy metadata
|
||||
- **THEN** missing metadata SHALL fail route governance validation
|
||||
|
||||
#### Scenario: CI gate blocks deferred route contract gaps
|
||||
- **WHEN** CI evaluates route-governance completeness for this follow-up change
|
||||
- **THEN** any deferred route missing required contract fields SHALL block promotion
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
## 1. Scope and Governance Freeze
|
||||
|
||||
- [ ] 1.1 Publish frozen in-scope matrix for `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`
|
||||
- [ ] 1.2 Define completion criteria, deprecation milestones, and exception registry updates for deferred-route phase
|
||||
- [ ] 1.3 Record explicit upstream linkage to `full-modernization-architecture-blueprint` handoff artifacts
|
||||
|
||||
## 2. Shell Route Contract Completion
|
||||
|
||||
- [ ] 2.1 Promote deferred routes to in-scope in shell route contracts with complete metadata
|
||||
- [ ] 2.2 Implement governed navigation targets and visibility policy validation for all deferred routes
|
||||
- [ ] 2.3 Add CI-blocking checks for missing deferred-route contract metadata in this phase
|
||||
|
||||
## 3. Canonical Routing and Compatibility
|
||||
|
||||
- [ ] 3.1 Define canonical shell entry behavior for each deferred route
|
||||
- [ ] 3.2 Implement explicit compatibility policy for direct non-canonical entry with query continuity
|
||||
- [ ] 3.3 Add integration tests for canonical redirect and compatibility semantics
|
||||
|
||||
## 4. Page-Content Modernization Safety
|
||||
|
||||
- [ ] 4.1 Define per-route content contracts (filter semantics, payload, chart/table shape, state transitions)
|
||||
- [ ] 4.2 Build golden fixtures and interaction parity checks for each deferred route
|
||||
- [ ] 4.3 Add route-scoped feature flags and rollback controls for deferred-route cutover
|
||||
- [ ] 4.4 Define and enforce per-route manual acceptance checklist and sign-off records
|
||||
- [ ] 4.5 Record known-bug baselines before implementation and require bug replay during acceptance
|
||||
- [ ] 4.6 Block sign-off and legacy retirement when known bugs reproduce on modernized routes
|
||||
|
||||
## 5. Asset Readiness and Fallback Retirement
|
||||
|
||||
- [ ] 5.1 Extend asset-readiness manifest/checks to deferred routes
|
||||
- [ ] 5.2 Enforce fail-fast release behavior when deferred-route assets are missing
|
||||
- [ ] 5.3 Retire deferred-route runtime fallback posture per governance milestones
|
||||
|
||||
## 6. Quality Gates, CI, and Rollout
|
||||
|
||||
- [ ] 6.1 Extend functional/visual/accessibility/performance gates to deferred routes
|
||||
- [ ] 6.2 Wire CI jobs for route governance, quality gates, and readiness checks for deferred scope
|
||||
- [ ] 6.3 Update rollout runbook, rollback controls, and observability checkpoints for deferred-route cutover
|
||||
@@ -0,0 +1,40 @@
|
||||
# asset-readiness-and-fallback-retirement Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change full-modernization-architecture-blueprint. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: In-scope frontend assets SHALL be release-ready before deployment
|
||||
In-scope routes SHALL rely on build/deploy readiness guarantees instead of runtime fallback behavior as the primary resilience mechanism.
|
||||
|
||||
#### Scenario: Build-readiness enforcement
|
||||
- **WHEN** release artifacts are prepared for deployment
|
||||
- **THEN** in-scope route assets SHALL be validated for presence and loadability
|
||||
- **THEN** missing required in-scope assets SHALL fail the release gate
|
||||
|
||||
### Requirement: Runtime fallback retirement SHALL follow a governed phase policy
|
||||
Runtime fallback behavior for in-scope modernization routes SHALL be retired under explicit governance milestones.
|
||||
|
||||
#### Scenario: Fallback retirement in phase scope
|
||||
- **WHEN** a route is marked in-scope for fallback retirement
|
||||
- **THEN** runtime fallback behavior for that route SHALL be removed or disabled by policy
|
||||
- **THEN** reliability for that route SHALL be guaranteed by release-time readiness gates
|
||||
|
||||
### Requirement: Deferred routes SHALL keep existing fallback posture in this phase
|
||||
Routes deferred from this modernization phase SHALL retain their existing fallback posture until handled by a follow-up change.
|
||||
|
||||
#### Scenario: Deferred fallback continuity
|
||||
- **WHEN** `/tables`, `/excel-query`, `/query-tool`, or `/mid-section-defect` is evaluated in this phase
|
||||
- **THEN** fallback retirement SHALL NOT be required for phase completion
|
||||
- **THEN** fallback retirement decisions for those routes SHALL be addressed in a follow-up modernization change
|
||||
|
||||
### Requirement: Fallback-retirement failure response SHALL be consistent across route hosts
|
||||
When in-scope runtime fallback retirement is enabled and route assets are unavailable, app-level and blueprint-level route handlers SHALL return a consistent retired-fallback response surface.
|
||||
|
||||
#### Scenario: App-level in-scope route enters retired fallback state
|
||||
- **WHEN** an in-scope app-level route cannot serve required dist assets and fallback retirement is enabled
|
||||
- **THEN** the route SHALL return the standardized retired-fallback response contract
|
||||
|
||||
#### Scenario: Blueprint-level in-scope route enters retired fallback state
|
||||
- **WHEN** an in-scope blueprint-level route cannot serve required dist assets and fallback retirement is enabled
|
||||
- **THEN** the route SHALL return the same standardized retired-fallback response contract used by app-level routes
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# frontend-platform-modernization-governance Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change full-modernization-architecture-blueprint. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Frontend modernization scope SHALL be explicitly governed
|
||||
The modernization program SHALL define an explicit in-scope and out-of-scope route matrix for each phase, and SHALL treat that matrix as a release-governed contract artifact.
|
||||
|
||||
#### Scenario: Scope matrix publication
|
||||
- **WHEN** a modernization phase is created
|
||||
- **THEN** the phase SHALL publish an explicit in-scope route list and out-of-scope route list
|
||||
- **THEN** the matrix SHALL include `/admin/pages` and `/admin/performance` in scope for this phase
|
||||
- **THEN** the matrix SHALL mark `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` as deferred routes for a follow-up phase
|
||||
|
||||
#### Scenario: Scope drift prevention
|
||||
- **WHEN** implementation tasks are derived from the phase specs
|
||||
- **THEN** tasks targeting routes outside the in-scope matrix SHALL be rejected for this phase
|
||||
|
||||
### Requirement: Modernization phases SHALL define completion and deprecation milestones
|
||||
Each modernization phase SHALL define measurable completion criteria and deprecation milestones for legacy-era patterns.
|
||||
|
||||
#### Scenario: Phase completion criteria
|
||||
- **WHEN** a phase reaches release review
|
||||
- **THEN** it SHALL provide objective completion criteria for route governance, style governance, and quality gates
|
||||
- **THEN** it SHALL identify any remaining deferred routes and their next-phase linkage
|
||||
|
||||
#### Scenario: Legacy deprecation milestones
|
||||
- **WHEN** legacy fallback or legacy style exceptions remain in phase scope
|
||||
- **THEN** the phase SHALL define a dated milestone or release gate to remove those exceptions
|
||||
|
||||
### Requirement: Operator-facing environment defaults SHALL be onboarding-safe
|
||||
`.env.example` SHALL prioritize local onboarding safety while clearly documenting production hardening recommendations for modernization controls.
|
||||
|
||||
#### Scenario: Local bootstrap from `.env.example`
|
||||
- **WHEN** a developer initializes `.env` from `.env.example` in a local non-production environment
|
||||
- **THEN** startup-critical modernization flags SHALL default to onboarding-safe values that do not fail boot solely because dist readiness gates are strict by default
|
||||
|
||||
#### Scenario: Production recommendation visibility
|
||||
- **WHEN** operators review `.env.example` for deployment configuration
|
||||
- **THEN** production-recommended values for shell-first and modernization-hardening flags SHALL be explicitly documented in adjacent comments
|
||||
|
||||
### Requirement: Policy cache refresh model SHALL be explicit in governance docs
|
||||
Governance-owned policy artifacts that are loaded with in-process caching SHALL document runtime refresh behavior and operator expectations.
|
||||
|
||||
#### Scenario: Cached policy artifact behavior documentation
|
||||
- **WHEN** maintainers read modernization governance artifacts
|
||||
- **THEN** they SHALL find explicit guidance on whether policy JSON updates require process restart, cache clear, or automatic reload
|
||||
|
||||
29
openspec/specs/frontend-quality-gate-modernization/spec.md
Normal file
29
openspec/specs/frontend-quality-gate-modernization/spec.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# frontend-quality-gate-modernization Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change full-modernization-architecture-blueprint. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Modernization releases SHALL pass multi-dimensional frontend quality gates
|
||||
In-scope modernization releases SHALL pass functional, visual, accessibility, and performance gates before promotion.
|
||||
|
||||
#### Scenario: Gate bundle at release candidate
|
||||
- **WHEN** a release candidate includes in-scope modernization changes
|
||||
- **THEN** it SHALL execute functional behavior parity checks for affected routes
|
||||
- **THEN** it SHALL execute critical-state visual regression checks for affected routes
|
||||
- **THEN** it SHALL execute accessibility checks for keyboard and reduced-motion behavior
|
||||
- **THEN** it SHALL execute performance budget checks for defined shell/route thresholds
|
||||
|
||||
### Requirement: Gate failures SHALL block release promotion
|
||||
Blocking quality gates SHALL prevent release promotion for in-scope modernization changes.
|
||||
|
||||
#### Scenario: Blocking gate failure
|
||||
- **WHEN** any mandatory modernization quality gate fails
|
||||
- **THEN** release promotion SHALL be blocked until the failure is resolved or explicitly waived per governance policy
|
||||
|
||||
### Requirement: Deferred routes SHALL be excluded from this phase gate baseline
|
||||
The route baseline for this modernization phase SHALL exclude deferred routes.
|
||||
|
||||
#### Scenario: Deferred route baseline exclusion
|
||||
- **WHEN** gate baseline is computed for this phase
|
||||
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be excluded from mandatory modernization gate coverage
|
||||
|
||||
@@ -2,22 +2,27 @@
|
||||
Define stable requirements for full-vite-page-modularization.
|
||||
## Requirements
|
||||
### Requirement: Major Pages SHALL be Managed by Vite Modules
|
||||
The system SHALL provide Vite-managed module entries for major portal pages under a phased SPA-shell migration while keeping direct route access compatible.
|
||||
The system SHALL provide Vite-managed module entries for all in-scope modernization routes under shell-first governance, including admin surfaces `/admin/pages` and `/admin/performance` as governed targets. Deferred routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) are excluded from this phase's required module-governance completeness.
|
||||
|
||||
#### Scenario: Portal shell module loading
|
||||
- **WHEN** the portal experience is rendered
|
||||
- **THEN** it MUST load its behavior from a Vite-built module asset when available
|
||||
#### Scenario: In-scope module governance completeness
|
||||
- **WHEN** modernization route coverage is validated for this phase
|
||||
- **THEN** every in-scope route SHALL have deterministic module-governance metadata and ownership mapping
|
||||
|
||||
#### Scenario: Module fallback continuity
|
||||
- **WHEN** a required Vite asset is unavailable
|
||||
- **THEN** the system MUST keep affected page behavior functional through explicit fallback logic
|
||||
#### Scenario: Deferred route exclusion in this phase
|
||||
- **WHEN** completeness validation executes for this phase
|
||||
- **THEN** deferred routes SHALL be excluded from mandatory pass criteria
|
||||
|
||||
### Requirement: Build Pipeline SHALL Produce Backend-Served Assets
|
||||
Vite build output MUST be emitted into backend static paths and served by Flask/Gunicorn on the same origin.
|
||||
Vite build output for in-scope modernization routes MUST be emitted into backend static paths and validated at release time. Missing required in-scope assets SHALL fail release gates instead of relying on runtime fallback behavior.
|
||||
|
||||
#### Scenario: Build artifact placement
|
||||
- **WHEN** frontend build is executed
|
||||
- **THEN** generated JS/CSS files SHALL be written to the configured backend static dist directory
|
||||
#### Scenario: Build artifact readiness for in-scope routes
|
||||
- **WHEN** frontend build is executed for release
|
||||
- **THEN** required in-scope route artifacts SHALL be present in configured backend static dist paths
|
||||
- **THEN** missing required artifacts SHALL fail readiness checks
|
||||
|
||||
#### Scenario: Deferred route fallback posture unchanged in this phase
|
||||
- **WHEN** deferred routes are evaluated in this phase
|
||||
- **THEN** existing fallback posture SHALL not block this phase's completion
|
||||
|
||||
### Requirement: Vite Page Modules SHALL Reuse Shared Chart and Query Building Blocks
|
||||
Page entry modules MUST consume shared chart/query/drawer utilities for common behaviors.
|
||||
@@ -83,3 +88,4 @@ WIP overview and WIP detail Vite entry modules SHALL use shared frontend core ut
|
||||
#### Scenario: Shared utility change propagates across both pages
|
||||
- **WHEN** autocomplete mapping rules are updated in the shared core module
|
||||
- **THEN** both WIP overview and WIP detail modules MUST consume the updated behavior without duplicated page-local logic edits
|
||||
|
||||
|
||||
@@ -17,3 +17,21 @@ Cache, throttling, and index-related numeric literals that control behavior MUST
|
||||
- **WHEN** operators need to tune cache/index thresholds
|
||||
- **THEN** they MUST find values in named constants or environment variables rather than scattered inline literals
|
||||
|
||||
### Requirement: Feature-flag resolution SHALL use shared helper semantics
|
||||
Environment/config/default feature-flag resolution logic SHALL be implemented through shared helper utilities instead of duplicated per-module parsing.
|
||||
|
||||
#### Scenario: Feature-flag evaluation in app and policy modules
|
||||
- **WHEN** modules resolve boolean feature flags from environment variables and Flask config
|
||||
- **THEN** they SHALL use a shared helper that enforces consistent precedence and truthy/falsey parsing behavior
|
||||
|
||||
### Requirement: Cached policy payloads SHALL protect against shared mutable-state corruption
|
||||
Policy loader functions that cache JSON payloads in-process SHALL prevent downstream callers from mutating the shared cached object reference.
|
||||
|
||||
#### Scenario: Cached policy payload consumed by multiple callers
|
||||
- **WHEN** multiple callers read cached policy payloads during process lifetime
|
||||
- **THEN** one caller's accidental mutation SHALL NOT alter another caller's observed policy state through shared reference side effects
|
||||
|
||||
#### Scenario: Policy cache behavior documentation
|
||||
- **WHEN** maintainers inspect cached policy loader code
|
||||
- **THEN** they SHALL find explicit comments describing refresh/invalidation behavior expectations
|
||||
|
||||
|
||||
58
openspec/specs/page-content-modernization-safety/spec.md
Normal file
58
openspec/specs/page-content-modernization-safety/spec.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# page-content-modernization-safety Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change full-modernization-architecture-blueprint. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: In-scope page-content modernization SHALL be contract-first
|
||||
Before chart/filter/page interaction refactors are cut over, each in-scope route SHALL define a contract baseline that captures data and interaction semantics.
|
||||
|
||||
#### Scenario: Route contract baseline defined
|
||||
- **WHEN** an in-scope route is selected for chart/filter modernization
|
||||
- **THEN** the route SHALL define filter input semantics, query payload expectations, and chart data-shape contracts
|
||||
- **THEN** the route SHALL define critical state expectations for loading, empty, error, and success interactions
|
||||
|
||||
### Requirement: Cutover SHALL require parity evidence against baseline behavior
|
||||
In-scope chart/filter modernization cutover SHALL require parity evidence against baseline fixtures and critical interaction flows.
|
||||
|
||||
#### Scenario: Parity gate before default switch
|
||||
- **WHEN** a route is proposed for defaulting to a modernized chart/filter implementation
|
||||
- **THEN** golden fixture parity checks SHALL pass for defined critical states
|
||||
- **THEN** interaction parity checks SHALL pass for filter apply/reset and chart selection/drill behaviors
|
||||
|
||||
### Requirement: Route-level content cutover SHALL be reversible
|
||||
Modernized chart/filter content rollouts SHALL use reversible controls that allow immediate rollback without reverting unrelated shell architecture work.
|
||||
|
||||
#### Scenario: Controlled rollout and rollback
|
||||
- **WHEN** a modernized route is enabled for users
|
||||
- **THEN** the route SHALL be controlled by route-scoped feature flag or equivalent switch
|
||||
- **THEN** rollback procedure SHALL be documented and executable within one release cycle
|
||||
|
||||
### Requirement: Page-content modernization progression SHALL require manual route acceptance
|
||||
In-scope chart/filter/page-content migration SHALL progress one route at a time with explicit manual acceptance records.
|
||||
|
||||
#### Scenario: Route-by-route manual acceptance gate
|
||||
- **WHEN** an in-scope route completes modernization implementation and parity checks
|
||||
- **THEN** that route SHALL be manually accepted using a defined checklist covering filter flows, chart interactions, empty/error behavior, and visual correctness
|
||||
- **THEN** the next route SHALL NOT begin cutover until manual acceptance for the current route is signed off
|
||||
|
||||
### Requirement: Known legacy bugs in migrated scope SHALL NOT be carried into modernized routes
|
||||
Modernized route acceptance SHALL include explicit revalidation of known legacy defects in migrated scope, and reproduced defects SHALL block sign-off.
|
||||
|
||||
#### Scenario: Route-level legacy bug baseline and replay
|
||||
- **WHEN** an in-scope route enters chart/filter/page-content modernization
|
||||
- **THEN** a route-level known-bug baseline (within migrated scope) SHALL be recorded before implementation
|
||||
- **THEN** manual acceptance SHALL replay those known-bug checks on the modernized route
|
||||
|
||||
#### Scenario: Legacy bug carry-over is blocked
|
||||
- **WHEN** manual acceptance finds that a known legacy bug is still reproducible in the modernized route
|
||||
- **THEN** route sign-off SHALL fail
|
||||
- **THEN** route cutover completion and legacy code retirement SHALL be blocked until the bug is fixed
|
||||
|
||||
### Requirement: Legacy content path retirement SHALL require parity and manual acceptance
|
||||
Legacy chart/filter implementations SHALL be removed only after parity checks and manual acceptance criteria are satisfied.
|
||||
|
||||
#### Scenario: Legacy removal approval
|
||||
- **WHEN** legacy chart/filter code is planned for removal on an in-scope route
|
||||
- **THEN** the route SHALL provide parity pass evidence and manual acceptance sign-off records
|
||||
- **THEN** unresolved parity failures or manual acceptance defects SHALL block legacy removal
|
||||
|
||||
@@ -2,46 +2,31 @@
|
||||
Define stable requirements for spa-shell-navigation.
|
||||
## Requirements
|
||||
### Requirement: Portal SHALL provide a SPA shell driven by Vue Router
|
||||
The portal frontend SHALL use a single SPA shell entry and Vue Router to render page modules without iframe embedding, and SHALL route each page through native route-view integration. The shell layout SHALL use a full-viewport fluid layout with flexbox, removing all max-width constraints and block-centered styling. The main content area (`.shell-content`) SHALL fill available space as a flex child, and the sidebar SHALL be a collapsible flex child that pushes content when expanded on desktop. The content area class SHALL be `.shell-content` (not `.content`) to avoid CSS collision with page-level `.content` classes.
|
||||
The portal frontend SHALL use a single SPA shell entry and Vue Router to render in-scope page modules without iframe embedding. In-scope routes for this phase SHALL include the governed report routes and admin surfaces `/admin/pages` and `/admin/performance`, while deferred routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) are explicitly excluded from this phase contract.
|
||||
|
||||
#### Scenario: Drawer navigation renders integrated route view
|
||||
- **WHEN** a user clicks a sidebar page entry whose migration mode is `native`
|
||||
- **THEN** the active route SHALL be updated through Vue Router
|
||||
- **THEN** the main content area SHALL render the corresponding page module inside shell route-view without iframe usage
|
||||
- **THEN** the content area SHALL fill the available viewport width minus the sidebar width (if sidebar is expanded)
|
||||
#### Scenario: In-scope route renders through shell governance
|
||||
- **WHEN** a user navigates to an in-scope shell-governed route
|
||||
- **THEN** the route SHALL resolve through Vue Router with shell contract metadata
|
||||
- **THEN** the shell SHALL render the corresponding module/target without iframe fallback
|
||||
|
||||
#### Scenario: Shell layout fills full viewport
|
||||
- **WHEN** the portal shell renders
|
||||
- **THEN** the shell SHALL span the full viewport width with no max-width constraint
|
||||
- **THEN** the header SHALL span edge-to-edge with no border-radius
|
||||
- **THEN** the sidebar and content area SHALL have no outer borders or border-radius
|
||||
#### Scenario: Admin route appears as governed target
|
||||
- **WHEN** an admin user opens shell navigation
|
||||
- **THEN** `/admin/pages` and `/admin/performance` SHALL be exposed as governed navigation targets per access policy
|
||||
|
||||
#### Scenario: Page-level max-width constraints are removed when embedded
|
||||
- **WHEN** a page module registered in the shell route contracts renders inside `.shell-content`
|
||||
- **THEN** page-level max-width constraints SHALL be overridden to allow full-width rendering
|
||||
- **THEN** page-level duplicate padding SHALL be removed to avoid double spacing
|
||||
- **THEN** standalone page rendering (outside the shell) SHALL remain unaffected
|
||||
|
||||
#### Scenario: Shell content class avoids collision with page-level classes
|
||||
- **WHEN** a page module that uses its own `.content` class renders inside the shell
|
||||
- **THEN** the shell's content wrapper (`.shell-content`) SHALL NOT interfere with the page's `.content` styling
|
||||
|
||||
#### Scenario: Wrapper route remains available during migration
|
||||
- **WHEN** a user clicks a sidebar page entry whose migration mode is `wrapper`
|
||||
- **THEN** Vue Router SHALL render the wrapper host in shell content area
|
||||
- **THEN** the wrapper SHALL preserve page reachability until native rewrite is completed
|
||||
#### Scenario: Deferred route is excluded from this phase route-governance requirement
|
||||
- **WHEN** phase-level shell-governance compliance is evaluated
|
||||
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be treated as deferred and excluded from pass/fail criteria for this phase
|
||||
|
||||
### Requirement: Existing route contracts SHALL remain stable in SPA mode
|
||||
Migration to SPA shell SHALL preserve existing route paths, deep-link behavior, and query semantics during both native and wrapper phases.
|
||||
Migration to the shell-first SPA model SHALL preserve route/query compatibility for in-scope routes while introducing canonical shell routing policy and explicit compatibility handling.
|
||||
|
||||
#### Scenario: Direct route entry remains functional
|
||||
- **WHEN** a user opens an existing route directly (bookmark or refresh)
|
||||
- **THEN** the route SHALL resolve to the same page functionality as before migration
|
||||
- **THEN** required query parameters SHALL continue to be interpreted with compatible semantics
|
||||
#### Scenario: Canonical shell path behavior for in-scope routes
|
||||
- **WHEN** a user opens an in-scope report route via canonical shell path
|
||||
- **THEN** route behavior and query semantics SHALL remain compatible with established baseline behavior
|
||||
|
||||
#### Scenario: Query continuity across shell navigation
|
||||
- **WHEN** users navigate from shell list pages to detail pages and back
|
||||
- **THEN** query-state parameters required by list/detail workflows SHALL remain consistent with pre-migration behavior
|
||||
#### Scenario: Compatibility policy for direct route entry
|
||||
- **WHEN** a user opens an in-scope report route via direct non-canonical entry
|
||||
- **THEN** the system SHALL apply explicit compatibility policy (preserve behavior or compatibility redirect) without breaking route semantics
|
||||
|
||||
### Requirement: SPA shell navigation SHALL enforce page visibility rules
|
||||
SPA navigation SHALL respect backend-defined drawer and page visibility outcomes, including admin entry visibility and route fallback for hidden routes.
|
||||
@@ -60,3 +45,22 @@ SPA navigation SHALL respect backend-defined drawer and page visibility outcomes
|
||||
- **THEN** the shell SHALL redirect to a safe fallback route
|
||||
- **THEN** the shell SHALL NOT expose iframe-based fallback rendering
|
||||
|
||||
### Requirement: Canonical redirect scope boundaries SHALL be explicit and intentional
|
||||
Canonical shell direct-entry redirects SHALL apply only to governed in-scope report routes and SHALL explicitly exclude admin external targets with documented rationale.
|
||||
|
||||
#### Scenario: In-scope report route direct entry
|
||||
- **WHEN** SPA shell mode is enabled and a user enters an in-scope report route directly
|
||||
- **THEN** the system SHALL redirect to the canonical `/portal-shell/...` route while preserving query semantics
|
||||
|
||||
#### Scenario: Admin external target direct entry
|
||||
- **WHEN** SPA shell mode is enabled and a user enters `/admin/pages` or `/admin/performance` directly
|
||||
- **THEN** the system SHALL NOT apply report-route canonical redirect policy
|
||||
- **THEN** the exclusion rationale SHALL be documented in code-level comments or governance docs
|
||||
|
||||
### Requirement: Missing-required-parameter redirects SHALL avoid avoidable multi-hop chains
|
||||
Routes with server-side required query parameters SHALL minimize redirect hops under SPA shell mode.
|
||||
|
||||
#### Scenario: Hold detail missing reason in SPA shell mode
|
||||
- **WHEN** a user opens `/hold-detail` without `reason` while SPA shell mode is enabled
|
||||
- **THEN** the route SHALL resolve via a single-hop redirect to the canonical overview shell path
|
||||
|
||||
|
||||
40
openspec/specs/style-isolation-and-token-enforcement/spec.md
Normal file
40
openspec/specs/style-isolation-and-token-enforcement/spec.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# style-isolation-and-token-enforcement Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change full-modernization-architecture-blueprint. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: In-scope pages SHALL enforce style isolation boundaries
|
||||
In-scope modernization pages SHALL avoid page-global selectors for page-local concerns and SHALL keep style concerns scoped to route-level containers or shared design-system layers.
|
||||
|
||||
#### Scenario: Global selector control
|
||||
- **WHEN** style governance checks analyze in-scope page styles
|
||||
- **THEN** page-local style changes SHALL NOT introduce new `:root` or `body` rules for route-local presentation concerns
|
||||
- **THEN** shared cross-route concerns SHALL be authored in designated shared style layers
|
||||
|
||||
### Requirement: In-scope shared semantics SHALL be token-first
|
||||
Shared UI semantics in in-scope routes SHALL be implemented with token-backed Tailwind/shared-style primitives before page-local overrides are allowed.
|
||||
|
||||
#### Scenario: Token-first UI pattern adoption
|
||||
- **WHEN** an in-scope route introduces or updates shared UI semantics (layout shell, card, filter, action, status)
|
||||
- **THEN** the route SHALL consume token-backed shared primitives
|
||||
- **THEN** page-local hard-coded visual values SHALL require explicit exception justification
|
||||
|
||||
### Requirement: Legacy style exceptions SHALL be tracked and sunset
|
||||
Legacy CSS exceptions for in-scope routes SHALL be tracked with ownership and removal milestones.
|
||||
|
||||
#### Scenario: Exception registry requirement
|
||||
- **WHEN** an in-scope route cannot yet remove legacy style behavior
|
||||
- **THEN** the route SHALL be registered with an exception owner and planned removal milestone
|
||||
- **THEN** unresolved exceptions past milestone SHALL fail modernization governance review
|
||||
|
||||
### Requirement: Route-local token usage SHALL include fallback values outside shell scope
|
||||
Route-level styles that reference shell-provided token variables SHALL define fallback values to preserve rendering correctness when rendered outside shell variable scope.
|
||||
|
||||
#### Scenario: Route rendered outside portal shell variable scope
|
||||
- **WHEN** a route-local stylesheet references shell token variables and the page is rendered without shell-level CSS variables
|
||||
- **THEN** visual-critical properties (for example header gradients) SHALL still resolve through explicit fallback token values
|
||||
|
||||
#### Scenario: Style governance check for unresolved shell variables
|
||||
- **WHEN** style-governance validation inspects in-scope route styles
|
||||
- **THEN** unresolved shell-variable references without fallback SHALL be flagged as governance failures or approved exceptions
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
## Purpose
|
||||
Define stable requirements for tailwind-design-system.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Frontend styles SHALL be governed by Tailwind design tokens
|
||||
The frontend SHALL define a Tailwind-based design token system for color, spacing, typography, radius, and elevation to ensure consistent styling across modules. The `--portal-shell-max-width` CSS variable SHALL be set to `none` to support the fluid layout. A `--portal-sidebar-width` variable SHALL be added for sidebar width reference. The `.u-content-shell` utility class SHALL use `width: 100%` instead of `max-width` constraint.
|
||||
The frontend SHALL enforce a token-governed style system for in-scope routes. Shared visual semantics SHALL be expressed through token-backed Tailwind/shared layers, and ad-hoc page-local hard-coded values for shared semantics SHALL require explicit exception governance.
|
||||
|
||||
#### Scenario: Shared token usage across modules
|
||||
- **WHEN** two report modules render equivalent UI elements (e.g., card, filter chip, primary button)
|
||||
#### Scenario: Shared token usage across in-scope modules
|
||||
- **WHEN** two in-scope modules render equivalent UI semantics (e.g., card, filter chip, primary action, status indicator)
|
||||
- **THEN** they SHALL use the same token-backed style semantics
|
||||
- **THEN** visual output SHALL remain consistent across modules
|
||||
- **THEN** visual output SHALL remain consistent across those modules
|
||||
|
||||
#### Scenario: Fluid layout tokens
|
||||
- **WHEN** the portal shell renders
|
||||
- **THEN** `--portal-shell-max-width` SHALL resolve to `none`
|
||||
- **THEN** `--portal-sidebar-width` SHALL resolve to `240px`
|
||||
- **THEN** `.u-content-shell` SHALL apply `width: 100%` without max-width constraint
|
||||
#### Scenario: Token governance review
|
||||
- **WHEN** an in-scope route introduces new shared UI styling
|
||||
- **THEN** the styling SHALL map to shared tokens/layers or be recorded in an approved exception registry
|
||||
|
||||
### Requirement: Tailwind migration SHALL support coexistence with legacy CSS
|
||||
The migration SHALL allow Tailwind and existing page CSS to coexist during phased rollout without breaking existing pages.
|
||||
Tailwind migration SHALL support controlled coexistence only as a transition state for this phase. In-scope routes SHALL move toward isolation-first style ownership and SHALL NOT introduce new page-global CSS side effects for route-local concerns.
|
||||
|
||||
#### Scenario: Legacy page remains functional during coexistence
|
||||
- **WHEN** a not-yet-migrated page is rendered
|
||||
- **THEN** existing CSS behavior SHALL remain intact
|
||||
- **THEN** Tailwind introduction SHALL NOT cause blocking style regressions
|
||||
#### Scenario: In-scope global selector control
|
||||
- **WHEN** in-scope route styles are reviewed
|
||||
- **THEN** new route-local styling SHALL NOT introduce page-global selectors (`:root`, `body`) for local presentation behavior
|
||||
|
||||
#### Scenario: Deferred route coexistence allowance
|
||||
- **WHEN** deferred routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) are evaluated during this phase
|
||||
- **THEN** existing coexistence posture SHALL be allowed and handled by a follow-up modernization change
|
||||
|
||||
### Requirement: New shared UI components SHALL prefer Tailwind-first styling
|
||||
Newly introduced shared components SHALL be implemented with Tailwind-first conventions to avoid expanding duplicated page-local CSS.
|
||||
@@ -32,3 +31,4 @@ Newly introduced shared components SHALL be implemented with Tailwind-first conv
|
||||
- **WHEN** a new shared component is introduced in migration scope
|
||||
- **THEN** its primary style contract SHALL be expressed through Tailwind utilities/components
|
||||
- **THEN** page-local CSS additions SHALL be minimized and justified
|
||||
|
||||
|
||||
51
openspec/specs/unified-shell-route-coverage/spec.md
Normal file
51
openspec/specs/unified-shell-route-coverage/spec.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# unified-shell-route-coverage Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change full-modernization-architecture-blueprint. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: In-scope routes SHALL be shell-contract governed
|
||||
All in-scope modernization routes SHALL be represented in shell route contracts, loader registration policy, and navigation visibility governance.
|
||||
|
||||
#### Scenario: In-scope coverage validation
|
||||
- **WHEN** shell route contract validation is executed
|
||||
- **THEN** every in-scope route SHALL have route metadata, ownership metadata, and visibility policy metadata
|
||||
- **THEN** missing in-scope route contracts SHALL fail validation
|
||||
|
||||
#### Scenario: Admin route inclusion
|
||||
- **WHEN** shell navigation is built for admin users
|
||||
- **THEN** `/admin/pages` and `/admin/performance` SHALL be represented as governed navigation targets according to visibility/access policy
|
||||
|
||||
### Requirement: Out-of-scope routes SHALL not block this phase
|
||||
Routes explicitly marked as out-of-scope for this modernization phase SHALL be excluded from required shell-coverage gates in this phase.
|
||||
|
||||
#### Scenario: Deferred route exclusion
|
||||
- **WHEN** modernization gates execute for this phase
|
||||
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be treated as deferred routes
|
||||
- **THEN** deferred route absence from new shell-governance gates SHALL NOT fail this phase
|
||||
|
||||
### Requirement: Route coverage governance SHALL be CI-enforced
|
||||
Route coverage and contract completeness checks for in-scope routes SHALL run as CI gates.
|
||||
|
||||
#### Scenario: CI gate failure on in-scope gap
|
||||
- **WHEN** CI detects an in-scope route without required contract metadata
|
||||
- **THEN** the modernization gate SHALL fail
|
||||
- **THEN** release promotion SHALL be blocked until resolved
|
||||
|
||||
### Requirement: Frontend and backend route-contract inventories SHALL be cross-validated
|
||||
Route-governance checks SHALL verify that frontend shell route contracts and backend route contract artifacts describe the same governed route set and scope classes.
|
||||
|
||||
#### Scenario: Cross-source contract parity gate
|
||||
- **WHEN** modernization governance checks run in CI
|
||||
- **THEN** mismatches between backend route contract JSON and frontend `routeContracts.js` route inventory SHALL fail the gate
|
||||
|
||||
#### Scenario: Scope classification drift detection
|
||||
- **WHEN** a route has inconsistent scope classification between frontend and backend contract sources
|
||||
- **THEN** governance checks SHALL report the specific route and conflicting scope values
|
||||
|
||||
### Requirement: Legacy contract-source fallback SHALL emit operational warning
|
||||
When contract loading falls back from the primary modernization contract artifact to a legacy artifact path, the service SHALL emit explicit warning telemetry.
|
||||
|
||||
#### Scenario: Legacy contract fallback path selected
|
||||
- **WHEN** the primary contract artifact is unavailable and a legacy contract file is loaded
|
||||
- **THEN** the system SHALL log a warning that includes the selected legacy source path
|
||||
|
||||
@@ -1,135 +1,139 @@
|
||||
## Purpose
|
||||
Define stable requirements for vue-vite-page-architecture.
|
||||
|
||||
## Requirements
|
||||
|
||||
|
||||
### Requirement: Pure Vite pages SHALL be served as static HTML
|
||||
The system SHALL support serving Vite-built HTML pages directly via Flask without Jinja2 rendering.
|
||||
|
||||
#### Scenario: Serve pure Vite page
|
||||
- **WHEN** user navigates to a pure Vite page route (e.g., `/qc-gate`)
|
||||
- **THEN** Flask SHALL serve the pre-built HTML file from `static/dist/` via `send_from_directory`
|
||||
- **THEN** the HTML SHALL NOT pass through Jinja2 template rendering
|
||||
|
||||
#### Scenario: Page works as top-level navigation target
|
||||
- **WHEN** a pure Vite page is opened from portal direct navigation
|
||||
- **THEN** the page SHALL render correctly as a top-level route without iframe embedding dependency
|
||||
- **THEN** page functionality SHALL NOT rely on portal-managed frame lifecycle
|
||||
|
||||
### Requirement: Vite config SHALL support Vue SFC and HTML entry points
|
||||
The Vite build configuration SHALL support Vue Single File Components alongside existing vanilla JS entries.
|
||||
|
||||
#### Scenario: Vue plugin coexistence
|
||||
- **WHEN** `vite build` is executed
|
||||
- **THEN** Vue SFC (`.vue` files) SHALL be compiled by `@vitejs/plugin-vue`
|
||||
- **THEN** existing vanilla JS entry points SHALL continue to build without modification
|
||||
|
||||
#### Scenario: HTML entry point
|
||||
- **WHEN** a page uses an HTML file as its Vite entry point
|
||||
- **THEN** Vite SHALL process the HTML and its referenced JS/CSS into `static/dist/`
|
||||
- **THEN** the output SHALL include `<page-name>.html`, `<page-name>.js`, and `<page-name>.css`
|
||||
|
||||
#### Scenario: Chunk splitting
|
||||
- **WHEN** Vite builds the project
|
||||
- **THEN** Vue runtime SHALL be split into a `vendor-vue` chunk
|
||||
- **THEN** ECharts modules (including TreemapChart, BarChart, LineChart) SHALL be split into the existing `vendor-echarts` chunk
|
||||
- **THEN** chunk splitting SHALL NOT affect existing page bundles
|
||||
|
||||
#### Scenario: Migrated page entry replacement
|
||||
- **WHEN** a vanilla JS page is migrated to Vue 3
|
||||
- **THEN** its Vite entry SHALL change from JS file to HTML file (e.g., `src/wip-overview/main.js` → `src/wip-overview/index.html`)
|
||||
- **THEN** the original JS entry SHALL be replaced, not kept alongside
|
||||
|
||||
#### Scenario: Hold Overview entry point
|
||||
- **WHEN** the hold-overview page is added
|
||||
- **THEN** `vite.config.js` input SHALL include `'hold-overview': resolve(__dirname, 'src/hold-overview/index.html')`
|
||||
- **THEN** the build SHALL produce `hold-overview.html`, `hold-overview.js`, and `hold-overview.css` in `static/dist/`
|
||||
|
||||
#### Scenario: Hold History entry point
|
||||
- **WHEN** the hold-history page is added
|
||||
- **THEN** `vite.config.js` input SHALL include `'hold-history': resolve(__dirname, 'src/hold-history/index.html')`
|
||||
- **THEN** the build SHALL produce `hold-history.html`, `hold-history.js`, and `hold-history.css` in `static/dist/`
|
||||
|
||||
#### Scenario: Shared CSS import across migrated pages
|
||||
- **WHEN** multiple migrated pages import a shared CSS module (e.g., `wip-shared/styles.css`)
|
||||
- **THEN** Vite SHALL bundle the shared CSS into each page's output CSS
|
||||
- **THEN** shared CSS SHALL NOT create a separate shared chunk that requires additional HTTP requests
|
||||
|
||||
#### Scenario: Shared composable import across module boundaries
|
||||
- **WHEN** a migrated page imports a composable from another shared module (e.g., `hold-history` imports `useAutoRefresh` from `wip-shared/`)
|
||||
- **THEN** the composable SHALL be bundled into the importing page's JS output
|
||||
- **THEN** cross-module imports SHALL NOT create unexpected shared chunks
|
||||
|
||||
### Requirement: Pure Vite pages SHALL handle API calls without legacy MesApi
|
||||
Pure Vite pages SHALL use the existing `frontend/src/core/api.js` module for API communication without depending on the global `window.MesApi` object from `_base.html`.
|
||||
|
||||
#### Scenario: API GET request from pure Vite page
|
||||
- **WHEN** a pure Vite page makes a GET API call
|
||||
- **THEN** the call SHALL use the `apiGet` function from `core/api.js`
|
||||
- **THEN** the call SHALL work without `window.MesApi` being present
|
||||
|
||||
### Requirement: Pure Vite pages SHALL handle POST API calls without legacy MesApi
|
||||
Pure Vite pages SHALL use the `apiPost` function from `core/api.js` for POST requests without depending on `window.MesApi`.
|
||||
|
||||
#### Scenario: API POST request from pure Vite page
|
||||
- **WHEN** a pure Vite page makes a POST API call
|
||||
- **THEN** the call SHALL use the `apiPost` function from `core/api.js`
|
||||
- **THEN** the call SHALL include `Content-Type: application/json` header
|
||||
- **THEN** the call SHALL work without `window.MesApi` being present
|
||||
|
||||
#### Scenario: CSRF token handling in POST requests
|
||||
- **WHEN** a pure Vite page calls `apiPost`
|
||||
- **THEN** `apiPost` SHALL attempt to read CSRF token from `<meta name="csrf-token">`
|
||||
- **THEN** if no meta tag exists, the request SHALL still proceed (non-admin APIs do not enforce CSRF)
|
||||
|
||||
### Requirement: Pure Vite pages with server-side route validation SHALL use send_from_directory with pre-validation
|
||||
Pages that require server-side parameter validation before serving SHALL validate parameters in the Flask route and then serve the static HTML.
|
||||
|
||||
#### Scenario: Hold Detail reason validation
|
||||
- **WHEN** user navigates to `/hold-detail` without a `reason` parameter
|
||||
- **THEN** Flask SHALL redirect to `/wip-overview`
|
||||
- **WHEN** user navigates to `/hold-detail?reason={value}`
|
||||
- **THEN** Flask SHALL serve the pre-built HTML file from `static/dist/` via `send_from_directory`
|
||||
- **THEN** the HTML SHALL NOT pass through Jinja2 template rendering
|
||||
|
||||
#### Scenario: Frontend fallback validation
|
||||
- **WHEN** the pure Vite hold-detail page loads
|
||||
- **THEN** the page SHALL read `reason` from URL parameters
|
||||
- **THEN** if `reason` is empty or missing, the page SHALL redirect to `/wip-overview`
|
||||
|
||||
### Requirement: Mid-section defect page SHALL separate filter state from query state
|
||||
The mid-section defect page SHALL maintain separate reactive state for UI input (`filters`) and committed query parameters (`committedFilters`).
|
||||
|
||||
#### Scenario: User changes date without clicking query
|
||||
- **WHEN** user modifies the date range in the filter bar but does not click "查詢"
|
||||
- **THEN** auto-refresh, pagination, and CSV export SHALL continue using the previously committed filter values
|
||||
- **THEN** the new date range SHALL NOT affect any API calls until "查詢" is clicked
|
||||
|
||||
#### Scenario: User clicks query button
|
||||
- **WHEN** user clicks "查詢"
|
||||
- **THEN** the current `filters` state SHALL be snapshotted into `committedFilters`
|
||||
- **THEN** all subsequent API calls SHALL use the committed values
|
||||
|
||||
#### Scenario: CSV export uses committed filters
|
||||
- **WHEN** user clicks "匯出 CSV" after modifying filters without re-querying
|
||||
- **THEN** the export SHALL use the committed filter values from the last query
|
||||
- **THEN** the export SHALL NOT use the current UI filter values
|
||||
|
||||
### Requirement: Mid-section defect page SHALL cancel in-flight requests on new query
|
||||
The mid-section defect page SHALL use `AbortController` to cancel in-flight API requests when a new query is initiated.
|
||||
|
||||
#### Scenario: New query cancels previous query
|
||||
- **WHEN** user clicks "查詢" while a previous query is still in-flight
|
||||
- **THEN** the previous query's summary and detail requests SHALL be aborted
|
||||
- **THEN** the AbortError SHALL be handled silently (no error banner shown)
|
||||
|
||||
#### Scenario: Page navigation cancels previous detail request
|
||||
- **WHEN** user clicks next page while a previous page request is still in-flight
|
||||
- **THEN** the previous page request SHALL be aborted
|
||||
- **THEN** the new page request SHALL proceed independently
|
||||
|
||||
#### Scenario: Query and pagination use independent abort keys
|
||||
- **WHEN** a query is in-flight and user triggers pagination
|
||||
- **THEN** the query SHALL NOT be cancelled by the pagination request
|
||||
- **THEN** the pagination SHALL use a separate abort key from the query
|
||||
## Purpose
|
||||
Define stable requirements for vue-vite-page-architecture.
|
||||
## Requirements
|
||||
### Requirement: Pure Vite pages SHALL be served as static HTML
|
||||
The system SHALL serve in-scope pure Vite pages through backend static HTML delivery under a shell-first canonical routing policy. Direct-entry compatibility for in-scope routes SHALL be explicit and governed. Admin targets `/admin/pages` and `/admin/performance` SHALL be represented as governed shell navigation targets, while maintaining backend auth/session authority.
|
||||
|
||||
#### Scenario: In-scope canonical shell entry
|
||||
- **WHEN** a user navigates to an in-scope canonical shell route
|
||||
- **THEN** the shell SHALL render the target route via governed route contracts and static asset delivery
|
||||
|
||||
#### Scenario: Direct-entry compatibility policy for in-scope routes
|
||||
- **WHEN** a user opens an in-scope route through direct non-canonical entry
|
||||
- **THEN** the system SHALL apply explicit compatibility behavior without breaking established query semantics
|
||||
|
||||
#### Scenario: Admin targets in shell governance
|
||||
- **WHEN** shell navigation is rendered for an authorized admin user
|
||||
- **THEN** `/admin/pages` and `/admin/performance` SHALL be reachable through governed admin navigation targets
|
||||
|
||||
#### Scenario: Deferred routes excluded from this phase architecture criteria
|
||||
- **WHEN** this phase architecture compliance is evaluated
|
||||
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be excluded and handled in a follow-up change
|
||||
|
||||
### Requirement: Vite config SHALL support Vue SFC and HTML entry points
|
||||
The Vite build configuration SHALL support Vue Single File Components alongside existing vanilla JS entries.
|
||||
|
||||
#### Scenario: Vue plugin coexistence
|
||||
- **WHEN** `vite build` is executed
|
||||
- **THEN** Vue SFC (`.vue` files) SHALL be compiled by `@vitejs/plugin-vue`
|
||||
- **THEN** existing vanilla JS entry points SHALL continue to build without modification
|
||||
|
||||
#### Scenario: HTML entry point
|
||||
- **WHEN** a page uses an HTML file as its Vite entry point
|
||||
- **THEN** Vite SHALL process the HTML and its referenced JS/CSS into `static/dist/`
|
||||
- **THEN** the output SHALL include `<page-name>.html`, `<page-name>.js`, and `<page-name>.css`
|
||||
|
||||
#### Scenario: Chunk splitting
|
||||
- **WHEN** Vite builds the project
|
||||
- **THEN** Vue runtime SHALL be split into a `vendor-vue` chunk
|
||||
- **THEN** ECharts modules (including TreemapChart, BarChart, LineChart) SHALL be split into the existing `vendor-echarts` chunk
|
||||
- **THEN** chunk splitting SHALL NOT affect existing page bundles
|
||||
|
||||
#### Scenario: Migrated page entry replacement
|
||||
- **WHEN** a vanilla JS page is migrated to Vue 3
|
||||
- **THEN** its Vite entry SHALL change from JS file to HTML file (e.g., `src/wip-overview/main.js` → `src/wip-overview/index.html`)
|
||||
- **THEN** the original JS entry SHALL be replaced, not kept alongside
|
||||
|
||||
#### Scenario: Hold Overview entry point
|
||||
- **WHEN** the hold-overview page is added
|
||||
- **THEN** `vite.config.js` input SHALL include `'hold-overview': resolve(__dirname, 'src/hold-overview/index.html')`
|
||||
- **THEN** the build SHALL produce `hold-overview.html`, `hold-overview.js`, and `hold-overview.css` in `static/dist/`
|
||||
|
||||
#### Scenario: Hold History entry point
|
||||
- **WHEN** the hold-history page is added
|
||||
- **THEN** `vite.config.js` input SHALL include `'hold-history': resolve(__dirname, 'src/hold-history/index.html')`
|
||||
- **THEN** the build SHALL produce `hold-history.html`, `hold-history.js`, and `hold-history.css` in `static/dist/`
|
||||
|
||||
#### Scenario: Shared CSS import across migrated pages
|
||||
- **WHEN** multiple migrated pages import a shared CSS module (e.g., `wip-shared/styles.css`)
|
||||
- **THEN** Vite SHALL bundle the shared CSS into each page's output CSS
|
||||
- **THEN** shared CSS SHALL NOT create a separate shared chunk that requires additional HTTP requests
|
||||
|
||||
#### Scenario: Shared composable import across module boundaries
|
||||
- **WHEN** a migrated page imports a composable from another shared module (e.g., `hold-history` imports `useAutoRefresh` from `wip-shared/`)
|
||||
- **THEN** the composable SHALL be bundled into the importing page's JS output
|
||||
- **THEN** cross-module imports SHALL NOT create unexpected shared chunks
|
||||
|
||||
### Requirement: Pure Vite pages SHALL handle API calls without legacy MesApi
|
||||
Pure Vite pages SHALL use the existing `frontend/src/core/api.js` module for API communication without depending on the global `window.MesApi` object from `_base.html`.
|
||||
|
||||
#### Scenario: API GET request from pure Vite page
|
||||
- **WHEN** a pure Vite page makes a GET API call
|
||||
- **THEN** the call SHALL use the `apiGet` function from `core/api.js`
|
||||
- **THEN** the call SHALL work without `window.MesApi` being present
|
||||
|
||||
### Requirement: Pure Vite pages SHALL handle POST API calls without legacy MesApi
|
||||
Pure Vite pages SHALL use the `apiPost` function from `core/api.js` for POST requests without depending on `window.MesApi`.
|
||||
|
||||
#### Scenario: API POST request from pure Vite page
|
||||
- **WHEN** a pure Vite page makes a POST API call
|
||||
- **THEN** the call SHALL use the `apiPost` function from `core/api.js`
|
||||
- **THEN** the call SHALL include `Content-Type: application/json` header
|
||||
- **THEN** the call SHALL work without `window.MesApi` being present
|
||||
|
||||
#### Scenario: CSRF token handling in POST requests
|
||||
- **WHEN** a pure Vite page calls `apiPost`
|
||||
- **THEN** `apiPost` SHALL attempt to read CSRF token from `<meta name="csrf-token">`
|
||||
- **THEN** if no meta tag exists, the request SHALL still proceed (non-admin APIs do not enforce CSRF)
|
||||
|
||||
### Requirement: Pure Vite pages with server-side route validation SHALL use send_from_directory with pre-validation
|
||||
Pages that require server-side parameter validation before serving SHALL validate parameters in the Flask route and then serve the static HTML.
|
||||
|
||||
#### Scenario: Hold Detail reason validation
|
||||
- **WHEN** user navigates to `/hold-detail` without a `reason` parameter
|
||||
- **THEN** Flask SHALL redirect to `/wip-overview`
|
||||
- **WHEN** user navigates to `/hold-detail?reason={value}`
|
||||
- **THEN** Flask SHALL serve the pre-built HTML file from `static/dist/` via `send_from_directory`
|
||||
- **THEN** the HTML SHALL NOT pass through Jinja2 template rendering
|
||||
|
||||
#### Scenario: Frontend fallback validation
|
||||
- **WHEN** the pure Vite hold-detail page loads
|
||||
- **THEN** the page SHALL read `reason` from URL parameters
|
||||
- **THEN** if `reason` is empty or missing, the page SHALL redirect to `/wip-overview`
|
||||
|
||||
### Requirement: Mid-section defect page SHALL separate filter state from query state
|
||||
The mid-section defect page SHALL maintain separate reactive state for UI input (`filters`) and committed query parameters (`committedFilters`).
|
||||
|
||||
#### Scenario: User changes date without clicking query
|
||||
- **WHEN** user modifies the date range in the filter bar but does not click "查詢"
|
||||
- **THEN** auto-refresh, pagination, and CSV export SHALL continue using the previously committed filter values
|
||||
- **THEN** the new date range SHALL NOT affect any API calls until "查詢" is clicked
|
||||
|
||||
#### Scenario: User clicks query button
|
||||
- **WHEN** user clicks "查詢"
|
||||
- **THEN** the current `filters` state SHALL be snapshotted into `committedFilters`
|
||||
- **THEN** all subsequent API calls SHALL use the committed values
|
||||
|
||||
#### Scenario: CSV export uses committed filters
|
||||
- **WHEN** user clicks "匯出 CSV" after modifying filters without re-querying
|
||||
- **THEN** the export SHALL use the committed filter values from the last query
|
||||
- **THEN** the export SHALL NOT use the current UI filter values
|
||||
|
||||
### Requirement: Mid-section defect page SHALL cancel in-flight requests on new query
|
||||
The mid-section defect page SHALL use `AbortController` to cancel in-flight API requests when a new query is initiated.
|
||||
|
||||
#### Scenario: New query cancels previous query
|
||||
- **WHEN** user clicks "查詢" while a previous query is still in-flight
|
||||
- **THEN** the previous query's summary and detail requests SHALL be aborted
|
||||
- **THEN** the AbortError SHALL be handled silently (no error banner shown)
|
||||
|
||||
#### Scenario: Page navigation cancels previous detail request
|
||||
- **WHEN** user clicks next page while a previous page request is still in-flight
|
||||
- **THEN** the previous page request SHALL be aborted
|
||||
- **THEN** the new page request SHALL proceed independently
|
||||
|
||||
#### Scenario: Query and pagination use independent abort keys
|
||||
- **WHEN** a query is in-flight and user triggers pagination
|
||||
- **THEN** the query SHALL NOT be cancelled by the pagination request
|
||||
- **THEN** the pagination SHALL use a separate abort key from the query
|
||||
|
||||
|
||||
Reference in New Issue
Block a user