Report Web Adaptation Plan (backtestWebsite + new_website)
Goal
Deploy new FinLab package (canonical payload) without breaking website rendering, while allowing phased migration away from legacy strategies docs.
Canonical source of truth:
users/{uid}/reports/{sid}
Legacy projection (kept during migration):
users/{uid}/strategies/{sid}users/{uid}/strategies/{sid}/positions/positionusers/{uid}/strategies/{sid}/articles/article(unchanged)
Current Status
- FinLab client already writes canonical payload (
report+execution) toreports/{sid}when using Firebaseid_token. - Cloud Function projection (
report_projection) can project canonical doc into legacy strategy/position documents. - Both frontend projects are still legacy-path readers.
Compatibility Contract During Deployment
For zero-break rollout, keep this invariant:
- New FinLab client writes canonical doc only.
- Trigger projects canonical -> legacy docs.
- Frontends continue reading legacy docs unchanged.
This lets us deploy package and server first, then frontend migration independently.
Impacted Frontend Touchpoints
backtestWebsite
Main legacy readers/writers:
store/strategy.js- realtime read:
/users/{uid}/strategies/{sid} components/PositionPanel.vue- reads
/users/{uid}/strategies/{sid}/positions/{position_id} - expects legacy
positionmap schema components/PositionPanelFinlab.vue- reads legacy position doc (
position2) plugins/strategy.js- copy/delete strategy docs under legacy path
new_website
Main legacy readers/writers:
src/lib/stores/strategy.js- realtime read: strategy root +
/positions/position+ article src/lib/components/strategy/viewer.svelte- expects
data.reportPosition?.position2 src/lib/components/chatpage/strategy.svelte- expects
data.reportPosition?.position2 src/lib/components/chatpage/panes/StrategyPane.svelte- direct live() path to legacy strategy + position + article
src/lib/js/strategyDatabase.ts- CRUD under legacy strategy/codes/position docs
src/routes/embed/+page.svelte- direct reads of legacy strategy/position/article docs
Phase Plan
Phase 1 (Now): Deploy Safe Compatibility
- Deploy
report_projectionfunction first. - Keep both websites reading legacy docs only.
- Validate parity on sampled
{uid, sid}: strategy.stats,strategy.returns,position.position2presence- visibility flags (
public_performance,public_code,public_position)
Exit criteria:
- Canonical write success rate high.
- Projection error rate low.
- Frontends render unchanged for migrated strategies.
Phase 2: Add Frontend Dual-Read (No UI Change)
Implement adapter layer that normalizes canonical payload to existing UI contract.
Read order:
- Legacy docs (fast path, current behavior).
- If missing, fallback to canonical
users/{uid}/reports/{sid}. - Normalize canonical payload to old fields consumed by UI:
strategyequivalent (returns,benchmark,stats, etc.)reportPosition.position2equivalent fromexecution
Why:
- Makes frontend resilient if projection is delayed or temporarily unhealthy.
- Allows canary users on canonical-only docs.
Phase 3: Canonical-First Frontend
- Flip read order to canonical-first, legacy fallback.
- Keep adapter output stable so components do not change.
- Optionally remove direct dependency on
position2in new components and useexecutiondirectly.
Phase 4: Legacy Cleanup
- Remove legacy write paths from frontend tools.
- Stop updating legacy paths except for read-only compatibility window.
- Decommission projection after all consumers are canonical.
Recommended Implementation Pattern
Create one shared adapter module per project:
- input:
- canonical doc (
report,execution) - or legacy docs
- output:
- stable “view model” currently used by components
Do not spread path branching (strategies vs reports) across many components.
Validation Checklist (Per Deployment)
- Upload strategy via new FinLab package and confirm:
- canonical doc exists at
users/{uid}/reports/{sid} - projected legacy docs exist and update within expected latency
- Open strategy page in both sites:
- performance chart renders
- position table renders
- permission-gated view behaves unchanged
- Test edge cases:
- no positions
- multi-strategy execution map
- private strategy (hide position, show performance)
Canary Script
Run a compatibility canary before each rollout:
uv run python scripts/report_web_canary.py \
--uid <uid> \
--sid <sid1> \
--sid <sid2> \
--check-legacy
Notes:
- Uses
FINLAB_ID_TOKENenv var by default, or pass--id-token. - Validates canonical payload can satisfy both websites' render contracts.
- With
--check-legacy, also checks projected legacy docs exist.
Suggested Execution Order Across Repos
- Server: deploy projection + monitoring.
new_website: implement adapter + dual-read first (smaller/faster iteration).backtestWebsite: keep legacy mode initially; add dual-read adapter only if needed.- After stable period, move both to canonical-first.