Skip to content

feat: module data-compatibility checks and smpy migrations prepare (#711) - #721

Merged
antosubash merged 5 commits into
mainfrom
feat/b34-data-compat
Oct 30, 2026
Merged

antosubash merged 5 commits into
mainfrom
feat/b34-data-compat

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Scaffolded hosts own their Alembic history, so data migrations shipped with framework modules never reached them. Hosts are now told when an upgrade is missing, and the CLI writes the revision for them.

Closes #711

What changed

  • Core hook ModuleBase.check_data_compatibility(db), returning DataCompatibilityIssue(upgrade_id, message, severity) (a frozen dataclass, so core gains no dependency). Checks are keyed by stable ids, not revision ids, so a host with its own equivalent port passes.
  • Two checks:
    • users.hashed_bearer_tokens_v1 (error): a token column too short for a SHA-256 digest, or any stored token that isn't a 64-character hex digest. This is one SELECT … LIMIT 1 over the whole table. An earlier version sampled rows, and the automated security review pointed out that plaintext rows behind hashed ones could slip through.
    • mail.settings_namespace_v1 (warning): system-scope users.mailer/SMTP keys that were never moved to mail.*.
  • Boot. Checks run in the hosting lifespan before settings hydration and module startup.
    • Behaviour change: an error refuses boot outside development; a warning only logs.
    • A never-migrated or partly migrated first run defers the check to the setup gate, which runs it once the schema is current and keeps the gate closed on an error. The setup wizard answers 409, not an opaque 500.
    • Modules without the hook open no session.
  • Doctor (make doctor, new smpy doctor) reports SM033.
    • A SQLite file that doesn't exist yet is skipped (doctor no longer creates an empty app.db).
    • An unreachable database is a warning; a crashing module check is an error.
    • smpy doctor without the framework installed prints a clear error.
  • smpy migrations prepare <upgrade-id> --head <label>@head writes a self-contained revision into the host's own migrations/versions from frozen recipes in the CLI package, and never applies it.
    • The token recipe deletes bearer tokens, then alters the columns, so clients sign in again; the upgrade guide says to stop old workers first.
    • The mail recipe moves keys with target-wins semantics.
    • A test ties the recipe ids to the module constants.
  • Role seeding stays a startup step (packaging: cap dependency ranges; ship module data migrations to scaffolded apps #600).
  • Docs: new docs/guide/upgrading.md, plus lifecycle, migrations, diagnostic codes (SM033), CLAUDE.md (hook list, what fails a production boot), the shipped simple-module-cli skill and the scaffold README.
  • Correction to the issue: a626b1c8d023 is not data-only. It deletes credentials and changes column types, which is why its recipe orders those steps.

Verification

  • make lint ✓ · make test-js ✓ · make test-py ✓ (6681 passed, 43 skipped) · make doctor ✓ (0 errors, 0 warnings)
  • New tests:
    • Boot: before hydration, refusing outside development, deferral on never-migrated and partly migrated first runs, gate replay and the wizard 409.
    • Checks: token column shapes, legacy rows (including plaintext rows behind 150 hashed ones), a missing table, and mail key states.
    • Doctor: missing file, unreachable database, crashing check.
    • CLI: generated revisions run on SQLite, --head handling, refusal to overwrite.
    • The Postgres recipe test (test_cli_prepare_data_postgres.py) runs in the Postgres workflow; I didn't run it locally.
  • Code review: three passes. Fixes include the boot condition, the token probe, doctor's error levels, the wizard 409 and the shipped skill. The remaining findings are rejected with reasons.

https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4

Setup wizard answers 409 on a required data upgrade; token check samples rows
and accepts any column wide enough for a digest; doctor skips a SQLite file
that doesn't exist and warns when the DB is unreachable; docs and CLI skill.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
…e token probe

Token probe checks the whole table (LIMIT 1) so plaintext rows behind hashed
ones are found; smpy doctor errors clearly without the framework installed;
shared alembic_host fixture; recipe ids tied to module constants; docs.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
Defer the boot check on a partly migrated first run; doctor fails on a
crashing module check and warns only when the DB is unreachable; modules
without the hook open no session.

Claude-Session: https://claude.ai/code/session_01M9neheZZEe3sVpDi2S3zT4
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Deploying simple-module-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: cf8ae56
Status: ✅  Deploy successful!
Preview URL: https://7c0389e7.simple-module-python.pages.dev
Branch Preview URL: https://feat-b34-data-compat.simple-module-python.pages.dev

View logs

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-10-30T23:42:59.548021Z cf8ae56 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@antosubash
antosubash merged commit 4ac779e into main Oct 30, 2026
17 checks passed
@antosubash
antosubash deleted the feat/b34-data-compat branch October 30, 2026 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

migrations: framework module data migrations don't reach scaffolded hosts

1 participant