Harden anchor_id column to NOT NULL #127

Merged
forgejo_admin merged 1 commit from 124-anchor-id-not-null into main 2026-03-09 03:48:13 +00:00

Summary

Applies a NOT NULL constraint to the anchor_id column on the blocks table, hardening the DB schema to match the application-level invariant that all blocks have non-null anchor_ids.

Changes

  • src/pal_e_docs/models.py: Changed anchor_id from Mapped[str | None] / nullable=True to Mapped[str] / nullable=False
  • alembic/versions/m3h4i5j6k7l8_anchor_id_not_null.py: New migration that first verifies zero NULL anchor_ids exist (fails loudly if any found), then applies ALTER COLUMN anchor_id SET NOT NULL. Downgrade reverts to nullable. Depends on l2g3h4i5j6k7 (vector embeddings), which itself depends on k1f2g3h4i5j6 (the backfill + unique constraint from PR #120).
  • tests/test_blocks_compiled_pages.py: Fixed two test helpers that created Block instances without anchor_id -- now provide explicit values.

Test Plan

  • All 566 tests pass
  • ruff lint clean on all changed files
  • Migration safety check: upgrade will abort if any NULL anchor_ids remain (should never happen since PR #120 backfilled them all)

Review Checklist

  • Model change matches migration (both set NOT NULL)
  • Migration has safety check before applying constraint
  • Downgrade path works (reverts to nullable)
  • All tests pass (566/566)
  • ruff lint clean
  • No test creates Block with anchor_id=None
  • Plan: todo-anchor-id-not-null (traceability)
  • Forgejo issue: #124
  • Depends on: PR #120 (backfill + unique constraint), PR #125 (test seed cleanup)
## Summary Applies a NOT NULL constraint to the `anchor_id` column on the `blocks` table, hardening the DB schema to match the application-level invariant that all blocks have non-null anchor_ids. ## Changes - **`src/pal_e_docs/models.py`**: Changed `anchor_id` from `Mapped[str | None]` / `nullable=True` to `Mapped[str]` / `nullable=False` - **`alembic/versions/m3h4i5j6k7l8_anchor_id_not_null.py`**: New migration that first verifies zero NULL anchor_ids exist (fails loudly if any found), then applies `ALTER COLUMN anchor_id SET NOT NULL`. Downgrade reverts to nullable. Depends on `l2g3h4i5j6k7` (vector embeddings), which itself depends on `k1f2g3h4i5j6` (the backfill + unique constraint from PR #120). - **`tests/test_blocks_compiled_pages.py`**: Fixed two test helpers that created Block instances without `anchor_id` -- now provide explicit values. ## Test Plan - All 566 tests pass - ruff lint clean on all changed files - Migration safety check: upgrade will abort if any NULL anchor_ids remain (should never happen since PR #120 backfilled them all) ## Review Checklist - [x] Model change matches migration (both set NOT NULL) - [x] Migration has safety check before applying constraint - [x] Downgrade path works (reverts to nullable) - [x] All tests pass (566/566) - [x] ruff lint clean - [x] No test creates Block with anchor_id=None ## Related - Plan: `todo-anchor-id-not-null` (traceability) - Forgejo issue: #124 - Depends on: PR #120 (backfill + unique constraint), PR #125 (test seed cleanup)
Harden anchor_id column to NOT NULL
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
9acc2fb270
Add Alembic migration that verifies zero NULL anchor_ids exist then
applies ALTER COLUMN SET NOT NULL. Update Block model to match.
Fix two test helpers that created blocks without anchor_id.

Closes #124

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
forgejo_admin deleted branch 124-anchor-id-not-null 2026-03-09 03:48:13 +00:00
Sign in to join this conversation.
No description provided.