feat(CORE-001D1): harden unit-aware workspace persistence

This commit is contained in:
Bu5hm4nn
2026-03-25 13:19:33 +01:00
parent cfb6abd842
commit 132aaed512
13 changed files with 464 additions and 87 deletions

View File

@@ -2,12 +2,11 @@ from __future__ import annotations
from datetime import date, datetime
from fastapi import Request
from fastapi.responses import RedirectResponse
from nicegui import ui
from app.domain.backtesting_math import asset_quantity_from_floats
from app.models.workspace import WORKSPACE_COOKIE, get_workspace_repository
from app.models.workspace import get_workspace_repository
from app.pages.common import dashboard_page, render_workspace_recovery
from app.services.backtesting.ui_service import BacktestPageRunResult, BacktestPageService
@@ -50,15 +49,6 @@ def _chart_options(result: BacktestPageRunResult) -> dict:
}
@ui.page("/backtests")
def legacy_backtests_page(request: Request):
repo = get_workspace_repository()
workspace_id = request.cookies.get(WORKSPACE_COOKIE, "")
if workspace_id and repo.workspace_exists(workspace_id):
return RedirectResponse(url=f"/{workspace_id}/backtests", status_code=307)
_render_backtests_page()
@ui.page("/{workspace_id}/backtests")
def workspace_backtests_page(workspace_id: str) -> None:
repo = get_workspace_repository()

View File

@@ -11,12 +11,8 @@ from app.models.portfolio import PortfolioConfig
from app.services.strategy_templates import StrategyTemplateService
NAV_ITEMS: list[tuple[str, str, str]] = [
("overview", "/", "Overview"),
("hedge", "/hedge", "Hedge Analysis"),
("welcome", "/", "Welcome"),
("options", "/options", "Options Chain"),
("backtests", "/backtests", "Backtests"),
("event-comparison", "/event-comparison", "Event Comparison"),
("settings", "/settings", "Settings"),
]

View File

@@ -1,11 +1,10 @@
from __future__ import annotations
from fastapi import Request
from fastapi.responses import RedirectResponse
from nicegui import ui
from app.domain.backtesting_math import asset_quantity_from_floats
from app.models.workspace import WORKSPACE_COOKIE, get_workspace_repository
from app.models.workspace import get_workspace_repository
from app.pages.common import dashboard_page, render_workspace_recovery
from app.services.event_comparison_ui import EventComparisonPageService
@@ -28,15 +27,6 @@ def _chart_options(dates: tuple[str, ...], series: tuple[dict[str, object], ...]
}
@ui.page("/event-comparison")
def legacy_event_comparison_page(request: Request):
repo = get_workspace_repository()
workspace_id = request.cookies.get(WORKSPACE_COOKIE, "")
if workspace_id and repo.workspace_exists(workspace_id):
return RedirectResponse(url=f"/{workspace_id}/event-comparison", status_code=307)
_render_event_comparison_page()
@ui.page("/{workspace_id}/event-comparison")
def workspace_event_comparison_page(workspace_id: str) -> None:
repo = get_workspace_repository()

View File

@@ -1,10 +1,9 @@
from __future__ import annotations
from fastapi import Request
from fastapi.responses import RedirectResponse
from nicegui import ui
from app.models.workspace import WORKSPACE_COOKIE, get_workspace_repository
from app.models.workspace import get_workspace_repository
from app.pages.common import (
dashboard_page,
demo_spot_price,
@@ -57,15 +56,6 @@ def _waterfall_options(metrics: dict) -> dict:
}
@ui.page("/hedge")
def legacy_hedge_page(request: Request):
repo = get_workspace_repository()
workspace_id = request.cookies.get(WORKSPACE_COOKIE, "")
if workspace_id and repo.workspace_exists(workspace_id):
return RedirectResponse(url=f"/{workspace_id}/hedge", status_code=307)
_render_hedge_page()
@ui.page("/{workspace_id}/hedge")
def workspace_hedge_page(workspace_id: str) -> None:
repo = get_workspace_repository()

View File

@@ -105,15 +105,6 @@ def welcome_page(request: Request):
)
@ui.page("/overview")
def legacy_overview_page(request: Request):
repo = get_workspace_repository()
workspace_id = request.cookies.get(WORKSPACE_COOKIE, "")
if workspace_id and repo.workspace_exists(workspace_id):
return RedirectResponse(url=f"/{workspace_id}", status_code=307)
return RedirectResponse(url="/", status_code=307)
@ui.page("/{workspace_id}")
@ui.page("/{workspace_id}/overview")
async def overview_page(workspace_id: str) -> None:

View File

@@ -1,11 +1,10 @@
from __future__ import annotations
from fastapi import Request
from fastapi.responses import RedirectResponse
from nicegui import ui
from app.models.portfolio import PortfolioConfig
from app.models.workspace import WORKSPACE_COOKIE, get_workspace_repository
from app.models.workspace import get_workspace_repository
from app.pages.common import dashboard_page
from app.services.alerts import AlertService, build_portfolio_alert_context
from app.services.settings_status import save_status_text
@@ -35,15 +34,6 @@ def _render_workspace_recovery() -> None:
)
@ui.page("/settings")
def legacy_settings_page(request: Request):
repo = get_workspace_repository()
workspace_id = request.cookies.get(WORKSPACE_COOKIE, "")
if workspace_id and repo.workspace_exists(workspace_id):
return RedirectResponse(url=f"/{workspace_id}/settings", status_code=307)
return RedirectResponse(url="/", status_code=307)
@ui.page("/{workspace_id}/settings")
def settings_page(workspace_id: str) -> None:
"""Settings page with workspace-scoped persistent portfolio configuration."""