Skip to content

fix: materialize chapters from outlines instead of claiming all are generated - #291

Merged
andyhsu6 merged 1 commit into
mainfrom
fix/materialize-chapters-from-outlines
Nov 12, 2026
Merged

andyhsu6 merged 1 commit into
mainfrom
fix/materialize-chapters-from-outlines

Conversation

@andyhsu6

@andyhsu6 andyhsu6 commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

Closes #290.

Symptom

A project with 70 outlines and 58 chapter rows answered "所有章节都已生成内容" when the user tried to batch-generate, so the 12 outlined-but-unbuilt chapters were unreachable from the UI.

Cause

handleOpenBatchGenerate looked for the first chapter with empty content among existing chapter rows:

const firstIncompleteChapter = sortedChapters.find(ch => !ch.content || ch.content.trim() === '');
if (!firstIncompleteChapter) { message.info(t('toast.allGenerated')); return; }

An outline without a chapter row is invisible to that scan. Deleting chapters (rows removed, outlines kept as the plan) produces exactly this state; so does any import that created outlines without chapters. The backend had the same blind spot — stats reported only chapter count and max chapter number, and nothing could build a chapter from its outline.

Change

  • GET /project/{id}/stats now returns outline_total, max_outline_number and missing_from_outlines.
  • POST /project/{id}/materialize-outlines creates the missing chapter rows from their outlines: idempotent, never overwrites an existing chapter, keeps the outline link and its title, empty content, status=draft.
  • The batch entry point materialises the missing rows first and then continues with the normal flow, instead of stopping at the "all generated" toast.

Verification (real project)

stats before: {'total': 58, 'max_chapter_number': 58, 'outline_total': 70, 'missing_from_outlines': 12}
materialize:  {'created': [59..70], 'count': 12}
stats after:  {'total': 70, 'max_chapter_number': 70, 'outline_total': 70, 'missing_from_outlines': 0}

Test plan

cd backend && .venv/bin/python -m pytest tests/test_chapter_materialize_from_outlines.py -q   → 3 passed
cd backend && .venv/bin/python -m pytest tests/ -q -p no:cacheprovider                        → 1659 passed
cd frontend && npx vitest run                                                                 → 232 passed (28 files)
cd frontend && npm run build                                                                  → built

Tests cover the stats gap, idempotency, "never overwrites an existing chapter", and outlines without an order_index being skipped.

Desensitized per repository policy: no source text, titles or character names are included.

…enerated

The batch entry point only scanned existing chapter rows for an empty body, so a
project with 70 outlines but 58 chapter rows reported "all chapters generated"
and the 12 outlined-but-unbuilt chapters were unreachable.

- `GET /project/{id}/stats` now also reports `outline_total`,
  `max_outline_number` and `missing_from_outlines`.
- `POST /project/{id}/materialize-outlines` creates the missing chapter rows from
  their outlines (idempotent, never overwrites, keeps the outline link and title,
  empty content, draft status).
- The batch entry point materialises them first and then continues, instead of
  stopping at the "all generated" toast.

Verified on the affected project: stats reported 12 missing, materialisation
created chapters 59-70, stats then reported 0 missing and 70 total.

Refs #290
@andyhsu6 andyhsu6 added the status:in-progress Work started, PR is open label Nov 12, 2026
@andyhsu6
andyhsu6 merged commit 6241182 into main Nov 12, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:in-progress Work started, PR is open

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Chapter management says all chapters are generated while outlines remain without chapters

1 participant