> For the complete documentation index, see [llms.txt](https://klassdocs.gitbook.io/klassapp-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://klassdocs.gitbook.io/klassapp-documentation/docs/proposals/2026-10-06-mysql-migration-guard.md).

# Proposal: catch MySQL-only migration problems before deploy (not built)

Status: proposal, 2026-10-06. Follows the user\_preferences incident: the migration passed the sqlite test suite twice, then failed on staging MySQL twice (foreign key type mismatch 3780 because users.id is INT UNSIGNED while the new column was BIGINT; then a half-created table made the retry fail with 1050). It was fixed forward (#994, #995), and on 2026-10-06 the clean create path was proven on staging MySQL: the migration was rolled back alone, the drop was confirmed, a fresh migrate succeeded, and a second migrate was a no-op.

## What sqlite cannot see

* Foreign key column type compatibility (BIGINT vs INT UNSIGNED): sqlite ignores column types, MySQL rejects at constraint time; if the CREATE already ran, a failure leaves a half-created table behind.
* Unique-key length limits under utf8mb4 (191 vs 255), index prefix rules, reserved words, engine-specific defaults, date/datetime strictness.

## Proposed guard (small, CI only)

* A CI job, "MySQL migration smoke", that starts a mysql:8 service container and runs `php artisan migrate --force` from an empty database, then runs `php artisan migrate` again to prove the second run is a no-op. Full history is the honest check; `migrate --pretend` prints SQL without executing, so it would NOT have caught the 3780 case (the ALTER only fails when it runs).
* Scope: mark it required only for pull requests that touch database/migrations (path filter), so ordinary PRs stay fast.
* Keep it in GitHub Actions with the same PHP version as the app; budget about a minute or two per run.

Do not build until Rasta approves; it is one workflow file plus a service container.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://klassdocs.gitbook.io/klassapp-documentation/docs/proposals/2026-10-06-mysql-migration-guard.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
