feat: finalize portal no-iframe migration baseline and archive change
This commit is contained in:
27
openspec/specs/frontend-motion-system/spec.md
Normal file
27
openspec/specs/frontend-motion-system/spec.md
Normal file
@@ -0,0 +1,27 @@
|
||||
## Purpose
|
||||
Define stable requirements for frontend-motion-system.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Navigation transitions SHALL use a maintainable baseline motion system
|
||||
The frontend SHALL provide route and panel transition effects using a baseline motion mechanism suitable for long-term maintenance.
|
||||
|
||||
#### Scenario: Route transition feedback
|
||||
- **WHEN** a user navigates between report modules
|
||||
- **THEN** the shell SHALL provide consistent transition feedback
|
||||
- **THEN** transitions SHALL NOT block route completion or data loading
|
||||
|
||||
### Requirement: Motion behavior SHALL support reduced-motion accessibility
|
||||
The motion system SHALL respect reduced-motion user preferences.
|
||||
|
||||
#### Scenario: Reduced-motion preference
|
||||
- **WHEN** user agent indicates reduced motion preference
|
||||
- **THEN** non-essential animations SHALL be minimized or disabled
|
||||
- **THEN** primary interactions SHALL remain fully usable
|
||||
|
||||
### Requirement: Motion effects SHALL preserve functional correctness
|
||||
Animation implementation SHALL NOT alter data correctness, query timing semantics, or interaction outcomes.
|
||||
|
||||
#### Scenario: Interactive action during motion
|
||||
- **WHEN** users perform filtering, refresh, or drill-down actions during transitions
|
||||
- **THEN** resulting API calls and state updates SHALL remain functionally equivalent to non-animated execution
|
||||
@@ -2,15 +2,15 @@
|
||||
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, replacing inline scripts in a phased manner.
|
||||
The system SHALL provide Vite-managed module entries for major portal pages under a phased SPA-shell migration while keeping direct route access compatible.
|
||||
|
||||
#### Scenario: Portal module loading
|
||||
- **WHEN** the portal page is rendered
|
||||
#### 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: Page module fallback
|
||||
#### Scenario: Module fallback continuity
|
||||
- **WHEN** a required Vite asset is unavailable
|
||||
- **THEN** the system MUST keep page behavior functional through explicit fallback logic
|
||||
- **THEN** the system MUST keep affected page behavior functional through explicit fallback logic
|
||||
|
||||
### 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.
|
||||
@@ -27,12 +27,16 @@ Page entry modules MUST consume shared chart/query/drawer utilities for common b
|
||||
- **THEN** the behavior MUST be provided by shared Vite modules rather than duplicated page-local implementations
|
||||
|
||||
### Requirement: Modularization MUST Preserve Established Navigation and Drill-Down Semantics
|
||||
Refactoring into Vite modules SHALL not alter existing page transitions, independent tabs, and drill-down entry points.
|
||||
Refactoring into Vite modules and SPA shell routing SHALL not alter existing route paths, query semantics, and drill-down entry points.
|
||||
|
||||
#### Scenario: User follows existing drill-down path
|
||||
- **WHEN** the user navigates from summary page to detail views
|
||||
- **THEN** the resulting flow and parameter semantics MUST match the established baseline behavior
|
||||
|
||||
#### Scenario: Direct detail route remains valid
|
||||
- **WHEN** users open existing detail routes directly with query parameters (e.g., `/wip-detail?workcenter=...`, `/hold-detail?reason=...`)
|
||||
- **THEN** route-level behavior MUST remain compatible with established baseline expectations
|
||||
|
||||
### Requirement: Module Boundaries SHALL Support Frontend Compute Expansion
|
||||
Vite module structure MUST keep compute logic decoupled from DOM wiring so additional backend-to-frontend computation shifts can be added safely.
|
||||
|
||||
|
||||
26
openspec/specs/legacy-page-wrapper-strategy/spec.md
Normal file
26
openspec/specs/legacy-page-wrapper-strategy/spec.md
Normal file
@@ -0,0 +1,26 @@
|
||||
## Purpose
|
||||
Define stable requirements for legacy-page-wrapper-strategy.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Selected legacy pages SHALL be integrated via wrapper-first strategy
|
||||
The migration SHALL integrate `job-query`, `excel-query`, `query-tool`, and `tmtt-defect` through wrapper-based routing before full rewrites.
|
||||
|
||||
#### Scenario: Wrapper route availability for selected pages
|
||||
- **WHEN** users navigate to each selected legacy page from the new shell
|
||||
- **THEN** the route SHALL remain reachable and functionally usable through the wrapper layer
|
||||
|
||||
### Requirement: Wrapper mode SHALL preserve legacy functional parity
|
||||
Wrapper integration SHALL preserve current API interactions, core user workflows, and error handling semantics for wrapped pages.
|
||||
|
||||
#### Scenario: Legacy workflow parity under wrapper
|
||||
- **WHEN** users execute core operations on a wrapped page (query/filter/export where applicable)
|
||||
- **THEN** operation results SHALL remain behaviorally equivalent to pre-wrapper baseline
|
||||
|
||||
### Requirement: Wrapper phase SHALL define rewrite exit criteria
|
||||
Each wrapped page SHALL have explicit readiness criteria that gate transition from wrapper mode to full Vue module rewrite.
|
||||
|
||||
#### Scenario: Rewrite readiness decision
|
||||
- **WHEN** a wrapped page reaches agreed quality and parity thresholds
|
||||
- **THEN** the page SHALL be eligible for rewrite scheduling
|
||||
- **THEN** wrapper decommission SHALL only occur after rewrite parity validation passes
|
||||
@@ -2,19 +2,27 @@
|
||||
Define stable requirements for migration-gates-and-rollout.
|
||||
## Requirements
|
||||
### Requirement: Migration Gates SHALL Define Cutover Readiness
|
||||
The system SHALL define explicit migration gates for functional parity, build integrity, and operational health before final cutover.
|
||||
The system SHALL define explicit migration gates for functional parity, build integrity, drawer visibility parity, and operational health before final cutover.
|
||||
|
||||
#### Scenario: Gate evaluation before cutover
|
||||
- **WHEN** release is prepared for final cutover
|
||||
- **THEN** all required migration gates MUST pass or cutover SHALL be blocked
|
||||
|
||||
#### Scenario: Functional parity gate fails
|
||||
- **WHEN** any critical route or core workflow parity check fails during gate execution
|
||||
- **THEN** release governance MUST treat the cutover as failed and prevent promotion
|
||||
|
||||
### Requirement: Rollout and Rollback Procedures MUST be Actionable
|
||||
The system SHALL document actionable rollout and rollback procedures for root migration.
|
||||
The system SHALL document actionable rollout and rollback procedures for SPA-shell migration and iframe decommission.
|
||||
|
||||
#### Scenario: Rollback execution
|
||||
- **WHEN** post-cutover validation fails critical checks
|
||||
- **THEN** operators MUST be able to execute documented rollback steps to restore previous stable behavior
|
||||
|
||||
#### Scenario: Kill-switch rollback
|
||||
- **WHEN** severe production regression is detected after cutover
|
||||
- **THEN** operators MUST be able to disable the new navigation path through a documented kill-switch mechanism and recover service usability within the defined rollback target time
|
||||
|
||||
### Requirement: Migration Gates SHALL Include Runtime Resilience Validation
|
||||
Cutover readiness gates MUST include resilience checks for pool exhaustion handling, circuit-breaker fail-fast behavior, and recovery flow.
|
||||
|
||||
|
||||
@@ -3,9 +3,8 @@ Define stable requirements for portal-drawer-navigation.
|
||||
|
||||
## Requirements
|
||||
|
||||
|
||||
### Requirement: Portal Navigation SHALL Group Entries by Functional Drawers
|
||||
The portal SHALL group navigation entries into functional drawers as defined in the `drawers` configuration of `page_status.json`, rendered dynamically via Jinja2 loop instead of hardcoded HTML.
|
||||
The portal SHALL group navigation entries into functional drawers as defined in the `drawers` configuration of `page_status.json`, rendered by the active portal runtime (server template or SPA shell) without changing drawer assignment semantics.
|
||||
|
||||
#### Scenario: Drawer grouping visibility
|
||||
- **WHEN** users open the portal
|
||||
@@ -17,29 +16,33 @@ The portal SHALL group navigation entries into functional drawers as defined in
|
||||
- **THEN** the drawer and all its pages SHALL NOT be rendered in the sidebar
|
||||
|
||||
#### Scenario: Empty drawer visibility
|
||||
- **WHEN** a drawer has no visible pages (all filtered out by `can_view_page()`)
|
||||
- **WHEN** a drawer has no visible pages (all filtered out by page visibility checks)
|
||||
- **THEN** the drawer group title SHALL NOT be rendered
|
||||
|
||||
### Requirement: Existing Page Behavior SHALL Remain Compatible
|
||||
The portal navigation refactor SHALL preserve existing target routes and lazy-load behavior for content frames.
|
||||
The portal navigation refactor SHALL preserve existing target routes while replacing iframe-based page embedding with route-driven navigation.
|
||||
|
||||
#### Scenario: Route continuity
|
||||
- **WHEN** a user selects an existing page entry from a dynamically rendered drawer
|
||||
- **WHEN** a user selects an existing page entry from a drawer
|
||||
- **THEN** the corresponding original route SHALL be loaded without changing page business logic behavior
|
||||
|
||||
#### Scenario: Iframe lazy-load continuity
|
||||
- **WHEN** a sidebar item is clicked for the first time
|
||||
- **THEN** the iframe SHALL lazy-load its content from the page's route, consistent with current behavior
|
||||
#### Scenario: Direct navigation without iframe
|
||||
- **WHEN** a sidebar item is clicked
|
||||
- **THEN** the browser SHALL navigate to the page's route in the same window
|
||||
- **THEN** the portal SHALL NOT render or activate iframe elements for page content
|
||||
|
||||
### Requirement: First-run migration SHALL populate drawer configuration automatically
|
||||
When `page_status.json` does not contain a `drawers` field, the system SHALL automatically create the default drawer structure matching the current hardcoded layout and assign existing pages to their corresponding drawers.
|
||||
### Requirement: Drawer Configuration and Visibility SHALL Remain Deterministic During Migration
|
||||
Migration to SPA navigation SHALL preserve the effective drawer visibility outcomes defined by current `drawers + pages + status + admin_only` rules.
|
||||
|
||||
#### Scenario: First startup after deployment
|
||||
- **WHEN** the application starts and `page_status.json` has no `drawers` field
|
||||
- **THEN** the system SHALL create three default drawers (報表類, 查詢類, 開發工具)
|
||||
- **THEN** the system SHALL assign each existing page to its historically correct drawer
|
||||
- **THEN** the system SHALL persist the updated configuration immediately
|
||||
#### Scenario: Non-admin visible drawer pages remain stable
|
||||
- **WHEN** a non-admin user opens the portal after migration
|
||||
- **THEN** only pages with released visibility in non-admin drawers SHALL be visible
|
||||
- **THEN** admin-only drawers SHALL remain hidden
|
||||
|
||||
#### Scenario: Subsequent startup
|
||||
- **WHEN** the application starts and `page_status.json` already contains a `drawers` field
|
||||
- **THEN** the system SHALL NOT modify the existing drawer configuration
|
||||
#### Scenario: Admin visible drawer pages remain stable
|
||||
- **WHEN** an admin user opens the portal after migration
|
||||
- **THEN** all pages allowed by drawer assignment and page status rules SHALL remain visible
|
||||
|
||||
#### Scenario: Duplicate order values resolve deterministically
|
||||
- **WHEN** multiple pages or drawers share the same `order` value
|
||||
- **THEN** rendering order SHALL still be deterministic and repeatable across requests
|
||||
|
||||
31
openspec/specs/spa-shell-navigation/spec.md
Normal file
31
openspec/specs/spa-shell-navigation/spec.md
Normal file
@@ -0,0 +1,31 @@
|
||||
## Purpose
|
||||
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.
|
||||
|
||||
#### Scenario: Drawer navigation renders router view
|
||||
- **WHEN** a user clicks a sidebar page entry
|
||||
- **THEN** the active route SHALL be updated through Vue Router
|
||||
- **THEN** the main content area SHALL render the corresponding route view without iframe usage
|
||||
|
||||
### Requirement: Existing route contracts SHALL remain stable in SPA mode
|
||||
Migration to SPA shell SHALL preserve existing route paths and deep-link behavior.
|
||||
|
||||
#### 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
|
||||
|
||||
### Requirement: SPA shell navigation SHALL enforce page visibility rules
|
||||
SPA navigation SHALL respect backend-defined drawer and page visibility outcomes.
|
||||
|
||||
#### Scenario: Non-admin visibility in SPA shell
|
||||
- **WHEN** a non-admin user opens the shell
|
||||
- **THEN** routes and drawer items restricted to admin-only visibility SHALL NOT be presented as navigable entries
|
||||
|
||||
#### Scenario: Admin visibility in SPA shell
|
||||
- **WHEN** an admin user opens the shell
|
||||
- **THEN** pages allowed by drawer and page status rules SHALL be presented as navigable entries
|
||||
28
openspec/specs/tailwind-design-system/spec.md
Normal file
28
openspec/specs/tailwind-design-system/spec.md
Normal file
@@ -0,0 +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.
|
||||
|
||||
#### Scenario: Shared token usage across modules
|
||||
- **WHEN** two report modules render equivalent UI elements (e.g., card, filter chip, primary button)
|
||||
- **THEN** they SHALL use the same token-backed style semantics
|
||||
- **THEN** visual output SHALL remain consistent across modules
|
||||
|
||||
### 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.
|
||||
|
||||
#### 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
|
||||
|
||||
### 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.
|
||||
|
||||
#### Scenario: Shared component adoption
|
||||
- **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
|
||||
@@ -12,10 +12,10 @@ The system SHALL support serving Vite-built HTML pages directly via Flask withou
|
||||
- **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 in portal iframe
|
||||
- **WHEN** the pure Vite page is loaded inside the portal iframe
|
||||
- **THEN** the page SHALL render correctly within the iframe context
|
||||
- **THEN** CSP `frame-ancestors 'self'` SHALL allow the embedding
|
||||
#### 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.
|
||||
|
||||
Reference in New Issue
Block a user