M2: frontend walkthrough fixes + explicit dev compose stack
Post-M2 self-walkthrough polish, batched into one commit. Map / heat: - fix heat-layer white-screen crash after login (add layer to map before setLatLngs; an off-map leaflet.heat layer has a null _map and throws) - normalize each heat layer to the densest pixel cell visible in the CURRENT viewport (maxZoom:0 so intensity factor f=1) and recompute on moveend/zoomend, so sparse poo data reaches red and stays normalized at any zoom level - dark CARTO basemap tiles when the color scheme is dark UI: - dark-mode toggle in the top-right, beside the settings gear - switch top-right nav (records / theme / settings / logout) to Feather icons with hover tooltips - home: Grafana-style quick time-range presets + back/forward shift buttons, placed between the From/To pickers and Apply; fix Select/tooltip z-index (Leaflet stacking) and the shift-button height alignment API client: - stop flooding GET /api/session with 401s: the session probe and the login endpoint own their 401s (no global redirect), which fixes the logout hang and the spinning login page Compose: - rename docker-compose.override.yml -> docker-compose.dev.yml as an explicit, non-auto-layered dev stack (8001, -dev container names, prod-copy ./data DB); update tests/test_deployment.py (read dev.yml, tolerate the !override tag) and the README "Docker Compose" section Tests: - pixel-grid peak counter, time-range presets, heat-layer ordering regression, and 401-redirect regression
This commit is contained in:
@@ -14,8 +14,25 @@ from scripts.run_migrations import run_all_migrations
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class _ComposeLoader(yaml.SafeLoader):
|
||||
"""SafeLoader that tolerates docker-compose merge tags (e.g. ``!override``,
|
||||
``!reset``), which appear in docker-compose.dev.yml's ``ports`` and which
|
||||
plain ``safe_load`` rejects as unknown constructors."""
|
||||
|
||||
|
||||
def _construct_compose_tag(loader: yaml.Loader, _suffix: str, node: yaml.Node):
|
||||
if isinstance(node, yaml.MappingNode):
|
||||
return loader.construct_mapping(node, deep=True)
|
||||
if isinstance(node, yaml.SequenceNode):
|
||||
return loader.construct_sequence(node, deep=True)
|
||||
return loader.construct_scalar(node)
|
||||
|
||||
|
||||
_ComposeLoader.add_multi_constructor("!", _construct_compose_tag)
|
||||
|
||||
|
||||
def _read_yaml(path: str) -> dict:
|
||||
return yaml.safe_load((PROJECT_ROOT / path).read_text())
|
||||
return yaml.load((PROJECT_ROOT / path).read_text(), Loader=_ComposeLoader)
|
||||
|
||||
|
||||
async def _run_lifespan(app) -> None:
|
||||
@@ -41,7 +58,9 @@ def _configure_database_env(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) ->
|
||||
|
||||
def test_compose_uses_migration_job_before_app() -> None:
|
||||
compose = _read_yaml("docker-compose.yml")
|
||||
override = _read_yaml("docker-compose.override.yml")
|
||||
# Local dev overrides live in docker-compose.dev.yml (explicitly layered;
|
||||
# see README "Docker Compose"). It supplies build: . for local-source builds.
|
||||
dev = _read_yaml("docker-compose.dev.yml")
|
||||
|
||||
migration_service = compose["services"]["migration"]
|
||||
app_service = compose["services"]["app"]
|
||||
@@ -49,8 +68,8 @@ def test_compose_uses_migration_job_before_app() -> None:
|
||||
assert migration_service["command"] == ["python", "-m", "scripts.run_migrations"]
|
||||
assert migration_service["restart"] == "no"
|
||||
assert app_service["depends_on"]["migration"]["condition"] == "service_completed_successfully"
|
||||
assert override["services"]["migration"]["build"] == "."
|
||||
assert override["services"]["app"]["build"] == "."
|
||||
assert dev["services"]["migration"]["build"] == "."
|
||||
assert dev["services"]["app"]["build"] == "."
|
||||
|
||||
|
||||
def test_image_defaults_to_uvicorn_only() -> None:
|
||||
|
||||
Reference in New Issue
Block a user