Repository navigation
feat: CSV shift import with preview and confirmation, weekly CSV export - #7
Merged
Merged
Conversation
Add a two-step shift import and a weekly CSV export:
- POST /api/shift-imports/preview parses the CSV body, validates every
row and stores a pending import; no shift is created.
- POST /api/shift-imports/{id}/confirm validates the stored file again
against the current schedule and, if every row is still valid,
creates all shifts in one transaction. An import is confirmed once
(conditional status update), and a file with the same content can be
confirmed once (filtered unique index on the content hash).
- GET /api/schedule/export returns the Monday-Sunday week in the import
format, so a week can be edited and imported again.
Row validation reports date, shift type, skill, employee and duplicate
problems and runs the ISchedulingRule implementations registered for
schedule generation, so imported assignments follow the same rules.
Values that spreadsheets run as formulas are refused on import and
neutralised on export. Demo reset now also clears import history.
Migration AddShiftImports only adds a table. 38 unit and 17 integration
tests cover parsing, validation, duplicates, confirmation, concurrency
guards and the export round trip.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add an "Import og eksport" dashboard page: choose a CSV file, review the preview with every row's errors and warnings in Danish, and save only by confirming. A schedule that changed after the preview shows the new result and saves nothing; an already imported file is refused. The page links to the CSV export of a chosen week and stacks the preview rows as cards on narrow screens. The fake API used by the tests now passes non-JSON request bodies through as text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Document the import format, validation, confirmation and export in the README, correct the test counts, add sample files with and without errors, screenshots from a real local run, and a project walkthrough. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Purpose
Let a planner import a week of shifts from a spreadsheet safely: preview every row before anything is saved, see row-level problems, confirm explicitly, and export a week back to CSV. Previously listed under "Future Improvements" as "CSV import/export demo".
Implementation
API
POST /api/shift-imports/preview(raw CSV body): parses, validates every row, stores a pending import, creates no shifts. Unreadable files →400withfileErrors.POST /api/shift-imports/{id}/confirm: re-validates the stored file against the current schedule; if still valid, inserts all shifts and marks the import confirmed in one transaction.409if already confirmed or no longer valid (with a fresh preview),404if unknown.GET /api/schedule/export?weekStart=: the Monday–Sunday week in the import format (round-trips).Validation (
ShiftImportValidator)ISchedulingRules (max assignments, same day, night→day, high load), with the saved schedule plus earlier file rows as planned shifts, just as schedule generation does.Consistency
UPDATE … WHERE Status = 'Pending'inside the insert transaction.ContentHashwhere confirmed.AddShiftImportsmigration is additive. Demo reset also clears import history.Frontend: new "Import og eksport" page (Danish), preview table with errors and warnings, confirm button enabled only when valid, export link; rows stack as cards at phone width.
Existing scheduling rules, endpoints and tests are unchanged. The only refactors:
ShiftEntity.FromDomain(shared mapping) and a shared test helper for the rule list.Testing
dotnet test: 101 unit (38 new) and 46 integration (17 new) passed.npm test13 (5 new),npm run lintclean,npm run buildOK.Pendingcondition, skipping re-validation, or removing the file-input reset each makes a test fail.shift-schedule-2026-05-11.csv.docs/images/import-*.png.Notes
docs/PROJECT_WALKTHROUGH.md.🤖 Generated with Claude Code