Cody Schaefer 495d87dd72 Fix T8.6 migration: boolean default that Postgres rejects outright
NOT part of D13. Found while testing T10.3's migration against a real Postgres,
which could not be reached because the chain dies two revisions earlier.

a1b8c6d4e2f9 (T8.6 / D6, 190144c, Aug 19) creates material_items.active as:

    sa.Column('active', sa.Boolean(), nullable=False, server_default=sa.text('1'))

sa.text() emits raw SQL, so that is an integer literal, and Postgres refuses it:

    psycopg.errors.DatatypeMismatch: column "active" is of type boolean but
    default expression is of type integer

SQLite accepts 1 as a boolean without complaint, which is why this passed every
local test. The sibling migration e2a4c7d91b30 creates the identical column
correctly with sa.true() - so the two are inconsistent and the older one is
right. Fixed to match, which renders as `true` on both engines.

THIS IS VERY LIKELY THE PRODUCTION 502. The Dockerfile CMD is
`alembic upgrade head && exec gunicorn ...`, so a failed migration means
gunicorn is never reached: no API process, nginx cannot reach api:8000, and
every /api/ route returns 502 while the static site keeps serving normally.
That is exactly the observed symptom - login.html 200, /api/health 502 - and
this migration landed Aug 19, so the first deploy carrying it would be the
first to break. `docker compose logs api` should show the DatatypeMismatch
above.

Committed separately from the D13 work so it can be cherry-picked to main ahead
of this branch. It is a one-line fix to a shipped wave 8 migration and should
not wait for an auth wave to merge.

Verified on postgres:16-alpine (the image docker-compose uses): the full chain
from empty now reaches head.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 15:51:43 -05:00
Description
No description provided
8.9 MiB
Languages
Python 49.3%
JavaScript 32.6%
CSS 8.9%
HTML 8.7%
Shell 0.4%