feat: add reviewed municipal file intake - #1222
Merged
Merged
Conversation
9 tasks
klaasnicolaas
marked this pull request as draft
September 8, 2026 07:16
8 tasks
12 tasks
11 tasks
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
There are confirmed correctness/contract mismatches in validation and a nullable-field access that can lead to incorrect rejection or runtime errors.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR introduces a reviewed intake + publication flow for municipal “snapshot” JSON deliveries (starting with the Amsterdam E6a pilot), including validation, diff/review UI, and atomic publication into the existing parking_municipal_spaces table while preserving identity and protecting manual corrections.
Changes:
- Add municipal delivery ingestion, validation (including PostGIS geometry checks/derivation), review diffing, and transactional publication with concurrency safeguards.
- Add admin UI (Inertia/React) for listing deliveries, reviewing per-record changes/derivations, and approving/rejecting deliveries; add sidebar navigation and translations.
- Add dataset registration + terms confirmation flow, plus extensive Pest feature tests and supporting docs/migration/factories.
File summaries
| File | Description |
|---|---|
| tests/Feature/MunicipalImportTest.php | End-to-end feature coverage for intake, review, publication, conflicts, ordering, rollback, and geometry derivations. |
| routes/web.php | Adds admin routes for municipal import intake/review and dataset enable action. |
| resources/locales/backend/nl/sidebar.json | Adds sidebar label for municipal imports (NL). |
| resources/locales/backend/nl/municipal-imports.json | Adds NL translations for municipal import UI. |
| resources/locales/backend/en/sidebar.json | Adds sidebar label for municipal imports (EN). |
| resources/locales/backend/en/municipal-imports.json | Adds EN translations for municipal import UI. |
| resources/js/types/index.d.ts | Makes ParkingMunicipal.number nullable to reflect “unknown vs 0”. |
| resources/js/pages/backend/parking-municipal/columns.tsx | Renders unknown capacity explicitly in the municipal table. |
| resources/js/pages/backend/municipal-imports/show.tsx | New review screen to inspect diffs, derivations, and approve/reject deliveries. |
| resources/js/pages/backend/municipal-imports/index.tsx | New listing + dataset terms confirmation + upload screen. |
| resources/js/components/map/card-location-marker.tsx | Allows children overlays for showing polygons/derivations in the map card. |
| resources/js/components/app-sidebar.tsx | Adds admin navigation entry for municipal imports. |
| docs/product/trust-and-provenance.md | Links to data-foundation and import-contract direction docs. |
| docs/product/feature-inventory.md | Updates product sequencing notes for the data foundation work. |
| docs/product/data-foundation.md | New product/architecture direction document for the batch import approach. |
| docs/development/quality-checks.md | Documents how the municipal intake tests fit into quality checks. |
| docs/development/data-import-pilot.md | New Amsterdam pilot evidence + constraints + measured results. |
| docs/development/data-import-contract.md | New provisional single-file contract for the pilot intake. |
| docs/development/data-foundation-stack.md | New first-chain stack summary (core + producer responsibilities). |
| docs/development/data-foundation-delivery.md | New implementation/acceptance sequencing document for batch imports. |
| database/migrations/2026_09_14_065958_create_municipal_import_tables.php | Adds dataset source + municipal import tables and extends parking_municipal_spaces for imports. |
| database/factories/MunicipalImportFactory.php | Factory for municipal import records. |
| database/factories/DatasetSourceFactory.php | Factory for dataset source registration defaults. |
| CONTEXT.md | Adds terminology definitions for dataset sources, corrections, and publication decisions. |
| app/Support/MunicipalSnapshot.php | Implements JSON decoding, duplicate-key rejection, record validation, and PostGIS geometry assessment/derivation. |
| app/Services/MunicipalImportService.php | Implements intake, review diffing, publication decision enforcement, and atomic upsert publication. |
| app/Policies/MunicipalImportPolicy.php | Restricts municipal import actions to administrators. |
| app/Models/ParkingMunicipal.php | Hides source payload fields from serialization and adds casts for import-related JSON fields. |
| app/Models/MunicipalImport.php | New model for stored deliveries + review state. |
| app/Models/DatasetSource.php | New model for dataset registration/configuration fingerprinting. |
| app/Http/Requests/App/StoreMunicipalImportRequest.php | Validates upload size for staged deliveries. |
| app/Http/Controllers/Admin/MunicipalImportController.php | Admin endpoints for listing, staging uploads, reviewing deliveries, deciding publish/reject, and enabling dataset terms. |
| app/Console/Commands/RegisterAmsterdamDataset.php | Artisan command to register the Amsterdam pilot dataset with publication disabled. |
Review details
- Files reviewed: 32/33 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An administrator can upload the Amsterdam producer's JSON file, inspect source changes and approve or reject one delivery. Publication updates the existing municipal source table in one transaction, preserves identity/favorites/manual values, and never deletes missing records. The public map continues to show only markers.
Core retains the original source geometry. For an invalid polygon it proposes a separate
ST_MakeValidlinework derivation, retaining the result, reason and engine version. Only valid, non-empty Polygon/MultiPolygon results are admitted; collapsed or mixed geometries still fail the delivery. Review shows the original and derived shapes only in the administration screen. Publication requires explicit confirmation of all derivations, enforced in the service.ST_PointOnSurfacederives the marker; polygon parts never create extra parking records.Dataset registration starts with publication disabled and records a source-terms review. The bounded intake validates completeness, identity, geometry, scope and ordering. Duplicate bytes return the existing delivery; conflicting reuse, stale reviews, older deliveries and conflicting manual corrections block publication. Received claims, prior values and review decisions remain available for recovery. This replaces the former schema/Opis prototype and fixture corpus with one actual intake service and small behavioral tests. No Python runtime or cloud transport is added to core.
The review interface puts deliveries first, keeps source settings secondary, and uses compact expandable records with explicit geometry-review badges. Record pagination is available above and below the list; decisions follow the records with validation feedback in place. The responsive layout and review maps were checked at desktop and mobile widths; scrolling the review page no longer zooms the embedded map.
Amsterdam
source_updated_atmust be explicitly null until a source update meaning is established; empty strings and arrays are rejected. Missing previous import values block publication, and the publication step also guards its nullable baseline. Regression coverage includes the baseline disappearing after review.Validation:
composer ci:check: 285 backend tests / 1,190 assertions, 3 frontend tests, formatting, lint, TypeScript and production build passed locally. Geometry tests also ran under DDEV/PHP 8.4/PostGIS. Public-map response coverage confirms marker coordinates without source or derived polygons.odp-amsterdam==7.0.0/ disabled-parking#783 export: all 1,420 records admitted and published in the local test environment after review. All source claims were preserved and ten geometry derivations stored separately. Every derived marker is inside its usable geometry; source envelopes are unchanged.Operational boundary: the long combined probe exceeded the local 128 MiB PHP limit while holding several deliveries; the isolated full-source conflict probe passed with a 108 MiB peak. The 32 MiB file cap is not a measured capacity guarantee. Larger datasets and long-lived workers require memory/runtime measurements before activation. No process failure partially published a delivery.
The source-geometry blocker is addressed by the owner's reviewed-derivation decision. Source terms still need rechecking before public use. Production activation, existing-data reconciliation and bucket automation remain outside this PR. Migration rollback removes import audit/source linkage and is not data recovery.
Refs #1214, #1215 and NIPKaart/disabled-parking#774. No automatic issue closure. Execution, recovery and recorded source evidence are in
docs/development/data-import-contract.mdanddata-import-pilot.md.