Project
FarmersMarketplace — Backend (Categories / Schema Management)
Description
backend/src/routes/categories.js defines and immediately invokes ensureCategorySchema() at module load time:
async function ensureCategorySchema() {
const createSql = `CREATE TABLE IF NOT EXISTS categories (...)`;
const alterSql = `ALTER TABLE products ADD COLUMN category_id INTEGER REFERENCES categories(id)`;
try {
if (typeof db.exec === 'function') { await db.exec(createSql); await db.exec(alterSql); }
else if (typeof db.query === 'function') { await db.query(createSql); await db.query(alterSql); }
} catch {
// Ignore migration failures during test/bootstrap; route handlers will still work.
}
}
void ensureCategorySchema();
This entirely bypasses the versioned migration system documented in the README (backend/migrations/NNN_description.sql, tracked in a migrations table, applied via npm run migrate). Running schema DDL as a side effect of require()-ing a route file means: (1) the categories table's existence depends on whether this specific route module has been loaded at least once, not on a reproducible migration history; (2) the bare catch {} swallows every error, not just "already exists" — a genuine permissions error, a locked table, or a real syntax error on some future Postgres version would fail completely silently and the app would continue running with categories/category_id missing, later surfacing as confusing 500s deep inside route handlers instead of a clear startup failure.
Acceptance Criteria
Project
FarmersMarketplace — Backend (Categories / Schema Management)
Description
backend/src/routes/categories.jsdefines and immediately invokesensureCategorySchema()at module load time:This entirely bypasses the versioned migration system documented in the README (
backend/migrations/NNN_description.sql, tracked in amigrationstable, applied vianpm run migrate). Running schema DDL as a side effect ofrequire()-ing a route file means: (1) thecategoriestable's existence depends on whether this specific route module has been loaded at least once, not on a reproducible migration history; (2) the barecatch {}swallows every error, not just "already exists" — a genuine permissions error, a locked table, or a real syntax error on some future Postgres version would fail completely silently and the app would continue running withcategories/category_idmissing, later surfacing as confusing 500s deep inside route handlers instead of a clear startup failure.Acceptance Criteria
categoriestable andproducts.category_idcolumn are created via a proper file inbackend/migrations/, tracked like every other schema change.ensureCategorySchema()/void ensureCategorySchema()is removed fromcategories.js.catch {}pattern is not reintroduced — any migration failure surfaces at startup, consistent with howrunMigrations()alreadyprocess.exit(1)s on failure for the Postgres path indb/schema.js.