feature: generate a spec-scoped PDF extract and post its link on linked issues #30

Merged
Gilles merged 1 commit from feat/spec-pdf-extract into master 2026-10-31 21:37:23 +00:00
Owner

Closes #29.

Third and last slice of the Forgejo issue <-> spec link feature, on top of thierryade/backend#26/#28 (both merged).

  • PdfExportJob.spec (FK, nullable, exclusive with project_version): a third export target alongside "this validated version" and "the project's current state" -- "this one spec's live subtree" (rooted at the spec's place). build_current_context() takes an optional root_place.
  • No new endpoint: reuses PdfExportJobViewSet/the existing Celery task (POST /api/pdf-export-jobs/ {"spec": id}).
  • Once a spec-scoped export finishes, every SpecVersionIssueLink on that spec gets it as its pdf_export_job and its confirmation comment is re-synced to fold in a "📄 Extrait PDF" download link -- edited into the same comment, never a separate one.
  • Manual trigger only, per the plan.

Test plan

  • manage.py test -- 204/204 passing (7 new)
  • pylint apps config -- 10.00/10
  • autopep8 --diff clean
  • bandit -r apps config -- 0 issues
  • Migrations apply cleanly on a fresh database

🤖 Generated with Claude Code

https://claude.ai/code/session_014HiJrn6J6vhyFfC2qyY4uh

Closes #29. Third and last slice of the Forgejo issue <-> spec link feature, on top of thierryade/backend#26/#28 (both merged). - `PdfExportJob.spec` (FK, nullable, exclusive with `project_version`): a third export target alongside "this validated version" and "the project's current state" -- "this one spec's live subtree" (rooted at the spec's place). `build_current_context()` takes an optional `root_place`. - No new endpoint: reuses `PdfExportJobViewSet`/the existing Celery task (`POST /api/pdf-export-jobs/ {"spec": id}`). - Once a spec-scoped export finishes, every `SpecVersionIssueLink` on that spec gets it as its `pdf_export_job` and its confirmation comment is re-synced to fold in a "📄 Extrait PDF" download link -- edited into the same comment, never a separate one. - Manual trigger only, per the plan. ## Test plan - [x] `manage.py test` -- 204/204 passing (7 new) - [x] `pylint apps config` -- 10.00/10 - [x] `autopep8 --diff` clean - [x] `bandit -r apps config` -- 0 issues - [x] Migrations apply cleanly on a fresh database --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_014HiJrn6J6vhyFfC2qyY4uh
feature: generate a spec-scoped PDF extract and post its link on linked issues
All checks were successful
ci / test (pull_request) Successful in 3m28s
ci / e2e (pull_request) Has been skipped
ci / docker (pull_request) Has been skipped
ci / deploy (pull_request) Has been skipped
11feecbc66
Closes #29.

PdfExportJob.spec (FK, nullable, exclusive with project_version): a
third export target alongside "this validated version" and "the
project's current state" -- "this one spec's live subtree" (rooted at
the spec's place, same shape as every other export, just lower in the
tree). build_current_context() takes an optional root_place to render
it, used from generate_pdf_export when job.spec_id is set.

No new endpoint: reuses PdfExportJobViewSet/the existing Celery task
(POST /api/pdf-export-jobs/ {"spec": id}).

Once a spec-scoped export finishes, every SpecVersionIssueLink on that
spec gets it as its new pdf_export_job (lazy "exports.PdfExportJob"
string FK on the specs side -- apps.exports already depends on
apps.specs, so a direct import back would be circular) and its
confirmation comment is re-synced to fold in a "📄 Extrait PDF"
download link, edited into the same comment the link feature already
posts, never a separate one.

Manual trigger only (no auto-regeneration on every validation), per
the plan agreed in chat.

## Test plan
- [x] `manage.py test` -- 204/204 passing (7 new)
- [x] `pylint apps config` -- 10.00/10
- [x] `autopep8 --diff` clean
- [x] `bandit -r apps config` -- 0 issues
- [x] Migrations apply cleanly on a fresh database (two new ones,
  exports and specs, each depending on the other's prior state -- no
  cycle, Django ordered them fine)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014HiJrn6J6vhyFfC2qyY4uh
Author
Owner
<!-- argus-link-bot:thierryade/backend --> 📊 [Rapports Argus pour cette PR](https://reports.stationmyr.net/thierryade/backend/pr/30)
Gilles merged commit f7eb22f958 into master 2026-10-31 21:37:23 +00:00
Gilles deleted branch feat/spec-pdf-extract 2026-10-31 21:37:24 +00:00
Sign in to join this conversation.
No description provided.