make a layout column refuse a non-layout
This commit is contained in:
@@ -1,6 +1,20 @@
|
||||
import { pgTable, serial, text, integer, timestamp, jsonb, uniqueIndex } from 'drizzle-orm/pg-core';
|
||||
import type { AnyPgColumn } from 'drizzle-orm/pg-core';
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { pgTable, serial, text, integer, timestamp, jsonb, uniqueIndex, check } from 'drizzle-orm/pg-core';
|
||||
import { users } from './auth';
|
||||
|
||||
/**
|
||||
* A `LayoutNode` is an object, and the whole write path to these columns is `unknown` — the PATCH body is
|
||||
* `Record<string, unknown>`, the query layer casts `as never` to satisfy drizzle, and jsonb accepts
|
||||
* anything. So the only place the rule can actually be enforced is here.
|
||||
*
|
||||
* `'[]'` reached both columns as a *default* and turned `normalizeLayout` into a white screen; the client
|
||||
* now refuses to hand over a non-object and the read omits one, but neither of those stops a bad value
|
||||
* being stored — they stop it being served. This does. NULL stays legal: it means "none stored", which is
|
||||
* the honest state of a dashboard created without a layout.
|
||||
*/
|
||||
const layoutIsObject = (column: AnyPgColumn) => sql`${column} IS NULL OR jsonb_typeof(${column}) = 'object'`;
|
||||
|
||||
export const dashboards = pgTable(
|
||||
'dashboards',
|
||||
{
|
||||
@@ -29,7 +43,10 @@ export const dashboards = pgTable(
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
},
|
||||
(table) => [uniqueIndex('uq_dashboards_user_id').on(table.userId, table.id)],
|
||||
(table) => [
|
||||
uniqueIndex('uq_dashboards_user_id').on(table.userId, table.id),
|
||||
check('ck_dashboards_layout_object', layoutIsObject(table.layout)),
|
||||
],
|
||||
);
|
||||
|
||||
export const screens = pgTable(
|
||||
@@ -46,7 +63,10 @@ export const screens = pgTable(
|
||||
hostTerminals: jsonb('host_terminals').notNull().default({}),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
},
|
||||
(table) => [uniqueIndex('uq_screens_user_name').on(table.userId, table.name)],
|
||||
(table) => [
|
||||
uniqueIndex('uq_screens_user_name').on(table.userId, table.name),
|
||||
check('ck_screens_layout_object', layoutIsObject(table.layout)),
|
||||
],
|
||||
);
|
||||
|
||||
export const dashboardDefaults = pgTable('dashboard_defaults', {
|
||||
|
||||
Reference in New Issue
Block a user