- Catalog table ids (device_categories, port_types, cable_types, device_templates) switch from uuid to text so the existing stable, human-readable ids (pt-hdmi, dt-display, ...) survive the move instead of every diagram's references silently orphaning. - supabase/seed.sql is generated (scripts/generate-seed.mjs), not hand-written, so the seed data can't drift from the actual source of truth in domain/library.ts. Re-run the script after editing the built-in library. - Also committing ideas.md/organized-ideas.md, which have been driving every backend decision this whole project but were never actually checked in. RLS test suite re-run clean (23/23) after both the schema change and the seed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
63 lines
2.8 KiB
JavaScript
63 lines
2.8 KiB
JavaScript
// Generates supabase/seed.sql from src/domain/library.ts, so the public
|
|
// catalog seed data is derived directly from the source of truth instead of
|
|
// hand-transcribed (and risking drift/typos). Run via: node scripts/generate-seed.mjs
|
|
import { BUILT_IN_CABLE_TYPES, BUILT_IN_DEVICE_CATEGORIES, BUILT_IN_DEVICE_TEMPLATES, BUILT_IN_PORT_TYPES } from '../src/domain/library.ts'
|
|
import { writeFileSync } from 'node:fs'
|
|
import { randomUUID } from 'node:crypto'
|
|
|
|
function sqlString(value) {
|
|
if (value === undefined || value === null) return 'null'
|
|
return `'${String(value).replace(/'/g, "''")}'`
|
|
}
|
|
|
|
function sqlTextArray(values) {
|
|
if (!values || values.length === 0) return "'{}'"
|
|
return `'{${values.map((v) => `"${v.replace(/"/g, '\\"')}"`).join(',')}}'`
|
|
}
|
|
|
|
const lines = []
|
|
lines.push('-- Generated by scripts/generate-seed.mjs from src/domain/library.ts. Do not hand-edit —')
|
|
lines.push('-- re-run the script after changing the built-in library instead.')
|
|
lines.push('-- Seeds the public catalog: is_public = true, owner_id = null (system-owned).')
|
|
lines.push('')
|
|
|
|
lines.push('-- Device categories')
|
|
for (const c of BUILT_IN_DEVICE_CATEGORIES) {
|
|
lines.push(
|
|
`insert into public.device_categories (id, name, is_public) values (${sqlString(c.id)}, ${sqlString(c.name)}, true);`,
|
|
)
|
|
}
|
|
lines.push('')
|
|
|
|
lines.push('-- Port types')
|
|
for (const pt of BUILT_IN_PORT_TYPES) {
|
|
lines.push(
|
|
`insert into public.port_types (id, name, category, family, compatible_family_ids, max_connections, is_public) values (${sqlString(pt.id)}, ${sqlString(pt.name)}, ${sqlString(pt.category)}, ${sqlString(pt.family)}, ${sqlTextArray(pt.compatibleFamilyIds)}, ${pt.maxConnections ?? 'null'}, true);`,
|
|
)
|
|
}
|
|
lines.push('')
|
|
|
|
lines.push('-- Cable types')
|
|
for (const ct of BUILT_IN_CABLE_TYPES) {
|
|
lines.push(
|
|
`insert into public.cable_types (id, name, family, family2, unit, is_public) values (${sqlString(ct.id)}, ${sqlString(ct.name)}, ${sqlString(ct.family)}, ${sqlString(ct.family2)}, ${sqlString(ct.unit)}, true);`,
|
|
)
|
|
}
|
|
lines.push('')
|
|
|
|
lines.push('-- Device templates + their ports')
|
|
for (const dt of BUILT_IN_DEVICE_TEMPLATES) {
|
|
lines.push(
|
|
`insert into public.device_templates (id, name, category_id, is_public) values (${sqlString(dt.id)}, ${sqlString(dt.name)}, ${sqlString(dt.category)}, true);`,
|
|
)
|
|
for (const [index, port] of dt.ports.entries()) {
|
|
lines.push(
|
|
`insert into public.device_template_ports (id, device_template_id, name, direction, port_type_id, sort_order) values (${sqlString(randomUUID())}, ${sqlString(dt.id)}, ${sqlString(port.name)}, ${sqlString(port.direction)}, ${sqlString(port.portTypeId)}, ${index});`,
|
|
)
|
|
}
|
|
}
|
|
lines.push('')
|
|
|
|
writeFileSync(new URL('../supabase/seed.sql', import.meta.url), lines.join('\n') + '\n')
|
|
console.log(`Wrote supabase/seed.sql (${lines.length} lines)`)
|