"Change template" answered "no slide layout" for 28 of the 41 presentations in production: the theme lived only inside the deck JSON, and a presentation whose deck reply failed twice and fell back to markdown slides had nowhere to keep one. The theme is a column now, written at generation and by the picker, and the markdown slide builder carries it to the same renderer field a designed deck uses. A deck's own theme field is kept in step. Articles are the only thing refused — they have no slides. A deck reply that fails to parse is logged with its first 240 characters, so the next "the reply was not a deck" can be read rather than guessed at. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
16 lines
748 B
JavaScript
16 lines
748 B
JavaScript
// A presentation's theme, whether or not the model produced a structured deck.
|
|
//
|
|
// The theme lived only inside the deck JSON, so a presentation that fell back
|
|
// to markdown slides — 28 of the 41 in production — had nowhere to keep one,
|
|
// and "change template" answered that it had no layout to change. The column
|
|
// holds the author's choice for every presentation; a deck's own theme field
|
|
// is kept in step with it.
|
|
|
|
exports.up = pgm => pgm.sql(`
|
|
ALTER TABLE user_resources ADD COLUMN IF NOT EXISTS theme TEXT;
|
|
UPDATE user_resources SET theme = deck->>'theme' WHERE theme IS NULL AND deck IS NOT NULL AND deck->>'theme' IS NOT NULL;
|
|
`);
|
|
|
|
exports.down = pgm => pgm.sql(`
|
|
ALTER TABLE user_resources DROP COLUMN IF EXISTS theme;
|
|
`);
|