docs(web/guides): correct migrations and seeding guides to verified 4.0.x behavior - #3094
Merged
Merged
Conversation
….0.x behavior Audit batch 2 (p1-14-migrations) corrections, all behavior-verified on CLI 4.0.3 + develop source: - migrate info/doctor have no common-port fallback — they require the project-bound port config like the write commands (#3080) - failed migrations currently exit 0; warn against gating CI on $? (#3081) - generator filename is <ts>_<NameAsTyped>.cfc verbatim from the local clock — the snake_case _table shape belongs to the model generator - columnName (singular) is an accepted alias; null is never accepted - remove the nonexistent 'limit=8 maps to BIGINT on MySQL' mapping; point at t.bigInteger() - NOW() fails on SQLite (default DB) and SQL Server; the portable spelling is CURRENT_TIMESTAMP; execute() has no parameters argument - replace nonexistent 'wheels generate seed [--all]' with 'wheels generate snippets seed-data' - mark 'wheels seed --generate' as non-functional (#3082) - document the seedOnce validation-failure outcome (rollback + non-zero exit as of 4.0.4; silent on 4.0.3) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Peter Amiri <peter@alurium.com>
Contributor
There was a problem hiding this comment.
Wheels Bot — Reviewer
TL;DR: This PR corrects the migrations and seeding guides to match verified 4.0.x behavior — port-fallback semantics for migrate info/doctor, exit-code caveat, generator filename shape, the limit→BIGINT myth, the columnName alias, NOW() vs CURRENT_TIMESTAMP portability, the nonexistent wheels generate seed command, the broken --generate flag, and the seedOnce validation-failure path. I independently verified every factual claim against the source on this branch; all nine check out, the three new tracking issues exist with matching titles, and the commit is commitlint-clean. Verdict: approve.
Correctness
Each correction verified against the code, not just the PR's citations:
migrate info/doctorport binding —runMigration()incli/lucli/Module.cfcroutes all actions (includinginfo/doctor) through$requireRunningServer(requireProjectConfig = true); there is no read-side common-port fallback. #3080 is open and matches ("migrate info/doctor refuse the common-port fallback…"). The old aside was wrong; the new text is right.- Exit-code caveat — #3081 is open and matches ("migrate latest/up/down exit 0 on a failed migration"). One-sentence caution is appropriately scoped.
- Generator filename —
generateMigration()builds"#timestamp#_#migrationName#.cfc"with the name verbatim (no snake_casing, no_tablesuffix), andHelpers.cfc:141generateMigrationTimestamp()usesnow()— local clock, confirming the "UTC-ish" removal. The contrast note is also right: the snake_case shape comes from the model/scaffold path (cli/lucli/services/Scaffold.cfc:287,className = "create_#tableName#_table"). limit=8→ BIGINT row — no such mapping exists.vendor/wheels/databaseAdapters/MySQL/mapsinteger→INT, andAbstract.cfc::typeToSQL()appends(#options.limit#)to the type name. Pointing readers att.bigInteger()is correct.columnNamesingular alias —TableDefinition.cfc:134($addTypedColumns) runs$combineArguments(combine = "columnNames,columnName", required = true)for every typed column helper, exactly as the new prose says;allowNullis the only nullable flag (vendor/wheels/migrator/CLAUDE.mddocuments both).execute()/NOW()—Migration.cfc:460ispublic void function execute(required string sql)— no parameters argument, so "parameter binding is unreliable" was indeed the wrong framing. No adapter rewritesNOW()(grep finds it only in two reference-doc examples), SQLite has noNOW()function, and T-SQL has no nativeNOW()—CURRENT_TIMESTAMPis the portable ANSI form across all five engines named. The{test:compile}tag on the example block is preserved.wheels generate seed— confirmed nonexistent: thegenerate()switch inModule.cfchas noseedcase and throwsWheels.InvalidArgumentswith exactlyUnknown generator type: seed(Module.cfc:578–581). The replacement path is accurate: theseed-datasnippets generator writesapp/snippets/seeds.cfmandapp/snippets/seeds-development.cfm(Module.cfc:3661–3673).wheels seed --generate— #3082 is open and its title matches the new prose verbatim ("non-functional — every model errors, zero rows created, reports success").- seedOnce third outcome —
vendor/wheels/Seeder.cfc:90–102rolls back and returnssuccess = falsewhentotalFailed > 0, matching the documented 4.0.4 behavior; the comment at Seeder.cfc:39 corroborates that commit-with-report was the prior (silent) behavior.
Docs
- Non-blocking, already disclosed in the PR body: root
CLAUDE.mdanti-pattern #5 still tells contributors to "useNOW()for database-agnostic dates (MySQL/PG/MSSQL/H2/SQLite)" and that "parameter binding inexecute()is unreliable" — both now contradicted by this guide (and byMigration.cfc:460). Deferring to the campaign's collateral sweep is reasonable, but until it lands the repo's own instructions steer agents toward seed SQL that fails on the defaultwheels newdatabase. Worth landing that sweep promptly. - Changelog fragment correctly omitted —
docs-type guide correction, not a user-facingfix/feat.
Commits
- Single commit
docs(web/guides): correct migrations and seeding guides to verified 4.0.x behavior— valid type, free-form scope, subject under 100 chars, not ALL-CAPS. Clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Guide-behavioral-audit batch 2, work item p1-14-migrations. Fixes the docs-affected findings in
basics/migrations.mdxandbasics/seeding.mdx. Every correction documents verified current behavior (CLI 4.0.3 + develop source) and cites the tracking issue where the underlying behavior is broken-but-unfixed.Corrections
basics/migrations.mdx
migrate info/migrate doctorport fallback (claimmig-08, both) — the aside claimed read-only commands "still probe common ports as a fallback". Verified false on 4.0.3 and develop: both route throughrequireProjectConfig=true(Module.cfc:3796-3804) and refuse withWheels.ServerNotRunningeven when the server runs on 8080. Rewritten to current behavior, citing #3080.mig-09/mig-28, group note) — added a one-sentence caution that a failed migration currently still exits0, so pipelines should not gate on$?alone (#3081).mig-11, docs-wrong) —wheels generate migration CreatePostsproduces<ts>_CreatePosts.cfcverbatim (Module.cfc:3094), never snake_cased or_table-suffixed; timestamp is the local clock, not "UTC-ish". Fixed the example and the Filename format section, with a contrast note that the snake_case shape comes from the model generator (wheels g model Post→<ts>_create_posts_table.cfc).limit=8→ BIGINT row (claimmig-17, docs-wrong) — no such mapping exists anywhere (MySQLinteger→INT;Abstract.typeToSQLappends(limit)as a display width). Row now points att.bigInteger().columnNamealias (sketch item 4) — softened "notcolumnNameandnull": singularcolumnNameIS accepted via$combineArgumentson every helper;nullremains never-accepted (allowNull).mig-26/mig-27, docs-wrong) — the guide's ownNOW()example fails on SQLite (no such function: NOW), the defaultwheels newdatabase, and SQL Server has no nativeNOW(); no adapter rewrites it. Example and prose now useCURRENT_TIMESTAMP(works on MySQL/PG/MSSQL/H2/SQLite). "Parameter binding in execute() is unreliable" corrected to the real contract:execute(required string sql)has no parameters argument at all (Migration.cfc:460).basics/seeding.mdx
wheels generate seedbullets (claimsseed-08/seed-09, docs-wrong) — both bullets removed: the command errors withUnknown generator type: seedon 4.0.3 and develop (noseedcase in the generate() switch), and no--allvariant exists. Replaced with the verified scaffold pathwheels generate snippets seed-dataplus an explicit "no such command" note.wheels seed --generate(claimseed-10, code-broken) — paragraph rewritten: the flag is currently non-functional (every model errors, zero rows created, success still reported), citing #3082.seed-11) — documented the validation-failure path: entry recorded as failed and the run rolls back; as of 4.0.4 withsuccess=falseand a non-zero exit (fix(seed): fail and roll back when seedOnce entries fail validation #2987), while 4.0.3 rolled back silently and still reported created counts.Verification
pnpm verify:docs src/content/docs/v4-0-0/basics/migrations.mdx src/content/docs/v4-0-0/basics/seeding.mdx→ 13 tagged blocks, 13 passed, exit 0Note: repo CLAUDE.md anti-pattern #5 repeats the NOW()/binding errors; the worktree's CLAUDE.md was already updated on develop for the generate-seed/snippets facts, and the CLAUDE.md NOW() fix is left to the campaign's collateral sweep (out of this PR's scoped files).
🤖 Generated with Claude Code