Repository navigation
Conversation
Summary:
The /api/v1/solutions/{id}/export endpoint returned 501 Not Implemented
for format=ics with a stale 'StringIO bug' TODO. The
generate_ics_from_events helper in api/utils/calendar_utils already
produces well-formed VCALENDAR output; wire it into the export branch
so admins get a proper ICS download (matching the CSV path). The
per-person scope filter that already existed on the endpoint carries
over — a person: scope trims the event list before ICS assembly.
Changed files:
- api/routers/solutions.py: replace the 501 branch with an
event-per-VEVENT build via generate_ics_from_events, honouring the
existing scope filter and returning text/calendar with a
solution_<id>.ics Content-Disposition.
- tests/api/test_solution_export_ics.py: new test module — org-scope
happy path (two VEVENTs, right summaries, proper headers),
person-scope filter (only that person's events), empty-solution
guard, and unknown-solution 404.
Validation:
- poetry run pytest tests/api/ (336 passed)
- poetry run pytest tests/unit/ (350 passed, 21 skipped)
- poetry run pytest tests/contract/ (snapshot still matches — endpoint
shape unchanged)
- poetry run black api tests / poetry run ruff check api tests clean
- poetry run mypy api/utils api/core api/schemas (strict, clean)
Follow-ups:
- The endpoint still has no Depends(get_current_user) / admin gate;
that's a separate auth-hardening task (parallel to PR 4.5b/c/d for
calendar) and out of scope here.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018bCm1FtKXgqSdDdev7ZXHW
This was referenced Sep 9, 2026
Owner
Author
|
Superseded by #333, now merged to The replacement implementation is based on current Closing this stale draft without deleting its source branch. |
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.
Summary
POST /api/v1/solutions/{id}/exportreturned501 Not Implementedforformat: "ics"with a staleTODO: ICS export has StringIO bug – needs fixing.The
generate_ics_from_eventshelper inapi/utils/calendar_utilsalreadyproduces well-formed
VCALENDARoutput for the calendar router, so this PRwires it into the export branch and closes the gap. Admins can now download
solution_<id>.icsalongside the existing JSON / CSV / PDF formats.Changes
api/routers/solutions.py— replace the 501 branch with anevent-per-
VEVENTbuild viagenerate_ics_from_events. The per-personscope: "person:{id}"filter that was already applied to the workingassignmentslist carries over (a person scope trims the event list andstrips other people's names from assignment descriptions). Response is
text/calendar; charset=utf-8with asolution_<id>.icsContent-Disposition.tests/api/test_solution_export_ics.py— new test module:VEVENTs, rightSUMMARYvalues, headers)Validation
poetry run pytest tests/api/— 336 passedpoetry run pytest tests/unit/— 350 passed, 21 skippedpoetry run pytest tests/contract/— snapshot still matches (endpointshape is unchanged — FastAPI already declared the response as
application/jsonwith an empty schema; the dynamic media type isn'treflected in the OpenAPI doc so no snapshot refresh is needed)
poetry run black api testsandpoetry run ruff check api testscleanpoetry run mypy api/utils api/core api/schemas— strict, cleanFollow-ups
POST /solutions/{id}/exportstill has noDepends(get_current_user)/admin gate — a separate auth-hardening task (parallel to PR 4.5b/c/d for
calendar).
🤖 Generated with Claude Code
https://claude.ai/code/session_018bCm1FtKXgqSdDdev7ZXHW
Generated by Claude Code