seam: FleetPulseDocument shape fix, ingest stub-test update, eslint generated-client ignore (from #17) #84

Open
opened 2026-09-11 13:34:38 +00:00 by patrick · 0 comments
Owner

Found while working #17 (T-B — ingest & projector)

Three small fixes outside backend/src/polaris/ingest/**, backend/src/polaris/projector/**, backend/src/polaris/worker/handlers/project_windows.py, backend/src/polaris/api/routers/ingest/**, backend/tests/**/{ingest,projector}/**, frontend/src/app/features/ingest/**, frontend/src/app/features/vehicles/components/heatmap* (#17's owned paths), made directly in #17's PR rather than leaving the ticket blocked or broken, per the precedent in issues #52/#57/#66. Flagged here for traceability.

1. backend/src/polaris/api/dto/ingest.pyFleetPulseDocument shape corrected

This file's own docstring already flagged the problem: FleetPulseDocument/FleetPulseSite/FleetPulseTimeBlock were declared with an inferred shape (PH1.7, issue #15 — no real sample existed yet) — flat time_blocks per site, a top-level vehicle_id, WKT polygon text. The real feed (confirmed against docs/design_document.md "The raw feed we receive" and the sample feed #14 built at backend/src/polaris/seed/data/fleetpulse_sample.json) has no top-level vehicle_id (it repeats per-site — a document is "per vehicle"), observations_per_day keyed by weekday name with a list of observation groups per weekday (Q4), and a nested GeoJSON polygon.geometry.

Fix (already in #17's PR): the canonical schema now lives in polaris.ingest.schema (T-B's owned package — the ingest pipeline and its tests must not depend on polaris.api), and polaris.api.dto.ingest re-exports those same classes for the API boundary/OpenAPI, same pattern every other DTO in that module already follows. backend/openapi.json regenerated in the same PR (docs/12-implementation-plan.md's PH1.7 row: "openapi.json regenerated only in PRs that change a DTO").

Owns: backend/src/polaris/api/dto/ingest.py (the FleetPulseDocument/FleetPulseSite/FleetPulseTimeBlock/FleetPulseObservationGroup/FleetPulsePolygon/FleetPulseGeometry re-exports only — IngestResponse/IngestRecordRead are unaffected), backend/openapi.json.

2. backend/tests/unit/api/routers/plans_locks_assignments_stub_test.py — two ingest endpoints are no longer 501

This PH1.7 shared stub-test module asserted 501 for GET /ingest/records[/{id}] and POST /ingest/fleetpulse under the right role. Both are real, DB-touching implementations now. Since this module is a plain TestClient unit test with no database, the "wrong role → 403" coverage for these paths stays (a 403 never reaches the DB-touching handler body); the "right role → real behaviour" coverage moved to backend/tests/integration/ingest/test_pipeline.py (T-B's owned path, testcontainers-backed).

Owns: backend/tests/unit/api/routers/plans_locks_assignments_stub_test.py (the ingest-specific list entries/test functions only — every other router's stub coverage in that file is untouched).

3. frontend/eslint.config.js — ignore core/api/generated/**

openapi-typescript's generated client (npm run api:gen, git-ignored, never hand-written) emits index-signature types ({ [key: string]: T }) for every additionalProperties/Dict-shaped schema. tseslint.configs.stylistic's @typescript-eslint/consistent-indexed-object-style flags every one of them — over 200 errors the moment backend/openapi.json actually exists to generate from, which is exactly what #17 is the first ticket to hit (ng lint was green before because no session had generated the client and then linted). Added an ignores: ['src/app/core/api/generated/**'] block — the generated file's style was never "ours" to fix per .gitignore's own comment ("never hand-written, never committed").

Owns: frontend/eslint.config.js (the added ignores block only).

No action needed

Already resolved in #17's PR — this issue is for traceability, same as #57/#66, not a blocker.

## Found while working #17 (T-B — ingest & projector) Three small fixes outside `backend/src/polaris/ingest/**`, `backend/src/polaris/projector/**`, `backend/src/polaris/worker/handlers/project_windows.py`, `backend/src/polaris/api/routers/ingest/**`, `backend/tests/**/{ingest,projector}/**`, `frontend/src/app/features/ingest/**`, `frontend/src/app/features/vehicles/components/heatmap*` (#17's owned paths), made directly in #17's PR rather than leaving the ticket blocked or broken, per the precedent in issues #52/#57/#66. Flagged here for traceability. ### 1. `backend/src/polaris/api/dto/ingest.py` — `FleetPulseDocument` shape corrected This file's own docstring already flagged the problem: `FleetPulseDocument`/`FleetPulseSite`/`FleetPulseTimeBlock` were declared with an **inferred** shape (PH1.7, issue #15 — no real sample existed yet) — flat `time_blocks` per site, a top-level `vehicle_id`, WKT `polygon` text. The real feed (confirmed against `docs/design_document.md` "The raw feed we receive" and the sample feed #14 built at `backend/src/polaris/seed/data/fleetpulse_sample.json`) has no top-level `vehicle_id` (it repeats per-site — a document is "per vehicle"), `observations_per_day` keyed by weekday name with a list of observation groups per weekday (Q4), and a nested GeoJSON `polygon.geometry`. **Fix** (already in #17's PR): the canonical schema now lives in `polaris.ingest.schema` (T-B's owned package — the ingest pipeline and its tests must not depend on `polaris.api`), and `polaris.api.dto.ingest` re-exports those same classes for the API boundary/OpenAPI, same pattern every other DTO in that module already follows. `backend/openapi.json` regenerated in the same PR (`docs/12-implementation-plan.md`'s PH1.7 row: "openapi.json regenerated only in PRs that change a DTO"). **Owns**: `backend/src/polaris/api/dto/ingest.py` (the `FleetPulseDocument`/`FleetPulseSite`/`FleetPulseTimeBlock`/`FleetPulseObservationGroup`/`FleetPulsePolygon`/`FleetPulseGeometry` re-exports only — `IngestResponse`/`IngestRecordRead` are unaffected), `backend/openapi.json`. ### 2. `backend/tests/unit/api/routers/plans_locks_assignments_stub_test.py` — two ingest endpoints are no longer `501` This PH1.7 shared stub-test module asserted `501` for `GET /ingest/records[/{id}]` and `POST /ingest/fleetpulse` under the right role. Both are real, DB-touching implementations now. Since this module is a plain `TestClient` unit test with no database, the "wrong role → 403" coverage for these paths stays (a 403 never reaches the DB-touching handler body); the "right role → real behaviour" coverage moved to `backend/tests/integration/ingest/test_pipeline.py` (T-B's owned path, `testcontainers`-backed). **Owns**: `backend/tests/unit/api/routers/plans_locks_assignments_stub_test.py` (the ingest-specific list entries/test functions only — every other router's stub coverage in that file is untouched). ### 3. `frontend/eslint.config.js` — ignore `core/api/generated/**` `openapi-typescript`'s generated client (`npm run api:gen`, git-ignored, never hand-written) emits index-signature types (`{ [key: string]: T }`) for every `additionalProperties`/`Dict`-shaped schema. `tseslint.configs.stylistic`'s `@typescript-eslint/consistent-indexed-object-style` flags every one of them — over 200 errors the moment `backend/openapi.json` actually exists to generate from, which is exactly what #17 is the first ticket to hit (`ng lint` was green before because no session had generated the client and then linted). Added an `ignores: ['src/app/core/api/generated/**']` block — the generated file's style was never "ours" to fix per `.gitignore`'s own comment ("never hand-written, never committed"). **Owns**: `frontend/eslint.config.js` (the added `ignores` block only). ## No action needed Already resolved in #17's PR — this issue is for traceability, same as #57/#66, not a blocker.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
patrick/Polaris#84
No description provided.