From 3f2d30117f4940bd89bff24054c22878a9352d9f Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:59:12 -0800 Subject: [PATCH 01/10] refactor!: technical debt and switch to remote functions (#179) * refactor!: technical debt and switch to remote functions * lint From 0dff1df9851d4c58c656ea22674088c5511ed662 Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Sun, 22 Feb 2026 12:03:53 -0800 Subject: [PATCH 02/10] fix: add missing import --- apps/web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/package.json b/apps/web/package.json index 800099c1..5b6494f2 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -60,4 +60,4 @@ "marked": "^15.0.12", "sanitize-html": "^2.17.0" } -} +} \ No newline at end of file From 525db3bb7ffe20992360d045724c91a550bebde7 Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Sun, 22 Feb 2026 12:06:25 -0800 Subject: [PATCH 03/10] fix: add missing dependencies --- apps/web/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/package.json b/apps/web/package.json index 5b6494f2..800099c1 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -60,4 +60,4 @@ "marked": "^15.0.12", "sanitize-html": "^2.17.0" } -} \ No newline at end of file +} From 13cd2ed0c823f90269582e2b576a2650c31aaada Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Sun, 22 Feb 2026 12:11:36 -0800 Subject: [PATCH 04/10] fix: async local storage compatiability error From ab9903ded5a1ee6ee5351d9df4a615ff3250a4e0 Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Sat, 31 Jan 2026 23:42:57 -0800 Subject: [PATCH 05/10] create schema for dms --- packages/db/src/relations.ts | 23 +++++++++ .../db/src/schema/documentManagementSystem.ts | 51 +++++++++++++++++++ packages/db/src/schema/index.ts | 1 + 3 files changed, 75 insertions(+) create mode 100644 packages/db/src/schema/documentManagementSystem.ts diff --git a/packages/db/src/relations.ts b/packages/db/src/relations.ts index 2f451411..924db93c 100644 --- a/packages/db/src/relations.ts +++ b/packages/db/src/relations.ts @@ -2,6 +2,29 @@ import { defineRelations } from "drizzle-orm"; import * as schema from "./schema"; export const relations = defineRelations(schema, (r) => ({ + dmsGroups: { + documents: r.many.dmsDocuments({ + from: r.dmsDocuments.groupId, + to: r.dmsGroups.id, + }), + }, + dmsAssets: { + document: r.one.dmsDocuments({ + from: r.dmsAssets.documentId, + to: r.dmsDocuments.id, + optional: false, + }), + }, + dmsDocuments: { + group: r.one.dmsGroups({ + from: r.dmsDocuments.groupId, + to: r.dmsGroups.id, + }), + assets: r.many.dmsAssets({ + from: r.dmsAssets.documentId, + to: r.dmsDocuments.id, + }), + }, users: { flags: r.many.flags({ from: r.users.cid.through(r.usersToFlags.userId), diff --git a/packages/db/src/schema/documentManagementSystem.ts b/packages/db/src/schema/documentManagementSystem.ts new file mode 100644 index 00000000..ba506998 --- /dev/null +++ b/packages/db/src/schema/documentManagementSystem.ts @@ -0,0 +1,51 @@ +import { type InferSelectModel } from "drizzle-orm"; +import { index, int, sqliteTable, text } from "drizzle-orm/sqlite-core"; + +export const dmsDocuments = sqliteTable( + "dms_documents", + { + id: text() + .primaryKey() + .$defaultFn(() => crypto.randomUUID()), + required: int({ mode: "boolean" }).notNull(), + name: text().notNull(), + description: text(), + groupId: text().references(() => dmsGroups.id, { onDelete: "set null" }), + short: text(), + }, + (table) => [index("dms_documents_group_id_idx").on(table.groupId)], +); +export type DmsDocument = InferSelectModel; + +export const dmsGroups = sqliteTable("dms_groups", { + id: text() + .primaryKey() + .$defaultFn(() => crypto.randomUUID()), + name: text().notNull(), + sort: int().notNull().default(99), +}); +export type DmsGroup = InferSelectModel; + +export const dmsAssets = sqliteTable( + "dms_assets", + { + id: text() + .primaryKey() + .$defaultFn(() => crypto.randomUUID()), + documentId: text() + .notNull() + .references(() => dmsDocuments.id, { onDelete: "cascade" }), + version: text().notNull(), + effectiveDate: int({ mode: "timestamp" }) + .notNull() + .$defaultFn(() => new Date()), + expiryDate: int({ mode: "timestamp" }), + public: int({ mode: "boolean" }).notNull().default(false), + url: text().notNull(), + }, + (table) => [ + index("dms_assets_document_id_idx").on(table.documentId), + index("dms_assets_effective_date_idx").on(table.effectiveDate), + ], +); +export type DmsAsset = InferSelectModel; diff --git a/packages/db/src/schema/index.ts b/packages/db/src/schema/index.ts index deab0110..aaf4b457 100644 --- a/packages/db/src/schema/index.ts +++ b/packages/db/src/schema/index.ts @@ -18,3 +18,4 @@ export * from "./waitlist"; export * from "./moodle"; export * from "./notifications"; export * from "./jobs"; +export * from "./documentManagementSystem"; From 5abd546d44509a7233c4c62ca844492004e0688d Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Sun, 22 Feb 2026 18:08:08 -0800 Subject: [PATCH 06/10] create dms models --- apps/overseer/src/lib/remote/dms.remote.ts | 47 ++ apps/overseer/src/routes/+layout.svelte | 6 + apps/overseer/src/routes/a/dms/+page.svelte | 26 + .../routes/a/dms/document/create/+page.svelte | 63 +++ apps/overseer/src/routes/a/files/+page.svelte | 6 +- packages/common/src/models/dms.ts | 510 ++++++++++++++++++ packages/common/src/models/index.ts | 1 + packages/db/src/relations.ts | 8 +- 8 files changed, 662 insertions(+), 5 deletions(-) create mode 100644 apps/overseer/src/lib/remote/dms.remote.ts create mode 100644 apps/overseer/src/routes/a/dms/+page.svelte create mode 100644 apps/overseer/src/routes/a/dms/document/create/+page.svelte create mode 100644 packages/common/src/models/dms.ts diff --git a/apps/overseer/src/lib/remote/dms.remote.ts b/apps/overseer/src/lib/remote/dms.remote.ts new file mode 100644 index 00000000..077675c0 --- /dev/null +++ b/apps/overseer/src/lib/remote/dms.remote.ts @@ -0,0 +1,47 @@ +import { getRequestEvent, query } from '$app/server'; +import { db } from '$lib/db'; +import { User } from '@czqm/common'; +import { error } from '@sveltejs/kit'; +import { asc } from 'drizzle-orm'; + +export const getDocuments = query(async () => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user) { + throw error(401, 'Unauthorized'); + } + + const documents = await db.query.dmsDocuments.findMany({ + with: { + assets: true, + group: true + } + }); + + return documents; +}); + +export const getGroups = query(async () => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user) { + throw error(401, 'Unauthorized'); + } + + const groups = await db.query.dmsGroups.findMany({ + with: { + documents: true + }, + orderBy: (group) => [asc(group.sort)] + }); + + return groups; +}); diff --git a/apps/overseer/src/routes/+layout.svelte b/apps/overseer/src/routes/+layout.svelte index 4c71d1e3..b2773ac8 100644 --- a/apps/overseer/src/routes/+layout.svelte +++ b/apps/overseer/src/routes/+layout.svelte @@ -40,6 +40,9 @@
  • News
  • Resources
  • File Upload
  • + {#if data.user?.flags.some( (f) => ['admin', 'web', 'cheif', 'deputy', 'chief-instructor'].includes(f.name) )} +
  • Documents
  • + {/if} {/if} @@ -58,6 +61,9 @@
  • News
  • Resources
  • File Upload
  • + {#if data.user?.flags.some( (f) => ['admin', 'web', 'cheif', 'deputy', 'chief-instructor'].includes(f.name) )} +
  • Documents
  • + {/if} {/if} diff --git a/apps/overseer/src/routes/a/dms/+page.svelte b/apps/overseer/src/routes/a/dms/+page.svelte new file mode 100644 index 00000000..94550b31 --- /dev/null +++ b/apps/overseer/src/routes/a/dms/+page.svelte @@ -0,0 +1,26 @@ +
    +

    Document Management System

    +
    + +
    +

    Documents

    + New Document +
    + + + + + + + + + + + + + + + + +
    TitlePublicEffective DateExpiry DateActions
    PLACEHOLDER
    +
    diff --git a/apps/overseer/src/routes/a/dms/document/create/+page.svelte b/apps/overseer/src/routes/a/dms/document/create/+page.svelte new file mode 100644 index 00000000..a416f26c --- /dev/null +++ b/apps/overseer/src/routes/a/dms/document/create/+page.svelte @@ -0,0 +1,63 @@ + + +
    +

    DMS - Create New Document

    + {'<'} Return to DMS +
    + +
    +

    + To create a new document, please fill out all required fields below. Please note: updated + versions of pre-existing documents shall be created as assets on the existing document +

    +

    + A "short link" is a simple, short, direct link to the most recent asset of the document + intended to be used as a publically distributed access point to the document. +

    +
    + +
    +
    + Document Name + +
    + +
    + Description + +
    + +
    + Acknowledgement Required + +
    + +
    + Short Link + + Optional +
    + +
    + Document Group + +
    +
    +
    diff --git a/apps/overseer/src/routes/a/files/+page.svelte b/apps/overseer/src/routes/a/files/+page.svelte index b729eae1..1e3d6319 100644 --- a/apps/overseer/src/routes/a/files/+page.svelte +++ b/apps/overseer/src/routes/a/files/+page.svelte @@ -12,7 +12,11 @@

    File Upload

    - +

    + This file upload method should only be used when the Document Management System cannot be used. +

    diff --git a/packages/common/src/models/dms.ts b/packages/common/src/models/dms.ts new file mode 100644 index 00000000..bbfffaf0 --- /dev/null +++ b/packages/common/src/models/dms.ts @@ -0,0 +1,510 @@ +import { dmsAssets, dmsDocuments, dmsGroups } from "@czqm/db/schema"; +import { asc, desc, eq } from "drizzle-orm"; +import type { DB } from "../db"; + +type CreateDmsDocumentInput = { + required: boolean; + name: string; + description?: string | null; + groupId?: string | null; + short?: string | null; +}; + +type UpdateDmsDocumentInput = { + required: boolean; + name: string; + description?: string | null; + groupId?: string | null; + short?: string | null; +}; + +type CreateDmsGroupInput = { + name: string; + sort?: number; +}; + +type UpdateDmsGroupInput = { + name: string; + sort: number; +}; + +type CreateDmsAssetInput = { + documentId: string; + version: string; + effectiveDate?: Date; + expiryDate?: Date | null; + public?: boolean; + url: string; +}; + +type UpdateDmsAssetInput = { + documentId: string; + version: string; + effectiveDate: Date; + expiryDate?: Date | null; + public: boolean; + url: string; +}; + +export class DmsDocument { + id: string; + required: boolean; + name: string; + description: string | null; + groupId: string | null; + short: string | null; + assets: DmsAsset[]; + group: DmsGroup | null; + private db: DB; + + constructor( + input: { + id: string; + required: boolean; + name: string; + description: string | null; + groupId: string | null; + short: string | null; + assets?: DmsAsset[]; + group?: DmsGroup | null; + }, + db: DB, + ) { + this.id = input.id; + this.required = input.required; + this.name = input.name; + this.description = input.description; + this.groupId = input.groupId; + this.short = input.short; + this.assets = input.assets ?? []; + this.group = input.group ?? null; + this.db = db; + } + + static async fromId(db: DB, id: string): Promise { + const document = await db.query.dmsDocuments.findFirst({ + where: { id }, + with: { + assets: { + orderBy: (asset) => [desc(asset.effectiveDate)], + }, + group: true, + }, + }); + + if (!document) { + throw new Error("DMS document not found"); + } + + const dmsDocument = new DmsDocument( + { + id: document.id, + required: document.required, + name: document.name, + description: document.description, + groupId: document.groupId, + short: document.short, + }, + db, + ); + + dmsDocument.assets = document.assets.map( + (asset) => + new DmsAsset( + { + id: asset.id, + documentId: asset.documentId, + version: asset.version, + effectiveDate: asset.effectiveDate, + expiryDate: asset.expiryDate, + public: asset.public, + url: asset.url, + document: dmsDocument, + }, + db, + ), + ); + + if (document.group) { + dmsDocument.group = new DmsGroup( + { + id: document.group.id, + name: document.group.name, + sort: document.group.sort, + documents: [dmsDocument], + }, + db, + ); + } + + return dmsDocument; + } + + static async fetchAll(db: DB): Promise { + const documents = await db.query.dmsDocuments.findMany({ + with: { + assets: { + orderBy: (asset) => [desc(asset.effectiveDate)], + }, + group: true, + }, + orderBy: (document) => [asc(document.name)], + }); + + return documents.map((document) => { + const dmsDocument = new DmsDocument( + { + id: document.id, + required: document.required, + name: document.name, + description: document.description, + groupId: document.groupId, + short: document.short, + }, + db, + ); + + dmsDocument.assets = document.assets.map( + (asset) => + new DmsAsset( + { + id: asset.id, + documentId: asset.documentId, + version: asset.version, + effectiveDate: asset.effectiveDate, + expiryDate: asset.expiryDate, + public: asset.public, + url: asset.url, + document: dmsDocument, + }, + db, + ), + ); + + if (document.group) { + dmsDocument.group = new DmsGroup( + { + id: document.group.id, + name: document.group.name, + sort: document.group.sort, + documents: [dmsDocument], + }, + db, + ); + } + + return dmsDocument; + }); + } + + static async create(db: DB, data: CreateDmsDocumentInput) { + return await db.insert(dmsDocuments).values({ + required: data.required, + name: data.name, + description: data.description ?? null, + groupId: data.groupId ?? null, + short: data.short ?? null, + }); + } + + static async update(db: DB, id: string, data: UpdateDmsDocumentInput) { + return await db + .update(dmsDocuments) + .set({ + required: data.required, + name: data.name, + description: data.description ?? null, + groupId: data.groupId ?? null, + short: data.short ?? null, + }) + .where(eq(dmsDocuments.id, id)); + } + + static async remove(db: DB, id: string) { + return await db.delete(dmsDocuments).where(eq(dmsDocuments.id, id)); + } +} + +export class DmsGroup { + id: string; + name: string; + sort: number; + documents: DmsDocument[]; + private db: DB; + + constructor( + input: { + id: string; + name: string; + sort: number; + documents?: DmsDocument[]; + }, + db: DB, + ) { + this.id = input.id; + this.name = input.name; + this.sort = input.sort; + this.documents = input.documents ?? []; + this.db = db; + } + + static async fromId(db: DB, id: string): Promise { + const group = await db.query.dmsGroups.findFirst({ + where: { id }, + with: { + documents: { + orderBy: (document) => [asc(document.name)], + }, + }, + }); + + if (!group) { + throw new Error("DMS group not found"); + } + + const dmsGroup = new DmsGroup( + { + id: group.id, + name: group.name, + sort: group.sort, + }, + db, + ); + + dmsGroup.documents = group.documents.map( + (document) => + new DmsDocument( + { + id: document.id, + required: document.required, + name: document.name, + description: document.description, + groupId: document.groupId, + short: document.short, + group: dmsGroup, + }, + db, + ), + ); + + return dmsGroup; + } + + static async fetchAll(db: DB): Promise { + const groups = await db.query.dmsGroups.findMany({ + with: { + documents: { + orderBy: (document) => [asc(document.name)], + }, + }, + orderBy: (group) => [asc(group.sort)], + }); + + return groups.map((group) => { + const dmsGroup = new DmsGroup( + { + id: group.id, + name: group.name, + sort: group.sort, + }, + db, + ); + + dmsGroup.documents = group.documents.map( + (document) => + new DmsDocument( + { + id: document.id, + required: document.required, + name: document.name, + description: document.description, + groupId: document.groupId, + short: document.short, + group: dmsGroup, + }, + db, + ), + ); + + return dmsGroup; + }); + } + + static async create(db: DB, data: CreateDmsGroupInput) { + return await db.insert(dmsGroups).values({ + name: data.name, + sort: data.sort ?? 99, + }); + } + + static async update(db: DB, id: string, data: UpdateDmsGroupInput) { + return await db + .update(dmsGroups) + .set({ + name: data.name, + sort: data.sort, + }) + .where(eq(dmsGroups.id, id)); + } + + static async remove(db: DB, id: string) { + return await db.delete(dmsGroups).where(eq(dmsGroups.id, id)); + } +} + +export class DmsAsset { + id: string; + documentId: string; + version: string; + effectiveDate: Date; + expiryDate: Date | null; + public: boolean; + url: string; + document: DmsDocument; + private db: DB; + + constructor( + input: { + id: string; + documentId: string; + version: string; + effectiveDate: Date; + expiryDate: Date | null; + public: boolean; + url: string; + document: DmsDocument; + }, + db: DB, + ) { + this.id = input.id; + this.documentId = input.documentId; + this.version = input.version; + this.effectiveDate = input.effectiveDate; + this.expiryDate = input.expiryDate; + this.public = input.public; + this.url = input.url; + this.document = input.document; + this.db = db; + } + + static async fromId(db: DB, id: string): Promise { + const asset = await db.query.dmsAssets.findFirst({ + where: { id }, + with: { + document: true, + }, + }); + + if (!asset) { + throw new Error("DMS asset not found"); + } + + const document = new DmsDocument( + { + id: asset.document.id, + required: asset.document.required, + name: asset.document.name, + description: asset.document.description, + groupId: asset.document.groupId, + short: asset.document.short, + }, + db, + ); + + const dmsAsset = new DmsAsset( + { + id: asset.id, + documentId: asset.documentId, + version: asset.version, + effectiveDate: asset.effectiveDate, + expiryDate: asset.expiryDate, + public: asset.public, + url: asset.url, + document, + }, + db, + ); + + document.assets = [dmsAsset]; + + return dmsAsset; + } + + static async fetchAll(db: DB): Promise { + const assets = await db.query.dmsAssets.findMany({ + with: { + document: true, + }, + orderBy: (asset) => [desc(asset.effectiveDate)], + }); + + return assets.map((asset) => { + const document = new DmsDocument( + { + id: asset.document.id, + required: asset.document.required, + name: asset.document.name, + description: asset.document.description, + groupId: asset.document.groupId, + short: asset.document.short, + }, + db, + ); + + const dmsAsset = new DmsAsset( + { + id: asset.id, + documentId: asset.documentId, + version: asset.version, + effectiveDate: asset.effectiveDate, + expiryDate: asset.expiryDate, + public: asset.public, + url: asset.url, + document, + }, + db, + ); + + document.assets = [dmsAsset]; + + return dmsAsset; + }); + } + + static async fetchByDocumentId( + db: DB, + documentId: string, + ): Promise { + const document = await DmsDocument.fromId(db, documentId); + return document.assets; + } + + static async create(db: DB, data: CreateDmsAssetInput) { + return await db.insert(dmsAssets).values({ + documentId: data.documentId, + version: data.version, + effectiveDate: data.effectiveDate ?? new Date(), + expiryDate: data.expiryDate ?? null, + public: data.public ?? false, + url: data.url, + }); + } + + static async update(db: DB, id: string, data: UpdateDmsAssetInput) { + return await db + .update(dmsAssets) + .set({ + documentId: data.documentId, + version: data.version, + effectiveDate: data.effectiveDate, + expiryDate: data.expiryDate ?? null, + public: data.public, + url: data.url, + }) + .where(eq(dmsAssets.id, id)); + } + + static async remove(db: DB, id: string) { + return await db.delete(dmsAssets).where(eq(dmsAssets.id, id)); + } +} diff --git a/packages/common/src/models/index.ts b/packages/common/src/models/index.ts index 3d85fb99..95925ad2 100644 --- a/packages/common/src/models/index.ts +++ b/packages/common/src/models/index.ts @@ -4,3 +4,4 @@ export * from "./soloEndorsements"; export * from "./event"; export * from "./newsArticle"; export * from "./userWrite"; +export * from "./dms"; diff --git a/packages/db/src/relations.ts b/packages/db/src/relations.ts index 924db93c..8826823f 100644 --- a/packages/db/src/relations.ts +++ b/packages/db/src/relations.ts @@ -4,8 +4,8 @@ import * as schema from "./schema"; export const relations = defineRelations(schema, (r) => ({ dmsGroups: { documents: r.many.dmsDocuments({ - from: r.dmsDocuments.groupId, - to: r.dmsGroups.id, + from: r.dmsGroups.id, + to: r.dmsDocuments.groupId, }), }, dmsAssets: { @@ -21,8 +21,8 @@ export const relations = defineRelations(schema, (r) => ({ to: r.dmsGroups.id, }), assets: r.many.dmsAssets({ - from: r.dmsAssets.documentId, - to: r.dmsDocuments.id, + from: r.dmsDocuments.id, + to: r.dmsAssets.documentId, }), }, users: { From 6043e815f2ca2263c147b60864bfac7edc34ebd1 Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:50:49 -0700 Subject: [PATCH 07/10] add group management --- apps/overseer/src/lib/remote/dms.remote.ts | 170 +- apps/overseer/src/routes/a/dms/+page.svelte | 214 +- .../routes/a/dms/document/create/+page.svelte | 63 - .../overseer/src/routes/a/dms/groups/+page.ts | 6 + .../src/routes/a/dms/groups/[id]/+page.svelte | 70 + .../src/routes/a/dms/new-group/+page.svelte | 46 + packages/common/src/models/dms.ts | 139 +- packages/common/src/transport.ts | 89 +- .../migration.sql | 79 + .../snapshot.json | 3019 ++++++++++++++++ .../migration.sql | 12 + .../snapshot.json | 3028 ++++++++++++++++ .../migration.sql | 1 + .../snapshot.json | 3038 +++++++++++++++++ .../db/src/schema/documentManagementSystem.ts | 2 + pnpm-lock.yaml | 30 +- 16 files changed, 9853 insertions(+), 153 deletions(-) delete mode 100644 apps/overseer/src/routes/a/dms/document/create/+page.svelte create mode 100644 apps/overseer/src/routes/a/dms/groups/+page.ts create mode 100644 apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte create mode 100644 apps/overseer/src/routes/a/dms/new-group/+page.svelte create mode 100644 packages/db/migrations/20260223022946_unknown_infant_terrible/migration.sql create mode 100644 packages/db/migrations/20260223022946_unknown_infant_terrible/snapshot.json create mode 100644 packages/db/migrations/20260223023434_productive_frightful_four/migration.sql create mode 100644 packages/db/migrations/20260223023434_productive_frightful_four/snapshot.json create mode 100644 packages/db/migrations/20260224020012_deep_moira_mactaggert/migration.sql create mode 100644 packages/db/migrations/20260224020012_deep_moira_mactaggert/snapshot.json diff --git a/apps/overseer/src/lib/remote/dms.remote.ts b/apps/overseer/src/lib/remote/dms.remote.ts index 077675c0..2ee67e2e 100644 --- a/apps/overseer/src/lib/remote/dms.remote.ts +++ b/apps/overseer/src/lib/remote/dms.remote.ts @@ -1,8 +1,8 @@ -import { getRequestEvent, query } from '$app/server'; +import { command, form, getRequestEvent, query } from '$app/server'; import { db } from '$lib/db'; -import { User } from '@czqm/common'; -import { error } from '@sveltejs/kit'; -import { asc } from 'drizzle-orm'; +import { DmsDocument, DmsGroup, User } from '@czqm/common'; +import { error, invalid, redirect } from '@sveltejs/kit'; +import { type } from 'arktype'; export const getDocuments = query(async () => { const event = getRequestEvent(); @@ -15,17 +15,12 @@ export const getDocuments = query(async () => { throw error(401, 'Unauthorized'); } - const documents = await db.query.dmsDocuments.findMany({ - with: { - assets: true, - group: true - } - }); + const documents = await DmsDocument.fetchAll(db); return documents; }); -export const getGroups = query(async () => { +export const getDocumentsByGroup = query(type('string'), async (groupId) => { const event = getRequestEvent(); const user = await User.resolveAuthenticatedUser(db, { cid: event.locals.user?.cid, @@ -36,12 +31,155 @@ export const getGroups = query(async () => { throw error(401, 'Unauthorized'); } - const groups = await db.query.dmsGroups.findMany({ - with: { - documents: true - }, - orderBy: (group) => [asc(group.sort)] + const group = await DmsGroup.fromId(db, groupId); + + if (!group) { + throw error(404, 'Group not found'); + } + + return group.documents; +}); + +export const getGroups = query(async () => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') }); + if (!user) { + throw error(401, 'Unauthorized'); + } + + const groups = await DmsGroup.fetchAll(db); + return groups; }); + +export const getGroup = query(type('string'), async (id) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user) { + throw error(401, 'Unauthorized'); + } + + const group = await DmsGroup.fromId(db, id); + + if (!group) { + throw error(404, 'Group not found'); + } + + return group; +}); + +export const createGroup = form( + type({ + name: 'string', + slug: type.string.pipe((str) => str.toLowerCase().trim()), + sort: 'number?' + }), + async ({ name, slug, sort = 99 }, issue) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user || !user.hasFlag(['admin', 'staff'])) { + throw error(401, 'Unauthorized'); + } + + if (!/^[a-z0-9-]+$/.test(slug)) { + invalid(issue.slug('Slug can only contain lowercase letters, numbers, and dashes')); + } + + if (!(0 <= sort && sort <= 99)) { + invalid(issue.sort('Sort must be a number between 0 and 99')); + } + + const existingGroup = await DmsGroup.fromSlug(db, slug); + + if (existingGroup) { + invalid(issue.slug(`Slug is already in use by another group`)); + } + + const newGroup = await DmsGroup.create(db, { + name, + slug, + sort + }); + + return redirect(303, `/a/dms/groups/${newGroup.id}`); + } +); + +export const deleteGroup = command(type('string'), async (id) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user || !user.hasFlag(['admin', 'staff'])) { + throw error(401, 'Unauthorized'); + } + + const group = await DmsGroup.fromId(db, id); + + if (!group) { + throw error(404, 'Group not found'); + } + + await group.delete(); + + getGroups().refresh(); + getDocuments().refresh(); + + return; +}); + +export const editGroup = form( + type({ + id: 'string', + name: 'string', + slug: type.string.pipe((str) => str.toLowerCase().trim()), + sort: 'number' + }), + async ({ id, name, slug, sort }, issue) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user || !user.hasFlag(['admin', 'staff'])) { + throw error(401, 'Unauthorized'); + } + + if (!/^[a-z0-9-]+$/.test(slug)) { + invalid(issue.slug('Slug can only contain lowercase letters, numbers, and dashes')); + } + + if (!(0 <= sort && sort <= 99)) { + invalid(issue.sort('Sort must be a number between 0 and 99')); + } + + await DmsGroup.update(db, id, { + name, + sort, + slug + }); + + return { + ok: true, + id, + name, + slug, + sort + }; + } +); diff --git a/apps/overseer/src/routes/a/dms/+page.svelte b/apps/overseer/src/routes/a/dms/+page.svelte index 94550b31..2e0b118e 100644 --- a/apps/overseer/src/routes/a/dms/+page.svelte +++ b/apps/overseer/src/routes/a/dms/+page.svelte @@ -1,26 +1,196 @@ -
    -

    Document Management System

    -
    + + +
    +
    +

    CZQM Document Management System

    +
    +
    +

    + Welcome to the CZQM Document management system! Please select a group of documents to + continue or create a new group. +

    + Create New Group +
    + +
    + {#await getGroups()} +

    Loading groups...

    + {:then groups} + + + + + + + + + + + + + {#each groups as { name, documents, slug, sort, id }, index (id)} + + + + + + + + {/each} + +
    #Group NameSlug# of DocumentsActions
    {index + 1}{name}/{slug}{documents.length} + + + Manage Documents +
    + {/await} +
    - - - - - - - - - - - - - - - -
    TitlePublicEffective DateExpiry DateActions
    PLACEHOLDER
    + + + + + + + +
    diff --git a/apps/overseer/src/routes/a/dms/document/create/+page.svelte b/apps/overseer/src/routes/a/dms/document/create/+page.svelte deleted file mode 100644 index a416f26c..00000000 --- a/apps/overseer/src/routes/a/dms/document/create/+page.svelte +++ /dev/null @@ -1,63 +0,0 @@ - - -
    -

    DMS - Create New Document

    - {'<'} Return to DMS -
    - -
    -

    - To create a new document, please fill out all required fields below. Please note: updated - versions of pre-existing documents shall be created as assets on the existing document -

    -

    - A "short link" is a simple, short, direct link to the most recent asset of the document - intended to be used as a publically distributed access point to the document. -

    -
    - -
    -
    - Document Name - -
    - -
    - Description - -
    - -
    - Acknowledgement Required - -
    - -
    - Short Link - - Optional -
    - -
    - Document Group - -
    -
    -
    diff --git a/apps/overseer/src/routes/a/dms/groups/+page.ts b/apps/overseer/src/routes/a/dms/groups/+page.ts new file mode 100644 index 00000000..d5d783e6 --- /dev/null +++ b/apps/overseer/src/routes/a/dms/groups/+page.ts @@ -0,0 +1,6 @@ +import { redirect } from '@sveltejs/kit'; +import type { PageLoad } from './$types'; + +export const load = (async () => { + redirect(303, '/a/dms'); +}) satisfies PageLoad; diff --git a/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte b/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte new file mode 100644 index 00000000..bade0bcf --- /dev/null +++ b/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte @@ -0,0 +1,70 @@ + + +
    +
    + {#await getGroup(id)} +

    DMS Group: Loading Group

    + {:then group} +

    DMS Group: {group.name} ( /{group.slug} )

    + {:catch error} +

    Error loading group: {error.message}

    + {/await} + + + Back to DMS + +
    + +
    + {#await getDocumentsByGroup(id)} +

    Loading documents...

    + {:then documents} + + + + + + + + + + + + {#if documents.length === 0} + + + + {:else} + {#each documents as { id: documentId, name, short, required, sort }, index (documentId)} + + + + + + + + {/each} + {/if} + +
    #Document NameShortRequiredSort
    + No documents found for this group. +
    {index + 1}{name}{short ?? '-'}{required ? 'Yes' : 'No'}{sort}
    + {:catch error} +

    Error loading documents: {error.message}

    + {/await} +
    +
    +
    diff --git a/apps/overseer/src/routes/a/dms/new-group/+page.svelte b/apps/overseer/src/routes/a/dms/new-group/+page.svelte new file mode 100644 index 00000000..c0c3f2a4 --- /dev/null +++ b/apps/overseer/src/routes/a/dms/new-group/+page.svelte @@ -0,0 +1,46 @@ + + +
    +
    +

    Create New Group

    + + Back to DMS + +
    + +
    +
    + Group Name + +
    + +
    + Slug + +

    + {createGroup.fields.slug + .issues() + ?.map((issue) => issue.message) + .join(' ')} +

    +
    + +
    + Sort Order + +

    + {createGroup.fields.sort + .issues() + ?.map((issue) => issue.message) + .join(' ')} +

    +

    Groups are sorted from 1-99 by this value.

    +
    + + +
    +
    +
    diff --git a/packages/common/src/models/dms.ts b/packages/common/src/models/dms.ts index bbfffaf0..5d69543f 100644 --- a/packages/common/src/models/dms.ts +++ b/packages/common/src/models/dms.ts @@ -8,6 +8,7 @@ type CreateDmsDocumentInput = { description?: string | null; groupId?: string | null; short?: string | null; + sort?: number; }; type UpdateDmsDocumentInput = { @@ -16,16 +17,19 @@ type UpdateDmsDocumentInput = { description?: string | null; groupId?: string | null; short?: string | null; + sort?: number; }; type CreateDmsGroupInput = { name: string; sort?: number; + slug: string; }; type UpdateDmsGroupInput = { name: string; sort: number; + slug: string; }; type CreateDmsAssetInput = { @@ -55,6 +59,7 @@ export class DmsDocument { short: string | null; assets: DmsAsset[]; group: DmsGroup | null; + sort: number; private db: DB; constructor( @@ -67,6 +72,7 @@ export class DmsDocument { short: string | null; assets?: DmsAsset[]; group?: DmsGroup | null; + sort?: number; }, db: DB, ) { @@ -78,6 +84,7 @@ export class DmsDocument { this.short = input.short; this.assets = input.assets ?? []; this.group = input.group ?? null; + this.sort = input.sort ?? 99; this.db = db; } @@ -104,6 +111,7 @@ export class DmsDocument { description: document.description, groupId: document.groupId, short: document.short, + sort: document.sort ?? 99, }, db, ); @@ -132,6 +140,7 @@ export class DmsDocument { name: document.group.name, sort: document.group.sort, documents: [dmsDocument], + slug: document.group.slug, }, db, ); @@ -148,7 +157,7 @@ export class DmsDocument { }, group: true, }, - orderBy: (document) => [asc(document.name)], + orderBy: (document) => [asc(document.sort), asc(document.name)], }); return documents.map((document) => { @@ -160,6 +169,7 @@ export class DmsDocument { description: document.description, groupId: document.groupId, short: document.short, + sort: document.sort ?? 99, }, db, ); @@ -188,6 +198,7 @@ export class DmsDocument { name: document.group.name, sort: document.group.sort, documents: [dmsDocument], + slug: document.group.slug, }, db, ); @@ -198,13 +209,21 @@ export class DmsDocument { } static async create(db: DB, data: CreateDmsDocumentInput) { - return await db.insert(dmsDocuments).values({ - required: data.required, - name: data.name, - description: data.description ?? null, - groupId: data.groupId ?? null, - short: data.short ?? null, - }); + const doc = ( + await db + .insert(dmsDocuments) + .values({ + required: data.required, + name: data.name, + description: data.description ?? null, + groupId: data.groupId ?? null, + short: data.short ?? null, + sort: data.sort ?? 99, + }) + .returning({ id: dmsDocuments.id }) + )[0]; + + return (await DmsDocument.fromId(db, doc.id)) as DmsDocument; } static async update(db: DB, id: string, data: UpdateDmsDocumentInput) { @@ -216,6 +235,7 @@ export class DmsDocument { description: data.description ?? null, groupId: data.groupId ?? null, short: data.short ?? null, + sort: data.sort ?? 99, }) .where(eq(dmsDocuments.id, id)); } @@ -229,6 +249,7 @@ export class DmsGroup { id: string; name: string; sort: number; + slug: string; documents: DmsDocument[]; private db: DB; @@ -238,6 +259,7 @@ export class DmsGroup { name: string; sort: number; documents?: DmsDocument[]; + slug: string; }, db: DB, ) { @@ -245,10 +267,11 @@ export class DmsGroup { this.name = input.name; this.sort = input.sort; this.documents = input.documents ?? []; + this.slug = input.slug; this.db = db; } - static async fromId(db: DB, id: string): Promise { + static async fromId(db: DB, id: string): Promise { const group = await db.query.dmsGroups.findFirst({ where: { id }, with: { @@ -259,7 +282,7 @@ export class DmsGroup { }); if (!group) { - throw new Error("DMS group not found"); + return null; } const dmsGroup = new DmsGroup( @@ -267,6 +290,7 @@ export class DmsGroup { id: group.id, name: group.name, sort: group.sort, + slug: group.slug, }, db, ); @@ -290,14 +314,26 @@ export class DmsGroup { return dmsGroup; } + static async fromSlug(db: DB, slug: string): Promise { + const group = await db.query.dmsGroups.findFirst({ + where: { slug }, + }); + + if (!group) { + return null; + } + + return DmsGroup.fromId(db, group.id); + } + static async fetchAll(db: DB): Promise { const groups = await db.query.dmsGroups.findMany({ with: { documents: { - orderBy: (document) => [asc(document.name)], + orderBy: (document) => [asc(document.sort), asc(document.name)], }, }, - orderBy: (group) => [asc(group.sort)], + orderBy: (group) => [asc(group.sort), asc(group.name)], }); return groups.map((group) => { @@ -306,6 +342,7 @@ export class DmsGroup { id: group.id, name: group.name, sort: group.sort, + slug: group.slug, }, db, ); @@ -331,10 +368,18 @@ export class DmsGroup { } static async create(db: DB, data: CreateDmsGroupInput) { - return await db.insert(dmsGroups).values({ - name: data.name, - sort: data.sort ?? 99, - }); + const group = ( + await db + .insert(dmsGroups) + .values({ + name: data.name, + sort: data.sort ?? 99, + slug: data.slug, + }) + .returning({ id: dmsGroups.id }) + )[0]; + + return (await DmsGroup.fromId(db, group.id)) as DmsGroup; } static async update(db: DB, id: string, data: UpdateDmsGroupInput) { @@ -343,6 +388,7 @@ export class DmsGroup { .set({ name: data.name, sort: data.sort, + slug: data.slug, }) .where(eq(dmsGroups.id, id)); } @@ -350,6 +396,10 @@ export class DmsGroup { static async remove(db: DB, id: string) { return await db.delete(dmsGroups).where(eq(dmsGroups.id, id)); } + + async delete() { + return await DmsGroup.remove(this.db, this.id); + } } export class DmsAsset { @@ -480,14 +530,21 @@ export class DmsAsset { } static async create(db: DB, data: CreateDmsAssetInput) { - return await db.insert(dmsAssets).values({ - documentId: data.documentId, - version: data.version, - effectiveDate: data.effectiveDate ?? new Date(), - expiryDate: data.expiryDate ?? null, - public: data.public ?? false, - url: data.url, - }); + const asset = ( + await db + .insert(dmsAssets) + .values({ + documentId: data.documentId, + version: data.version, + effectiveDate: data.effectiveDate ?? new Date(), + expiryDate: data.expiryDate ?? null, + public: data.public ?? false, + url: data.url, + }) + .returning({ id: dmsAssets.id }) + )[0]; + + return (await DmsAsset.fromId(db, asset.id)) as DmsAsset; } static async update(db: DB, id: string, data: UpdateDmsAssetInput) { @@ -508,3 +565,37 @@ export class DmsAsset { return await db.delete(dmsAssets).where(eq(dmsAssets.id, id)); } } + +export class DMS { + static Document = DmsDocument; + static Group = DmsGroup; + static Asset = DmsAsset; + + groups: DmsGroup[]; + documents: DmsDocument[]; + assets: DmsAsset[]; + + private db: DB; + + constructor( + db: DB, + groups: DmsGroup[], + documents: DmsDocument[], + assets: DmsAsset[], + ) { + this.groups = groups; + this.documents = documents; + this.assets = assets; + this.db = db; + } + + static async fetch(db: DB) { + const [groups, documents, assets] = await Promise.all([ + DmsGroup.fetchAll(db), + DmsDocument.fetchAll(db), + DmsAsset.fetchAll(db), + ]); + + return new DMS(db, groups, documents, assets); + } +} diff --git a/packages/common/src/transport.ts b/packages/common/src/transport.ts index 252d32fe..77b47e22 100644 --- a/packages/common/src/transport.ts +++ b/packages/common/src/transport.ts @@ -1,4 +1,11 @@ -import { User, UserHours, type SoloEndorsementWithPosition } from "./models"; +import { + DmsAsset, + DmsDocument, + DmsGroup, + User, + UserHours, + type SoloEndorsementWithPosition, +} from "./models"; import type { Flag } from "@czqm/db/schema"; const parse = (value: unknown) => JSON.parse(value as string); @@ -86,4 +93,84 @@ export const sharedTransport = { }, decode: parse, }, + + DmsDocument: { + encode: (document: unknown) => { + if (!(document instanceof DmsDocument)) return; + + return JSON.stringify({ + id: document.id, + required: document.required, + name: document.name, + description: document.description, + groupId: document.groupId, + short: document.short, + assets: document.assets.map((asset) => ({ + id: asset.id, + documentId: asset.documentId, + version: asset.version, + effectiveDate: asset.effectiveDate, + expiryDate: asset.expiryDate, + public: asset.public, + url: asset.url, + })), + group: document.group + ? { + id: document.group.id, + name: document.group.name, + sort: document.group.sort, + slug: document.group.slug, + } + : null, + }); + }, + decode: parse, + }, + + DmsGroup: { + encode: (group: unknown) => { + if (!(group instanceof DmsGroup)) return; + + return JSON.stringify({ + id: group.id, + name: group.name, + sort: group.sort, + slug: group.slug, + documents: group.documents.map((document) => ({ + id: document.id, + required: document.required, + name: document.name, + description: document.description, + groupId: document.groupId, + short: document.short, + })), + }); + }, + decode: parse, + }, + + DmsAsset: { + encode: (asset: unknown) => { + if (!(asset instanceof DmsAsset)) return; + + return JSON.stringify({ + id: asset.id, + documentId: asset.documentId, + version: asset.version, + effectiveDate: asset.effectiveDate, + expiryDate: asset.expiryDate, + public: asset.public, + url: asset.url, + document: { + id: asset.document.id, + required: asset.document.required, + name: asset.document.name, + description: asset.document.description, + groupId: asset.document.groupId, + short: asset.document.short, + }, + }); + }, + decode: parse, + }, }; diff --git a/packages/db/migrations/20260223022946_unknown_infant_terrible/migration.sql b/packages/db/migrations/20260223022946_unknown_infant_terrible/migration.sql new file mode 100644 index 00000000..1751d0cd --- /dev/null +++ b/packages/db/migrations/20260223022946_unknown_infant_terrible/migration.sql @@ -0,0 +1,79 @@ +ALTER TABLE `dms_groups` ADD `slug` text NOT NULL;--> statement-breakpoint +PRAGMA foreign_keys=OFF;--> statement-breakpoint +CREATE TABLE `__new_integrations` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `type` integer NOT NULL, + `integration_user_id` text NOT NULL, + `cid` integer NOT NULL, + `integration_user_name` text, + `last_synced_at` integer, + CONSTRAINT `integrations_cid_users_cid_fk` FOREIGN KEY (`cid`) REFERENCES `users`(`cid`) ON DELETE CASCADE, + CONSTRAINT `integrations_cid_type_unique` UNIQUE(`cid`,`type`) +); +--> statement-breakpoint +INSERT INTO `__new_integrations`(`id`, `type`, `integration_user_id`, `cid`, `integration_user_name`, `last_synced_at`) SELECT `id`, `type`, `integration_user_id`, `cid`, `integration_user_name`, `last_synced_at` FROM `integrations`;--> statement-breakpoint +DROP TABLE `integrations`;--> statement-breakpoint +ALTER TABLE `__new_integrations` RENAME TO `integrations`;--> statement-breakpoint +PRAGMA foreign_keys=ON;--> statement-breakpoint +PRAGMA foreign_keys=OFF;--> statement-breakpoint +CREATE TABLE `__new_preferences` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `cid` integer NOT NULL, + `key` text NOT NULL, + `value` text NOT NULL, + CONSTRAINT `preferences_cid_users_cid_fk` FOREIGN KEY (`cid`) REFERENCES `users`(`cid`) ON DELETE CASCADE, + CONSTRAINT `preferences_cid_key_unique` UNIQUE(`cid`,`key`) +); +--> statement-breakpoint +INSERT INTO `__new_preferences`(`id`, `cid`, `key`, `value`) SELECT `id`, `cid`, `key`, `value` FROM `preferences`;--> statement-breakpoint +DROP TABLE `preferences`;--> statement-breakpoint +ALTER TABLE `__new_preferences` RENAME TO `preferences`;--> statement-breakpoint +PRAGMA foreign_keys=ON;--> statement-breakpoint +PRAGMA foreign_keys=OFF;--> statement-breakpoint +CREATE TABLE `__new_users` ( + `cid` integer PRIMARY KEY, + `name_first` text NOT NULL, + `name_last` text NOT NULL, + `name_full` text NOT NULL, + `email` text NOT NULL UNIQUE, + `ratingID` integer NOT NULL, + `division` text, + `region` text, + `subdivision` text, + `bio` text, + `discord_id` integer, + `active` integer DEFAULT 1 NOT NULL, + `hoursLastUpdated` integer DEFAULT 0 NOT NULL, + CONSTRAINT `users_ratingID_ratings_id_fk` FOREIGN KEY (`ratingID`) REFERENCES `ratings`(`id`) +); +--> statement-breakpoint +INSERT INTO `__new_users`(`cid`, `name_first`, `name_last`, `name_full`, `email`, `ratingID`, `division`, `region`, `subdivision`, `bio`, `discord_id`, `active`, `hoursLastUpdated`) SELECT `cid`, `name_first`, `name_last`, `name_full`, `email`, `ratingID`, `division`, `region`, `subdivision`, `bio`, `discord_id`, `active`, `hoursLastUpdated` FROM `users`;--> statement-breakpoint +DROP TABLE `users`;--> statement-breakpoint +ALTER TABLE `__new_users` RENAME TO `users`;--> statement-breakpoint +PRAGMA foreign_keys=ON;--> statement-breakpoint +PRAGMA foreign_keys=OFF;--> statement-breakpoint +CREATE TABLE `__new_positions` ( + `id` integer PRIMARY KEY AUTOINCREMENT, + `callsign` text NOT NULL UNIQUE, + `frequency` text NOT NULL, + `name` text NOT NULL +); +--> statement-breakpoint +INSERT INTO `__new_positions`(`id`, `callsign`, `frequency`, `name`) SELECT `id`, `callsign`, `frequency`, `name` FROM `positions`;--> statement-breakpoint +DROP TABLE `positions`;--> statement-breakpoint +ALTER TABLE `__new_positions` RENAME TO `positions`;--> statement-breakpoint +PRAGMA foreign_keys=ON;--> statement-breakpoint +DROP INDEX IF EXISTS `users_email_unique`;--> statement-breakpoint +DROP INDEX IF EXISTS `positions_callsign_unique`;--> statement-breakpoint +DROP INDEX IF EXISTS `integrations_cid_type_unique`;--> statement-breakpoint +DROP INDEX IF EXISTS `preferences_cid_key_unique`;--> statement-breakpoint +CREATE INDEX `integrations_cid_idx` ON `integrations` (`cid`);--> statement-breakpoint +CREATE INDEX `integrations_type_idx` ON `integrations` (`type`);--> statement-breakpoint +CREATE INDEX `integrations_integrationUserId_idx` ON `integrations` (`integration_user_id`);--> statement-breakpoint +CREATE INDEX `preferences_cid_idx` ON `preferences` (`cid`);--> statement-breakpoint +CREATE INDEX `preferences_key_idx` ON `preferences` (`key`);--> statement-breakpoint +CREATE INDEX `users_ratingID_idx` ON `users` (`ratingID`);--> statement-breakpoint +CREATE INDEX `users_discord_id_idx` ON `users` (`discord_id`);--> statement-breakpoint +CREATE INDEX `users_active_idx` ON `users` (`active`);--> statement-breakpoint +CREATE INDEX `positions_frequency_idx` ON `positions` (`frequency`);--> statement-breakpoint +CREATE INDEX `positions_name_idx` ON `positions` (`name`); \ No newline at end of file diff --git a/packages/db/migrations/20260223022946_unknown_infant_terrible/snapshot.json b/packages/db/migrations/20260223022946_unknown_infant_terrible/snapshot.json new file mode 100644 index 00000000..88e41b17 --- /dev/null +++ b/packages/db/migrations/20260223022946_unknown_infant_terrible/snapshot.json @@ -0,0 +1,3019 @@ +{ + "version": "7", + "dialect": "sqlite", + "id": "c8798f48-042f-4106-b5b9-cb80175aff9e", + "prevIds": [ + "42541b71-73eb-4bc9-9e88-373bc24e8c70" + ], + "ddl": [ + { + "name": "flags", + "entityType": "tables" + }, + { + "name": "ratings", + "entityType": "tables" + }, + { + "name": "user_flags", + "entityType": "tables" + }, + { + "name": "users", + "entityType": "tables" + }, + { + "name": "events", + "entityType": "tables" + }, + { + "name": "news", + "entityType": "tables" + }, + { + "name": "positions", + "entityType": "tables" + }, + { + "name": "sessions", + "entityType": "tables" + }, + { + "name": "auth_sessions", + "entityType": "tables" + }, + { + "name": "ticket_messages", + "entityType": "tables" + }, + { + "name": "ticket_types", + "entityType": "tables" + }, + { + "name": "tickets", + "entityType": "tables" + }, + { + "name": "resources", + "entityType": "tables" + }, + { + "name": "solo_endorsements", + "entityType": "tables" + }, + { + "name": "roster", + "entityType": "tables" + }, + { + "name": "integrations", + "entityType": "tables" + }, + { + "name": "preferences", + "entityType": "tables" + }, + { + "name": "online_sessions", + "entityType": "tables" + }, + { + "name": "enrolled_users", + "entityType": "tables" + }, + { + "name": "waiting_users", + "entityType": "tables" + }, + { + "name": "waitlists", + "entityType": "tables" + }, + { + "name": "moodle_queue", + "entityType": "tables" + }, + { + "name": "notifications", + "entityType": "tables" + }, + { + "name": "dms_assets", + "entityType": "tables" + }, + { + "name": "dms_documents", + "entityType": "tables" + }, + { + "name": "dms_groups", + "entityType": "tables" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "flags" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "flags" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": "true", + "generated": null, + "name": "showInSelect", + "entityType": "columns", + "table": "flags" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "ratings" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "long", + "entityType": "columns", + "table": "ratings" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "short", + "entityType": "columns", + "table": "ratings" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "flag_id", + "entityType": "columns", + "table": "user_flags" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "user_id", + "entityType": "columns", + "table": "user_flags" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name_first", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name_last", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name_full", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "email", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "ratingID", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "division", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "region", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "subdivision", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "bio", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "discord_id", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "1", + "generated": null, + "name": "active", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "hoursLastUpdated", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "events" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "events" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "start", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "end", + "entityType": "columns", + "table": "events" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "image", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "false", + "generated": null, + "name": "recurring", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "news" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "title", + "entityType": "columns", + "table": "news" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "text", + "entityType": "columns", + "table": "news" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "date", + "entityType": "columns", + "table": "news" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "author_id", + "entityType": "columns", + "table": "news" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "image", + "entityType": "columns", + "table": "news" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "positions" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "callsign", + "entityType": "columns", + "table": "positions" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "frequency", + "entityType": "columns", + "table": "positions" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "positions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "userId", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "positionId", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "duration", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "logonTime", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "ratingId", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "aircraftTracked", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "aircraftSeen", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "flightsAmended", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "handoffsInitiated", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "handoffsReceived", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "handoffsRefused", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "squawksAssigned", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "cruiseAltsModified", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "tempAltsModified", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "scratchpadMods", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "auth_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "user_id", + "entityType": "columns", + "table": "auth_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "expires_at", + "entityType": "columns", + "table": "auth_sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "ticket_id", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "author_id", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "message", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "created_at", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "ticket_types" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "ticket_types" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "subject", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "author_id", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type_id", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": "'open'", + "generated": null, + "name": "status", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "created_at", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "url", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "category", + "entityType": "columns", + "table": "resources" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "true", + "generated": null, + "name": "public", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "resources" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "controller_id", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "expires_at", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position_id", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "roster" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "controller_id", + "entityType": "columns", + "table": "roster" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position", + "entityType": "columns", + "table": "roster" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "status", + "entityType": "columns", + "table": "roster" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "integration_user_id", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "integration_user_name", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "last_synced_at", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "key", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "value", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "userId", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "positionId", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "start", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "waitlist_id", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "enrolled_at", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "hidden_at", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "waitlist_id", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "waiting_since", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "wait_time", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "waitlist_cohort", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "enrolled_cohort", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cohort_id", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "timestamp", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "true", + "generated": null, + "name": "add", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "timestamp", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "userId", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "message", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "sent", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "buttons", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": "'email'", + "generated": null, + "name": "location", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "documentId", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "version", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "effectiveDate", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "expiryDate", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "false", + "generated": null, + "name": "public", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "url", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "required", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "groupId", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "short", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "dms_groups" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "dms_groups" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "99", + "generated": null, + "name": "sort", + "entityType": "columns", + "table": "dms_groups" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "slug", + "entityType": "columns", + "table": "dms_groups" + }, + { + "columns": [ + "flag_id" + ], + "tableTo": "flags", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "user_flags_flag_id_flags_id_fk", + "entityType": "fks", + "table": "user_flags" + }, + { + "columns": [ + "user_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "user_flags_user_id_users_cid_fk", + "entityType": "fks", + "table": "user_flags" + }, + { + "columns": [ + "ratingID" + ], + "tableTo": "ratings", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "users_ratingID_ratings_id_fk", + "entityType": "fks", + "table": "users" + }, + { + "columns": [ + "author_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "nameExplicit": false, + "name": "news_author_id_users_cid_fk", + "entityType": "fks", + "table": "news" + }, + { + "columns": [ + "userId" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "sessions_userId_users_cid_fk", + "entityType": "fks", + "table": "sessions" + }, + { + "columns": [ + "positionId" + ], + "tableTo": "positions", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "sessions_positionId_positions_id_fk", + "entityType": "fks", + "table": "sessions" + }, + { + "columns": [ + "ratingId" + ], + "tableTo": "ratings", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "sessions_ratingId_ratings_id_fk", + "entityType": "fks", + "table": "sessions" + }, + { + "columns": [ + "user_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "auth_sessions_user_id_users_cid_fk", + "entityType": "fks", + "table": "auth_sessions" + }, + { + "columns": [ + "ticket_id" + ], + "tableTo": "tickets", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "ticket_messages_ticket_id_tickets_id_fk", + "entityType": "fks", + "table": "ticket_messages" + }, + { + "columns": [ + "author_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "ticket_messages_author_id_users_cid_fk", + "entityType": "fks", + "table": "ticket_messages" + }, + { + "columns": [ + "author_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "tickets_author_id_users_cid_fk", + "entityType": "fks", + "table": "tickets" + }, + { + "columns": [ + "type_id" + ], + "tableTo": "ticket_types", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "tickets_type_id_ticket_types_id_fk", + "entityType": "fks", + "table": "tickets" + }, + { + "columns": [ + "controller_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "solo_endorsements_controller_id_users_cid_fk", + "entityType": "fks", + "table": "solo_endorsements" + }, + { + "columns": [ + "position_id" + ], + "tableTo": "positions", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "solo_endorsements_position_id_positions_id_fk", + "entityType": "fks", + "table": "solo_endorsements" + }, + { + "columns": [ + "controller_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "roster_controller_id_users_cid_fk", + "entityType": "fks", + "table": "roster" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "integrations_cid_users_cid_fk", + "entityType": "fks", + "table": "integrations" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "preferences_cid_users_cid_fk", + "entityType": "fks", + "table": "preferences" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "enrolled_users_cid_users_cid_fk", + "entityType": "fks", + "table": "enrolled_users" + }, + { + "columns": [ + "waitlist_id" + ], + "tableTo": "waitlists", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "enrolled_users_waitlist_id_waitlists_id_fk", + "entityType": "fks", + "table": "enrolled_users" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "waiting_users_cid_users_cid_fk", + "entityType": "fks", + "table": "waiting_users" + }, + { + "columns": [ + "waitlist_id" + ], + "tableTo": "waitlists", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "waiting_users_waitlist_id_waitlists_id_fk", + "entityType": "fks", + "table": "waiting_users" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "moodle_queue_cid_users_cid_fk", + "entityType": "fks", + "table": "moodle_queue" + }, + { + "columns": [ + "userId" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "notifications_userId_users_cid_fk", + "entityType": "fks", + "table": "notifications" + }, + { + "columns": [ + "documentId" + ], + "tableTo": "dms_documents", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "dms_assets_documentId_dms_documents_id_fk", + "entityType": "fks", + "table": "dms_assets" + }, + { + "columns": [ + "groupId" + ], + "tableTo": "dms_groups", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "nameExplicit": false, + "name": "dms_documents_groupId_dms_groups_id_fk", + "entityType": "fks", + "table": "dms_documents" + }, + { + "columns": [ + "user_id", + "flag_id" + ], + "nameExplicit": false, + "name": "user_flags_user_id_flag_id_pk", + "entityType": "pks", + "table": "user_flags" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "flags_pk", + "table": "flags", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "ratings_pk", + "table": "ratings", + "entityType": "pks" + }, + { + "columns": [ + "cid" + ], + "nameExplicit": false, + "name": "users_pk", + "table": "users", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "events_pk", + "table": "events", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "news_pk", + "table": "news", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "positions_pk", + "table": "positions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "sessions_pk", + "table": "sessions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "auth_sessions_pk", + "table": "auth_sessions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "ticket_messages_pk", + "table": "ticket_messages", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "ticket_types_pk", + "table": "ticket_types", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "tickets_pk", + "table": "tickets", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "resources_pk", + "table": "resources", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "solo_endorsements_pk", + "table": "solo_endorsements", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "roster_pk", + "table": "roster", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "integrations_pk", + "table": "integrations", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "preferences_pk", + "table": "preferences", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "online_sessions_pk", + "table": "online_sessions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "enrolled_users_pk", + "table": "enrolled_users", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "waiting_users_pk", + "table": "waiting_users", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "waitlists_pk", + "table": "waitlists", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "moodle_queue_pk", + "table": "moodle_queue", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "notifications_pk", + "table": "notifications", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "dms_assets_pk", + "table": "dms_assets", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "dms_documents_pk", + "table": "dms_documents", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "dms_groups_pk", + "table": "dms_groups", + "entityType": "pks" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "flags_name_idx", + "entityType": "indexes", + "table": "flags" + }, + { + "columns": [ + { + "value": "long", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ratings_long_idx", + "entityType": "indexes", + "table": "ratings" + }, + { + "columns": [ + { + "value": "short", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ratings_short_idx", + "entityType": "indexes", + "table": "ratings" + }, + { + "columns": [ + { + "value": "flag_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "user_flags_flagId_idx", + "entityType": "indexes", + "table": "user_flags" + }, + { + "columns": [ + { + "value": "user_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "user_flags_userId_idx", + "entityType": "indexes", + "table": "user_flags" + }, + { + "columns": [ + { + "value": "ratingID", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "users_ratingID_idx", + "entityType": "indexes", + "table": "users" + }, + { + "columns": [ + { + "value": "discord_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "users_discord_id_idx", + "entityType": "indexes", + "table": "users" + }, + { + "columns": [ + { + "value": "active", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "users_active_idx", + "entityType": "indexes", + "table": "users" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "events_name_idx", + "entityType": "indexes", + "table": "events" + }, + { + "columns": [ + { + "value": "start", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "events_start_idx", + "entityType": "indexes", + "table": "events" + }, + { + "columns": [ + { + "value": "end", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "events_end_idx", + "entityType": "indexes", + "table": "events" + }, + { + "columns": [ + { + "value": "author_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "news_authorID_idx", + "entityType": "indexes", + "table": "news" + }, + { + "columns": [ + { + "value": "date", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "news_date_idx", + "entityType": "indexes", + "table": "news" + }, + { + "columns": [ + { + "value": "title", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "news_title_idx", + "entityType": "indexes", + "table": "news" + }, + { + "columns": [ + { + "value": "frequency", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "positions_frequency_idx", + "entityType": "indexes", + "table": "positions" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "positions_name_idx", + "entityType": "indexes", + "table": "positions" + }, + { + "columns": [ + { + "value": "userId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "sessions_userId_idx", + "entityType": "indexes", + "table": "sessions" + }, + { + "columns": [ + { + "value": "positionId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "sessions_positionId_idx", + "entityType": "indexes", + "table": "sessions" + }, + { + "columns": [ + { + "value": "logonTime", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "sessions_logonTime_idx", + "entityType": "indexes", + "table": "sessions" + }, + { + "columns": [ + { + "value": "user_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "auth_sessions_userId_idx", + "entityType": "indexes", + "table": "auth_sessions" + }, + { + "columns": [ + { + "value": "expires_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "auth_sessions_expiresAt_idx", + "entityType": "indexes", + "table": "auth_sessions" + }, + { + "columns": [ + { + "value": "ticket_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_messages_ticketId_idx", + "entityType": "indexes", + "table": "ticket_messages" + }, + { + "columns": [ + { + "value": "author_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_messages_authorId_idx", + "entityType": "indexes", + "table": "ticket_messages" + }, + { + "columns": [ + { + "value": "created_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_messages_createdAt_idx", + "entityType": "indexes", + "table": "ticket_messages" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_types_name_idx", + "entityType": "indexes", + "table": "ticket_types" + }, + { + "columns": [ + { + "value": "author_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_authorId_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "type_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_typeId_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "status", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_status_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "created_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_createdAt_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_name_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "category", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_category_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "public", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_public_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "type", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_type_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "controller_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "controller_id_idx", + "entityType": "indexes", + "table": "solo_endorsements" + }, + { + "columns": [ + { + "value": "controller_id", + "isExpression": false + }, + { + "value": "position_id", + "isExpression": false + } + ], + "isUnique": true, + "where": null, + "origin": "manual", + "name": "controller_position_idx", + "entityType": "indexes", + "table": "solo_endorsements" + }, + { + "columns": [ + { + "value": "controller_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "roster_controllerId_idx", + "entityType": "indexes", + "table": "roster" + }, + { + "columns": [ + { + "value": "position", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "roster_position_idx", + "entityType": "indexes", + "table": "roster" + }, + { + "columns": [ + { + "value": "status", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "roster_status_idx", + "entityType": "indexes", + "table": "roster" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "integrations_cid_idx", + "entityType": "indexes", + "table": "integrations" + }, + { + "columns": [ + { + "value": "type", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "integrations_type_idx", + "entityType": "indexes", + "table": "integrations" + }, + { + "columns": [ + { + "value": "integration_user_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "integrations_integrationUserId_idx", + "entityType": "indexes", + "table": "integrations" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "preferences_cid_idx", + "entityType": "indexes", + "table": "preferences" + }, + { + "columns": [ + { + "value": "key", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "preferences_key_idx", + "entityType": "indexes", + "table": "preferences" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_cid_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "waitlist_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_waitlistId_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "enrolled_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_enrolledAt_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "hidden_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_hidden_at_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_cid_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "waitlist_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_waitlistId_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "position", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_position_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "waiting_since", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_waitingSince_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "userId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "notifications_user_id_idx", + "entityType": "indexes", + "table": "notifications" + }, + { + "columns": [ + { + "value": "timestamp", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "notifications_timestamp_idx", + "entityType": "indexes", + "table": "notifications" + }, + { + "columns": [ + { + "value": "userId", + "isExpression": false + }, + { + "value": "timestamp", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "notifications_user_timestamp_idx", + "entityType": "indexes", + "table": "notifications" + }, + { + "columns": [ + { + "value": "documentId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "dms_assets_document_id_idx", + "entityType": "indexes", + "table": "dms_assets" + }, + { + "columns": [ + { + "value": "effectiveDate", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "dms_assets_effective_date_idx", + "entityType": "indexes", + "table": "dms_assets" + }, + { + "columns": [ + { + "value": "groupId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "dms_documents_group_id_idx", + "entityType": "indexes", + "table": "dms_documents" + }, + { + "columns": [ + "cid", + "type" + ], + "nameExplicit": false, + "name": "integrations_cid_type_unique", + "entityType": "uniques", + "table": "integrations" + }, + { + "columns": [ + "cid", + "key" + ], + "nameExplicit": true, + "name": "preferences_cid_key_unique", + "entityType": "uniques", + "table": "preferences" + }, + { + "columns": [ + "email" + ], + "nameExplicit": false, + "name": "users_email_unique", + "entityType": "uniques", + "table": "users" + }, + { + "columns": [ + "callsign" + ], + "nameExplicit": false, + "name": "positions_callsign_unique", + "entityType": "uniques", + "table": "positions" + } + ], + "renames": [] +} \ No newline at end of file diff --git a/packages/db/migrations/20260223023434_productive_frightful_four/migration.sql b/packages/db/migrations/20260223023434_productive_frightful_four/migration.sql new file mode 100644 index 00000000..0695981b --- /dev/null +++ b/packages/db/migrations/20260223023434_productive_frightful_four/migration.sql @@ -0,0 +1,12 @@ +PRAGMA foreign_keys=OFF;--> statement-breakpoint +CREATE TABLE `__new_dms_groups` ( + `id` text PRIMARY KEY, + `name` text NOT NULL, + `sort` integer DEFAULT 99 NOT NULL, + `slug` text NOT NULL UNIQUE +); +--> statement-breakpoint +INSERT INTO `__new_dms_groups`(`id`, `name`, `sort`, `slug`) SELECT `id`, `name`, `sort`, `slug` FROM `dms_groups`;--> statement-breakpoint +DROP TABLE `dms_groups`;--> statement-breakpoint +ALTER TABLE `__new_dms_groups` RENAME TO `dms_groups`;--> statement-breakpoint +PRAGMA foreign_keys=ON; \ No newline at end of file diff --git a/packages/db/migrations/20260223023434_productive_frightful_four/snapshot.json b/packages/db/migrations/20260223023434_productive_frightful_four/snapshot.json new file mode 100644 index 00000000..15637c1e --- /dev/null +++ b/packages/db/migrations/20260223023434_productive_frightful_four/snapshot.json @@ -0,0 +1,3028 @@ +{ + "version": "7", + "dialect": "sqlite", + "id": "6965f703-9de8-4a7d-9601-011ae891e145", + "prevIds": [ + "c8798f48-042f-4106-b5b9-cb80175aff9e" + ], + "ddl": [ + { + "name": "flags", + "entityType": "tables" + }, + { + "name": "ratings", + "entityType": "tables" + }, + { + "name": "user_flags", + "entityType": "tables" + }, + { + "name": "users", + "entityType": "tables" + }, + { + "name": "events", + "entityType": "tables" + }, + { + "name": "news", + "entityType": "tables" + }, + { + "name": "positions", + "entityType": "tables" + }, + { + "name": "sessions", + "entityType": "tables" + }, + { + "name": "auth_sessions", + "entityType": "tables" + }, + { + "name": "ticket_messages", + "entityType": "tables" + }, + { + "name": "ticket_types", + "entityType": "tables" + }, + { + "name": "tickets", + "entityType": "tables" + }, + { + "name": "resources", + "entityType": "tables" + }, + { + "name": "solo_endorsements", + "entityType": "tables" + }, + { + "name": "roster", + "entityType": "tables" + }, + { + "name": "integrations", + "entityType": "tables" + }, + { + "name": "preferences", + "entityType": "tables" + }, + { + "name": "online_sessions", + "entityType": "tables" + }, + { + "name": "enrolled_users", + "entityType": "tables" + }, + { + "name": "waiting_users", + "entityType": "tables" + }, + { + "name": "waitlists", + "entityType": "tables" + }, + { + "name": "moodle_queue", + "entityType": "tables" + }, + { + "name": "notifications", + "entityType": "tables" + }, + { + "name": "dms_assets", + "entityType": "tables" + }, + { + "name": "dms_documents", + "entityType": "tables" + }, + { + "name": "dms_groups", + "entityType": "tables" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "flags" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "flags" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": "true", + "generated": null, + "name": "showInSelect", + "entityType": "columns", + "table": "flags" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "ratings" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "long", + "entityType": "columns", + "table": "ratings" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "short", + "entityType": "columns", + "table": "ratings" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "flag_id", + "entityType": "columns", + "table": "user_flags" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "user_id", + "entityType": "columns", + "table": "user_flags" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name_first", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name_last", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name_full", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "email", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "ratingID", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "division", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "region", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "subdivision", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "bio", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "discord_id", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "1", + "generated": null, + "name": "active", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "hoursLastUpdated", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "events" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "events" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "start", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "end", + "entityType": "columns", + "table": "events" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "image", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "false", + "generated": null, + "name": "recurring", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "news" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "title", + "entityType": "columns", + "table": "news" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "text", + "entityType": "columns", + "table": "news" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "date", + "entityType": "columns", + "table": "news" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "author_id", + "entityType": "columns", + "table": "news" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "image", + "entityType": "columns", + "table": "news" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "positions" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "callsign", + "entityType": "columns", + "table": "positions" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "frequency", + "entityType": "columns", + "table": "positions" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "positions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "userId", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "positionId", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "duration", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "logonTime", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "ratingId", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "aircraftTracked", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "aircraftSeen", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "flightsAmended", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "handoffsInitiated", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "handoffsReceived", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "handoffsRefused", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "squawksAssigned", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "cruiseAltsModified", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "tempAltsModified", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "scratchpadMods", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "auth_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "user_id", + "entityType": "columns", + "table": "auth_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "expires_at", + "entityType": "columns", + "table": "auth_sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "ticket_id", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "author_id", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "message", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "created_at", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "ticket_types" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "ticket_types" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "subject", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "author_id", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type_id", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": "'open'", + "generated": null, + "name": "status", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "created_at", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "url", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "category", + "entityType": "columns", + "table": "resources" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "true", + "generated": null, + "name": "public", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "resources" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "controller_id", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "expires_at", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position_id", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "roster" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "controller_id", + "entityType": "columns", + "table": "roster" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position", + "entityType": "columns", + "table": "roster" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "status", + "entityType": "columns", + "table": "roster" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "integration_user_id", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "integration_user_name", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "last_synced_at", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "key", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "value", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "userId", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "positionId", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "start", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "waitlist_id", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "enrolled_at", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "hidden_at", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "waitlist_id", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "waiting_since", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "wait_time", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "waitlist_cohort", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "enrolled_cohort", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cohort_id", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "timestamp", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "true", + "generated": null, + "name": "add", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "timestamp", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "userId", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "message", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "sent", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "buttons", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": "'email'", + "generated": null, + "name": "location", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "documentId", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "version", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "effectiveDate", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "expiryDate", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "false", + "generated": null, + "name": "public", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "url", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "required", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "groupId", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "short", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "dms_groups" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "dms_groups" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "99", + "generated": null, + "name": "sort", + "entityType": "columns", + "table": "dms_groups" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "slug", + "entityType": "columns", + "table": "dms_groups" + }, + { + "columns": [ + "flag_id" + ], + "tableTo": "flags", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "user_flags_flag_id_flags_id_fk", + "entityType": "fks", + "table": "user_flags" + }, + { + "columns": [ + "user_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "user_flags_user_id_users_cid_fk", + "entityType": "fks", + "table": "user_flags" + }, + { + "columns": [ + "ratingID" + ], + "tableTo": "ratings", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "users_ratingID_ratings_id_fk", + "entityType": "fks", + "table": "users" + }, + { + "columns": [ + "author_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "nameExplicit": false, + "name": "news_author_id_users_cid_fk", + "entityType": "fks", + "table": "news" + }, + { + "columns": [ + "userId" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "sessions_userId_users_cid_fk", + "entityType": "fks", + "table": "sessions" + }, + { + "columns": [ + "positionId" + ], + "tableTo": "positions", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "sessions_positionId_positions_id_fk", + "entityType": "fks", + "table": "sessions" + }, + { + "columns": [ + "ratingId" + ], + "tableTo": "ratings", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "sessions_ratingId_ratings_id_fk", + "entityType": "fks", + "table": "sessions" + }, + { + "columns": [ + "user_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "auth_sessions_user_id_users_cid_fk", + "entityType": "fks", + "table": "auth_sessions" + }, + { + "columns": [ + "ticket_id" + ], + "tableTo": "tickets", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "ticket_messages_ticket_id_tickets_id_fk", + "entityType": "fks", + "table": "ticket_messages" + }, + { + "columns": [ + "author_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "ticket_messages_author_id_users_cid_fk", + "entityType": "fks", + "table": "ticket_messages" + }, + { + "columns": [ + "author_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "tickets_author_id_users_cid_fk", + "entityType": "fks", + "table": "tickets" + }, + { + "columns": [ + "type_id" + ], + "tableTo": "ticket_types", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "tickets_type_id_ticket_types_id_fk", + "entityType": "fks", + "table": "tickets" + }, + { + "columns": [ + "controller_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "solo_endorsements_controller_id_users_cid_fk", + "entityType": "fks", + "table": "solo_endorsements" + }, + { + "columns": [ + "position_id" + ], + "tableTo": "positions", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "solo_endorsements_position_id_positions_id_fk", + "entityType": "fks", + "table": "solo_endorsements" + }, + { + "columns": [ + "controller_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "roster_controller_id_users_cid_fk", + "entityType": "fks", + "table": "roster" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "integrations_cid_users_cid_fk", + "entityType": "fks", + "table": "integrations" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "preferences_cid_users_cid_fk", + "entityType": "fks", + "table": "preferences" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "enrolled_users_cid_users_cid_fk", + "entityType": "fks", + "table": "enrolled_users" + }, + { + "columns": [ + "waitlist_id" + ], + "tableTo": "waitlists", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "enrolled_users_waitlist_id_waitlists_id_fk", + "entityType": "fks", + "table": "enrolled_users" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "waiting_users_cid_users_cid_fk", + "entityType": "fks", + "table": "waiting_users" + }, + { + "columns": [ + "waitlist_id" + ], + "tableTo": "waitlists", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "waiting_users_waitlist_id_waitlists_id_fk", + "entityType": "fks", + "table": "waiting_users" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "moodle_queue_cid_users_cid_fk", + "entityType": "fks", + "table": "moodle_queue" + }, + { + "columns": [ + "userId" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "notifications_userId_users_cid_fk", + "entityType": "fks", + "table": "notifications" + }, + { + "columns": [ + "documentId" + ], + "tableTo": "dms_documents", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "dms_assets_documentId_dms_documents_id_fk", + "entityType": "fks", + "table": "dms_assets" + }, + { + "columns": [ + "groupId" + ], + "tableTo": "dms_groups", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "nameExplicit": false, + "name": "dms_documents_groupId_dms_groups_id_fk", + "entityType": "fks", + "table": "dms_documents" + }, + { + "columns": [ + "user_id", + "flag_id" + ], + "nameExplicit": false, + "name": "user_flags_user_id_flag_id_pk", + "entityType": "pks", + "table": "user_flags" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "flags_pk", + "table": "flags", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "ratings_pk", + "table": "ratings", + "entityType": "pks" + }, + { + "columns": [ + "cid" + ], + "nameExplicit": false, + "name": "users_pk", + "table": "users", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "events_pk", + "table": "events", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "news_pk", + "table": "news", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "positions_pk", + "table": "positions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "sessions_pk", + "table": "sessions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "auth_sessions_pk", + "table": "auth_sessions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "ticket_messages_pk", + "table": "ticket_messages", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "ticket_types_pk", + "table": "ticket_types", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "tickets_pk", + "table": "tickets", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "resources_pk", + "table": "resources", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "solo_endorsements_pk", + "table": "solo_endorsements", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "roster_pk", + "table": "roster", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "integrations_pk", + "table": "integrations", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "preferences_pk", + "table": "preferences", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "online_sessions_pk", + "table": "online_sessions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "enrolled_users_pk", + "table": "enrolled_users", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "waiting_users_pk", + "table": "waiting_users", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "waitlists_pk", + "table": "waitlists", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "moodle_queue_pk", + "table": "moodle_queue", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "notifications_pk", + "table": "notifications", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "dms_assets_pk", + "table": "dms_assets", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "dms_documents_pk", + "table": "dms_documents", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "dms_groups_pk", + "table": "dms_groups", + "entityType": "pks" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "flags_name_idx", + "entityType": "indexes", + "table": "flags" + }, + { + "columns": [ + { + "value": "long", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ratings_long_idx", + "entityType": "indexes", + "table": "ratings" + }, + { + "columns": [ + { + "value": "short", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ratings_short_idx", + "entityType": "indexes", + "table": "ratings" + }, + { + "columns": [ + { + "value": "flag_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "user_flags_flagId_idx", + "entityType": "indexes", + "table": "user_flags" + }, + { + "columns": [ + { + "value": "user_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "user_flags_userId_idx", + "entityType": "indexes", + "table": "user_flags" + }, + { + "columns": [ + { + "value": "ratingID", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "users_ratingID_idx", + "entityType": "indexes", + "table": "users" + }, + { + "columns": [ + { + "value": "discord_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "users_discord_id_idx", + "entityType": "indexes", + "table": "users" + }, + { + "columns": [ + { + "value": "active", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "users_active_idx", + "entityType": "indexes", + "table": "users" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "events_name_idx", + "entityType": "indexes", + "table": "events" + }, + { + "columns": [ + { + "value": "start", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "events_start_idx", + "entityType": "indexes", + "table": "events" + }, + { + "columns": [ + { + "value": "end", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "events_end_idx", + "entityType": "indexes", + "table": "events" + }, + { + "columns": [ + { + "value": "author_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "news_authorID_idx", + "entityType": "indexes", + "table": "news" + }, + { + "columns": [ + { + "value": "date", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "news_date_idx", + "entityType": "indexes", + "table": "news" + }, + { + "columns": [ + { + "value": "title", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "news_title_idx", + "entityType": "indexes", + "table": "news" + }, + { + "columns": [ + { + "value": "frequency", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "positions_frequency_idx", + "entityType": "indexes", + "table": "positions" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "positions_name_idx", + "entityType": "indexes", + "table": "positions" + }, + { + "columns": [ + { + "value": "userId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "sessions_userId_idx", + "entityType": "indexes", + "table": "sessions" + }, + { + "columns": [ + { + "value": "positionId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "sessions_positionId_idx", + "entityType": "indexes", + "table": "sessions" + }, + { + "columns": [ + { + "value": "logonTime", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "sessions_logonTime_idx", + "entityType": "indexes", + "table": "sessions" + }, + { + "columns": [ + { + "value": "user_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "auth_sessions_userId_idx", + "entityType": "indexes", + "table": "auth_sessions" + }, + { + "columns": [ + { + "value": "expires_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "auth_sessions_expiresAt_idx", + "entityType": "indexes", + "table": "auth_sessions" + }, + { + "columns": [ + { + "value": "ticket_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_messages_ticketId_idx", + "entityType": "indexes", + "table": "ticket_messages" + }, + { + "columns": [ + { + "value": "author_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_messages_authorId_idx", + "entityType": "indexes", + "table": "ticket_messages" + }, + { + "columns": [ + { + "value": "created_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_messages_createdAt_idx", + "entityType": "indexes", + "table": "ticket_messages" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_types_name_idx", + "entityType": "indexes", + "table": "ticket_types" + }, + { + "columns": [ + { + "value": "author_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_authorId_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "type_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_typeId_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "status", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_status_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "created_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_createdAt_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_name_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "category", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_category_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "public", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_public_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "type", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_type_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "controller_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "controller_id_idx", + "entityType": "indexes", + "table": "solo_endorsements" + }, + { + "columns": [ + { + "value": "controller_id", + "isExpression": false + }, + { + "value": "position_id", + "isExpression": false + } + ], + "isUnique": true, + "where": null, + "origin": "manual", + "name": "controller_position_idx", + "entityType": "indexes", + "table": "solo_endorsements" + }, + { + "columns": [ + { + "value": "controller_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "roster_controllerId_idx", + "entityType": "indexes", + "table": "roster" + }, + { + "columns": [ + { + "value": "position", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "roster_position_idx", + "entityType": "indexes", + "table": "roster" + }, + { + "columns": [ + { + "value": "status", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "roster_status_idx", + "entityType": "indexes", + "table": "roster" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "integrations_cid_idx", + "entityType": "indexes", + "table": "integrations" + }, + { + "columns": [ + { + "value": "type", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "integrations_type_idx", + "entityType": "indexes", + "table": "integrations" + }, + { + "columns": [ + { + "value": "integration_user_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "integrations_integrationUserId_idx", + "entityType": "indexes", + "table": "integrations" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "preferences_cid_idx", + "entityType": "indexes", + "table": "preferences" + }, + { + "columns": [ + { + "value": "key", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "preferences_key_idx", + "entityType": "indexes", + "table": "preferences" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_cid_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "waitlist_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_waitlistId_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "enrolled_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_enrolledAt_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "hidden_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_hidden_at_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_cid_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "waitlist_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_waitlistId_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "position", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_position_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "waiting_since", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_waitingSince_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "userId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "notifications_user_id_idx", + "entityType": "indexes", + "table": "notifications" + }, + { + "columns": [ + { + "value": "timestamp", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "notifications_timestamp_idx", + "entityType": "indexes", + "table": "notifications" + }, + { + "columns": [ + { + "value": "userId", + "isExpression": false + }, + { + "value": "timestamp", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "notifications_user_timestamp_idx", + "entityType": "indexes", + "table": "notifications" + }, + { + "columns": [ + { + "value": "documentId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "dms_assets_document_id_idx", + "entityType": "indexes", + "table": "dms_assets" + }, + { + "columns": [ + { + "value": "effectiveDate", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "dms_assets_effective_date_idx", + "entityType": "indexes", + "table": "dms_assets" + }, + { + "columns": [ + { + "value": "groupId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "dms_documents_group_id_idx", + "entityType": "indexes", + "table": "dms_documents" + }, + { + "columns": [ + "cid", + "type" + ], + "nameExplicit": false, + "name": "integrations_cid_type_unique", + "entityType": "uniques", + "table": "integrations" + }, + { + "columns": [ + "cid", + "key" + ], + "nameExplicit": true, + "name": "preferences_cid_key_unique", + "entityType": "uniques", + "table": "preferences" + }, + { + "columns": [ + "email" + ], + "nameExplicit": false, + "name": "users_email_unique", + "entityType": "uniques", + "table": "users" + }, + { + "columns": [ + "callsign" + ], + "nameExplicit": false, + "name": "positions_callsign_unique", + "entityType": "uniques", + "table": "positions" + }, + { + "columns": [ + "slug" + ], + "nameExplicit": false, + "name": "dms_groups_slug_unique", + "entityType": "uniques", + "table": "dms_groups" + } + ], + "renames": [] +} \ No newline at end of file diff --git a/packages/db/migrations/20260224020012_deep_moira_mactaggert/migration.sql b/packages/db/migrations/20260224020012_deep_moira_mactaggert/migration.sql new file mode 100644 index 00000000..c01f671a --- /dev/null +++ b/packages/db/migrations/20260224020012_deep_moira_mactaggert/migration.sql @@ -0,0 +1 @@ +ALTER TABLE `dms_documents` ADD `sort` integer DEFAULT 99 NOT NULL; \ No newline at end of file diff --git a/packages/db/migrations/20260224020012_deep_moira_mactaggert/snapshot.json b/packages/db/migrations/20260224020012_deep_moira_mactaggert/snapshot.json new file mode 100644 index 00000000..d725e648 --- /dev/null +++ b/packages/db/migrations/20260224020012_deep_moira_mactaggert/snapshot.json @@ -0,0 +1,3038 @@ +{ + "version": "7", + "dialect": "sqlite", + "id": "673428bf-455e-4dd3-a1c5-8b5ea0e7368b", + "prevIds": [ + "6965f703-9de8-4a7d-9601-011ae891e145" + ], + "ddl": [ + { + "name": "flags", + "entityType": "tables" + }, + { + "name": "ratings", + "entityType": "tables" + }, + { + "name": "user_flags", + "entityType": "tables" + }, + { + "name": "users", + "entityType": "tables" + }, + { + "name": "events", + "entityType": "tables" + }, + { + "name": "news", + "entityType": "tables" + }, + { + "name": "positions", + "entityType": "tables" + }, + { + "name": "sessions", + "entityType": "tables" + }, + { + "name": "auth_sessions", + "entityType": "tables" + }, + { + "name": "ticket_messages", + "entityType": "tables" + }, + { + "name": "ticket_types", + "entityType": "tables" + }, + { + "name": "tickets", + "entityType": "tables" + }, + { + "name": "resources", + "entityType": "tables" + }, + { + "name": "solo_endorsements", + "entityType": "tables" + }, + { + "name": "roster", + "entityType": "tables" + }, + { + "name": "integrations", + "entityType": "tables" + }, + { + "name": "preferences", + "entityType": "tables" + }, + { + "name": "online_sessions", + "entityType": "tables" + }, + { + "name": "enrolled_users", + "entityType": "tables" + }, + { + "name": "waiting_users", + "entityType": "tables" + }, + { + "name": "waitlists", + "entityType": "tables" + }, + { + "name": "moodle_queue", + "entityType": "tables" + }, + { + "name": "notifications", + "entityType": "tables" + }, + { + "name": "dms_assets", + "entityType": "tables" + }, + { + "name": "dms_documents", + "entityType": "tables" + }, + { + "name": "dms_groups", + "entityType": "tables" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "flags" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "flags" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": "true", + "generated": null, + "name": "showInSelect", + "entityType": "columns", + "table": "flags" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "ratings" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "long", + "entityType": "columns", + "table": "ratings" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "short", + "entityType": "columns", + "table": "ratings" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "flag_id", + "entityType": "columns", + "table": "user_flags" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "user_id", + "entityType": "columns", + "table": "user_flags" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name_first", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name_last", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name_full", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "email", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "ratingID", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "division", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "region", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "subdivision", + "entityType": "columns", + "table": "users" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "bio", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "discord_id", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "1", + "generated": null, + "name": "active", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "hoursLastUpdated", + "entityType": "columns", + "table": "users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "events" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "events" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "start", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "end", + "entityType": "columns", + "table": "events" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "image", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "false", + "generated": null, + "name": "recurring", + "entityType": "columns", + "table": "events" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "news" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "title", + "entityType": "columns", + "table": "news" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "text", + "entityType": "columns", + "table": "news" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "date", + "entityType": "columns", + "table": "news" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "author_id", + "entityType": "columns", + "table": "news" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "image", + "entityType": "columns", + "table": "news" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "positions" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "callsign", + "entityType": "columns", + "table": "positions" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "frequency", + "entityType": "columns", + "table": "positions" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "positions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "userId", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "positionId", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "duration", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "logonTime", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "ratingId", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "aircraftTracked", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "aircraftSeen", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "flightsAmended", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "handoffsInitiated", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "handoffsReceived", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "handoffsRefused", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "squawksAssigned", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "cruiseAltsModified", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "tempAltsModified", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "scratchpadMods", + "entityType": "columns", + "table": "sessions" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "auth_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "user_id", + "entityType": "columns", + "table": "auth_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "expires_at", + "entityType": "columns", + "table": "auth_sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "ticket_id", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "author_id", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "message", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "created_at", + "entityType": "columns", + "table": "ticket_messages" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "ticket_types" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "ticket_types" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "subject", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "author_id", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type_id", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": "'open'", + "generated": null, + "name": "status", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "created_at", + "entityType": "columns", + "table": "tickets" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "url", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "category", + "entityType": "columns", + "table": "resources" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "true", + "generated": null, + "name": "public", + "entityType": "columns", + "table": "resources" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "resources" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "controller_id", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "expires_at", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position_id", + "entityType": "columns", + "table": "solo_endorsements" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "roster" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "controller_id", + "entityType": "columns", + "table": "roster" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position", + "entityType": "columns", + "table": "roster" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "status", + "entityType": "columns", + "table": "roster" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "integration_user_id", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "integration_user_name", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "last_synced_at", + "entityType": "columns", + "table": "integrations" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "key", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "value", + "entityType": "columns", + "table": "preferences" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "userId", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "positionId", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "start", + "entityType": "columns", + "table": "online_sessions" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "waitlist_id", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "enrolled_at", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "hidden_at", + "entityType": "columns", + "table": "enrolled_users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "waitlist_id", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "position", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "waiting_since", + "entityType": "columns", + "table": "waiting_users" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "wait_time", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "waitlist_cohort", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "enrolled_cohort", + "entityType": "columns", + "table": "waitlists" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": true, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cid", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "cohort_id", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "0", + "generated": null, + "name": "timestamp", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "true", + "generated": null, + "name": "add", + "entityType": "columns", + "table": "moodle_queue" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "timestamp", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "userId", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "type", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "message", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "sent", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "buttons", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": "'email'", + "generated": null, + "name": "location", + "entityType": "columns", + "table": "notifications" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "documentId", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "version", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "effectiveDate", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "integer", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "expiryDate", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "false", + "generated": null, + "name": "public", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "url", + "entityType": "columns", + "table": "dms_assets" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "required", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "description", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "groupId", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "short", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "99", + "generated": null, + "name": "sort", + "entityType": "columns", + "table": "dms_documents" + }, + { + "type": "text", + "notNull": false, + "autoincrement": false, + "default": null, + "generated": null, + "name": "id", + "entityType": "columns", + "table": "dms_groups" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "name", + "entityType": "columns", + "table": "dms_groups" + }, + { + "type": "integer", + "notNull": true, + "autoincrement": false, + "default": "99", + "generated": null, + "name": "sort", + "entityType": "columns", + "table": "dms_groups" + }, + { + "type": "text", + "notNull": true, + "autoincrement": false, + "default": null, + "generated": null, + "name": "slug", + "entityType": "columns", + "table": "dms_groups" + }, + { + "columns": [ + "flag_id" + ], + "tableTo": "flags", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "user_flags_flag_id_flags_id_fk", + "entityType": "fks", + "table": "user_flags" + }, + { + "columns": [ + "user_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "user_flags_user_id_users_cid_fk", + "entityType": "fks", + "table": "user_flags" + }, + { + "columns": [ + "ratingID" + ], + "tableTo": "ratings", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "users_ratingID_ratings_id_fk", + "entityType": "fks", + "table": "users" + }, + { + "columns": [ + "author_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "nameExplicit": false, + "name": "news_author_id_users_cid_fk", + "entityType": "fks", + "table": "news" + }, + { + "columns": [ + "userId" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "sessions_userId_users_cid_fk", + "entityType": "fks", + "table": "sessions" + }, + { + "columns": [ + "positionId" + ], + "tableTo": "positions", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "sessions_positionId_positions_id_fk", + "entityType": "fks", + "table": "sessions" + }, + { + "columns": [ + "ratingId" + ], + "tableTo": "ratings", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "sessions_ratingId_ratings_id_fk", + "entityType": "fks", + "table": "sessions" + }, + { + "columns": [ + "user_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "auth_sessions_user_id_users_cid_fk", + "entityType": "fks", + "table": "auth_sessions" + }, + { + "columns": [ + "ticket_id" + ], + "tableTo": "tickets", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "ticket_messages_ticket_id_tickets_id_fk", + "entityType": "fks", + "table": "ticket_messages" + }, + { + "columns": [ + "author_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "ticket_messages_author_id_users_cid_fk", + "entityType": "fks", + "table": "ticket_messages" + }, + { + "columns": [ + "author_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "tickets_author_id_users_cid_fk", + "entityType": "fks", + "table": "tickets" + }, + { + "columns": [ + "type_id" + ], + "tableTo": "ticket_types", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "tickets_type_id_ticket_types_id_fk", + "entityType": "fks", + "table": "tickets" + }, + { + "columns": [ + "controller_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "solo_endorsements_controller_id_users_cid_fk", + "entityType": "fks", + "table": "solo_endorsements" + }, + { + "columns": [ + "position_id" + ], + "tableTo": "positions", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "solo_endorsements_position_id_positions_id_fk", + "entityType": "fks", + "table": "solo_endorsements" + }, + { + "columns": [ + "controller_id" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "roster_controller_id_users_cid_fk", + "entityType": "fks", + "table": "roster" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "integrations_cid_users_cid_fk", + "entityType": "fks", + "table": "integrations" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "preferences_cid_users_cid_fk", + "entityType": "fks", + "table": "preferences" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "enrolled_users_cid_users_cid_fk", + "entityType": "fks", + "table": "enrolled_users" + }, + { + "columns": [ + "waitlist_id" + ], + "tableTo": "waitlists", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "enrolled_users_waitlist_id_waitlists_id_fk", + "entityType": "fks", + "table": "enrolled_users" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "waiting_users_cid_users_cid_fk", + "entityType": "fks", + "table": "waiting_users" + }, + { + "columns": [ + "waitlist_id" + ], + "tableTo": "waitlists", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "waiting_users_waitlist_id_waitlists_id_fk", + "entityType": "fks", + "table": "waiting_users" + }, + { + "columns": [ + "cid" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "moodle_queue_cid_users_cid_fk", + "entityType": "fks", + "table": "moodle_queue" + }, + { + "columns": [ + "userId" + ], + "tableTo": "users", + "columnsTo": [ + "cid" + ], + "onUpdate": "NO ACTION", + "onDelete": "NO ACTION", + "nameExplicit": false, + "name": "notifications_userId_users_cid_fk", + "entityType": "fks", + "table": "notifications" + }, + { + "columns": [ + "documentId" + ], + "tableTo": "dms_documents", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "nameExplicit": false, + "name": "dms_assets_documentId_dms_documents_id_fk", + "entityType": "fks", + "table": "dms_assets" + }, + { + "columns": [ + "groupId" + ], + "tableTo": "dms_groups", + "columnsTo": [ + "id" + ], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "nameExplicit": false, + "name": "dms_documents_groupId_dms_groups_id_fk", + "entityType": "fks", + "table": "dms_documents" + }, + { + "columns": [ + "user_id", + "flag_id" + ], + "nameExplicit": false, + "name": "user_flags_user_id_flag_id_pk", + "entityType": "pks", + "table": "user_flags" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "flags_pk", + "table": "flags", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "ratings_pk", + "table": "ratings", + "entityType": "pks" + }, + { + "columns": [ + "cid" + ], + "nameExplicit": false, + "name": "users_pk", + "table": "users", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "events_pk", + "table": "events", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "news_pk", + "table": "news", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "positions_pk", + "table": "positions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "sessions_pk", + "table": "sessions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "auth_sessions_pk", + "table": "auth_sessions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "ticket_messages_pk", + "table": "ticket_messages", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "ticket_types_pk", + "table": "ticket_types", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "tickets_pk", + "table": "tickets", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "resources_pk", + "table": "resources", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "solo_endorsements_pk", + "table": "solo_endorsements", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "roster_pk", + "table": "roster", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "integrations_pk", + "table": "integrations", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "preferences_pk", + "table": "preferences", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "online_sessions_pk", + "table": "online_sessions", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "enrolled_users_pk", + "table": "enrolled_users", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "waiting_users_pk", + "table": "waiting_users", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "waitlists_pk", + "table": "waitlists", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "moodle_queue_pk", + "table": "moodle_queue", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "notifications_pk", + "table": "notifications", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "dms_assets_pk", + "table": "dms_assets", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "dms_documents_pk", + "table": "dms_documents", + "entityType": "pks" + }, + { + "columns": [ + "id" + ], + "nameExplicit": false, + "name": "dms_groups_pk", + "table": "dms_groups", + "entityType": "pks" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "flags_name_idx", + "entityType": "indexes", + "table": "flags" + }, + { + "columns": [ + { + "value": "long", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ratings_long_idx", + "entityType": "indexes", + "table": "ratings" + }, + { + "columns": [ + { + "value": "short", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ratings_short_idx", + "entityType": "indexes", + "table": "ratings" + }, + { + "columns": [ + { + "value": "flag_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "user_flags_flagId_idx", + "entityType": "indexes", + "table": "user_flags" + }, + { + "columns": [ + { + "value": "user_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "user_flags_userId_idx", + "entityType": "indexes", + "table": "user_flags" + }, + { + "columns": [ + { + "value": "ratingID", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "users_ratingID_idx", + "entityType": "indexes", + "table": "users" + }, + { + "columns": [ + { + "value": "discord_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "users_discord_id_idx", + "entityType": "indexes", + "table": "users" + }, + { + "columns": [ + { + "value": "active", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "users_active_idx", + "entityType": "indexes", + "table": "users" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "events_name_idx", + "entityType": "indexes", + "table": "events" + }, + { + "columns": [ + { + "value": "start", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "events_start_idx", + "entityType": "indexes", + "table": "events" + }, + { + "columns": [ + { + "value": "end", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "events_end_idx", + "entityType": "indexes", + "table": "events" + }, + { + "columns": [ + { + "value": "author_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "news_authorID_idx", + "entityType": "indexes", + "table": "news" + }, + { + "columns": [ + { + "value": "date", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "news_date_idx", + "entityType": "indexes", + "table": "news" + }, + { + "columns": [ + { + "value": "title", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "news_title_idx", + "entityType": "indexes", + "table": "news" + }, + { + "columns": [ + { + "value": "frequency", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "positions_frequency_idx", + "entityType": "indexes", + "table": "positions" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "positions_name_idx", + "entityType": "indexes", + "table": "positions" + }, + { + "columns": [ + { + "value": "userId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "sessions_userId_idx", + "entityType": "indexes", + "table": "sessions" + }, + { + "columns": [ + { + "value": "positionId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "sessions_positionId_idx", + "entityType": "indexes", + "table": "sessions" + }, + { + "columns": [ + { + "value": "logonTime", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "sessions_logonTime_idx", + "entityType": "indexes", + "table": "sessions" + }, + { + "columns": [ + { + "value": "user_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "auth_sessions_userId_idx", + "entityType": "indexes", + "table": "auth_sessions" + }, + { + "columns": [ + { + "value": "expires_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "auth_sessions_expiresAt_idx", + "entityType": "indexes", + "table": "auth_sessions" + }, + { + "columns": [ + { + "value": "ticket_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_messages_ticketId_idx", + "entityType": "indexes", + "table": "ticket_messages" + }, + { + "columns": [ + { + "value": "author_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_messages_authorId_idx", + "entityType": "indexes", + "table": "ticket_messages" + }, + { + "columns": [ + { + "value": "created_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_messages_createdAt_idx", + "entityType": "indexes", + "table": "ticket_messages" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "ticket_types_name_idx", + "entityType": "indexes", + "table": "ticket_types" + }, + { + "columns": [ + { + "value": "author_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_authorId_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "type_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_typeId_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "status", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_status_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "created_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "tickets_createdAt_idx", + "entityType": "indexes", + "table": "tickets" + }, + { + "columns": [ + { + "value": "name", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_name_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "category", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_category_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "public", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_public_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "type", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "resources_type_idx", + "entityType": "indexes", + "table": "resources" + }, + { + "columns": [ + { + "value": "controller_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "controller_id_idx", + "entityType": "indexes", + "table": "solo_endorsements" + }, + { + "columns": [ + { + "value": "controller_id", + "isExpression": false + }, + { + "value": "position_id", + "isExpression": false + } + ], + "isUnique": true, + "where": null, + "origin": "manual", + "name": "controller_position_idx", + "entityType": "indexes", + "table": "solo_endorsements" + }, + { + "columns": [ + { + "value": "controller_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "roster_controllerId_idx", + "entityType": "indexes", + "table": "roster" + }, + { + "columns": [ + { + "value": "position", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "roster_position_idx", + "entityType": "indexes", + "table": "roster" + }, + { + "columns": [ + { + "value": "status", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "roster_status_idx", + "entityType": "indexes", + "table": "roster" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "integrations_cid_idx", + "entityType": "indexes", + "table": "integrations" + }, + { + "columns": [ + { + "value": "type", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "integrations_type_idx", + "entityType": "indexes", + "table": "integrations" + }, + { + "columns": [ + { + "value": "integration_user_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "integrations_integrationUserId_idx", + "entityType": "indexes", + "table": "integrations" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "preferences_cid_idx", + "entityType": "indexes", + "table": "preferences" + }, + { + "columns": [ + { + "value": "key", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "preferences_key_idx", + "entityType": "indexes", + "table": "preferences" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_cid_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "waitlist_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_waitlistId_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "enrolled_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_enrolledAt_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "hidden_at", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "enrolled_users_hidden_at_idx", + "entityType": "indexes", + "table": "enrolled_users" + }, + { + "columns": [ + { + "value": "cid", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_cid_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "waitlist_id", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_waitlistId_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "position", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_position_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "waiting_since", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "waiting_users_waitingSince_idx", + "entityType": "indexes", + "table": "waiting_users" + }, + { + "columns": [ + { + "value": "userId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "notifications_user_id_idx", + "entityType": "indexes", + "table": "notifications" + }, + { + "columns": [ + { + "value": "timestamp", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "notifications_timestamp_idx", + "entityType": "indexes", + "table": "notifications" + }, + { + "columns": [ + { + "value": "userId", + "isExpression": false + }, + { + "value": "timestamp", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "notifications_user_timestamp_idx", + "entityType": "indexes", + "table": "notifications" + }, + { + "columns": [ + { + "value": "documentId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "dms_assets_document_id_idx", + "entityType": "indexes", + "table": "dms_assets" + }, + { + "columns": [ + { + "value": "effectiveDate", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "dms_assets_effective_date_idx", + "entityType": "indexes", + "table": "dms_assets" + }, + { + "columns": [ + { + "value": "groupId", + "isExpression": false + } + ], + "isUnique": false, + "where": null, + "origin": "manual", + "name": "dms_documents_group_id_idx", + "entityType": "indexes", + "table": "dms_documents" + }, + { + "columns": [ + "cid", + "type" + ], + "nameExplicit": false, + "name": "integrations_cid_type_unique", + "entityType": "uniques", + "table": "integrations" + }, + { + "columns": [ + "cid", + "key" + ], + "nameExplicit": true, + "name": "preferences_cid_key_unique", + "entityType": "uniques", + "table": "preferences" + }, + { + "columns": [ + "email" + ], + "nameExplicit": false, + "name": "users_email_unique", + "entityType": "uniques", + "table": "users" + }, + { + "columns": [ + "callsign" + ], + "nameExplicit": false, + "name": "positions_callsign_unique", + "entityType": "uniques", + "table": "positions" + }, + { + "columns": [ + "slug" + ], + "nameExplicit": false, + "name": "dms_groups_slug_unique", + "entityType": "uniques", + "table": "dms_groups" + } + ], + "renames": [] +} \ No newline at end of file diff --git a/packages/db/src/schema/documentManagementSystem.ts b/packages/db/src/schema/documentManagementSystem.ts index ba506998..af681de5 100644 --- a/packages/db/src/schema/documentManagementSystem.ts +++ b/packages/db/src/schema/documentManagementSystem.ts @@ -12,6 +12,7 @@ export const dmsDocuments = sqliteTable( description: text(), groupId: text().references(() => dmsGroups.id, { onDelete: "set null" }), short: text(), + sort: int().notNull().default(99), }, (table) => [index("dms_documents_group_id_idx").on(table.groupId)], ); @@ -23,6 +24,7 @@ export const dmsGroups = sqliteTable("dms_groups", { .$defaultFn(() => crypto.randomUUID()), name: text().notNull(), sort: int().notNull().default(99), + slug: text().notNull().unique(), }); export type DmsGroup = InferSelectModel; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31a1d137..f3f6cdd7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -486,6 +486,9 @@ importers: specifier: ^13.0.0 version: 13.0.0 devDependencies: + '@libsql/client': + specifier: ^0.15.0 + version: 0.15.9 dotenv: specifier: ^16.5.0 version: 16.6.1 @@ -3812,20 +3815,17 @@ packages: transitivePeerDependencies: - bufferutil - utf-8-validate - dev: false /@libsql/core@0.15.9: resolution: {integrity: sha512-4OVdeAmuaCUq5hYT8NNn0nxlO9AcA/eTjXfUZ+QK8MT3Dz7Z76m73x7KxjU6I64WyXX98dauVH2b9XM+d84npw==} dependencies: js-base64: 3.7.7 - dev: false /@libsql/darwin-arm64@0.5.13: resolution: {integrity: sha512-ASz/EAMLDLx3oq9PVvZ4zBXXHbz2TxtxUwX2xpTRFR4V4uSHAN07+jpLu3aK5HUBLuv58z7+GjaL5w/cyjR28Q==} cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@libsql/darwin-x64@0.5.13: @@ -3833,7 +3833,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@libsql/hrana-client@0.7.0: @@ -3846,12 +3845,10 @@ packages: transitivePeerDependencies: - bufferutil - utf-8-validate - dev: false /@libsql/isomorphic-fetch@0.3.1: resolution: {integrity: sha512-6kK3SUK5Uu56zPq/Las620n5aS9xJq+jMBcNSOmjhNf/MUvdyji4vrMTqD7ptY7/4/CAVEAYDeotUz60LNQHtw==} engines: {node: '>=18.0.0'} - dev: false /@libsql/isomorphic-ws@0.1.5: resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==} @@ -3861,14 +3858,12 @@ packages: transitivePeerDependencies: - bufferutil - utf-8-validate - dev: false /@libsql/linux-arm-gnueabihf@0.5.13: resolution: {integrity: sha512-UEW+VZN2r0mFkfztKOS7cqfS8IemuekbjUXbXCwULHtusww2QNCXvM5KU9eJCNE419SZCb0qaEWYytcfka8qeA==} cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@libsql/linux-arm-musleabihf@0.5.13: @@ -3876,7 +3871,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@libsql/linux-arm64-gnu@0.5.13: @@ -3884,7 +3878,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@libsql/linux-arm64-musl@0.5.13: @@ -3892,7 +3885,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@libsql/linux-x64-gnu@0.5.13: @@ -3900,7 +3892,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@libsql/linux-x64-musl@0.5.13: @@ -3908,7 +3899,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@libsql/win32-x64-msvc@0.5.13: @@ -3916,7 +3906,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /@lucide/svelte@0.577.0(svelte@5.46.1): @@ -3929,7 +3918,6 @@ packages: /@neon-rs/load@0.0.4: resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} - dev: false /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -5748,7 +5736,6 @@ packages: resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} dependencies: '@types/node': 22.15.31 - dev: false /@typescript-eslint/eslint-plugin@8.34.0(@typescript-eslint/parser@8.34.0)(eslint@9.39.4)(typescript@5.8.3): resolution: {integrity: sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==} @@ -6217,7 +6204,6 @@ packages: /data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} - dev: false /debug@4.4.1: resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} @@ -6279,7 +6265,6 @@ packages: /detect-libc@2.0.2: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} - dev: false /detect-libc@2.0.4: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} @@ -7097,7 +7082,6 @@ packages: dependencies: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 - dev: false /file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} @@ -7152,7 +7136,6 @@ packages: engines: {node: '>=12.20.0'} dependencies: fetch-blob: 3.2.0 - dev: false /forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} @@ -7447,7 +7430,6 @@ packages: /js-base64@3.7.7: resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} - dev: false /js-md4@0.3.2: resolution: {integrity: sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==} @@ -7551,7 +7533,6 @@ packages: '@libsql/linux-x64-gnu': 0.5.13 '@libsql/linux-x64-musl': 0.5.13 '@libsql/win32-x64-msvc': 0.5.13 - dev: false /lightningcss-android-arm64@1.31.1: resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} @@ -7898,7 +7879,6 @@ packages: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} deprecated: Use your platform's native DOMException instead - dev: false /node-fetch@3.3.2: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} @@ -7907,7 +7887,6 @@ packages: data-uri-to-buffer: 4.0.1 fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 - dev: false /object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} @@ -8218,7 +8197,6 @@ packages: /promise-limit@2.7.0: resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} - dev: false /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} @@ -9126,7 +9104,6 @@ packages: /web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} - dev: false /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} @@ -9258,7 +9235,6 @@ packages: optional: true utf-8-validate: optional: true - dev: false /wsl-utils@0.1.0: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} From 439af1549ad39ee16a01ac517d371883d428c404 Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Wed, 18 Mar 2026 21:58:53 -0700 Subject: [PATCH 08/10] add create document --- apps/overseer/src/lib/remote/dms.remote.ts | 85 +++++++++++- .../src/routes/a/dms/groups/[id]/+page.svelte | 18 ++- .../dms/groups/[id]/new-document/+page.svelte | 123 ++++++++++++++++++ packages/common/src/models/dms.ts | 4 +- 4 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 apps/overseer/src/routes/a/dms/groups/[id]/new-document/+page.svelte diff --git a/apps/overseer/src/lib/remote/dms.remote.ts b/apps/overseer/src/lib/remote/dms.remote.ts index 2ee67e2e..83d764e9 100644 --- a/apps/overseer/src/lib/remote/dms.remote.ts +++ b/apps/overseer/src/lib/remote/dms.remote.ts @@ -3,6 +3,7 @@ import { db } from '$lib/db'; import { DmsDocument, DmsGroup, User } from '@czqm/common'; import { error, invalid, redirect } from '@sveltejs/kit'; import { type } from 'arktype'; +import { asc } from 'drizzle-orm'; export const getDocuments = query(async () => { const event = getRequestEvent(); @@ -37,7 +38,11 @@ export const getDocumentsByGroup = query(type('string'), async (groupId) => { throw error(404, 'Group not found'); } - return group.documents; + return await db.query.dmsDocuments.findMany({ + where: { groupId }, + with: { group: true }, + orderBy: (document) => [asc(document.sort), asc(document.name)] + }); }); export const getGroups = query(async () => { @@ -117,6 +122,84 @@ export const createGroup = form( } ); +export const createDocument = form( + type({ + groupId: 'string', + name: type.string.pipe((str) => str.trim()), + required: type.string.pipe((value) => value === 'true'), + short: 'string?', + description: 'string?', + sort: type('string|number|undefined').pipe((value) => { + if (value === undefined || value === '') { + return 99; + } + + if (typeof value === 'number') { + return value; + } + + return Number(value); + }) + }), + async ({ groupId, name, required, short, description, sort }, issue) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user || !user.hasFlag(['admin', 'staff'])) { + throw error(401, 'Unauthorized'); + } + + if (name.length === 0) { + invalid(issue.name('Name is required')); + } + + if (!Number.isFinite(sort)) { + invalid(issue.sort('Sort must be a number')); + } + + if (!(0 <= sort && sort <= 99)) { + invalid(issue.sort('Sort must be a number between 0 and 99')); + } + + const group = await DmsGroup.fromId(db, groupId); + + if (!group) { + invalid(issue.groupId('Group not found')); + } + + const normalizedShort = short?.trim().toLowerCase() || null; + + if (normalizedShort) { + const documents = await DmsDocument.fetchAll(db); + const hasDuplicateShort = documents.some( + (document) => document.short?.trim().toLowerCase() === normalizedShort + ); + + if (hasDuplicateShort) { + invalid(issue.short('Short URL is already in use')); + } + } + + await DmsDocument.create(db, { + groupId, + name, + required, + short: normalizedShort, + description: description?.trim() ? description.trim() : null, + sort + }); + + getGroup(groupId).refresh(); + getDocumentsByGroup(groupId).refresh(); + getDocuments().refresh(); + + return redirect(303, `/a/dms/groups/${groupId}`); + } +); + export const deleteGroup = command(type('string'), async (id) => { const event = getRequestEvent(); const user = await User.resolveAuthenticatedUser(db, { diff --git a/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte b/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte index bade0bcf..e054ad49 100644 --- a/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte +++ b/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte @@ -26,12 +26,18 @@ Back to DMS +
    {#await getDocumentsByGroup(id)}

    Loading documents...

    {:then documents} + {@const sortedDocuments = [...documents].sort( + (a, b) => (a.sort ?? 99) - (b.sort ?? 99) || a.name.localeCompare(b.name) + )} @@ -43,20 +49,24 @@ - {#if documents.length === 0} + {#if sortedDocuments.length === 0} {:else} - {#each documents as { id: documentId, name, short, required, sort }, index (documentId)} + {#each sortedDocuments as { id: documentId, name, short, required, sort, group }, index (documentId)} - + {#if short} + + {:else} + + {/if} - + {/each} {/if} diff --git a/apps/overseer/src/routes/a/dms/groups/[id]/new-document/+page.svelte b/apps/overseer/src/routes/a/dms/groups/[id]/new-document/+page.svelte new file mode 100644 index 00000000..27d327c8 --- /dev/null +++ b/apps/overseer/src/routes/a/dms/groups/[id]/new-document/+page.svelte @@ -0,0 +1,123 @@ + + +
    +
    + {#await getGroup(id)} +

    Create Document: Loading Group

    + {:then group} +

    Create Document: {group.name}

    + {:catch error} +

    Error loading group: {error.message}

    + {/await} + + + Back to Group + +
    + +
    + + +
    + Document Name + +

    + {createDocument.fields.name + .issues() + ?.map((issue) => issue.message) + .join(' ')} +

    + {#if hasDuplicateName} +

    Document name must be unique.

    + {/if} +
    + +
    + Short Name + +

    + {createDocument.fields.short + .issues() + ?.map((issue) => issue.message) + .join(' ')} +

    +

    Optional short label used in compact views.

    +
    + +
    + Description + +

    Optional additional details for this document type.

    +
    + +
    + Required + +
    + +
    + Sort Order + +

    + {createDocument.fields.sort + .issues() + ?.map((issue) => issue.message) + .join(' ')} +

    +

    Documents are sorted from 0-99 by this value.

    +
    + +

    + {createDocument.fields.groupId + .issues() + ?.map((issue) => issue.message) + .join(' ')} +

    + + + +
    +
    diff --git a/packages/common/src/models/dms.ts b/packages/common/src/models/dms.ts index 5d69543f..4ac0799d 100644 --- a/packages/common/src/models/dms.ts +++ b/packages/common/src/models/dms.ts @@ -276,7 +276,7 @@ export class DmsGroup { where: { id }, with: { documents: { - orderBy: (document) => [asc(document.name)], + orderBy: (document) => [asc(document.sort), asc(document.name)], }, }, }); @@ -305,6 +305,7 @@ export class DmsGroup { description: document.description, groupId: document.groupId, short: document.short, + sort: document.sort ?? 99, group: dmsGroup, }, db, @@ -357,6 +358,7 @@ export class DmsGroup { description: document.description, groupId: document.groupId, short: document.short, + sort: document.sort ?? 99, group: dmsGroup, }, db, From 6c5fde38603c1826ef00785688b659e74254598e Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Fri, 10 Apr 2026 13:54:47 -0700 Subject: [PATCH 09/10] add ability to upload and manage assets among other features --- .cursor/settings.json | 7 + apps/overseer/src/lib/env.ts | 6 +- apps/overseer/src/lib/publicEnv.ts | 6 +- apps/overseer/src/lib/remote/dms.remote.ts | 315 ++++++++- apps/overseer/src/routes/a/dms/+page.svelte | 5 +- .../src/routes/a/dms/document/+page.ts | 6 + .../routes/a/dms/document/[id]/+page.svelte | 652 ++++++++++++++++++ .../src/routes/a/dms/groups/[id]/+page.svelte | 7 + .../dms/groups/[id]/new-document/+page.svelte | 35 +- apps/web/package.json | 1 + .../[groupSlug]/[documentShort]/+server.ts | 64 ++ packages/common/src/models/dms.ts | 111 ++- .../db/src/schema/documentManagementSystem.ts | 2 +- pnpm-lock.yaml | 434 +++++++----- 14 files changed, 1461 insertions(+), 190 deletions(-) create mode 100644 .cursor/settings.json create mode 100644 apps/overseer/src/routes/a/dms/document/+page.ts create mode 100644 apps/overseer/src/routes/a/dms/document/[id]/+page.svelte create mode 100644 apps/web/src/routes/docs/[groupSlug]/[documentShort]/+server.ts diff --git a/.cursor/settings.json b/.cursor/settings.json new file mode 100644 index 00000000..6595b051 --- /dev/null +++ b/.cursor/settings.json @@ -0,0 +1,7 @@ +{ + "plugins": { + "svelte": { + "enabled": true + } + } +} diff --git a/apps/overseer/src/lib/env.ts b/apps/overseer/src/lib/env.ts index 07e44c33..a8fcf05a 100644 --- a/apps/overseer/src/lib/env.ts +++ b/apps/overseer/src/lib/env.ts @@ -10,7 +10,8 @@ export const Env = type({ R2_BUCKET_NAME: 'string', TURSO_URL: 'string', TURSO_TOKEN: 'string', - PUBLIC_WEB_URL: 'string.url' + PUBLIC_WEB_URL: 'string.url', + PUBLIC_FILES_BASE_URL: 'string.url' }); let parsedEnv: typeof Env.infer | undefined; @@ -19,7 +20,8 @@ function getEnv(): typeof Env.infer { if (!parsedEnv) { const result = Env({ ...dynamicPrivateEnv, - ...dynamicPublicEnv + ...dynamicPublicEnv, + PUBLIC_FILES_BASE_URL: dynamicPublicEnv.PUBLIC_FILES_BASE_URL ?? 'https://files.czqm.ca' }); if (result instanceof type.errors) { diff --git a/apps/overseer/src/lib/publicEnv.ts b/apps/overseer/src/lib/publicEnv.ts index cdfa3459..2681fb00 100644 --- a/apps/overseer/src/lib/publicEnv.ts +++ b/apps/overseer/src/lib/publicEnv.ts @@ -2,11 +2,13 @@ import { type } from 'arktype'; import { env as dynamicPublicEnv } from '$env/dynamic/public'; export const Env = type({ - PUBLIC_WEB_URL: 'string.url' + PUBLIC_WEB_URL: 'string.url', + PUBLIC_FILES_BASE_URL: 'string.url' }); const parsedEnv = Env({ - ...dynamicPublicEnv + ...dynamicPublicEnv, + PUBLIC_FILES_BASE_URL: dynamicPublicEnv.PUBLIC_FILES_BASE_URL ?? 'https://files.czqm.ca' }); if (parsedEnv instanceof type.errors) { diff --git a/apps/overseer/src/lib/remote/dms.remote.ts b/apps/overseer/src/lib/remote/dms.remote.ts index 83d764e9..a4810bc3 100644 --- a/apps/overseer/src/lib/remote/dms.remote.ts +++ b/apps/overseer/src/lib/remote/dms.remote.ts @@ -1,9 +1,11 @@ import { command, form, getRequestEvent, query } from '$app/server'; import { db } from '$lib/db'; -import { DmsDocument, DmsGroup, User } from '@czqm/common'; +import env from '$lib/env'; +import { DmsAsset, DmsDocument, DmsGroup, User } from '@czqm/common'; import { error, invalid, redirect } from '@sveltejs/kit'; import { type } from 'arktype'; import { asc } from 'drizzle-orm'; +import { DeleteObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3'; export const getDocuments = query(async () => { const event = getRequestEvent(); @@ -21,6 +23,305 @@ export const getDocuments = query(async () => { return documents; }); +export const getDocument = query(type('string'), async (id: string) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user) { + throw error(401, 'Unauthorized'); + } + + const document = await DmsDocument.fromId(db, id); + + if (!document) { + throw error(404, 'Document not found'); + } + + return document; +}); + +export const editDocument = form( + type({ + id: 'string', + name: 'string', + short: 'string', + sort: type('string').pipe((value) => { + if (value === '') { + return 99; + } + + return Number(value); + }), + required: type('string').pipe((value) => value === 'true'), + description: 'string?' + }), + async ({ sort, short, id, name, required, description }, issue) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user || !user.hasFlag(['admin', 'staff'])) { + throw error(401, 'Unauthorized'); + } + + if (!(0 <= sort && sort <= 99)) { + invalid(issue.sort('Sort must be a number between 0 and 99')); + } + + if (!/^[a-z0-9-]+$/i.test(short)) { + invalid(issue.short('Short URL may only contain letters, numbers, and dashes')); + } + + const normalizedName = name.trim(); + const normalizedShort = short.trim().toLowerCase(); + const normalizedDescription = description?.trim() ? description.trim() : null; + + await DmsDocument.update(db, id, { + name: normalizedName, + required, + short: normalizedShort, + description: normalizedDescription, + sort + }); + + getDocuments().refresh(); + getDocument(id).refresh(); + + return { + ok: true, + message: 'Document details updated successfully.' + }; + } +); + +const getSingleValue = (value: unknown) => { + if (Array.isArray(value)) { + return value[0]; + } + + return value; +}; + +const sanitizeFileName = (name: string) => name.replace(/[^a-zA-Z0-9._-]/g, '_'); + +const parseDateInput = (value: unknown) => { + if (typeof value !== 'string' || value.trim().length === 0) { + return null; + } + + // datetime-local inputs do not include timezone information. + // Treat them as UTC so UI and stored values stay consistent. + const date = new Date(`${value}Z`); + return Number.isNaN(date.getTime()) ? null : date; +}; + +const getR2Client = () => + new S3Client({ + region: 'auto', + endpoint: `https://${env.CLOUDFLARE_ACCOUNT_ID}.r2.cloudflarestorage.com`, + credentials: { + accessKeyId: env.R2_ACCESS_KEY_ID, + secretAccessKey: env.R2_ACCESS_KEY + } + }); + +const uploadDmsAsset = async (documentId: string, file: File) => { + const fileName = `dms/${documentId}/${Date.now()}-${sanitizeFileName(file.name)}`; + const s3 = getR2Client(); + + try { + await s3.send( + new PutObjectCommand({ + Bucket: env.R2_BUCKET_NAME, + Key: fileName, + Body: new Uint8Array(await file.arrayBuffer()), + ContentType: file.type + }) + ); + } catch { + throw error(500, 'Failed to upload document asset'); + } + + return fileName; +}; + +export const createDocumentAsset = form('unchecked', async (rawData) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user || !user.hasFlag(['admin', 'staff'])) { + throw error(401, 'Unauthorized'); + } + + const documentId = getSingleValue(rawData.documentId); + const versionInput = getSingleValue(rawData.version); + const effectiveDateInput = getSingleValue(rawData.effectiveDate); + const expiryDateInput = getSingleValue(rawData.expiryDate); + const fileInput = getSingleValue(rawData.file); + const isPublic = getSingleValue(rawData.public) === 'on'; + + if (typeof documentId !== 'string' || documentId.length === 0) { + throw error(400, 'Document id is required'); + } + + if (typeof versionInput !== 'string' || versionInput.trim().length === 0) { + throw error(400, 'Version is required'); + } + + const file = fileInput instanceof File ? fileInput : undefined; + if (!file || file.name.length === 0 || file.size === 0) { + throw error(400, 'Document asset file is required'); + } + + const effectiveDate = parseDateInput(effectiveDateInput); + if (!effectiveDate) { + throw error(400, 'Effective date is required'); + } + + const expiryDate = parseDateInput(expiryDateInput); + if ( + expiryDate && + expiryDate.getTime() <= effectiveDate.getTime() + ) { + throw error(400, 'Expiry date must be after the effective date'); + } + + let document: DmsDocument; + try { + document = await DmsDocument.fromId(db, documentId); + } catch { + throw error(404, 'Document not found'); + } + + const url = await uploadDmsAsset(document.id, file); + + await DmsAsset.create(db, { + documentId: document.id, + version: versionInput.trim(), + effectiveDate, + expiryDate, + public: isPublic, + url + }); + + getDocument(document.id).refresh(); + getDocuments().refresh(); + + return { + ok: true, + message: 'Document asset uploaded successfully.' + }; +}); + +export const updateDocumentAsset = form('unchecked', async (rawData) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user || !user.hasFlag(['admin', 'staff'])) { + throw error(401, 'Unauthorized'); + } + + const assetId = getSingleValue(rawData.assetId); + const effectiveDateInput = getSingleValue(rawData.effectiveDate); + const expiryDateInput = getSingleValue(rawData.expiryDate); + const isPublic = getSingleValue(rawData.public) === 'on'; + + if (typeof assetId !== 'string' || assetId.length === 0) { + return { ok: false, message: 'Asset id is required.' }; + } + + const effectiveDate = parseDateInput(effectiveDateInput); + if (!effectiveDate) { + return { ok: false, message: 'Effective date is required.' }; + } + + const expiryDate = parseDateInput(expiryDateInput); + if (expiryDate && expiryDate.getTime() <= effectiveDate.getTime()) { + return { ok: false, message: 'Expiry date must be after the effective date.' }; + } + + let asset: DmsAsset; + try { + asset = await DmsAsset.fromId(db, assetId); + } catch { + return { ok: false, message: 'Asset not found.' }; + } + + await DmsAsset.update(db, asset.id, { + documentId: asset.documentId, + version: asset.version, + effectiveDate, + expiryDate, + public: isPublic, + url: asset.url + }); + + getDocument(asset.documentId).refresh(); + getDocuments().refresh(); + + return { + ok: true, + message: 'Document asset updated successfully.' + }; +}); + +export const deleteDocumentAsset = form('unchecked', async (rawData) => { + const event = getRequestEvent(); + const user = await User.resolveAuthenticatedUser(db, { + cid: event.locals.user?.cid, + sessionToken: event.cookies.get('session') + }); + + if (!user || !user.hasFlag(['admin', 'staff'])) { + throw error(401, 'Unauthorized'); + } + + const assetId = getSingleValue(rawData.assetId); + if (typeof assetId !== 'string' || assetId.length === 0) { + return { ok: false, message: 'Asset id is required.' }; + } + + let asset: DmsAsset; + try { + asset = await DmsAsset.fromId(db, assetId); + } catch { + return { ok: false, message: 'Asset not found.' }; + } + + const s3 = getR2Client(); + try { + await s3.send( + new DeleteObjectCommand({ + Bucket: env.R2_BUCKET_NAME, + Key: asset.url + }) + ); + } catch { + return { ok: false, message: 'Failed to delete asset file from R2.' }; + } + + await DmsAsset.remove(db, asset.id); + + getDocument(asset.documentId).refresh(); + getDocuments().refresh(); + + return { + ok: true, + message: 'Document asset deleted successfully.' + }; +}); + export const getDocumentsByGroup = query(type('string'), async (groupId) => { const event = getRequestEvent(); const user = await User.resolveAuthenticatedUser(db, { @@ -127,17 +428,13 @@ export const createDocument = form( groupId: 'string', name: type.string.pipe((str) => str.trim()), required: type.string.pipe((value) => value === 'true'), - short: 'string?', + short: 'string', description: 'string?', - sort: type('string|number|undefined').pipe((value) => { - if (value === undefined || value === '') { + sort: type('string').pipe((value) => { + if (value === '') { return 99; } - if (typeof value === 'number') { - return value; - } - return Number(value); }) }), @@ -170,7 +467,7 @@ export const createDocument = form( invalid(issue.groupId('Group not found')); } - const normalizedShort = short?.trim().toLowerCase() || null; + const normalizedShort = short?.trim().toLowerCase(); if (normalizedShort) { const documents = await DmsDocument.fetchAll(db); diff --git a/apps/overseer/src/routes/a/dms/+page.svelte b/apps/overseer/src/routes/a/dms/+page.svelte index 2e0b118e..c74d0a46 100644 --- a/apps/overseer/src/routes/a/dms/+page.svelte +++ b/apps/overseer/src/routes/a/dms/+page.svelte @@ -104,7 +104,10 @@

    Are you sure you want to delete {selectedGroupName}?

    -

    This action cannot be undone.

    +

    + Warning: deleting this group will also delete all documents within the group. This + action cannot be undone. +

    No documents found for this group.
    {index + 1} {name}{short ?? '-'}{group?.slug} / {short}-{required ? 'Yes' : 'No'}{sort}{sort ?? 99}
    + + + + + + + + + + + + + {#if currentDocument.assets.length === 0} + + + + {:else} + {#each currentDocument.assets as asset (asset.id)} + + + + + + + + + + {/each} + {/if} + +
    VersionStatusPublicEffectiveExpiryAssetActions
    No assets uploaded yet.
    {asset.version}{getAssetStatus(asset)}{asset.public ? 'Yes' : 'No'}{formatDate(asset.effectiveDate)}{formatDate(asset.expiryDate)} + + View + + +
    + + +
    +
    +
    + {#each currentDocument.assets as asset (asset.id)} + + + + {/each} + + + + + {#if updateAssetMessage} +

    + {updateAssetMessage.text} +

    + {/if} + {#if deleteAssetMessage} +

    + {deleteAssetMessage.text} +

    + {/if} + + {/if} + +
    + + diff --git a/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte b/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte index e054ad49..a096df1b 100644 --- a/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte +++ b/apps/overseer/src/routes/a/dms/groups/[id]/+page.svelte @@ -46,6 +46,7 @@ Short Required Sort + @@ -67,6 +68,12 @@ {/if} {required ? 'Yes' : 'No'} {sort ?? 99} + + Manage + {/each} {/if} diff --git a/apps/overseer/src/routes/a/dms/groups/[id]/new-document/+page.svelte b/apps/overseer/src/routes/a/dms/groups/[id]/new-document/+page.svelte index 27d327c8..ef8b8882 100644 --- a/apps/overseer/src/routes/a/dms/groups/[id]/new-document/+page.svelte +++ b/apps/overseer/src/routes/a/dms/groups/[id]/new-document/+page.svelte @@ -1,7 +1,7 @@
    @@ -51,8 +67,6 @@
    - -
    Document Name
    - Short Name - + Short URL +

    {createDocument.fields.short .issues() ?.map((issue) => issue.message) .join(' ')}

    -

    Optional short label used in compact views.

    +

    The short identifier for this document used in URLs

    @@ -110,6 +130,7 @@

    Documents are sorted from 0-99 by this value.

    +

    {createDocument.fields.groupId .issues() diff --git a/apps/web/package.json b/apps/web/package.json index 800099c1..418a6c36 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -48,6 +48,7 @@ "wrangler": "^3.99.0" }, "dependencies": { + "@aws-sdk/client-s3": "^3.916.0", "@czqm/common": "workspace:*", "@czqm/db": "workspace:*", "@libsql/client": "^0.15.0", diff --git a/apps/web/src/routes/docs/[groupSlug]/[documentShort]/+server.ts b/apps/web/src/routes/docs/[groupSlug]/[documentShort]/+server.ts new file mode 100644 index 00000000..fe97b5a8 --- /dev/null +++ b/apps/web/src/routes/docs/[groupSlug]/[documentShort]/+server.ts @@ -0,0 +1,64 @@ +import { db } from '$lib/db'; +import { DmsDocument } from '@czqm/common'; +import { GetObjectCommand, S3Client, type GetObjectCommandOutput } from '@aws-sdk/client-s3'; +import { env } from '$env/dynamic/private'; +import { error, type RequestHandler } from '@sveltejs/kit'; + +const getR2Client = () => + new S3Client({ + region: 'auto', + endpoint: `https://${env.CLOUDFLARE_ACCOUNT_ID}.r2.cloudflarestorage.com`, + credentials: { + accessKeyId: env.R2_ACCESS_KEY_ID, + secretAccessKey: env.R2_ACCESS_KEY + } + }); + +export const GET: RequestHandler = async ({ params }) => { + const document = await DmsDocument.fromGroupSlugAndShort( + db, + params.groupSlug ?? '', + params.documentShort ?? '' + ); + + if (!document) { + throw error(404, 'Document not found'); + } + + const currentAsset = document.getCurrentAsset(); + if (!currentAsset) { + throw error(404, 'No current asset available for this document'); + } + + const s3 = getR2Client(); + let assetObject: GetObjectCommandOutput; + try { + assetObject = await s3.send( + new GetObjectCommand({ + Bucket: env.R2_BUCKET_NAME, + Key: currentAsset.url + }) + ); + } catch { + throw error(500, 'Failed to fetch asset from R2'); + } + + if (!assetObject.Body) { + throw error(404, 'Asset file not found'); + } + + const body = await assetObject.Body.transformToByteArray(); + const headers = new Headers({ + 'Content-Type': assetObject.ContentType ?? 'application/octet-stream', + 'Cache-Control': 'public, max-age=60' + }); + + if (typeof assetObject.ContentLength === 'number') { + headers.set('Content-Length', String(assetObject.ContentLength)); + } + + return new Response(body, { + status: 200, + headers + }); +}; diff --git a/packages/common/src/models/dms.ts b/packages/common/src/models/dms.ts index 4ac0799d..3210a67a 100644 --- a/packages/common/src/models/dms.ts +++ b/packages/common/src/models/dms.ts @@ -5,9 +5,9 @@ import type { DB } from "../db"; type CreateDmsDocumentInput = { required: boolean; name: string; + short: string; description?: string | null; groupId?: string | null; - short?: string | null; sort?: number; }; @@ -16,7 +16,7 @@ type UpdateDmsDocumentInput = { name: string; description?: string | null; groupId?: string | null; - short?: string | null; + short: string; sort?: number; }; @@ -50,13 +50,72 @@ type UpdateDmsAssetInput = { url: string; }; +type DmsAssetLike = { + id: string; + effectiveDate: Date | string; + expiryDate: Date | string | null; + public: boolean; +}; + +const toDate = (value: Date | string | null | undefined) => { + if (!value) { + return null; + } + + const date = value instanceof Date ? value : new Date(value); + return Number.isNaN(date.getTime()) ? null : date; +}; + +export const getCurrentDmsAsset = ( + assets: T[], + nowInput: Date | string = new Date(), +): T | null => { + const now = toDate(nowInput); + if (!now) { + return null; + } + + const eligibleAssets = assets.filter((asset) => { + if (!asset.public) { + return false; + } + + const effectiveDate = toDate(asset.effectiveDate); + if (!effectiveDate || effectiveDate > now) { + return false; + } + + const expiryDate = toDate(asset.expiryDate); + if (expiryDate && expiryDate <= now) { + return false; + } + + return true; + }); + + if (eligibleAssets.length === 0) { + return null; + } + + return eligibleAssets.sort((a, b) => { + const aEffective = toDate(a.effectiveDate)?.getTime() ?? 0; + const bEffective = toDate(b.effectiveDate)?.getTime() ?? 0; + + if (aEffective !== bEffective) { + return bEffective - aEffective; + } + + return a.id.localeCompare(b.id); + })[0]; +}; + export class DmsDocument { id: string; required: boolean; name: string; description: string | null; groupId: string | null; - short: string | null; + short: string; assets: DmsAsset[]; group: DmsGroup | null; sort: number; @@ -69,7 +128,7 @@ export class DmsDocument { name: string; description: string | null; groupId: string | null; - short: string | null; + short: string; assets?: DmsAsset[]; group?: DmsGroup | null; sort?: number; @@ -149,6 +208,40 @@ export class DmsDocument { return dmsDocument; } + static async fromGroupSlugAndShort( + db: DB, + groupSlug: string, + documentShort: string, + ): Promise { + const normalizedGroupSlug = groupSlug.trim().toLowerCase(); + const normalizedDocumentShort = documentShort.trim().toLowerCase(); + + if (!normalizedGroupSlug || !normalizedDocumentShort) { + return null; + } + + const group = await db.query.dmsGroups.findFirst({ + where: { slug: normalizedGroupSlug }, + }); + + if (!group) { + return null; + } + + const document = await db.query.dmsDocuments.findFirst({ + where: { + groupId: group.id, + short: normalizedDocumentShort, + }, + }); + + if (!document) { + return null; + } + + return await DmsDocument.fromId(db, document.id); + } + static async fetchAll(db: DB): Promise { const documents = await db.query.dmsDocuments.findMany({ with: { @@ -215,9 +308,9 @@ export class DmsDocument { .values({ required: data.required, name: data.name, + short: data.short, description: data.description ?? null, groupId: data.groupId ?? null, - short: data.short ?? null, sort: data.sort ?? 99, }) .returning({ id: dmsDocuments.id }) @@ -234,7 +327,7 @@ export class DmsDocument { name: data.name, description: data.description ?? null, groupId: data.groupId ?? null, - short: data.short ?? null, + short: data.short, sort: data.sort ?? 99, }) .where(eq(dmsDocuments.id, id)); @@ -243,6 +336,10 @@ export class DmsDocument { static async remove(db: DB, id: string) { return await db.delete(dmsDocuments).where(eq(dmsDocuments.id, id)); } + + getCurrentAsset(now: Date | string = new Date()) { + return getCurrentDmsAsset(this.assets, now); + } } export class DmsGroup { @@ -358,7 +455,7 @@ export class DmsGroup { description: document.description, groupId: document.groupId, short: document.short, - sort: document.sort ?? 99, + sort: document.sort ?? 99, group: dmsGroup, }, db, diff --git a/packages/db/src/schema/documentManagementSystem.ts b/packages/db/src/schema/documentManagementSystem.ts index af681de5..77da7738 100644 --- a/packages/db/src/schema/documentManagementSystem.ts +++ b/packages/db/src/schema/documentManagementSystem.ts @@ -11,7 +11,7 @@ export const dmsDocuments = sqliteTable( name: text().notNull(), description: text(), groupId: text().references(() => dmsGroups.id, { onDelete: "set null" }), - short: text(), + short: text().notNull(), sort: int().notNull().default(99), }, (table) => [index("dms_documents_group_id_idx").on(table.groupId)], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f3f6cdd7..bfcd2e2a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,7 +16,7 @@ importers: version: 6.2.4(svelte@5.46.1)(vite@7.3.1) drizzle-orm: specifier: 1.0.0-beta.13-f728631 - version: 1.0.0-beta.13-f728631(@types/mssql@9.1.9)(mssql@11.0.1) + version: 1.0.0-beta.13-f728631(@types/mssql@9.1.11)(mssql@11.0.1) svelte: specifier: ^5.46.1 version: 5.46.1 @@ -47,13 +47,13 @@ importers: version: link:../../packages/db '@iconify/svelte': specifier: ^4.2.0 - version: 4.2.0(svelte@5.46.1) + version: 4.2.0(svelte@5.55.0) '@libsql/client': specifier: ^0.15.0 version: 0.15.9 '@lucide/svelte': specifier: ^0.577.0 - version: 0.577.0(svelte@5.46.1) + version: 0.577.0(svelte@5.55.0) '@oslojs/crypto': specifier: ^1.0.1 version: 1.0.1 @@ -81,22 +81,22 @@ importers: version: 9.39.4 '@sveltejs/adapter-auto': specifier: ^7.0.0 - version: 7.0.1(@sveltejs/kit@2.49.4) + version: 7.0.1(@sveltejs/kit@2.55.0) '@sveltejs/adapter-cloudflare': specifier: ^5.0.3 - version: 5.1.0(@sveltejs/kit@2.49.4)(wrangler@3.114.9) + version: 5.1.0(@sveltejs/kit@2.55.0)(wrangler@3.114.9) '@sveltejs/adapter-netlify': specifier: ^5.0.2 - version: 5.2.4(@sveltejs/kit@2.49.4) + version: 5.2.4(@sveltejs/kit@2.55.0) '@sveltejs/adapter-node': specifier: ^5.3.3 - version: 5.3.3(@sveltejs/kit@2.49.4) + version: 5.3.3(@sveltejs/kit@2.55.0) '@sveltejs/kit': specifier: ^2.49.4 - version: 2.49.4(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(typescript@5.8.3)(vite@7.3.1) + version: 2.55.0(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(typescript@5.8.3)(vite@7.3.1) '@sveltejs/vite-plugin-svelte': specifier: ^6.2.4 - version: 6.2.4(svelte@5.46.1)(vite@7.3.1) + version: 6.2.4(svelte@5.55.0)(vite@7.3.1) '@tailwindcss/vite': specifier: ^4.0.0 version: 4.2.1(vite@7.3.1) @@ -117,7 +117,7 @@ importers: version: 10.1.5(eslint@9.39.4) eslint-plugin-svelte: specifier: ^3.0.0 - version: 3.9.2(eslint@9.39.4)(svelte@5.46.1) + version: 3.9.2(eslint@9.39.4)(svelte@5.55.0) globals: specifier: ^16.0.0 version: 16.5.0 @@ -126,16 +126,16 @@ importers: version: 3.5.3 prettier-plugin-svelte: specifier: ^3.3.3 - version: 3.5.1(prettier@3.5.3)(svelte@5.46.1) + version: 3.5.1(prettier@3.5.3)(svelte@5.55.0) prettier-plugin-tailwindcss: specifier: ^0.6.11 version: 0.6.12(prettier-plugin-svelte@3.5.1)(prettier@3.5.3) svelte: specifier: ^5.46.1 - version: 5.46.1 + version: 5.55.0 svelte-check: specifier: ^4.0.0 - version: 4.4.5(svelte@5.46.1)(typescript@5.8.3) + version: 4.4.5(svelte@5.55.0)(typescript@5.8.3) tailwindcss: specifier: ^4.0.0 version: 4.2.1 @@ -165,13 +165,13 @@ importers: version: link:../../packages/db '@iconify/svelte': specifier: ^4.2.0 - version: 4.2.0(svelte@5.46.1) + version: 4.2.0(svelte@5.55.0) '@libsql/client': specifier: ^0.15.0 version: 0.15.9 '@lucide/svelte': specifier: ^0.577.0 - version: 0.577.0(svelte@5.46.1) + version: 0.577.0(svelte@5.55.0) '@oslojs/crypto': specifier: ^1.0.1 version: 1.0.1 @@ -199,22 +199,22 @@ importers: version: 9.39.4 '@sveltejs/adapter-auto': specifier: ^7.0.0 - version: 7.0.1(@sveltejs/kit@2.49.4) + version: 7.0.1(@sveltejs/kit@2.55.0) '@sveltejs/adapter-cloudflare': specifier: ^5.0.3 - version: 5.1.0(@sveltejs/kit@2.49.4)(wrangler@3.114.9) + version: 5.1.0(@sveltejs/kit@2.55.0)(wrangler@3.114.9) '@sveltejs/adapter-netlify': specifier: ^5.0.2 - version: 5.2.4(@sveltejs/kit@2.49.4) + version: 5.2.4(@sveltejs/kit@2.55.0) '@sveltejs/adapter-node': specifier: ^5.3.3 - version: 5.3.3(@sveltejs/kit@2.49.4) + version: 5.3.3(@sveltejs/kit@2.55.0) '@sveltejs/kit': specifier: ^2.49.4 - version: 2.49.4(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(typescript@5.8.3)(vite@7.3.1) + version: 2.55.0(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(typescript@5.8.3)(vite@7.3.1) '@sveltejs/vite-plugin-svelte': specifier: ^6.2.4 - version: 6.2.4(svelte@5.46.1)(vite@7.3.1) + version: 6.2.4(svelte@5.55.0)(vite@7.3.1) '@tailwindcss/vite': specifier: ^4.0.0 version: 4.2.1(vite@7.3.1) @@ -235,7 +235,7 @@ importers: version: 10.1.5(eslint@9.39.4) eslint-plugin-svelte: specifier: ^3.0.0 - version: 3.9.2(eslint@9.39.4)(svelte@5.46.1) + version: 3.9.2(eslint@9.39.4)(svelte@5.55.0) globals: specifier: ^16.0.0 version: 16.5.0 @@ -244,16 +244,16 @@ importers: version: 3.5.3 prettier-plugin-svelte: specifier: ^3.3.3 - version: 3.5.1(prettier@3.5.3)(svelte@5.46.1) + version: 3.5.1(prettier@3.5.3)(svelte@5.55.0) prettier-plugin-tailwindcss: specifier: ^0.6.11 version: 0.6.12(prettier-plugin-svelte@3.5.1)(prettier@3.5.3) svelte: specifier: ^5.46.1 - version: 5.46.1 + version: 5.55.0 svelte-check: specifier: ^4.0.0 - version: 4.4.5(svelte@5.46.1)(typescript@5.8.3) + version: 4.4.5(svelte@5.55.0)(typescript@5.8.3) tailwindcss: specifier: ^4.0.0 version: 4.2.1 @@ -272,6 +272,9 @@ importers: apps/web: dependencies: + '@aws-sdk/client-s3': + specifier: ^3.787.0 + version: 3.1009.0 '@czqm/common': specifier: workspace:* version: link:../../packages/common @@ -283,7 +286,7 @@ importers: version: 0.15.9 '@lucide/svelte': specifier: ^0.577.0 - version: 0.577.0(svelte@5.46.1) + version: 0.577.0(svelte@5.55.0) '@oslojs/crypto': specifier: ^1.0.1 version: 1.0.1 @@ -311,19 +314,19 @@ importers: version: 4.20260313.1 '@sveltejs/adapter-auto': specifier: ^7.0.0 - version: 7.0.1(@sveltejs/kit@2.49.4) + version: 7.0.1(@sveltejs/kit@2.55.0) '@sveltejs/adapter-cloudflare': specifier: ^5.0.0 - version: 5.1.0(@sveltejs/kit@2.49.4)(wrangler@3.114.9) + version: 5.1.0(@sveltejs/kit@2.55.0)(wrangler@3.114.9) '@sveltejs/adapter-netlify': specifier: ^5.0.2 - version: 5.2.4(@sveltejs/kit@2.49.4) + version: 5.2.4(@sveltejs/kit@2.55.0) '@sveltejs/kit': specifier: ^2.49.4 - version: 2.49.4(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(typescript@5.8.3)(vite@6.4.1) + version: 2.55.0(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(typescript@5.8.3)(vite@6.4.1) '@sveltejs/vite-plugin-svelte': specifier: ^6.2.4 - version: 6.2.4(svelte@5.46.1)(vite@6.4.1) + version: 6.2.4(svelte@5.55.0)(vite@6.4.1) '@tailwindcss/forms': specifier: ^0.5.9 version: 0.5.10(tailwindcss@4.2.1) @@ -350,25 +353,25 @@ importers: version: 10.1.5(eslint@9.39.4) eslint-plugin-svelte: specifier: ^2.36.0 - version: 2.46.1(eslint@9.39.4)(svelte@5.46.1) + version: 2.46.1(eslint@9.39.4)(svelte@5.55.0) globals: specifier: ^15.0.0 - version: 16.5.0 + version: 15.15.0 prettier: specifier: ^3.3.2 version: 3.5.3 prettier-plugin-svelte: specifier: ^3.2.6 - version: 3.5.1(prettier@3.5.3)(svelte@5.46.1) + version: 3.5.1(prettier@3.5.3)(svelte@5.55.0) prettier-plugin-tailwindcss: specifier: ^0.6.11 version: 0.6.12(prettier-plugin-svelte@3.5.1)(prettier@3.5.3) svelte: specifier: ^5.46.1 - version: 5.46.1 + version: 5.55.0 svelte-check: specifier: ^4.0.0 - version: 4.4.5(svelte@5.46.1)(typescript@5.8.3) + version: 4.4.5(svelte@5.55.0)(typescript@5.8.3) tailwindcss: specifier: ^4.0.13 version: 4.2.1 @@ -474,7 +477,7 @@ importers: version: 2.1.20 drizzle-orm: specifier: 1.0.0-beta.13-f728631 - version: 1.0.0-beta.13-f728631(@types/mssql@9.1.9)(mssql@11.0.1) + version: 1.0.0-beta.13-f728631(@types/mssql@9.1.11)(mssql@11.0.1) devDependencies: typescript: specifier: ^5.0.0 @@ -486,9 +489,6 @@ importers: specifier: ^13.0.0 version: 13.0.0 devDependencies: - '@libsql/client': - specifier: ^0.15.0 - version: 0.15.9 dotenv: specifier: ^16.5.0 version: 16.6.1 @@ -550,8 +550,8 @@ packages: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.957.0 - '@aws-sdk/util-locate-window': 3.804.0 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-locate-window': 3.965.5 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 dev: false @@ -561,7 +561,7 @@ packages: engines: {node: '>=16.0.0'} dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.957.0 + '@aws-sdk/types': 3.973.6 tslib: 2.8.1 dev: false @@ -1415,13 +1415,6 @@ packages: tslib: 2.8.1 dev: false - /@aws-sdk/util-locate-window@3.804.0: - resolution: {integrity: sha512-zVoRfpmBVPodYlnMjgVjfGoEZagyRF5IPn3Uo6ZvOZp24chnW/FRstH7ESDHDDRga4z3V+ElUQHKpFDXWyBW5A==} - engines: {node: '>=18.0.0'} - dependencies: - tslib: 2.8.1 - dev: false - /@aws-sdk/util-locate-window@3.965.5: resolution: {integrity: sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==} engines: {node: '>=20.0.0'} @@ -1619,8 +1612,8 @@ packages: - supports-color dev: false - /@azure/identity@4.13.0: - resolution: {integrity: sha512-uWC0fssc+hs1TGGVkkghiaFkkS7NkTxfnCH+Hdg+yTehTpMcehpok4PgUKKdyCH+9ldu6FhiHRv84Ntqj1vVcw==} + /@azure/identity@4.13.1: + resolution: {integrity: sha512-5C/2WD5Vb1lHnZS16dNQRPMjN6oV/Upba+C9nBIs15PmOi6A3ZGs4Lr2u60zw4S04gi+u3cEXiqTVP7M4Pz3kw==} engines: {node: '>=20.0.0'} dependencies: '@azure/abort-controller': 2.1.2 @@ -1630,8 +1623,8 @@ packages: '@azure/core-tracing': 1.3.1 '@azure/core-util': 1.13.1 '@azure/logger': 1.3.0 - '@azure/msal-browser': 4.29.1 - '@azure/msal-node': 3.8.9 + '@azure/msal-browser': 5.6.1 + '@azure/msal-node': 5.1.1 open: 10.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -1685,23 +1678,23 @@ packages: - supports-color dev: false - /@azure/msal-browser@4.29.1: - resolution: {integrity: sha512-1Vrt27du1cl4QHkzLc6L4aeXqliPIDIs5l/1I4hWWMXkXccY/EznJT1+pBdoVze0azTAI8sCyq5B4cBVYG1t9w==} + /@azure/msal-browser@5.6.1: + resolution: {integrity: sha512-Ylmp8yngH7YRLV5mA1aF4CNS6WsJTPbVXaA0Tb1x1Gv/J3BM3hE4Q7nDaf7dRfU00FcxDBBudTjqlpH74ZSsgw==} engines: {node: '>=0.8.0'} dependencies: - '@azure/msal-common': 15.16.1 + '@azure/msal-common': 16.4.0 dev: false - /@azure/msal-common@15.16.1: - resolution: {integrity: sha512-qxUG9TCl+TVSSX58onVDHDWrvT5CE0+NeeUAbkQqaESpSm79u5IePLnPWMMjCUnUR2zJd4+Bt9vioVRzLmJb2g==} + /@azure/msal-common@16.4.0: + resolution: {integrity: sha512-twXt09PYtj1PffNNIAzQlrBd0DS91cdA6i1gAfzJ6BnPM4xNk5k9q/5xna7jLIjU3Jnp0slKYtucshGM8OGNAw==} engines: {node: '>=0.8.0'} dev: false - /@azure/msal-node@3.8.9: - resolution: {integrity: sha512-jZ0pw/BbdEUWGhomCaAiVDfXRI/9K56m5hTNqB/CzcbZEYhXm5qpK1cDngN1iXfwSfmUMorOUQ2FC0dyuQ9uRg==} - engines: {node: '>=16'} + /@azure/msal-node@5.1.1: + resolution: {integrity: sha512-71grXU6+5hl+3CL3joOxlj/AW6rmhthuTlG0fRqsTrhPArQBpZuUFzCIlKOGdcafLUa/i1hBdV78ZxJdlvRA+g==} + engines: {node: '>=20'} dependencies: - '@azure/msal-common': 15.16.1 + '@azure/msal-common': 16.4.0 jsonwebtoken: 9.0.3 uuid: 8.3.2 dev: false @@ -1851,8 +1844,8 @@ packages: resolution: {integrity: sha512-hD3pekGiPg0WPCCGAZmusBBJsDqGUR66Y452YgQsZOnkdQ7ViEPKuyP4huUGEZQefp8g34RRodXYmJ2TbCH+tg==} dev: true - /@emnapi/runtime@1.9.0: - resolution: {integrity: sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==} + /@emnapi/runtime@1.9.1: + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} requiresBuild: true dependencies: tslib: 2.8.1 @@ -3564,13 +3557,13 @@ packages: resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} dev: true - /@iconify/svelte@4.2.0(svelte@5.46.1): + /@iconify/svelte@4.2.0(svelte@5.55.0): resolution: {integrity: sha512-fEl0T7SAPonK7xk6xUlRPDmFDZVDe2Z7ZstlqeDS/sS8ve2uyU+Qa8rTWbIqzZJlRvONkK5kVXiUf9nIc+6OOQ==} peerDependencies: svelte: ^5.46.1 dependencies: '@iconify/types': 2.0.0 - svelte: 5.46.1 + svelte: 5.55.0 dev: false /@iconify/types@2.0.0: @@ -3735,7 +3728,7 @@ packages: cpu: [wasm32] requiresBuild: true dependencies: - '@emnapi/runtime': 1.9.0 + '@emnapi/runtime': 1.9.1 dev: true optional: true @@ -3815,17 +3808,20 @@ packages: transitivePeerDependencies: - bufferutil - utf-8-validate + dev: false /@libsql/core@0.15.9: resolution: {integrity: sha512-4OVdeAmuaCUq5hYT8NNn0nxlO9AcA/eTjXfUZ+QK8MT3Dz7Z76m73x7KxjU6I64WyXX98dauVH2b9XM+d84npw==} dependencies: js-base64: 3.7.7 + dev: false /@libsql/darwin-arm64@0.5.13: resolution: {integrity: sha512-ASz/EAMLDLx3oq9PVvZ4zBXXHbz2TxtxUwX2xpTRFR4V4uSHAN07+jpLu3aK5HUBLuv58z7+GjaL5w/cyjR28Q==} cpu: [arm64] os: [darwin] requiresBuild: true + dev: false optional: true /@libsql/darwin-x64@0.5.13: @@ -3833,6 +3829,7 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true + dev: false optional: true /@libsql/hrana-client@0.7.0: @@ -3845,10 +3842,12 @@ packages: transitivePeerDependencies: - bufferutil - utf-8-validate + dev: false /@libsql/isomorphic-fetch@0.3.1: resolution: {integrity: sha512-6kK3SUK5Uu56zPq/Las620n5aS9xJq+jMBcNSOmjhNf/MUvdyji4vrMTqD7ptY7/4/CAVEAYDeotUz60LNQHtw==} engines: {node: '>=18.0.0'} + dev: false /@libsql/isomorphic-ws@0.1.5: resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==} @@ -3858,12 +3857,14 @@ packages: transitivePeerDependencies: - bufferutil - utf-8-validate + dev: false /@libsql/linux-arm-gnueabihf@0.5.13: resolution: {integrity: sha512-UEW+VZN2r0mFkfztKOS7cqfS8IemuekbjUXbXCwULHtusww2QNCXvM5KU9eJCNE419SZCb0qaEWYytcfka8qeA==} cpu: [arm] os: [linux] requiresBuild: true + dev: false optional: true /@libsql/linux-arm-musleabihf@0.5.13: @@ -3871,6 +3872,7 @@ packages: cpu: [arm] os: [linux] requiresBuild: true + dev: false optional: true /@libsql/linux-arm64-gnu@0.5.13: @@ -3878,6 +3880,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: false optional: true /@libsql/linux-arm64-musl@0.5.13: @@ -3885,6 +3888,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: false optional: true /@libsql/linux-x64-gnu@0.5.13: @@ -3892,6 +3896,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: false optional: true /@libsql/linux-x64-musl@0.5.13: @@ -3899,6 +3904,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: false optional: true /@libsql/win32-x64-msvc@0.5.13: @@ -3906,18 +3912,20 @@ packages: cpu: [x64] os: [win32] requiresBuild: true + dev: false optional: true - /@lucide/svelte@0.577.0(svelte@5.46.1): + /@lucide/svelte@0.577.0(svelte@5.55.0): resolution: {integrity: sha512-0P6mkySd2MapIEgq08tADPmcN4DHndC/02PWwaLkOerXlx5Sv9aT4BxyXLIY+eccr0g/nEyCYiJesqS61YdBZQ==} peerDependencies: svelte: ^5.46.1 dependencies: - svelte: 5.46.1 + svelte: 5.55.0 dev: false /@neon-rs/load@0.0.4: resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} + dev: false /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -5240,8 +5248,8 @@ packages: tslib: 2.8.1 dev: false - /@standard-schema/spec@1.0.0: - resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + /@standard-schema/spec@1.1.0: + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} dev: true /@sveltejs/acorn-typescript@1.0.6(acorn@8.15.0): @@ -5251,39 +5259,46 @@ packages: dependencies: acorn: 8.15.0 - /@sveltejs/adapter-auto@7.0.1(@sveltejs/kit@2.49.4): + /@sveltejs/acorn-typescript@1.0.9(acorn@8.16.0): + resolution: {integrity: sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==} + peerDependencies: + acorn: ^8.9.0 + dependencies: + acorn: 8.16.0 + + /@sveltejs/adapter-auto@7.0.1(@sveltejs/kit@2.55.0): resolution: {integrity: sha512-dvuPm1E7M9NI/+canIQ6KKQDU2AkEefEZ2Dp7cY6uKoPq9Z/PhOXABe526UdW2mN986gjVkuSLkOYIBnS/M2LQ==} peerDependencies: '@sveltejs/kit': ^2.0.0 dependencies: - '@sveltejs/kit': 2.49.4(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(typescript@5.8.3)(vite@7.3.1) + '@sveltejs/kit': 2.55.0(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(typescript@5.8.3)(vite@6.4.1) dev: true - /@sveltejs/adapter-cloudflare@5.1.0(@sveltejs/kit@2.49.4)(wrangler@3.114.9): + /@sveltejs/adapter-cloudflare@5.1.0(@sveltejs/kit@2.55.0)(wrangler@3.114.9): resolution: {integrity: sha512-moQwTcJTYY3cV/SA0FJClsJS+u7zjrziYNlDHLbb+lIbBc0Ze4Cki8MSYwY1qMmP3iarQIb8OXFn7m9TEisW1A==} peerDependencies: '@sveltejs/kit': ^2.0.0 wrangler: ^3.87.0 || ^4.0.0 dependencies: '@cloudflare/workers-types': 4.20260313.1 - '@sveltejs/kit': 2.49.4(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(typescript@5.8.3)(vite@7.3.1) + '@sveltejs/kit': 2.55.0(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(typescript@5.8.3)(vite@6.4.1) esbuild: 0.24.2 worktop: 0.8.0-next.18 wrangler: 3.114.9(@cloudflare/workers-types@4.20260313.1) dev: true - /@sveltejs/adapter-netlify@5.2.4(@sveltejs/kit@2.49.4): + /@sveltejs/adapter-netlify@5.2.4(@sveltejs/kit@2.55.0): resolution: {integrity: sha512-UtPcZq1HUA43hM8uLi+nsm5Q+YjHNj7/SMFoyeLZeY/VTloVWABEZ0tJ5WodTUmy/8j5QJ7oLZjj28aQxi8y3g==} peerDependencies: '@sveltejs/kit': ^2.4.0 dependencies: '@iarna/toml': 2.2.5 - '@sveltejs/kit': 2.49.4(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(typescript@5.8.3)(vite@7.3.1) + '@sveltejs/kit': 2.55.0(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(typescript@5.8.3)(vite@6.4.1) esbuild: 0.25.12 set-cookie-parser: 2.7.2 dev: true - /@sveltejs/adapter-node@5.3.3(@sveltejs/kit@2.49.4): + /@sveltejs/adapter-node@5.3.3(@sveltejs/kit@2.55.0): resolution: {integrity: sha512-SRDVuFBkmpKGsA9b0wYaCrrSChq2Yv5Dv8g7WiZcs8E69vdQNRamN0DzQV9/rEixvuRkojATLADNeQ+6FeyVNQ==} peerDependencies: '@sveltejs/kit': ^2.4.0 @@ -5291,81 +5306,79 @@ packages: '@rollup/plugin-commonjs': 28.0.6(rollup@4.43.0) '@rollup/plugin-json': 6.1.0(rollup@4.43.0) '@rollup/plugin-node-resolve': 16.0.1(rollup@4.43.0) - '@sveltejs/kit': 2.49.4(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(typescript@5.8.3)(vite@7.3.1) + '@sveltejs/kit': 2.55.0(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(typescript@5.8.3)(vite@7.3.1) rollup: 4.43.0 dev: true - /@sveltejs/kit@2.49.4(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(typescript@5.8.3)(vite@6.4.1): - resolution: {integrity: sha512-JFtOqDoU0DI/+QSG8qnq5bKcehVb3tCHhOG4amsSYth5/KgO4EkJvi42xSAiyKmXAAULW1/Zdb6lkgGEgSxdZg==} + /@sveltejs/kit@2.55.0(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(typescript@5.8.3)(vite@6.4.1): + resolution: {integrity: sha512-MdFRjevVxmAknf2NbaUkDF16jSIzXMWd4Nfah0Qp8TtQVoSp3bV4jKt8mX7z7qTUTWvgSaxtR0EG5WJf53gcuA==} engines: {node: '>=18.13'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.0.0 - '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 + '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0 svelte: ^5.46.1 typescript: ^5.3.3 - vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 + vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0 peerDependenciesMeta: '@opentelemetry/api': optional: true typescript: optional: true dependencies: - '@standard-schema/spec': 1.0.0 - '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.46.1)(vite@6.4.1) + '@standard-schema/spec': 1.1.0 + '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.0)(vite@6.4.1) '@types/cookie': 0.6.0 - acorn: 8.15.0 + acorn: 8.16.0 cookie: 0.6.0 - devalue: 5.4.2 + devalue: 5.6.4 esm-env: 1.2.2 kleur: 4.1.5 magic-string: 0.30.21 mrmime: 2.0.1 - sade: 1.8.1 - set-cookie-parser: 2.7.1 - sirv: 3.0.1 - svelte: 5.46.1 + set-cookie-parser: 3.1.0 + sirv: 3.0.2 + svelte: 5.55.0 typescript: 5.8.3 vite: 6.4.1(@types/node@22.15.31)(tsx@4.20.3) dev: true - /@sveltejs/kit@2.49.4(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(typescript@5.8.3)(vite@7.3.1): - resolution: {integrity: sha512-JFtOqDoU0DI/+QSG8qnq5bKcehVb3tCHhOG4amsSYth5/KgO4EkJvi42xSAiyKmXAAULW1/Zdb6lkgGEgSxdZg==} + /@sveltejs/kit@2.55.0(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(typescript@5.8.3)(vite@7.3.1): + resolution: {integrity: sha512-MdFRjevVxmAknf2NbaUkDF16jSIzXMWd4Nfah0Qp8TtQVoSp3bV4jKt8mX7z7qTUTWvgSaxtR0EG5WJf53gcuA==} engines: {node: '>=18.13'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.0.0 - '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 + '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0 svelte: ^5.46.1 typescript: ^5.3.3 - vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 + vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0 peerDependenciesMeta: '@opentelemetry/api': optional: true typescript: optional: true dependencies: - '@standard-schema/spec': 1.0.0 - '@sveltejs/acorn-typescript': 1.0.6(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.46.1)(vite@7.3.1) + '@standard-schema/spec': 1.1.0 + '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.0)(vite@7.3.1) '@types/cookie': 0.6.0 - acorn: 8.15.0 + acorn: 8.16.0 cookie: 0.6.0 - devalue: 5.4.2 + devalue: 5.6.4 esm-env: 1.2.2 kleur: 4.1.5 magic-string: 0.30.21 mrmime: 2.0.1 - sade: 1.8.1 - set-cookie-parser: 2.7.1 - sirv: 3.0.1 - svelte: 5.46.1 + set-cookie-parser: 3.1.0 + sirv: 3.0.2 + svelte: 5.55.0 typescript: 5.8.3 vite: 7.3.1 dev: true - /@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(vite@6.4.1): + /@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(vite@7.3.1): resolution: {integrity: sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==} engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: @@ -5373,13 +5386,27 @@ packages: svelte: ^5.46.1 vite: ^6.3.0 || ^7.0.0 dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.46.1)(vite@6.4.1) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.46.1)(vite@7.3.1) obug: 2.1.1 svelte: 5.46.1 + vite: 7.3.1 + dev: false + + /@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(vite@6.4.1): + resolution: {integrity: sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^6.0.0-next.0 + svelte: ^5.46.1 + vite: ^6.3.0 || ^7.0.0 + dependencies: + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.0)(vite@6.4.1) + obug: 2.1.1 + svelte: 5.55.0 vite: 6.4.1(@types/node@22.15.31)(tsx@4.20.3) dev: true - /@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(vite@7.3.1): + /@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(vite@7.3.1): resolution: {integrity: sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==} engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: @@ -5387,41 +5414,59 @@ packages: svelte: ^5.46.1 vite: ^6.3.0 || ^7.0.0 dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.46.1)(vite@7.3.1) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.55.0)(vite@7.3.1) obug: 2.1.1 - svelte: 5.46.1 + svelte: 5.55.0 vite: 7.3.1 + dev: true - /@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.46.1)(vite@6.4.1): + /@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.46.1)(vite@7.3.1): resolution: {integrity: sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==} engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: svelte: ^5.46.1 vite: ^6.3.0 || ^7.0.0 dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(vite@6.4.1) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(vite@7.3.1) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 svelte: 5.46.1 + vite: 7.3.1 + vitefu: 1.1.1(vite@7.3.1) + dev: false + + /@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.0)(vite@6.4.1): + resolution: {integrity: sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + svelte: ^5.46.1 + vite: ^6.3.0 || ^7.0.0 + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(vite@6.4.1) + deepmerge: 4.3.1 + magic-string: 0.30.21 + obug: 2.1.1 + svelte: 5.55.0 vite: 6.4.1(@types/node@22.15.31)(tsx@4.20.3) vitefu: 1.1.1(vite@6.4.1) dev: true - /@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.46.1)(vite@7.3.1): + /@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.55.0)(vite@7.3.1): resolution: {integrity: sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==} engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: svelte: ^5.46.1 vite: ^6.3.0 || ^7.0.0 dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.46.1)(vite@7.3.1) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4)(svelte@5.55.0)(vite@7.3.1) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 - svelte: 5.46.1 + svelte: 5.55.0 vite: 7.3.1 vitefu: 1.1.1(vite@7.3.1) + dev: true /@tailwindcss/forms@0.5.10(tailwindcss@4.2.1): resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==} @@ -5659,10 +5704,10 @@ packages: resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} dev: true - /@types/mssql@9.1.9(@azure/core-client@1.10.1): - resolution: {integrity: sha512-P0nCgw6vzY23UxZMnbI4N7fnLGANt4LI4yvxze1paPj+LuN28cFv5EI+QidP8udnId/BKhkcRhm/BleNsjK65A==} + /@types/mssql@9.1.11(@azure/core-client@1.10.1): + resolution: {integrity: sha512-vcujgrDbDezCxNDO4KY6gjwduLYOKfrexpRUwhoysRvcXZ3+IgZ/PMYFDgh8c3cQIxZ6skAwYo+H6ibMrBWPjQ==} dependencies: - '@types/node': 25.5.0 + '@types/node': 22.15.31 tarn: 3.0.2 tedious: 19.2.1(@azure/core-client@1.10.1) transitivePeerDependencies: @@ -5681,12 +5726,6 @@ packages: dependencies: undici-types: 6.21.0 - /@types/node@25.5.0: - resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==} - dependencies: - undici-types: 7.18.2 - dev: false - /@types/qs@6.14.0: resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} dev: true @@ -5698,7 +5737,7 @@ packages: /@types/readable-stream@4.0.23: resolution: {integrity: sha512-wwXrtQvbMHxCbBgjHaMGEmImFTQxxpfMOR/ZoQnXxB1woqkUbdLGFDgauo00Py9IudiaqSeiBiulSV9i6XIPig==} dependencies: - '@types/node': 25.5.0 + '@types/node': 22.15.31 dev: false /@types/resolve@1.20.2: @@ -5732,10 +5771,14 @@ packages: '@types/send': 0.17.5 dev: true + /@types/trusted-types@2.0.7: + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + /@types/ws@8.18.1: resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} dependencies: '@types/node': 22.15.31 + dev: false /@typescript-eslint/eslint-plugin@8.34.0(@typescript-eslint/parser@8.34.0)(eslint@9.39.4)(typescript@5.8.3): resolution: {integrity: sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==} @@ -5832,6 +5875,10 @@ packages: engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dev: true + /@typescript-eslint/types@8.57.2: + resolution: {integrity: sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + /@typescript-eslint/typescript-estree@8.34.0(typescript@5.8.3): resolution: {integrity: sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5912,6 +5959,14 @@ packages: acorn: 8.15.0 dev: true + /acorn-jsx@5.3.2(acorn@8.16.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.16.0 + dev: true + /acorn-walk@8.3.2: resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} @@ -5928,6 +5983,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + /acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + /agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -5953,6 +6013,10 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true + /aria-query@5.3.1: + resolution: {integrity: sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==} + engines: {node: '>= 0.4'} + /aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -6204,6 +6268,7 @@ packages: /data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} + dev: false /debug@4.4.1: resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} @@ -6265,6 +6330,7 @@ packages: /detect-libc@2.0.2: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} + dev: false /detect-libc@2.0.4: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} @@ -6275,13 +6341,12 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - /devalue@5.4.2: - resolution: {integrity: sha512-MwPZTKEPK2k8Qgfmqrd48ZKVvzSQjgW0lXLxiIBA8dQjtf/6mw6pggHNLcyDKyf+fI6eXxlQwPsfaCMTU5U+Bw==} - dev: true - /devalue@5.6.1: resolution: {integrity: sha512-jDwizj+IlEZBunHcOuuFVBnIMPAEHvTsJj0BcIp94xYguLRVBcXO853px/MyIJvbVzWdsGvrRweIUWJw8hBP7A==} + /devalue@5.6.4: + resolution: {integrity: sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==} + /dom-serializer@2.0.0: resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} dependencies: @@ -6334,7 +6399,7 @@ packages: jiti: 2.6.1 dev: true - /drizzle-orm@1.0.0-beta.13-f728631(@types/mssql@9.1.9)(mssql@11.0.1): + /drizzle-orm@1.0.0-beta.13-f728631(@types/mssql@9.1.11)(mssql@11.0.1): resolution: {integrity: sha512-P+QKVzS80WoeUm2cinAj6z5+56g3N1VlM4kfK29ppKOd1x6TOuYmY6RI9/ABTGxOCIrPEfrxijyqpAqIOwLrjg==} peerDependencies: '@aws-sdk/client-rds-data': '>=3' @@ -6440,7 +6505,7 @@ packages: sqlite3: optional: true dependencies: - '@types/mssql': 9.1.9(@azure/core-client@1.10.1) + '@types/mssql': 9.1.11(@azure/core-client@1.10.1) mssql: 11.0.1(@azure/core-client@1.10.1) dev: false @@ -6753,7 +6818,7 @@ packages: eslint: 9.39.4 dev: true - /eslint-plugin-svelte@2.46.1(eslint@9.39.4)(svelte@5.46.1): + /eslint-plugin-svelte@2.46.1(eslint@9.39.4)(svelte@5.55.0): resolution: {integrity: sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: @@ -6774,13 +6839,13 @@ packages: postcss-safe-parser: 6.0.0(postcss@8.5.5) postcss-selector-parser: 6.1.2 semver: 7.7.2 - svelte: 5.46.1 - svelte-eslint-parser: 0.43.0(svelte@5.46.1) + svelte: 5.55.0 + svelte-eslint-parser: 0.43.0(svelte@5.55.0) transitivePeerDependencies: - ts-node dev: true - /eslint-plugin-svelte@3.9.2(eslint@9.39.4)(svelte@5.46.1): + /eslint-plugin-svelte@3.9.2(eslint@9.39.4)(svelte@5.55.0): resolution: {integrity: sha512-aqzfHtG9RPaFhCUFm5QFC6eFY/yHFQIT8VYYFe7/mT2A9mbgVR3XV2keCqU19LN8iVD9mdvRvqHU+4+CzJImvg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: @@ -6800,8 +6865,8 @@ packages: postcss-load-config: 3.1.4(postcss@8.5.5) postcss-safe-parser: 7.0.1(postcss@8.5.5) semver: 7.7.2 - svelte: 5.46.1 - svelte-eslint-parser: 1.2.0(svelte@5.46.1) + svelte: 5.55.0 + svelte-eslint-parser: 1.2.0(svelte@5.55.0) transitivePeerDependencies: - ts-node dev: true @@ -6887,8 +6952,8 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 4.2.1 dev: true @@ -6913,6 +6978,12 @@ packages: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + /esrap@2.2.4: + resolution: {integrity: sha512-suICpxAmZ9A8bzJjEl/+rLJiDKC0X4gYWUxT6URAWBLvlXmtbZd5ySMu/N2ZGEtMCAmflUDPSehrP9BQcsGcSg==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@typescript-eslint/types': 8.57.2 + /esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -7082,6 +7153,7 @@ packages: dependencies: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 + dev: false /file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} @@ -7136,6 +7208,7 @@ packages: engines: {node: '>=12.20.0'} dependencies: fetch-blob: 3.2.0 + dev: false /forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} @@ -7217,6 +7290,11 @@ packages: engines: {node: '>=18'} dev: true + /globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + dev: true + /globals@16.5.0: resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} @@ -7430,6 +7508,7 @@ packages: /js-base64@3.7.7: resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + dev: false /js-md4@0.3.2: resolution: {integrity: sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==} @@ -7533,6 +7612,7 @@ packages: '@libsql/linux-x64-gnu': 0.5.13 '@libsql/linux-x64-musl': 0.5.13 '@libsql/win32-x64-msvc': 0.5.13 + dev: false /lightningcss-android-arm64@1.31.1: resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} @@ -7879,6 +7959,7 @@ packages: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} deprecated: Use your platform's native DOMException instead + dev: false /node-fetch@3.3.2: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} @@ -7887,6 +7968,7 @@ packages: data-uri-to-buffer: 4.0.1 fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + dev: false /object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} @@ -8121,6 +8203,16 @@ packages: svelte: 5.46.1 dev: true + /prettier-plugin-svelte@3.5.1(prettier@3.5.3)(svelte@5.55.0): + resolution: {integrity: sha512-65+fr5+cgIKWKiqM1Doum4uX6bY8iFCdztvvp2RcF+AJoieaw9kJOFMNcJo/bkmKYsxFaM9OsVZK/gWauG/5mg==} + peerDependencies: + prettier: ^3.0.0 + svelte: ^5.46.1 + dependencies: + prettier: 3.5.3 + svelte: 5.55.0 + dev: true + /prettier-plugin-tailwindcss@0.6.12(prettier-plugin-svelte@3.5.1)(prettier@3.5.3): resolution: {integrity: sha512-OuTQKoqNwV7RnxTPwXWzOFXy6Jc4z8oeRZYGuMpRyG3WbuR3jjXdQFK8qFBMBx8UHWdHrddARz2fgUenild6aw==} engines: {node: '>=14.21.3'} @@ -8177,7 +8269,7 @@ packages: optional: true dependencies: prettier: 3.5.3 - prettier-plugin-svelte: 3.5.1(prettier@3.5.3)(svelte@5.46.1) + prettier-plugin-svelte: 3.5.1(prettier@3.5.3)(svelte@5.55.0) dev: true /prettier@3.5.3: @@ -8197,6 +8289,7 @@ packages: /promise-limit@2.7.0: resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} + dev: false /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} @@ -8461,14 +8554,14 @@ packages: - supports-color dev: false - /set-cookie-parser@2.7.1: - resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} - dev: true - /set-cookie-parser@2.7.2: resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} dev: true + /set-cookie-parser@3.1.0: + resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} + dev: true + /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} dev: false @@ -8562,8 +8655,8 @@ packages: is-arrayish: 0.3.2 dev: true - /sirv@3.0.1: - resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + /sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} dependencies: '@polka/url': 1.0.0-next.29 @@ -8642,7 +8735,7 @@ packages: engines: {node: '>= 0.4'} dev: true - /svelte-check@4.4.5(svelte@5.46.1)(typescript@5.8.3): + /svelte-check@4.4.5(svelte@5.55.0)(typescript@5.8.3): resolution: {integrity: sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==} engines: {node: '>= 18.0.0'} hasBin: true @@ -8655,13 +8748,13 @@ packages: fdir: 6.5.0(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.46.1 + svelte: 5.55.0 typescript: 5.8.3 transitivePeerDependencies: - picomatch dev: true - /svelte-eslint-parser@0.43.0(svelte@5.46.1): + /svelte-eslint-parser@0.43.0(svelte@5.55.0): resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -8675,10 +8768,10 @@ packages: espree: 9.6.1 postcss: 8.5.5 postcss-scss: 4.0.9(postcss@8.5.5) - svelte: 5.46.1 + svelte: 5.55.0 dev: true - /svelte-eslint-parser@1.2.0(svelte@5.46.1): + /svelte-eslint-parser@1.2.0(svelte@5.55.0): resolution: {integrity: sha512-mbPtajIeuiyU80BEyGvwAktBeTX7KCr5/0l+uRGLq1dafwRNrjfM5kHGJScEBlPG3ipu6dJqfW/k0/fujvIEVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: @@ -8693,7 +8786,7 @@ packages: postcss: 8.5.5 postcss-scss: 4.0.9(postcss@8.5.5) postcss-selector-parser: 7.1.0 - svelte: 5.46.1 + svelte: 5.55.0 dev: true /svelte@5.46.1: @@ -8716,6 +8809,27 @@ packages: magic-string: 0.30.21 zimmerframe: 1.1.4 + /svelte@5.55.0: + resolution: {integrity: sha512-SThllKq6TRMBwPtat7ASnm/9CDXnIhBR0NPGw0ujn2DVYx9rVwsPZxDaDQcYGdUz/3BYVsCzdq7pZarRQoGvtw==} + engines: {node: '>=18'} + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) + '@types/estree': 1.0.8 + '@types/trusted-types': 2.0.7 + acorn: 8.16.0 + aria-query: 5.3.1 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.6.4 + esm-env: 1.2.2 + esrap: 2.2.4 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + /tailwindcss@4.2.1: resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==} @@ -8733,10 +8847,10 @@ packages: engines: {node: '>=18'} dependencies: '@azure/core-auth': 1.10.1 - '@azure/identity': 4.13.0 + '@azure/identity': 4.13.1 '@azure/keyvault-keys': 4.10.0(@azure/core-client@1.10.1) '@js-joda/core': 5.7.0 - '@types/node': 25.5.0 + '@types/node': 22.15.31 bl: 6.1.6 iconv-lite: 0.6.3 js-md4: 0.3.2 @@ -8752,10 +8866,10 @@ packages: engines: {node: '>=18.17'} dependencies: '@azure/core-auth': 1.10.1 - '@azure/identity': 4.13.0 + '@azure/identity': 4.13.1 '@azure/keyvault-keys': 4.10.0(@azure/core-client@1.10.1) '@js-joda/core': 5.7.0 - '@types/node': 25.5.0 + '@types/node': 22.15.31 bl: 6.1.6 iconv-lite: 0.7.2 js-md4: 0.3.2 @@ -8918,10 +9032,6 @@ packages: /undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - /undici-types@7.18.2: - resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - dev: false - /undici@5.29.0: resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} engines: {node: '>=14.0'} @@ -9104,6 +9214,7 @@ packages: /web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} + dev: false /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} @@ -9235,6 +9346,7 @@ packages: optional: true utf-8-validate: optional: true + dev: false /wsl-utils@0.1.0: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} From 45fc40a9a4552eb0e25aa6e639b65a3f8a53c8f8 Mon Sep 17 00:00:00 2001 From: Jack Koskie <65452167+jackkoskie@users.noreply.github.com> Date: Fri, 10 Apr 2026 14:03:38 -0700 Subject: [PATCH 10/10] lint --- apps/overseer/src/lib/remote/dms.remote.ts | 5 +- apps/overseer/src/routes/a/dms/+page.svelte | 4 +- .../routes/a/dms/document/[id]/+page.svelte | 14 +-- .../[groupSlug]/[documentShort]/+server.ts | 94 +++++++++---------- pnpm-lock.yaml | 8 +- 5 files changed, 62 insertions(+), 63 deletions(-) diff --git a/apps/overseer/src/lib/remote/dms.remote.ts b/apps/overseer/src/lib/remote/dms.remote.ts index a4810bc3..1bd0fb6a 100644 --- a/apps/overseer/src/lib/remote/dms.remote.ts +++ b/apps/overseer/src/lib/remote/dms.remote.ts @@ -187,10 +187,7 @@ export const createDocumentAsset = form('unchecked', async (rawData) => { } const expiryDate = parseDateInput(expiryDateInput); - if ( - expiryDate && - expiryDate.getTime() <= effectiveDate.getTime() - ) { + if (expiryDate && expiryDate.getTime() <= effectiveDate.getTime()) { throw error(400, 'Expiry date must be after the effective date'); } diff --git a/apps/overseer/src/routes/a/dms/+page.svelte b/apps/overseer/src/routes/a/dms/+page.svelte index c74d0a46..6d231a43 100644 --- a/apps/overseer/src/routes/a/dms/+page.svelte +++ b/apps/overseer/src/routes/a/dms/+page.svelte @@ -105,8 +105,8 @@ Are you sure you want to delete {selectedGroupName}?

    - Warning: deleting this group will also delete all documents within the group. This - action cannot be undone. + Warning: deleting this group will also delete all documents within the group. This action + cannot be undone.

    {/if} -

    Upload New Asset

    +

    Upload New Asset

    @@ -484,7 +486,7 @@

    {/if} -
    +
    @@ -551,7 +553,7 @@ {#each currentDocument.assets as asset (asset.id)}