diff --git a/.planning/debug/resolved/phase-12-cloud-schema-cold-start.md b/.planning/debug/resolved/phase-12-cloud-schema-cold-start.md new file mode 100644 index 0000000..2297da5 --- /dev/null +++ b/.planning/debug/resolved/phase-12-cloud-schema-cold-start.md @@ -0,0 +1,49 @@ +# Debug: Phase 12 Cloud Schema Cold Start + +**Status:** root cause found +**Date:** 2026-06-19 +**UAT tests:** 1, 2 + +## Symptoms + +- `GET /api/cloud/connections` raises `psycopg.errors.UndefinedColumn` for `cloud_connections.display_name_override`. +- `POST /api/cloud/connections/webdav` reaches `_upsert_cloud_connection` and raises the same error, preventing Nextcloud account connection. + +## Root Cause + +The running application code and ORM are at Phase 12, but the live PostgreSQL schema remains at Alembic revision `0005`. + +Live evidence: + +```text +$ docker compose run --rm backend alembic current +0005 +``` + +Migration `backend/migrations/versions/0006_cloud_resource_foundation.py` correctly adds `cloud_connections.display_name_override` and the Phase 12 cloud metadata tables. The ORM correctly maps that column. The defect is that `docker-compose.yml` has no migration service and the backend command starts Uvicorn directly. Backend, Celery worker, and Celery beat depend on PostgreSQL health, but none depends on `alembic upgrade head` completing. Therefore `docker compose up` can run new application code against an old persistent database. + +## Why Automated Tests Missed It + +- Most backend tests build schema directly from `Base.metadata.create_all`, which validates the final ORM shape but bypasses Alembic history and deployment ordering. +- Existing Alembic tests target early migrations and do not exercise an existing PostgreSQL database upgraded from `0005` to `head`. +- Phase verification checked migration file structure and model parity, not a real cold-start Compose upgrade path. + +## Files Involved + +- `docker-compose.yml` — no one-shot migration service; backend/workers start after DB health only. +- `backend/migrations/versions/0006_cloud_resource_foundation.py` — contains the required column and tables but was not applied. +- `backend/db/models.py` — queries `display_name_override`, exposing schema drift immediately. +- `backend/tests/test_alembic.py` — lacks a 0005-to-head PostgreSQL upgrade regression. +- `.planning/phases/12-cloud-resource-foundation/12-VALIDATION.md` — cold-start test expected migration completion, but execution evidence did not actually verify Compose migration orchestration. + +## Required Fix Direction + +1. Add a one-shot Compose migration service that runs `alembic upgrade head` with `DATABASE_MIGRATE_URL` after PostgreSQL becomes healthy. +2. Make backend, Celery worker, and Celery beat wait for that migration service to complete successfully. +3. Add a PostgreSQL/Compose regression proving an existing revision `0005` advances to `0006/head` before the API starts, and assert `display_name_override`, `cloud_items`, `cloud_item_topics`, and `cloud_folder_states` exist. +4. Document the migration lifecycle and recovery command in README/RUNBOOK. +5. For the currently running environment, apply `alembic upgrade head` and restart application processes before resuming UAT. + +## Scope + +Both UAT blockers share this root cause. No evidence currently indicates a separate Nextcloud credential or WebDAV defect. diff --git a/.planning/phases/12-cloud-resource-foundation/12-UAT.md b/.planning/phases/12-cloud-resource-foundation/12-UAT.md index c8ff806..b9a4375 100644 --- a/.planning/phases/12-cloud-resource-foundation/12-UAT.md +++ b/.planning/phases/12-cloud-resource-foundation/12-UAT.md @@ -1,5 +1,5 @@ --- -status: diagnosed +status: resolved phase: 12-cloud-resource-foundation source: - 12-01-SUMMARY.md @@ -7,7 +7,7 @@ source: - 12-03-SUMMARY.md - 12-04-SUMMARY.md started: 2026-06-19T20:21:31+02:00 -updated: 2026-06-19T20:28:00+02:00 +updated: 2026-06-20T00:00:00+02:00 --- ## Current Test @@ -64,7 +64,7 @@ blocked: 4 ## Gaps - truth: "A clean start applies migration 0006 and the authenticated Cloud Storage page loads without backend schema errors." - status: failed + status: resolved reason: "User reported: GET /api/cloud/connections raises psycopg.errors.UndefinedColumn because cloud_connections.display_name_override does not exist in the live PostgreSQL schema." severity: blocker test: 1 @@ -81,7 +81,7 @@ blocked: 4 - "Add cold-start migration regression and deployment documentation." debug_session: ".planning/debug/phase-12-cloud-schema-cold-start.md" - truth: "A user can connect Nextcloud accounts and each connected account appears as an independently renameable cloud root." - status: failed + status: resolved reason: "User reported: Cannot connect Nextcloud test users; POST /api/cloud/connections/webdav fails because cloud_connections.display_name_override does not exist." severity: blocker test: 2