| name | duc-schema-changes |
| description | Use this skill whenever implementing type, field, or schema changes across the duc monorepo. Triggers when the user asks to add a new field, change a type, rename a property, or propagate any data model change across the duc codebase. Also triggers when the user mentions duc.sql, schema migrations, DataState, or any of the cross-language duc type files (ducrs, ducjs, ducpy). Always use this skill before touching duc type files — it tells you exactly which files to edit and in what order.
|
duc Schema Changes
When any data model change is needed in the duc monorepo, changes must be propagated across three language targets in a consistent order, followed by builds and (if needed) SQL migrations.
Step 0 — Check what changed
Before writing any code, review the schema to understand the change:
duc/schema/duc.sql
If changes may already be staged and not on the duc.sql, check git diff --staged first to understand the changes.
Step 1 — Rust (ducrs)
Edit these three files in order:
| File | Purpose |
|---|
duc/packages/ducrs/src/types.rs | Struct/enum definitions |
duc/packages/ducrs/src/parse.rs | Deserialization logic |
duc/packages/ducrs/src/serialize.rs | Serialization logic |
Pattern: Add new fields to the struct in types.rs, then add matching parse/serialize arms in the other two. Keep field names consistent with the SQL schema.
Step 2 — TypeScript (ducjs)
Edit these files:
| File | Purpose |
|---|
duc/packages/ducjs/src/types/index.ts | Top-level type exports |
duc/packages/ducjs/src/types/elements/index.ts | Element-specific types |
duc/packages/ducjs/src/restore/restoreDataState.ts | DataState restore logic |
Also check for other restore files in duc/packages/ducjs/src/restore/ that may reference the changed type — grep for the field/type name and update any that appear.
Step 3 — Python (ducpy)
Edit these files:
| File | Purpose |
|---|
duc/packages/ducpy/src/ducpy/classes/DataStateClass.py | DataState class definition |
duc/packages/ducpy/src/ducpy/classes/ElementsClass.py | Elements class definition |
Step 4 — Build & Test
Run from the monorepo root using the scripts defined in duc/package.json:
cd duc
cat package.json | grep -A 30 '"scripts"'
Then run the relevant commands. Run for all three packages that were touched.
Step 5 — SQL Migrations (if needed)
If the schema itself changed (new columns, tables, type modifications), create a migration file:
- Find the latest migration in
duc/schema/migrations/ — migrations are numbered sequentially
- Create a new file on top of the last one, e.g.
3000015_to_3000016.sql
- Make destructive/rebuild migrations transactional and backfill data before dropping source tables
- Test the migration against a database created with the previous schema; verify payload bytes/lengths, row counts,
PRAGMA foreign_key_check, and the final PRAGMA user_version
- If existing readers cannot open the new file format or a published API is removed, evaluate a major schema version rather than a patch increment
- When promoting a prerelease schema to a major version, retain its natural sequential migration, add a final explicit major-version bridge, and scan checked-in fixtures for every represented
user_version
ls -1 duc/schema/migrations/ | sort | tail -5
Checklist