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,27 @@
|
||||
# Full Modernization Architecture Blueprint Artifacts
|
||||
|
||||
This directory stores execution artifacts for `full-modernization-architecture-blueprint`.
|
||||
|
||||
## Core Governance
|
||||
|
||||
- `route_scope_matrix.json`: frozen in-scope/deferred route contract matrix.
|
||||
- `governance_milestones.md`: completion and deprecation milestones.
|
||||
- `exception_registry.json`: approved temporary exceptions with owner and milestone.
|
||||
- Policy artifact runtime cache model:
|
||||
- `src/mes_dashboard/core/modernization_policy.py` caches `route_scope_matrix.json` and
|
||||
`asset_readiness_manifest.json` in-process with `lru_cache`.
|
||||
- Runtime behavior is restart-refresh by default: JSON edits take effect after worker restart.
|
||||
- Controlled refresh is available through `clear_modernization_policy_cache()` for tests or
|
||||
explicit maintenance hooks; no automatic file watcher/hot reload is active in production.
|
||||
|
||||
## Content Modernization Safety
|
||||
|
||||
- `page_content_manual_acceptance_checklist.md`: mandatory manual sign-off checklist.
|
||||
- `known_bug_baseline.json`: route-level known bug baseline and replay blocking policy.
|
||||
|
||||
## Rollout Operations
|
||||
|
||||
- `rollout_runbook.md`: phase steps and hold points.
|
||||
- `rollback_controls.md`: rollback and false-positive gate handling.
|
||||
- `observability_checkpoints.md`: route/gate/rollback observability contract.
|
||||
- `deferred_route_handoff.md`: explicit handoff package to deferred-route follow-up change.
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"in_scope_required_assets": {
|
||||
"/portal-shell": ["portal-shell.html", "portal-shell.js", "portal-shell.css", "tailwind.css"],
|
||||
"/wip-overview": ["wip-overview.html", "wip-overview.js"],
|
||||
"/wip-detail": ["wip-detail.html", "wip-detail.js"],
|
||||
"/hold-overview": ["hold-overview.html", "hold-overview.js"],
|
||||
"/hold-detail": ["hold-detail.html", "hold-detail.js"],
|
||||
"/hold-history": ["hold-history.html", "hold-history.js"],
|
||||
"/resource": ["resource-status.html", "resource-status.js"],
|
||||
"/resource-history": ["resource-history.html", "resource-history.js"],
|
||||
"/qc-gate": ["qc-gate.html", "qc-gate.js"],
|
||||
"/job-query": ["job-query.js"],
|
||||
"/tmtt-defect": ["tmtt-defect.js"]
|
||||
},
|
||||
"deferred_routes": [
|
||||
"/tables",
|
||||
"/excel-query",
|
||||
"/query-tool",
|
||||
"/mid-section-defect"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"records": [],
|
||||
"schema": {
|
||||
"route": "string",
|
||||
"known_bug_id": "string",
|
||||
"replay_date": "YYYY-MM-DD",
|
||||
"result": "pass|fail",
|
||||
"notes": "string",
|
||||
"signoff_owner": "string"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"canonical_policy": {
|
||||
"applies_when": "PORTAL_SPA_ENABLED=true",
|
||||
"report_routes": "redirect direct route entry to /portal-shell/<route>",
|
||||
"admin_routes": "shell target redirects to backend /admin/* while backend keeps auth authority"
|
||||
},
|
||||
"direct_entry_compatibility": {
|
||||
"query_semantics_must_be_preserved": true,
|
||||
"redirect_status_code": 302
|
||||
},
|
||||
"in_scope_report_routes": [
|
||||
"/wip-overview",
|
||||
"/wip-detail",
|
||||
"/hold-overview",
|
||||
"/hold-detail",
|
||||
"/hold-history",
|
||||
"/resource",
|
||||
"/resource-history",
|
||||
"/qc-gate",
|
||||
"/job-query",
|
||||
"/tmtt-defect"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
# Deferred Route Handoff (Phase 1 -> Follow-up)
|
||||
|
||||
## Source Change
|
||||
|
||||
- `openspec/changes/full-modernization-architecture-blueprint/`
|
||||
|
||||
## Deferred Routes (Not in Phase 1 Blocking Scope)
|
||||
|
||||
- `/tables`
|
||||
- `/excel-query`
|
||||
- `/query-tool`
|
||||
- `/mid-section-defect`
|
||||
|
||||
## Follow-up Change
|
||||
|
||||
- `openspec/changes/deferred-route-modernization-follow-up/`
|
||||
|
||||
## Handoff Content
|
||||
|
||||
1. Scope boundary contract:
|
||||
- Source: `docs/migration/full-modernization-architecture-blueprint/route_scope_matrix.json`
|
||||
|
||||
2. Required acceptance model to carry forward:
|
||||
- Parity fixtures/checks:
|
||||
- `docs/migration/full-modernization-architecture-blueprint/parity_golden_fixtures.json`
|
||||
- `docs/migration/full-modernization-architecture-blueprint/interaction_parity_checks.json`
|
||||
- Manual acceptance + bug replay:
|
||||
- `docs/migration/full-modernization-architecture-blueprint/page_content_manual_acceptance_checklist.md`
|
||||
- `docs/migration/full-modernization-architecture-blueprint/known_bug_baseline.json`
|
||||
- `docs/migration/full-modernization-architecture-blueprint/bug_revalidation_records.json`
|
||||
|
||||
3. Governance policy to carry forward:
|
||||
- `docs/migration/full-modernization-architecture-blueprint/quality_gate_policy.json`
|
||||
- `docs/migration/full-modernization-architecture-blueprint/governance_milestones.md`
|
||||
- `docs/migration/full-modernization-architecture-blueprint/asset_readiness_manifest.json`
|
||||
|
||||
## Transfer Rule
|
||||
|
||||
- Deferred routes remain excluded from phase-1 blocking criteria.
|
||||
- Follow-up change MUST promote these routes to in-scope and apply equivalent parity/manual-acceptance/bug-revalidation gates before legacy retirement.
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"version": 1,
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"fields": [
|
||||
"id",
|
||||
"type",
|
||||
"scope",
|
||||
"owner",
|
||||
"introduced_by",
|
||||
"reason",
|
||||
"mitigation",
|
||||
"status",
|
||||
"milestone",
|
||||
"tracking_issue"
|
||||
],
|
||||
"entries": [
|
||||
{
|
||||
"id": "style-admin-pages-inline-css",
|
||||
"type": "style",
|
||||
"scope": "/admin/pages",
|
||||
"owner": "frontend-platform-admin",
|
||||
"introduced_by": "legacy-template",
|
||||
"reason": "admin pages remain backend-rendered in this phase",
|
||||
"mitigation": "enforce shell contract governance while retaining backend auth authority",
|
||||
"status": "approved-temporary",
|
||||
"milestone": "2026-03-19",
|
||||
"tracking_issue": "deferred-route-modernization-follow-up/admin-template-modernization"
|
||||
},
|
||||
{
|
||||
"id": "style-admin-performance-inline-css",
|
||||
"type": "style",
|
||||
"scope": "/admin/performance",
|
||||
"owner": "frontend-platform-admin",
|
||||
"introduced_by": "legacy-template",
|
||||
"reason": "admin performance remains backend-rendered in this phase",
|
||||
"mitigation": "governed navigation + route-level fallback controls",
|
||||
"status": "approved-temporary",
|
||||
"milestone": "2026-03-19",
|
||||
"tracking_issue": "deferred-route-modernization-follow-up/admin-template-modernization"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
# Full Modernization Governance Milestones
|
||||
|
||||
## Phase Completion Criteria
|
||||
|
||||
A phase is complete only when all criteria below are true:
|
||||
|
||||
1. Route governance: 100% of in-scope routes in `route_scope_matrix.json` have valid shell contract metadata and ownership.
|
||||
2. Style governance: in-scope route-local styles do not introduce page-global selectors (`:root`, `body`) unless recorded in exception registry.
|
||||
3. Quality governance: functional parity, visual checkpoints, accessibility checks, and performance budgets pass at configured gate severity.
|
||||
4. Content safety governance: page-content parity evidence + manual acceptance sign-off exist for each migrated in-scope route.
|
||||
5. Bug carry-over governance: known-bug replay checks for migrated scope do not reproduce legacy defects.
|
||||
|
||||
## Legacy Deprecation Milestones
|
||||
|
||||
- 2026-02-20: route contract CI completeness gate enabled in `warn` mode.
|
||||
- 2026-02-27: route contract CI completeness gate promoted to `block` mode.
|
||||
- 2026-03-05: in-scope asset readiness gate promoted to `block` mode.
|
||||
- 2026-03-12: runtime fallback posture retired for in-scope routes in production policy.
|
||||
- 2026-03-19: unresolved style exceptions past milestone fail modernization review.
|
||||
|
||||
## Deferred Route Linkage
|
||||
|
||||
Deferred routes are not pass/fail criteria in this phase and are handed over to a follow-up change:
|
||||
|
||||
- `/tables`
|
||||
- `/excel-query`
|
||||
- `/query-tool`
|
||||
- `/mid-section-defect`
|
||||
|
||||
Follow-up change handoff is recorded in `openspec/changes/deferred-route-modernization-follow-up/`.
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"required_flows": {
|
||||
"/wip-overview": ["filter_apply", "filter_reset", "status_card_drill"],
|
||||
"/wip-detail": ["list_detail_continuity", "pagination", "filter_reset"],
|
||||
"/hold-overview": ["reason_toggle", "matrix_selection", "lot_scope_sync"],
|
||||
"/hold-detail": ["reason_required_redirect", "distribution_toggle", "lot_scope_sync"],
|
||||
"/hold-history": ["date_range_query", "pareto_selection", "duration_bucket_selection"],
|
||||
"/resource": ["status_filter", "workcenter_family_filter", "tooltip_open_close"],
|
||||
"/resource-history": ["query_submit", "export_csv", "chart_detail_sync"],
|
||||
"/qc-gate": ["chart_bucket_selection", "table_filter_sync", "filter_clear"],
|
||||
"/job-query": ["resource_select", "query_submit", "export_csv"],
|
||||
"/tmtt-defect": ["date_range_query", "chart_filter_link", "detail_sort"],
|
||||
"/admin/pages": ["drawer_crud", "page_status_update", "admin_visibility"],
|
||||
"/admin/performance": ["admin_auth_access", "performance_view_load"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"scope": "in-scope-routes-only",
|
||||
"routes": {
|
||||
"/wip-overview": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/wip-detail": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/hold-overview": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/hold-detail": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/hold-history": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/resource": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/resource-history": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/qc-gate": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/job-query": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/tmtt-defect": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/admin/pages": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
},
|
||||
"/admin/performance": {
|
||||
"baseline_status": "initialized",
|
||||
"known_bugs": []
|
||||
}
|
||||
},
|
||||
"revalidation_rule": {
|
||||
"reproduced_legacy_bug_blocks_signoff": true,
|
||||
"reproduced_legacy_bug_blocks_legacy_retirement": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"records": [],
|
||||
"rule": "next route cutover is blocked until current route has approved manual sign-off"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
# Modernization Observability Checkpoints
|
||||
|
||||
## Route Governance Signals
|
||||
|
||||
1. `navigation_contract_mismatch_total`
|
||||
- Source: `/api/portal/navigation` diagnostics.
|
||||
- Alert condition: non-zero for in-scope routes.
|
||||
|
||||
2. `route_contract_missing_metadata_total`
|
||||
- Source: route governance CI script.
|
||||
- Alert condition: >0 in block mode.
|
||||
|
||||
## Quality Gate Signals
|
||||
|
||||
1. `quality_gate_failed_total{gate_id}`
|
||||
- Source: quality gate report.
|
||||
- Alert condition: any mandatory gate failed.
|
||||
|
||||
2. `manual_acceptance_pending_routes`
|
||||
- Source: manual acceptance records.
|
||||
- Alert condition: cutover attempted with pending sign-off.
|
||||
|
||||
## Fallback and Rollback Signals
|
||||
|
||||
1. `in_scope_runtime_fallback_served_total`
|
||||
- Should remain zero after fallback retirement milestone.
|
||||
|
||||
2. `content_cutover_flag_rollbacks_total`
|
||||
- Track frequency and route impact.
|
||||
|
||||
3. `legacy_bug_replay_failures_total`
|
||||
- Any non-zero indicates carry-over risk and blocks sign-off.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Page Content Manual Acceptance Checklist
|
||||
|
||||
## Rule
|
||||
|
||||
- Route cutover proceeds one route at a time.
|
||||
- Next route cutover is blocked until current route is manually signed off.
|
||||
- Legacy code retirement is blocked until parity checks and manual sign-off are both complete.
|
||||
|
||||
## Mandatory Checks Per Route
|
||||
|
||||
1. Filter semantics match baseline (apply, reset, URL/query continuity).
|
||||
2. Chart interactions match baseline (drill/selection/clear behavior).
|
||||
3. Empty/loading/error/success states are correct and non-overlapping.
|
||||
4. Table/chart linked interactions remain deterministic.
|
||||
5. Accessibility: keyboard flow, focus visibility, `aria-*` semantics, reduced-motion behavior.
|
||||
6. Known-bug replay checks completed (see `known_bug_baseline.json`).
|
||||
7. No reproduced legacy bug in migrated scope.
|
||||
|
||||
## Sign-Off Template
|
||||
|
||||
- Route:
|
||||
- Owner:
|
||||
- Reviewer:
|
||||
- Date:
|
||||
- Parity evidence links:
|
||||
- Known-bug replay result:
|
||||
- Blocking defects:
|
||||
- Decision: `approved` | `rework-required`
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"fixtures": {
|
||||
"/wip-overview": ["tests/fixtures/frontend_compute_parity.json"],
|
||||
"/wip-detail": ["docs/migration/portal-shell-route-view-integration/wave-b-parity-evidence.json"],
|
||||
"/hold-overview": ["docs/migration/portal-shell-route-view-integration/baseline_interaction_evidence.json"],
|
||||
"/hold-detail": ["docs/migration/portal-shell-route-view-integration/baseline_interaction_evidence.json"],
|
||||
"/hold-history": ["docs/migration/portal-shell-route-view-integration/baseline_interaction_evidence.json"],
|
||||
"/resource": ["docs/migration/portal-shell-route-view-integration/baseline_api_payload_contracts.json"],
|
||||
"/resource-history": ["docs/migration/portal-shell-route-view-integration/baseline_api_payload_contracts.json"],
|
||||
"/qc-gate": ["docs/migration/portal-shell-route-view-integration/visual-regression-snapshots.json"],
|
||||
"/job-query": ["docs/migration/portal-shell-route-view-integration/wave-b-parity-evidence.json"],
|
||||
"/tmtt-defect": ["docs/migration/portal-shell-route-view-integration/wave-b-parity-evidence.json"],
|
||||
"/admin/pages": ["tests/test_portal_shell_routes.py"],
|
||||
"/admin/performance": ["tests/test_performance_integration.py"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"targets": {
|
||||
"shell_navigation_api_avg_ms": 150,
|
||||
"shell_navigation_api_p95_ms": 350,
|
||||
"portal_shell_entry_avg_ms": 200,
|
||||
"portal_shell_entry_p95_ms": 450
|
||||
},
|
||||
"source_baselines": [
|
||||
"docs/migration/portal-no-iframe/performance_baseline_spa.json",
|
||||
"docs/migration/portal-no-iframe/performance_baseline_legacy.json"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"severity_mode": {
|
||||
"current": "warn",
|
||||
"promotion_target": "block",
|
||||
"promotion_milestone": "2026-02-27"
|
||||
},
|
||||
"gates": [
|
||||
{"id": "Q1", "name": "functional-parity", "required": true},
|
||||
{"id": "Q2", "name": "visual-regression", "required": true},
|
||||
{"id": "Q3", "name": "accessibility-keyboard-aria-motion", "required": true},
|
||||
{"id": "Q4", "name": "performance-budget", "required": true},
|
||||
{"id": "Q5", "name": "manual-acceptance-and-bug-revalidation", "required": true}
|
||||
],
|
||||
"deferred_routes_excluded": [
|
||||
"/tables",
|
||||
"/excel-query",
|
||||
"/query-tool",
|
||||
"/mid-section-defect"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"mode": "block",
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"info": [],
|
||||
"passed": true
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
# Full Modernization Rollback Controls
|
||||
|
||||
## Route-Level Reversion Controls
|
||||
|
||||
- `PORTAL_SPA_ENABLED=false`:
|
||||
Disable shell-first navigation runtime globally.
|
||||
- Route-scoped contract fallback:
|
||||
Mark route contract with fallback strategy and redeploy shell assets.
|
||||
- Content cutover feature flag:
|
||||
Disable route-level modernized content path while keeping shell runtime up.
|
||||
|
||||
## False-Positive Gate Handling
|
||||
|
||||
1. Capture failing gate output and route impact.
|
||||
2. Confirm whether failure is test flake or product defect.
|
||||
3. If false-positive and production risk is high:
|
||||
- Temporarily switch gate severity from `block` to `warn`.
|
||||
- Record waiver with owner, reason, expiry.
|
||||
4. Restore `block` mode after corrective action.
|
||||
|
||||
## Required Rollback Evidence
|
||||
|
||||
- Incident timestamp and impacted routes.
|
||||
- Gate IDs that triggered rollback.
|
||||
- Route contract state before/after rollback.
|
||||
- Manual acceptance and known-bug replay references.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Full Modernization Rollout Runbook
|
||||
|
||||
## Phase Sequence
|
||||
|
||||
1. Governance freeze
|
||||
- Confirm `route_scope_matrix.json` has no pending route-scope changes.
|
||||
- Confirm exception registry entries include owner + milestone.
|
||||
|
||||
2. Route governance enforcement
|
||||
- Run route contract completeness checks in warn mode.
|
||||
- Fix all in-scope metadata gaps.
|
||||
- Promote route governance checks to block mode.
|
||||
|
||||
3. Style/content hardening
|
||||
- Apply style isolation checks for in-scope routes.
|
||||
- Execute parity checks and manual acceptance route-by-route.
|
||||
- Run known-bug replay checks per route.
|
||||
|
||||
4. Asset/gate enforcement
|
||||
- Validate in-scope asset readiness.
|
||||
- Run quality gate suite (functional, visual, accessibility, performance).
|
||||
- Promote gate severity from warn to block according to policy.
|
||||
|
||||
## Hold Points
|
||||
|
||||
- Hold-1: Any in-scope route missing contract metadata.
|
||||
- Hold-2: Any unresolved style exception past milestone.
|
||||
- Hold-3: Any parity failure or known-bug replay failure.
|
||||
- Hold-4: Any mandatory quality gate failure in block mode.
|
||||
|
||||
## Promotion Rule
|
||||
|
||||
Promotion is allowed only when all hold points are clear and no deferred-route checks were incorrectly included as blockers.
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"in_scope_routes": {
|
||||
"/wip-overview": {
|
||||
"filter_input_semantics": ["workorder", "lotid", "package", "type", "status"],
|
||||
"query_payload_contract": ["workorder", "lotid", "package", "type", "status"],
|
||||
"chart_data_shape": ["status_cards", "matrix", "pareto"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/wip-detail": {
|
||||
"filter_input_semantics": ["workcenter", "workorder", "lotid", "package", "type", "status", "page"],
|
||||
"query_payload_contract": ["workcenter", "workorder", "lotid", "package", "type", "status", "page"],
|
||||
"chart_data_shape": ["summary_cards", "lot_table"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/hold-overview": {
|
||||
"filter_input_semantics": ["hold_type", "reason", "workcenter", "package", "age_range", "page"],
|
||||
"query_payload_contract": ["hold_type", "reason", "workcenter", "package", "age_range", "page"],
|
||||
"chart_data_shape": ["summary_cards", "matrix", "treemap", "lot_table"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/hold-detail": {
|
||||
"filter_input_semantics": ["reason", "workcenter", "package", "age_range", "page"],
|
||||
"query_payload_contract": ["reason", "workcenter", "package", "age_range", "page"],
|
||||
"chart_data_shape": ["summary_cards", "distribution", "lot_table"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/hold-history": {
|
||||
"filter_input_semantics": ["start_date", "end_date", "hold_type", "record_type", "reason", "duration_range", "page"],
|
||||
"query_payload_contract": ["start_date", "end_date", "hold_type", "record_type", "reason", "duration_range", "page"],
|
||||
"chart_data_shape": ["trend", "reason_pareto", "duration", "detail_table"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/resource": {
|
||||
"filter_input_semantics": ["workcenter_groups", "families", "resource_ids", "statuses"],
|
||||
"query_payload_contract": ["workcenter_groups", "families", "resource_ids", "statuses"],
|
||||
"chart_data_shape": ["summary_cards", "status_matrix", "equipment_grid"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/resource-history": {
|
||||
"filter_input_semantics": ["start_date", "end_date", "granularity", "workcenter_groups", "families", "resource_ids", "is_production", "is_key", "is_monitor"],
|
||||
"query_payload_contract": ["start_date", "end_date", "granularity", "workcenter_groups", "families", "resource_ids", "is_production", "is_key", "is_monitor"],
|
||||
"chart_data_shape": ["kpi", "trend", "heatmap", "workcenter_comparison", "detail"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/qc-gate": {
|
||||
"filter_input_semantics": ["chart_bucket_selection", "table_sort"],
|
||||
"query_payload_contract": ["summary", "table", "pareto"],
|
||||
"chart_data_shape": ["station_stack_chart", "linked_lot_table"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/job-query": {
|
||||
"filter_input_semantics": ["resource_ids", "start_date", "end_date"],
|
||||
"query_payload_contract": ["resource_ids", "start_date", "end_date"],
|
||||
"chart_data_shape": ["job_table", "txn_table"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/tmtt-defect": {
|
||||
"filter_input_semantics": ["start_date", "end_date", "sort", "page"],
|
||||
"query_payload_contract": ["start_date", "end_date"],
|
||||
"chart_data_shape": ["kpi", "pareto", "trend", "detail_table"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/admin/pages": {
|
||||
"filter_input_semantics": ["drawer_crud", "page_status_edit", "order_updates"],
|
||||
"query_payload_contract": ["drawers", "pages", "status"],
|
||||
"chart_data_shape": ["n/a"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
},
|
||||
"/admin/performance": {
|
||||
"filter_input_semantics": ["date_range", "severity", "search"],
|
||||
"query_payload_contract": ["performance_summary", "log_stream"],
|
||||
"chart_data_shape": ["timeline", "status_summary"],
|
||||
"state_contract": ["loading", "empty", "error", "success"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"generated_at": "2026-02-12T00:00:00Z",
|
||||
"routes": [
|
||||
{
|
||||
"route": "/wip-overview",
|
||||
"route_id": "wip-overview",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/wip-overview",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/wip-detail",
|
||||
"route_id": "wip-detail",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/wip-detail",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/hold-overview",
|
||||
"route_id": "hold-overview",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/hold-overview",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/hold-detail",
|
||||
"route_id": "hold-detail",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/hold-detail",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/hold-history",
|
||||
"route_id": "hold-history",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/hold-history",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/resource",
|
||||
"route_id": "resource",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/resource",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/resource-history",
|
||||
"route_id": "resource-history",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/resource-history",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/qc-gate",
|
||||
"route_id": "qc-gate",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/qc-gate",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/job-query",
|
||||
"route_id": "job-query",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/job-query",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/tmtt-defect",
|
||||
"route_id": "tmtt-defect",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/tmtt-defect",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/admin/pages",
|
||||
"route_id": "admin-pages",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "external",
|
||||
"owner": "frontend-platform-admin",
|
||||
"visibility_policy": "admin_only",
|
||||
"canonical_shell_path": "/portal-shell/admin/pages",
|
||||
"rollback_strategy": "external_route_reversion"
|
||||
},
|
||||
{
|
||||
"route": "/admin/performance",
|
||||
"route_id": "admin-performance",
|
||||
"scope": "in-scope",
|
||||
"render_mode": "external",
|
||||
"owner": "frontend-platform-admin",
|
||||
"visibility_policy": "admin_only",
|
||||
"canonical_shell_path": "/portal-shell/admin/performance",
|
||||
"rollback_strategy": "external_route_reversion"
|
||||
},
|
||||
{
|
||||
"route": "/tables",
|
||||
"route_id": "tables",
|
||||
"scope": "deferred",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/tables",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/excel-query",
|
||||
"route_id": "excel-query",
|
||||
"scope": "deferred",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/excel-query",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/query-tool",
|
||||
"route_id": "query-tool",
|
||||
"scope": "deferred",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/query-tool",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
},
|
||||
{
|
||||
"route": "/mid-section-defect",
|
||||
"route_id": "mid-section-defect",
|
||||
"scope": "deferred",
|
||||
"render_mode": "native",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin",
|
||||
"canonical_shell_path": "/portal-shell/mid-section-defect",
|
||||
"rollback_strategy": "fallback_to_legacy_route"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"generated_at": "2026-02-12T00:00:00Z",
|
||||
"phase": "phase-1-shell-and-content-modernization",
|
||||
"policy": {
|
||||
"scope_is_frozen": true,
|
||||
"out_of_scope_tasks_must_be_rejected": true
|
||||
},
|
||||
"in_scope": [
|
||||
{
|
||||
"route": "/wip-overview",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/wip-overview",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/wip-detail",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/wip-detail",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/hold-overview",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/hold-overview",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/hold-detail",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/hold-detail",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/hold-history",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/hold-history",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/resource",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/resource",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/resource-history",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/resource-history",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/qc-gate",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/qc-gate",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/job-query",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/job-query",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/tmtt-defect",
|
||||
"category": "report",
|
||||
"canonical_shell_path": "/portal-shell/tmtt-defect",
|
||||
"owner": "frontend-mes-reporting",
|
||||
"visibility_policy": "released_or_admin"
|
||||
},
|
||||
{
|
||||
"route": "/admin/pages",
|
||||
"category": "admin",
|
||||
"canonical_shell_path": "/portal-shell/admin/pages",
|
||||
"owner": "frontend-platform-admin",
|
||||
"visibility_policy": "admin_only"
|
||||
},
|
||||
{
|
||||
"route": "/admin/performance",
|
||||
"category": "admin",
|
||||
"canonical_shell_path": "/portal-shell/admin/performance",
|
||||
"owner": "frontend-platform-admin",
|
||||
"visibility_policy": "admin_only"
|
||||
}
|
||||
],
|
||||
"deferred": [
|
||||
{
|
||||
"route": "/tables",
|
||||
"reason": "deferred-to-follow-up-change"
|
||||
},
|
||||
{
|
||||
"route": "/excel-query",
|
||||
"reason": "deferred-to-follow-up-change"
|
||||
},
|
||||
{
|
||||
"route": "/query-tool",
|
||||
"reason": "deferred-to-follow-up-change"
|
||||
},
|
||||
{
|
||||
"route": "/mid-section-defect",
|
||||
"reason": "deferred-to-follow-up-change"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"change": "full-modernization-architecture-blueprint",
|
||||
"generated_at": "2026-02-12T00:00:00Z",
|
||||
"in_scope_routes": {
|
||||
"/wip-overview": {"global_selectors": [], "status": "clean"},
|
||||
"/wip-detail": {"global_selectors": [], "status": "clean"},
|
||||
"/hold-overview": {"global_selectors": [], "status": "clean"},
|
||||
"/hold-detail": {"global_selectors": [], "status": "clean"},
|
||||
"/hold-history": {"global_selectors": [], "status": "clean"},
|
||||
"/resource": {"global_selectors": [], "status": "clean"},
|
||||
"/resource-history": {"global_selectors": [], "status": "clean"},
|
||||
"/qc-gate": {"global_selectors": [], "status": "clean-after-refactor"},
|
||||
"/job-query": {"global_selectors": [], "status": "clean"},
|
||||
"/tmtt-defect": {"global_selectors": [], "status": "clean"},
|
||||
"/admin/pages": {
|
||||
"global_selectors": ["body"],
|
||||
"status": "exception-registered",
|
||||
"exception_id": "style-admin-pages-inline-css"
|
||||
},
|
||||
"/admin/performance": {
|
||||
"global_selectors": ["body"],
|
||||
"status": "exception-registered",
|
||||
"exception_id": "style-admin-performance-inline-css"
|
||||
}
|
||||
},
|
||||
"shared_layers": {
|
||||
"frontend/src/styles/tailwind.css": [":root", "body"],
|
||||
"frontend/src/portal-shell/style.css": [":root", "body"]
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"generated_at": "2026-02-12T02:26:36.887797+00:00",
|
||||
"source": "data/page_status.json",
|
||||
"admin": [
|
||||
{
|
||||
@@ -16,7 +17,7 @@
|
||||
{
|
||||
"route": "/hold-overview",
|
||||
"name": "Hold 即時概況",
|
||||
"status": "dev",
|
||||
"status": "released",
|
||||
"order": 2
|
||||
},
|
||||
{
|
||||
@@ -42,7 +43,7 @@
|
||||
{
|
||||
"route": "/hold-history",
|
||||
"name": "Hold 歷史績效",
|
||||
"status": "dev",
|
||||
"status": "released",
|
||||
"order": 3
|
||||
},
|
||||
{
|
||||
@@ -106,7 +107,7 @@
|
||||
{
|
||||
"route": "/tmtt-defect",
|
||||
"name": "TMTT印字腳型不良分析",
|
||||
"status": "released",
|
||||
"status": "dev",
|
||||
"order": 5
|
||||
},
|
||||
{
|
||||
@@ -131,6 +132,12 @@
|
||||
"status": "released",
|
||||
"order": 1
|
||||
},
|
||||
{
|
||||
"route": "/hold-overview",
|
||||
"name": "Hold 即時概況",
|
||||
"status": "released",
|
||||
"order": 2
|
||||
},
|
||||
{
|
||||
"route": "/resource",
|
||||
"name": "設備即時概況",
|
||||
@@ -151,6 +158,12 @@
|
||||
"order": 2,
|
||||
"admin_only": false,
|
||||
"pages": [
|
||||
{
|
||||
"route": "/hold-history",
|
||||
"name": "Hold 歷史績效",
|
||||
"status": "released",
|
||||
"order": 3
|
||||
},
|
||||
{
|
||||
"route": "/resource-history",
|
||||
"name": "設備歷史績效",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated_at": "2026-02-11T07:44:03+00:00",
|
||||
"generated_at": "2026-02-12T02:26:36.887797+00:00",
|
||||
"source": "data/page_status.json",
|
||||
"admin": [
|
||||
{
|
||||
@@ -17,7 +17,7 @@
|
||||
{
|
||||
"route": "/hold-overview",
|
||||
"name": "Hold 即時概況",
|
||||
"status": "dev",
|
||||
"status": "released",
|
||||
"order": 2
|
||||
},
|
||||
{
|
||||
@@ -43,7 +43,7 @@
|
||||
{
|
||||
"route": "/hold-history",
|
||||
"name": "Hold 歷史績效",
|
||||
"status": "dev",
|
||||
"status": "released",
|
||||
"order": 3
|
||||
},
|
||||
{
|
||||
@@ -107,7 +107,7 @@
|
||||
{
|
||||
"route": "/tmtt-defect",
|
||||
"name": "TMTT印字腳型不良分析",
|
||||
"status": "released",
|
||||
"status": "dev",
|
||||
"order": 5
|
||||
},
|
||||
{
|
||||
@@ -132,6 +132,12 @@
|
||||
"status": "released",
|
||||
"order": 1
|
||||
},
|
||||
{
|
||||
"route": "/hold-overview",
|
||||
"name": "Hold 即時概況",
|
||||
"status": "released",
|
||||
"order": 2
|
||||
},
|
||||
{
|
||||
"route": "/resource",
|
||||
"name": "設備即時概況",
|
||||
@@ -152,6 +158,12 @@
|
||||
"order": 2,
|
||||
"admin_only": false,
|
||||
"pages": [
|
||||
{
|
||||
"route": "/hold-history",
|
||||
"name": "Hold 歷史績效",
|
||||
"status": "released",
|
||||
"order": 3
|
||||
},
|
||||
{
|
||||
"route": "/resource-history",
|
||||
"name": "設備歷史績效",
|
||||
|
||||
Reference in New Issue
Block a user