pdf-quiz-generator/backend/alembic/versions/b8c9d0e1f2a3_fix_question_quiz_fk.py
Daniel 76848c5947 fix: the reading browser counted the wrong thing, and the hover card fled
The number beside a folder in Topic reading was a question count while
the browser lists articles, so "Hyperinflammatory Sepsis 4" meant four
questions and opened onto no reading at all. It counts what it opens
now, rolled up over the subtree, and a branch with nothing to read in it
is not offered — a folder with a number on it is a promise.

The hover card could not be reached. Its body was pointer-events: none,
on the idea that a hint should not sit between the reader and the link —
but the card is offset below the link and never covered it, while the
pointer travelling down to Split view crossed a body it could not enter,
so no mouseenter fired and the hide timer closed it on the way. The card
takes the pointer now, with a bridge across the gap.

And clicking the words opens the card rather than the article. A
cross-reference is read mid-sentence, and navigating away to find out
whether it was worth following is the thing that breaks the thread; the
card's two controls — beside what you are reading, or a tab for later —
are how you go. That also gives touch a route, where hover has none.
Modified and middle clicks are still the browser's.

The listing sent content and sections for all 331 articles, 214KB of
prose a list never renders. It sends what a list needs, which is 21KB.

The footer sat wherever the content stopped, so a page still loading put
it halfway up the screen with background below it. The shell is a column
the height of the window.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TqXevQJhxFrM7jJg82cgZN
2026-09-11 21:24:04 +02:00

38 lines
1.5 KiB
Python

"""Deleting a quiz must not destroy the questions extracted for it.
`questions.quiz_id` was created ON DELETE CASCADE, while the model has long
declared SET NULL and its comment says the column is informational — "which
quiz this question was originally extracted for" — with real membership held
in `quiz_question_links`. The database was the one being obeyed, so removing a
quiz silently erased every question it had produced, along with their attempts,
exam membership, media and article links, and straight past the trash that was
built to make exactly that impossible.
The model's intent is the correct one and is what this applies.
`quizzes.user_id` is the opposite case: the database cascades and the model
said nothing, and here the database is right — deleting an account is
documented as removing what it made. The model is corrected to match rather
than the data.
Revision ID: b8c9d0e1f2a3
Revises: a7b8c9d0e1f2
"""
from alembic import op
revision = "b8c9d0e1f2a3"
down_revision = "a7b8c9d0e1f2"
branch_labels = None
depends_on = None
def upgrade() -> None:
op.drop_constraint("questions_quiz_id_fkey", "questions", type_="foreignkey")
op.create_foreign_key("questions_quiz_id_fkey", "questions", "quizzes",
["quiz_id"], ["id"], ondelete="SET NULL")
def downgrade() -> None:
op.drop_constraint("questions_quiz_id_fkey", "questions", type_="foreignkey")
op.create_foreign_key("questions_quiz_id_fkey", "questions", "quizzes",
["quiz_id"], ["id"], ondelete="CASCADE")