diff --git a/.vscode/settings.json b/.vscode/settings.json index 4feac46..2e791ac 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -57,6 +57,7 @@ "manadatory", "OCME", "onnotice", + "opendock", "ppoo", "prodlabels" ], diff --git a/backend/configs/scaler.config.ts b/backend/configs/scaler.config.ts index 8c329ce..7c4967b 100644 --- a/backend/configs/scaler.config.ts +++ b/backend/configs/scaler.config.ts @@ -5,12 +5,11 @@ import type { Express } from "express"; //const __filename = fileURLToPath(import.meta.url); // const __dirname = path.dirname(__filename); +import os from "node:os"; import { apiReference } from "@scalar/express-api-reference"; // const port = 3000; import type { OpenAPIV3_1 } from "openapi-types"; -import { datamartAddSpec } from "../scaler/datamartAdd.spec.js"; -import { datamartUpdateSpec } from "../scaler/datamartUpdate.spec.js"; -import { getDatamartSpec } from "../scaler/getDatamart.spec.js"; +import { cronerActiveJobs } from "../scaler/cronerActiveJobs.spec.js"; import { prodLoginSpec } from "../scaler/login.spec.js"; import { prodRestartSpec } from "../scaler/prodSqlRestart.spec.js"; import { prodStartSpec } from "../scaler/prodSqlStart.spec.js"; @@ -28,7 +27,8 @@ export const openApiBase: OpenAPIV3_1.Document = { }, servers: [ { - url: `http://localhost:3000${process.env.NODE_ENV?.trim() !== "production" ? "/lst" : "/"}`, + // TODO: change this to the https:// if we are in production and port if not. + url: `http://${os.hostname()}:3000${process.env.NODE_ENV?.trim() !== "production" ? "/lst" : "/"}`, description: "Development server", }, ], @@ -73,9 +73,8 @@ export const openApiBase: OpenAPIV3_1.Document = { description: "All system endpoints that will be available to run", }, { - name: "Datamart", - description: - "All Special queries to run based on there names.\n Refer to the docs to see all possible queries that can be ran here, you can also run the getQueries to see available.", + name: "Utils", + description: "All routes related to the utilities on the server", }, // { name: "TMS", description: "TMS integration" }, ], @@ -83,14 +82,21 @@ export const openApiBase: OpenAPIV3_1.Document = { }; export const setupApiDocsRoutes = (baseUrl: string, app: Express) => { - const mergedDatamart = { - "/api/datamart": { - ...(getDatamartSpec["/api/datamart"] ?? {}), - ...(datamartAddSpec["/api/datamart"] ?? {}), - ...(datamartUpdateSpec["/api/datamart"] ?? {}), - }, - "/api/datamart/{name}": getDatamartSpec["/api/datamart/{name}"], - }; + // const mergedDatamart = { + // "/api/datamart": { + // ...(cronerActiveJobs["/api/datamart"] ?? {}), + // ...(datamartAddSpec["/api/datamart"] ?? {}), + // ...(datamartUpdateSpec["/api/datamart"] ?? {}), + // }, + // "/api/datamart/{name}": getDatamartSpec["/api/datamart/{name}"], + // }; + + // const mergeUtils = { + // "/api/utils/croner": { + // ...(cronerActiveJobs["/api/utils/croner"] ?? {}), + // }, + // "/api/utils/{name}": cronerActiveJobs["/api/utils/{name}"], + // }; const fullSpec = { ...openApiBase, @@ -101,7 +107,8 @@ export const setupApiDocsRoutes = (baseUrl: string, app: Express) => { ...prodRestartSpec, ...prodLoginSpec, ...prodRegisterSpec, - ...mergedDatamart, + //...mergedDatamart, + ...cronerActiveJobs, // Add more specs here as you build features }, diff --git a/backend/db/dbCleanup.controller.ts b/backend/db/dbCleanup.controller.ts new file mode 100644 index 0000000..918bac8 --- /dev/null +++ b/backend/db/dbCleanup.controller.ts @@ -0,0 +1,72 @@ +import { createLogger } from "../logger/logger.controller.js"; +import { delay } from "../utils/delay.utils.js"; +import { db } from "./db.controller.js"; + +type DBCount = { + count: string; +}; + +const tableMap = { + logs: "logs", + jobs: "job_audit_log", + opendockApt: "opendock_apt", +} as const; + +type CleanupTable = keyof typeof tableMap; + +/** + * We will clean up the db based on age. + * @param name database to run the cleanup on + * @param daysToKeep optional default will be 90 days + */ +export const dbCleanup = async (name: CleanupTable, daysToKeep?: number) => { + const log = createLogger({ module: "db", subModule: "cleanup" }); + // TODO: send backup of this to another server, via post or something maybe have to reduce the limit but well tackle that later. + + if (!daysToKeep) { + daysToKeep = 90; + } + const limit = 1000; + const delayTime = 250; + let rowsDeleted: number; + + const dbCount = (await db.execute( + `select count(*) from public.${tableMap[name]} WHERE created_at < NOW() - INTERVAL '${daysToKeep} days'`, + )) as DBCount[]; + + const loopCount = Math.ceil( + parseInt(dbCount[0]?.count ?? `${limit}`, 10) / limit, + ); + + if (parseInt(dbCount[0]?.count ?? `${limit}`, 10) > 1) { + log.info( + `Table clean up for: ${name}, that are older than ${daysToKeep} day, will be removed, There is ${loopCount} loops to be completed, Approx time: ${((loopCount * delayTime) / 1000 / 60).toFixed(2)} min(s).`, + ); + } else { + log.info(`Table clean up for: ${name}, Currently has nothing to clean up.`); + return; + } + + do { + // cleanup logs + const deleted = await db.execute(` + DELETE FROM public.${tableMap[name]} + WHERE id IN ( + SELECT id + FROM public.${tableMap[name]} + WHERE created_at < NOW() - INTERVAL '${daysToKeep} days' + ORDER BY created_at + LIMIT ${limit} + ) + RETURNING id; + `); + + rowsDeleted = deleted.length; + + if (rowsDeleted > 0) { + await delay(delayTime); + } + } while (rowsDeleted === limit); + + log.info(`Table clean up for: ${name}, Has completed.`); +}; diff --git a/backend/db/schema/auditLog.schema.ts b/backend/db/schema/auditLog.schema.ts index a5baf05..fe4494f 100644 --- a/backend/db/schema/auditLog.schema.ts +++ b/backend/db/schema/auditLog.schema.ts @@ -1,4 +1,5 @@ import { + index, integer, jsonb, pgTable, @@ -9,17 +10,29 @@ import { import { createInsertSchema, createSelectSchema } from "drizzle-zod"; import type { z } from "zod"; -export const jobAuditLog = pgTable("job_audit_log", { - id: uuid("id").defaultRandom().primaryKey(), - jobName: text("job_name"), - startedAt: timestamp("start_at"), - finishedAt: timestamp("finished_at"), - durationMs: integer("duration_ms"), - status: text("status"), //success | error - errorMessage: text("error_message"), - errorStack: text("error_stack"), - metadata: jsonb("meta_data"), -}); +export const jobAuditLog = pgTable( + "job_audit_log", + { + id: uuid("id").defaultRandom().primaryKey(), + jobName: text("job_name"), + startedAt: timestamp("start_at"), + finishedAt: timestamp("finished_at"), + durationMs: integer("duration_ms"), + status: text("status"), //success | error + errorMessage: text("error_message"), + errorStack: text("error_stack"), + metadata: jsonb("meta_data"), + createdAt: timestamp("created_at").defaultNow(), + }, + (table) => { + return { + cleanupIdx: index("idx_job_audit_logs_cleanup").on( + table.startedAt, + table.id, + ), + }; + }, +); export const jobAuditLogSchema = createSelectSchema(jobAuditLog); export const newJobAuditLogSchema = createInsertSchema(jobAuditLog); diff --git a/backend/db/schema/opendock.schema.ts b/backend/db/schema/opendock.schema.ts index 0cbe1c7..140ddb4 100644 --- a/backend/db/schema/opendock.schema.ts +++ b/backend/db/schema/opendock.schema.ts @@ -9,7 +9,7 @@ import { import { createInsertSchema, createSelectSchema } from "drizzle-zod"; import type { z } from "zod"; -export const opendockApt = pgTable("opendock.apt", { +export const opendockApt = pgTable("opendock_apt", { id: uuid("id").defaultRandom().primaryKey(), release: integer("release").unique(), openDockAptId: text("open_dock_apt_id").notNull(), diff --git a/backend/opendock/releaseMonitor.utils.ts b/backend/opendock/releaseMonitor.utils.ts index 1c8a6cc..0b7b124 100644 --- a/backend/opendock/releaseMonitor.utils.ts +++ b/backend/opendock/releaseMonitor.utils.ts @@ -4,6 +4,7 @@ import { formatInTimeZone } from "date-fns-tz"; import { sql } from "drizzle-orm"; import { db } from "../db/db.controller.js"; import { opendockApt } from "../db/schema/opendock.schema.js"; +import { createLogger } from "../logger/logger.controller.js"; import { prodQuery } from "../prodSql/prodSqlQuery.controller.js"; import { type SqlQuery, @@ -23,8 +24,6 @@ let lastCheck = formatInTimeZone( //const queue: unknown[] = []; //const isProcessing: boolean = false; -let odToken: string | null = null; - type Releases = { ReleaseNumber: number; DeliveryState: number; @@ -36,10 +35,30 @@ type Releases = { LineItemArticleWeight: number; CustomerReleaseNumber: string; }; + +type ODToken = { + odToken: string | null; + tokenDate: Date | null; +}; + +let odToken: ODToken = { + odToken: null, + tokenDate: new Date(), +}; +const TWENTY_FOUR_HOURS = 24 * 60 * 60 * 1000; +const log = createLogger({ module: "opendock", subModule: "releaseMonitor" }); + const postRelease = async (release: Releases) => { - if (!odToken) { - console.info("Getting token"); - // TODO: add a time stamp on the token so it gets refreshed every 24hours + if (!odToken.odToken) { + log.info("Getting Auth Token"); + await getToken(); + } + + if ( + new Date(odToken.tokenDate || Date.now()).getTime() < + Date.now() - TWENTY_FOUR_HOURS + ) { + log.info("Refreshing Auth Token"); await getToken(); } /** @@ -145,7 +164,7 @@ const postRelease = async (release: Releases) => { ); if (aptError) { - console.error("Error getting apt data: ", aptError); + log.error({ error: aptError }, "Error getting apt data"); // TODO: send an error email on this one as it will cause issues return; } @@ -163,13 +182,13 @@ const postRelease = async (release: Releases) => { { headers: { "content-type": "application/json; charset=utf-8", - Authorization: `Bearer ${odToken}`, + Authorization: `Bearer ${odToken.odToken}`, }, }, ); if (response.status === 400) { - console.error(response.data.data.message); + log.error({}, response.data.data.message); return; } @@ -188,13 +207,13 @@ const postRelease = async (release: Releases) => { }) .returning(); - console.info(`${release.ReleaseNumber} was updated`); + log.info(`${release.ReleaseNumber} was updated`); } catch (e) { - console.error(e); + log.error(e); } } catch (e: any) { //console.info(newDockApt); - console.error(e.response.data); + log.error(e.response.data); return; } @@ -215,7 +234,7 @@ const postRelease = async (release: Releases) => { // this will be utilized when we are listening for the changes to the apts. that way we can update the state to arrived. we will run our own checks on this guy during the incoming messages. if (response.status === 400) { - console.error(response.data.data.message); + log.error(response.data.data.message); return; } @@ -236,12 +255,12 @@ const postRelease = async (release: Releases) => { }) .returning(); - console.info(`${release.ReleaseNumber} was created`); + log.info(`${release.ReleaseNumber} was created`); } catch (e) { - console.error(e); + log.error(e); } } catch (e: any) { - console.error(e.response.data); + log.error(e.response.data); return; } @@ -293,7 +312,8 @@ export const monitorReleaseChanges = async () => { } } } catch (e) { - console.error("Monitor error:", e); + console.error(e); + log.error({ error: e }, "Monitor error"); } }); } @@ -340,14 +360,14 @@ const getToken = async () => { ); if (status === 400) { - console.error(data.message); + log.error(data.message); return; } - odToken = data.access_token; - console.info("Token added"); + odToken = { odToken: data.access_token, tokenDate: new Date() }; + log.info("Token added"); } catch (e) { - console.error(e); + log.error(e); } }; diff --git a/backend/scaler/cronerActiveJobs.spec.ts b/backend/scaler/cronerActiveJobs.spec.ts new file mode 100644 index 0000000..cc8b7c1 --- /dev/null +++ b/backend/scaler/cronerActiveJobs.spec.ts @@ -0,0 +1,43 @@ +import type { OpenAPIV3_1 } from "openapi-types"; + +export const cronerActiveJobs: OpenAPIV3_1.PathsObject = { + "/api/utils/croner": { + get: { + summary: "Cron jobs", + description: "Returns all jobs on the server.", + tags: ["Utils"], + responses: { + "200": { + description: "Jobs returned", + content: { + "application/json": { + schema: { + type: "object", + properties: { + status: { + type: "boolean", + format: "boolean", + example: true, + }, + uptime: { + type: "number", + format: "3454.34", + example: 3454.34, + }, + memoryUsage: { + type: "string", + format: "Heap: 11.62 MB / RSS: 86.31 MB", + }, + sqlServerStats: { + type: "number", + format: "442127", + }, + }, + }, + }, + }, + }, + }, + }, + }, +}; diff --git a/backend/server.ts b/backend/server.ts index 3234a5a..330bcc3 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -1,10 +1,12 @@ import { createServer } from "node:http"; import os from "node:os"; import createApp from "./app.js"; +import { dbCleanup } from "./db/dbCleanup.controller.js"; import { createLogger } from "./logger/logger.controller.js"; import { monitorReleaseChanges } from "./opendock/releaseMonitor.utils.js"; import { connectProdSql } from "./prodSql/prodSqlConnection.controller.js"; import { setupSocketIORoutes } from "./socket.io/serverSetup.js"; +import { createCronJob } from "./utils/croner.utils.js"; const port = Number(process.env.PORT) || 3000; @@ -17,6 +19,13 @@ const start = async () => { // start long live processes setTimeout(() => { monitorReleaseChanges(); // this is od monitoring the db for all new releases + createCronJob("JobAuditLogCleanUp", "* 0 5 * * * *", () => + dbCleanup("jobs", 30), + ); + createCronJob("logsCleanup", "* 15 5 * * * *", () => dbCleanup("logs", 30)); + createCronJob("opendockAptCleanup", "* 30 5 * * * *", () => + dbCleanup("opendockApt", 90), + ); }, 5 * 1000); const { app, baseUrl } = await createApp(); diff --git a/backend/utils/croner.utils.ts b/backend/utils/croner.utils.ts index 6cadc82..0445776 100644 --- a/backend/utils/croner.utils.ts +++ b/backend/utils/croner.utils.ts @@ -1,7 +1,7 @@ -import { jobAuditLog } from "backend/db/schema/auditLog.schema.js"; import { Cron } from "croner"; import { eq } from "drizzle-orm"; import { db } from "../db/db.controller.js"; +import { jobAuditLog } from "../db/schema/auditLog.schema.js"; import { createLogger } from "../logger/logger.controller.js"; // example createJob @@ -19,6 +19,17 @@ export interface JobInfo { // Store running cronjobs export const runningCrons: Record = {}; +// how to se the times +// * ┌──────────────── (optional) second (0 - 59) \n +// * │ ┌────────────── minute (0 - 59) +// * │ │ ┌──────────── hour (0 - 23) +// * │ │ │ ┌────────── day of month (1 - 31) +// * │ │ │ │ ┌──────── month (1 - 12, JAN-DEC) +// * │ │ │ │ │ ┌────── day of week (0 - 6, SUN-Mon) +// * │ │ │ │ │ │ (0 to 6 are Sunday to Saturday; 7 is Sunday, the same as 0) +// * │ │ │ │ │ │ ┌──── (optional) year (1 - 9999) +// * │ │ │ │ │ │ │ +// * * 05 * * * * * /** * * @param name Name of the job we want to run diff --git a/backend/utils/cronnerActiveJobs.route.ts b/backend/utils/cronerActiveJobs.route.ts similarity index 100% rename from backend/utils/cronnerActiveJobs.route.ts rename to backend/utils/cronerActiveJobs.route.ts diff --git a/backend/utils/cronnerStatusChange.ts b/backend/utils/cronerStatusChange.ts similarity index 95% rename from backend/utils/cronnerStatusChange.ts rename to backend/utils/cronerStatusChange.ts index deee93d..5b91b4d 100644 --- a/backend/utils/cronnerStatusChange.ts +++ b/backend/utils/cronerStatusChange.ts @@ -1,6 +1,6 @@ import { Router } from "express"; -import { apiReturn } from "../utils/returnHelper.utils.js"; import { getAllJobs, resumeCronJob, stopCronJob } from "./croner.utils.js"; +import { apiReturn } from "./returnHelper.utils.js"; const r = Router(); diff --git a/backend/utils/utils.routes.ts b/backend/utils/utils.routes.ts index 97ea99f..92ded56 100644 --- a/backend/utils/utils.routes.ts +++ b/backend/utils/utils.routes.ts @@ -1,7 +1,6 @@ import type { Express } from "express"; - -import getActiveJobs from "./cronnerActiveJobs.route.js"; -import jobStatusChange from "./cronnerStatusChange.js"; +import getActiveJobs from "./cronerActiveJobs.route.js"; +import jobStatusChange from "./cronerStatusChange.js"; export const setupUtilsRoutes = (baseUrl: string, app: Express) => { app.use(`${baseUrl}/api/utils/croner`, getActiveJobs); app.use(`${baseUrl}/api/utils/croner`, jobStatusChange); diff --git a/migrations/0012_fantastic_randall_flagg.sql b/migrations/0012_fantastic_randall_flagg.sql new file mode 100644 index 0000000..c1b0e55 --- /dev/null +++ b/migrations/0012_fantastic_randall_flagg.sql @@ -0,0 +1 @@ +CREATE INDEX "idx_job_audit_logs_cleanup" ON "job_audit_log" USING btree ("start_at","id"); \ No newline at end of file diff --git a/migrations/0013_flaky_quicksilver.sql b/migrations/0013_flaky_quicksilver.sql new file mode 100644 index 0000000..b0104ad --- /dev/null +++ b/migrations/0013_flaky_quicksilver.sql @@ -0,0 +1,4 @@ +ALTER TABLE "opendock.apt" RENAME TO "opendock_apt";--> statement-breakpoint +ALTER TABLE "opendock_apt" DROP CONSTRAINT "opendock.apt_release_unique";--> statement-breakpoint +ALTER TABLE "job_audit_log" ADD COLUMN "created_at" timestamp DEFAULT now();--> statement-breakpoint +ALTER TABLE "opendock_apt" ADD CONSTRAINT "opendock_apt_release_unique" UNIQUE("release"); \ No newline at end of file diff --git a/migrations/meta/0012_snapshot.json b/migrations/meta/0012_snapshot.json new file mode 100644 index 0000000..f615c65 --- /dev/null +++ b/migrations/meta/0012_snapshot.json @@ -0,0 +1,1099 @@ +{ + "id": "06b55f8b-d84a-496e-afd0-d17408090902", + "prevId": "3243e266-61fa-4757-9d3f-d4901a27878e", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.job_audit_log": { + "name": "job_audit_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "job_name": { + "name": "job_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_at": { + "name": "start_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_stack": { + "name": "error_stack", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "meta_data": { + "name": "meta_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_job_audit_logs_cleanup": { + "name": "idx_job_audit_logs_cleanup", + "columns": [ + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "account_userId_idx": { + "name": "account_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.apikey": { + "name": "apikey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refill_interval": { + "name": "refill_interval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refill_amount": { + "name": "refill_amount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_refill_at": { + "name": "last_refill_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_enabled": { + "name": "rate_limit_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_time_window": { + "name": "rate_limit_time_window", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 86400000 + }, + "rate_limit_max": { + "name": "rate_limit_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 10 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_request": { + "name": "last_request", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "apikey_key_idx": { + "name": "apikey_key_idx", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "apikey_userId_idx": { + "name": "apikey_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "apikey_user_id_user_id_fk": { + "name": "apikey_user_id_user_id_fk", + "tableFrom": "apikey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.jwks": { + "name": "jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "session_userId_idx": { + "name": "session_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + }, + "user_username_unique": { + "name": "user_username_unique", + "nullsNotDistinct": false, + "columns": [ + "username" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "verification_identifier_idx": { + "name": "verification_identifier_idx", + "columns": [ + { + "expression": "identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.datamart": { + "name": "datamart", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "query": { + "name": "query", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "public_access": { + "name": "public_access", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "add_user": { + "name": "add_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'lst-system'" + }, + "upd_date": { + "name": "upd_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "upd_user": { + "name": "upd_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'lst-system'" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "datamart_name_unique": { + "name": "datamart_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.logs": { + "name": "logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "level": { + "name": "level", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subModule": { + "name": "subModule", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stack": { + "name": "stack", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "checked": { + "name": "checked", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.opendock.apt": { + "name": "opendock.apt", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "release": { + "name": "release", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "open_dock_apt_id": { + "name": "open_dock_apt_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appointment": { + "name": "appointment", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "upd_date": { + "name": "upd_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "opendock.apt_release_unique": { + "name": "opendock.apt_release_unique", + "nullsNotDistinct": false, + "columns": [ + "release" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "settings_id": { + "name": "settings_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "moduleName": { + "name": "moduleName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "roles": { + "name": "roles", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[\"systemAdmin\"]'::jsonb" + }, + "settingType": { + "name": "settingType", + "type": "setting_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "add_User": { + "name": "add_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "add_Date": { + "name": "add_Date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "upd_User": { + "name": "upd_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "upd_date": { + "name": "upd_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "name": { + "name": "name", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.setting_type": { + "name": "setting_type", + "schema": "public", + "values": [ + "feature", + "system", + "standard" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/migrations/meta/0013_snapshot.json b/migrations/meta/0013_snapshot.json new file mode 100644 index 0000000..66b7273 --- /dev/null +++ b/migrations/meta/0013_snapshot.json @@ -0,0 +1,1106 @@ +{ + "id": "4b3010f1-d9d4-44dd-84bf-62a0ea763ae1", + "prevId": "06b55f8b-d84a-496e-afd0-d17408090902", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.job_audit_log": { + "name": "job_audit_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "job_name": { + "name": "job_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_at": { + "name": "start_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_stack": { + "name": "error_stack", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "meta_data": { + "name": "meta_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "idx_job_audit_logs_cleanup": { + "name": "idx_job_audit_logs_cleanup", + "columns": [ + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "account_userId_idx": { + "name": "account_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.apikey": { + "name": "apikey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refill_interval": { + "name": "refill_interval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refill_amount": { + "name": "refill_amount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_refill_at": { + "name": "last_refill_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_enabled": { + "name": "rate_limit_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_time_window": { + "name": "rate_limit_time_window", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 86400000 + }, + "rate_limit_max": { + "name": "rate_limit_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 10 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_request": { + "name": "last_request", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "apikey_key_idx": { + "name": "apikey_key_idx", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "apikey_userId_idx": { + "name": "apikey_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "apikey_user_id_user_id_fk": { + "name": "apikey_user_id_user_id_fk", + "tableFrom": "apikey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.jwks": { + "name": "jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "session_userId_idx": { + "name": "session_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + }, + "user_username_unique": { + "name": "user_username_unique", + "nullsNotDistinct": false, + "columns": [ + "username" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "verification_identifier_idx": { + "name": "verification_identifier_idx", + "columns": [ + { + "expression": "identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.datamart": { + "name": "datamart", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "query": { + "name": "query", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "public_access": { + "name": "public_access", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "add_user": { + "name": "add_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'lst-system'" + }, + "upd_date": { + "name": "upd_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "upd_user": { + "name": "upd_user", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'lst-system'" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "datamart_name_unique": { + "name": "datamart_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.logs": { + "name": "logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "level": { + "name": "level", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subModule": { + "name": "subModule", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stack": { + "name": "stack", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "checked": { + "name": "checked", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.opendock_apt": { + "name": "opendock_apt", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "release": { + "name": "release", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "open_dock_apt_id": { + "name": "open_dock_apt_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "appointment": { + "name": "appointment", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'[]'::jsonb" + }, + "upd_date": { + "name": "upd_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "opendock_apt_release_unique": { + "name": "opendock_apt_release_unique", + "nullsNotDistinct": false, + "columns": [ + "release" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "settings_id": { + "name": "settings_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "moduleName": { + "name": "moduleName", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "roles": { + "name": "roles", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[\"systemAdmin\"]'::jsonb" + }, + "settingType": { + "name": "settingType", + "type": "setting_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "add_User": { + "name": "add_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "add_Date": { + "name": "add_Date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "upd_User": { + "name": "upd_User", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'LST_System'" + }, + "upd_date": { + "name": "upd_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": { + "name": { + "name": "name", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.setting_type": { + "name": "setting_type", + "schema": "public", + "values": [ + "feature", + "system", + "standard" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/migrations/meta/_journal.json b/migrations/meta/_journal.json index 860c8e5..9ac17b6 100644 --- a/migrations/meta/_journal.json +++ b/migrations/meta/_journal.json @@ -85,6 +85,20 @@ "when": 1771515240318, "tag": "0011_eminent_iron_patriot", "breakpoints": true + }, + { + "idx": 12, + "version": "7", + "when": 1771537852152, + "tag": "0012_fantastic_randall_flagg", + "breakpoints": true + }, + { + "idx": 13, + "version": "7", + "when": 1771598443244, + "tag": "0013_flaky_quicksilver", + "breakpoints": true } ] } \ No newline at end of file