import { type Kysely } from 'kysely'; /** * A derived index of scalar field values, so a listing can filter and sort on an item's own data. * * "Events whose start date is upcoming, soonest first" has no SQL path without this. `data` is TEXT * holding JSON, and the only reads into it anywhere in the codebase are `LIKE '%…%'` prefilters * verified afterwards in JS — fine for "does this blob mention this id", useless for a range or an * ordering. * * **A derived index rather than `json_extract`.** Reading the JSON in place would work on SQLite and * D1, but is an unindexed scan of every row unless an expression index exists per content type per field, which is the reason that survives in * the repo; it would also be an unindexed scan of every row unless an expression index existed per * content type per field. Plain columns sort and range-filter on all three dialects with no * branching and one index. * * **The precedent is `taxonomy_assignments`, deliberately.** Same shape, same rules: the authored * value in `content_items.data` stays the source of truth, this is rebuilt from it inside the same * atomic batch as the item write, and a revision restoring old `data` restores the index with it. * Storing values *only* here would lose them on a restore, exactly as storing tags only in the join * table would. * * **Nothing about status or visibility is denormalised in.** A listing joins back to * `content_items` and applies `visibleToPublic` there. Copying `status` or `publish_at` here would * mean a scheduled item became visible only when something happened to reindex it — and the whole * point of computing visibility on read is that it needs no sweep. * * Three value columns rather than one, because a type-correct comparison is the entire feature: * `'10' < '9'` is true as text and false as a number, and a date only sorts correctly as text * because ISO 8601 was designed that way. */ export declare function up(db: Kysely): Promise; export declare function down(db: Kysely): Promise;