From b84ecbf30c7e1b5e83bb4beb1bf156d7f1ad82a3 Mon Sep 17 00:00:00 2001 From: Blake Matthes Date: Tue, 30 Sep 2025 19:54:10 -0500 Subject: [PATCH] fix(contorller): env corrections on where to look for the file when running --- .gitignore | 1 + .vscode/settings.json | 3 +- .../app/admin/folder.bru | 8 + .../app/admin/server/Add Server.bru | 27 + .../app/admin/server/Get Servers.bru | 15 + .../app/admin/server/Update Server.bru | 15 + .../app/admin/server/folder.bru | 8 + app/src/internal/admin/routes.ts | 9 + .../admin/routes/servers/addServer.ts | 74 ++ .../admin/routes/servers/getServers.ts | 25 + .../admin/routes/servers/serverRoutes.ts | 12 + .../admin/routes/servers/updateServer.ts | 11 + app/src/internal/system/routes/stats.ts | 4 +- app/src/pkg/db/schema/servers.ts | 49 + app/src/pkg/middleware/restrictToHosts.ts | 30 + controller/go.mod | 6 +- controller/index.html | 23 +- controller/load_env.go | 45 + controller/main.go | 10 +- migrations/0010_watery_gravity.sql | 21 + migrations/0011_careless_banshee.sql | 9 + migrations/meta/0010_snapshot.json | 1056 +++++++++++++++++ migrations/meta/0011_snapshot.json | 1056 +++++++++++++++++ migrations/meta/_journal.json | 14 + package-lock.json | 132 +++ package.json | 1 + 26 files changed, 2637 insertions(+), 27 deletions(-) create mode 100644 LogisticsSupportTool_API_DOCS/app/admin/folder.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/admin/server/Add Server.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/admin/server/Get Servers.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/admin/server/Update Server.bru create mode 100644 LogisticsSupportTool_API_DOCS/app/admin/server/folder.bru create mode 100644 app/src/internal/admin/routes/servers/addServer.ts create mode 100644 app/src/internal/admin/routes/servers/getServers.ts create mode 100644 app/src/internal/admin/routes/servers/serverRoutes.ts create mode 100644 app/src/internal/admin/routes/servers/updateServer.ts create mode 100644 app/src/pkg/db/schema/servers.ts create mode 100644 app/src/pkg/middleware/restrictToHosts.ts create mode 100644 controller/load_env.go create mode 100644 migrations/0010_watery_gravity.sql create mode 100644 migrations/0011_careless_banshee.sql create mode 100644 migrations/meta/0010_snapshot.json create mode 100644 migrations/meta/0011_snapshot.json diff --git a/.gitignore b/.gitignore index 9720765..754ae9b 100644 --- a/.gitignore +++ b/.gitignore @@ -194,3 +194,4 @@ controller/Dockerfile controller/Dockerfile-ignore controller/docker-compose.yml controller/index.html +controller/index.html diff --git a/.vscode/settings.json b/.vscode/settings.json index 59ec064..8cea887 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -43,5 +43,6 @@ }, // Optional: Configure goimports instead of gofmt - "go.formatTool": "goimports" + "go.formatTool": "goimports", + "cSpell.words": ["alpla", "alplamart", "alplaprod", "ppoo"] } diff --git a/LogisticsSupportTool_API_DOCS/app/admin/folder.bru b/LogisticsSupportTool_API_DOCS/app/admin/folder.bru new file mode 100644 index 0000000..10f68e4 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/admin/folder.bru @@ -0,0 +1,8 @@ +meta { + name: admin + seq: 3 +} + +auth { + mode: inherit +} diff --git a/LogisticsSupportTool_API_DOCS/app/admin/server/Add Server.bru b/LogisticsSupportTool_API_DOCS/app/admin/server/Add Server.bru new file mode 100644 index 0000000..ec40af3 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/admin/server/Add Server.bru @@ -0,0 +1,27 @@ +meta { + name: Add Server + type: http + seq: 3 +} + +post { + url: {{url}}/lst/api/admin/server + body: json + auth: inherit +} + +body:json { + { + "name": "Test Server", + "serverDNS": "USMCD1VMS036", + "plantToken": "test3", + "ipAddress": "10.193.0.56", + "greatPlainsPlantCode": 0, + "lstServerPort": 4000, + "serverLoc": "E$\\LST" + } +} + +settings { + encodeUrl: true +} diff --git a/LogisticsSupportTool_API_DOCS/app/admin/server/Get Servers.bru b/LogisticsSupportTool_API_DOCS/app/admin/server/Get Servers.bru new file mode 100644 index 0000000..cd80ec5 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/admin/server/Get Servers.bru @@ -0,0 +1,15 @@ +meta { + name: Get Servers + type: http + seq: 1 +} + +get { + url: {{url}}/lst/api/admin/server + body: none + auth: inherit +} + +settings { + encodeUrl: true +} diff --git a/LogisticsSupportTool_API_DOCS/app/admin/server/Update Server.bru b/LogisticsSupportTool_API_DOCS/app/admin/server/Update Server.bru new file mode 100644 index 0000000..3226b9b --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/admin/server/Update Server.bru @@ -0,0 +1,15 @@ +meta { + name: Update Server + type: http + seq: 2 +} + +patch { + url: {{url}}/lst/api/admin/server + body: none + auth: inherit +} + +settings { + encodeUrl: true +} diff --git a/LogisticsSupportTool_API_DOCS/app/admin/server/folder.bru b/LogisticsSupportTool_API_DOCS/app/admin/server/folder.bru new file mode 100644 index 0000000..18662c4 --- /dev/null +++ b/LogisticsSupportTool_API_DOCS/app/admin/server/folder.bru @@ -0,0 +1,8 @@ +meta { + name: server + seq: 2 +} + +auth { + mode: inherit +} diff --git a/app/src/internal/admin/routes.ts b/app/src/internal/admin/routes.ts index 8962933..482babc 100644 --- a/app/src/internal/admin/routes.ts +++ b/app/src/internal/admin/routes.ts @@ -4,6 +4,8 @@ import { requireAuth } from "../../pkg/middleware/authMiddleware.js"; //admin routes import users from "./routes/getUserRoles.js"; import grantRoles from "./routes/grantRole.js"; +import servers from "./routes/servers/serverRoutes.js"; +import { restrictToHosts } from "../../pkg/middleware/restrictToHosts.js"; export const setupAdminRoutes = (app: Express, basePath: string) => { app.use( @@ -16,4 +18,11 @@ export const setupAdminRoutes = (app: Express, basePath: string) => { requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this grantRoles ); + + app.use( + basePath + "/api/admin/server", + requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this + restrictToHosts(["usmcd1vms036", "USMCD1VMS036"]), // what servers are allowed to see the server section + servers + ); }; diff --git a/app/src/internal/admin/routes/servers/addServer.ts b/app/src/internal/admin/routes/servers/addServer.ts new file mode 100644 index 0000000..bd6c3bc --- /dev/null +++ b/app/src/internal/admin/routes/servers/addServer.ts @@ -0,0 +1,74 @@ +import { Router } from "express"; +import type { Request, Response } from "express"; +import { + insertServerDataSchema, + serverData, +} from "../../../../pkg/db/schema/servers.js"; +import { db } from "../../../../pkg/db/db.js"; +import { tryCatch } from "../../../../pkg/utils/tryCatch.js"; +import type { DrizzleError } from "drizzle-orm"; +import axios from "axios"; +import { createLogger } from "../../../../pkg/logger/logger.js"; + +const router = Router(); + +router.post("/", async (req: Request, res: Response) => { + // when a new server is posted from localhost or 127.0.0.1 we also want to post it to the test server so we can see it from there + //res.status(200).json({ message: "Server added", ip: req.hostname }); + const log = createLogger({ module: "admin", subModule: "add server" }); + const parsed = insertServerDataSchema.safeParse(req.body); + + if (!parsed.success) { + return res.status(400).json({ errors: parsed.error.flatten() }); + } + + const { data, error } = await tryCatch( + db + .insert(serverData) + .values(parsed.data) + //.onConflictDoNothing() + .returning({ + name: serverData.name, + plantToken: serverData.plantToken, + }) + ); + + if (error) { + const err: DrizzleError = error; + return res.status(400).json({ + message: `Error adding the server`, + error: err.cause, + }); + } + + if (req.hostname === "localhost" && process.env.MAIN_SERVER) { + log.info({}, "Running in dev server about to add in a new server"); + const { data, error } = await tryCatch( + axios.post( + `${process.env.MAIN_SERVER}/lst/api/admin/server`, + parsed.data, + { + headers: { + "Content-Type": "application/json", + Cookie: req.headers.cookie ?? "", + }, + withCredentials: true, + } + ) + ); + + if (error) { + log.error( + { stack: error }, + "There was an error adding the server to Main Server" + ); + } + log.info({ stack: data }, "A new Server was just added to the server."); + } + + return res + .status(201) + .json({ message: `Server ${data[0]?.name} added`, data: data }); +}); + +export default router; diff --git a/app/src/internal/admin/routes/servers/getServers.ts b/app/src/internal/admin/routes/servers/getServers.ts new file mode 100644 index 0000000..85152c7 --- /dev/null +++ b/app/src/internal/admin/routes/servers/getServers.ts @@ -0,0 +1,25 @@ +import { Router } from "express"; +import type { Request, Response } from "express"; +import { tryCatch } from "../../../../pkg/utils/tryCatch.js"; +import { db } from "../../../../pkg/db/db.js"; +import { serverData } from "../../../../pkg/db/schema/servers.js"; +import { and, asc, eq } from "drizzle-orm"; + +const router = Router(); + +router.get("/", async (req: Request, res: Response) => { + const { data, error } = await tryCatch( + db + .select() + .from(serverData) + .where(eq(serverData.active, true)) + .orderBy(asc(serverData.name)) + ); + + if (error) { + return res.status(400).json({ error: error }); + } + res.status(200).json({ message: "Current Active server", data: data }); +}); + +export default router; diff --git a/app/src/internal/admin/routes/servers/serverRoutes.ts b/app/src/internal/admin/routes/servers/serverRoutes.ts new file mode 100644 index 0000000..4dd0350 --- /dev/null +++ b/app/src/internal/admin/routes/servers/serverRoutes.ts @@ -0,0 +1,12 @@ +import { Router } from "express"; +import addServer from "./addServer.js"; +import getServers from "./getServers.js"; +import updateServer from "./updateServer.js"; + +const router = Router(); + +router.get("/", getServers); +router.post("/", addServer); +router.patch("/", updateServer); + +export default router; diff --git a/app/src/internal/admin/routes/servers/updateServer.ts b/app/src/internal/admin/routes/servers/updateServer.ts new file mode 100644 index 0000000..59fd75b --- /dev/null +++ b/app/src/internal/admin/routes/servers/updateServer.ts @@ -0,0 +1,11 @@ +import { Router } from "express"; +import type { Request, Response } from "express"; + +const router = Router(); + +router.patch("/", async (req: Request, res: Response) => { + // when a server is updated and is posted from localhost or 127.0.0.1 we also want to post it to the test server so we can see it from there, we want to insert with update on conflict. + res.status(200).json({ message: "Server added" }); +}); + +export default router; diff --git a/app/src/internal/system/routes/stats.ts b/app/src/internal/system/routes/stats.ts index 982ce6d..0cee562 100644 --- a/app/src/internal/system/routes/stats.ts +++ b/app/src/internal/system/routes/stats.ts @@ -27,7 +27,9 @@ router.get("/", async (req, res) => { uptime: process.uptime(), build: statData[0]?.build, pendingUpdateFile: await checkBuildUpdate(["."]), - lastUpdate: format(statData[0].lastUpdate!, "MM/dd/yyyy HH:mm"), + lastUpdate: statData[0]?.lastUpdate + ? format(statData[0].lastUpdate, "MM/dd/yyyy HH:mm") + : "", }); }); diff --git a/app/src/pkg/db/schema/servers.ts b/app/src/pkg/db/schema/servers.ts new file mode 100644 index 0000000..5c5d39e --- /dev/null +++ b/app/src/pkg/db/schema/servers.ts @@ -0,0 +1,49 @@ +import { + boolean, + integer, + pgTable, + text, + timestamp, + uniqueIndex, + uuid, +} from "drizzle-orm/pg-core"; +import { createInsertSchema, createSelectSchema } from "drizzle-zod"; +import z from "zod"; + +export const serverData = pgTable( + "serverData", + { + server_id: uuid("server_id").defaultRandom().primaryKey(), + name: text("name").notNull(), + serverDNS: text("serverDNS").notNull(), + plantToken: text("plantToken").notNull(), + ipAddress: text("ipAddress").notNull(), + greatPlainsPlantCode: integer("greatPlainsPlantCode").notNull(), + streetAddress: text("streetAddress"), + cityState: text("cityState"), + zipcode: integer("zipcode"), + contactEmail: text("contactEmail"), + contactPhone: text("contactPhone"), + customerTiAcc: text("customerTiAcc"), + lstServerPort: integer("lstServerPort").notNull(), + active: boolean("active").default(true), + serverLoc: text("serverLoc").notNull(), + lastUpdated: timestamp("lastUpdated").defaultNow(), + isUpgrading: boolean("isUpgrading").default(false), + }, + + (table) => [ + // uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`), + uniqueIndex("plantToken").on(table.plantToken), + ] +); + +export const selectServerDataSchema = createSelectSchema(serverData); + +export const insertServerDataSchema = createInsertSchema(serverData).extend({ + contactEmail: z.email().optional(), + // zipcode: z + // .string() + // .regex(/^\d{5}$/) + // .optional(), +}); diff --git a/app/src/pkg/middleware/restrictToHosts.ts b/app/src/pkg/middleware/restrictToHosts.ts new file mode 100644 index 0000000..5570865 --- /dev/null +++ b/app/src/pkg/middleware/restrictToHosts.ts @@ -0,0 +1,30 @@ +import type { Request, Response, NextFunction } from "express"; + +/** + * Middleware to restrict access only to localhost or a whitelist of hosts. + */ +export function restrictToHosts(allowedHosts: string[] = []) { + return (req: Request, res: Response, next: NextFunction) => { + // `req.ip` gives the remote IP + const ip = req.ip!.replace("::ffff:", ""); // strip IPv6 prefix if present + + // Express sets req.hostname from the Host header + const hostname = req.hostname; + + const isLocal = + ip === "127.0.0.1" || ip === "::1" || hostname === "localhost"; + + const isAllowed = + isLocal || + allowedHosts.includes(ip) || + allowedHosts.includes(hostname); + + if (!isAllowed) { + return res + .status(403) + .json({ error: "Access not allowed from this host" }); + } + + next(); + }; +} diff --git a/controller/go.mod b/controller/go.mod index ddc1850..ef0237b 100644 --- a/controller/go.mod +++ b/controller/go.mod @@ -3,13 +3,15 @@ module lst.net go 1.24.3 require ( + github.com/bwmarrin/discordgo v0.29.0 github.com/gin-gonic/gin v1.10.1 github.com/googollee/go-socket.io v1.7.0 + github.com/jackc/pgx/v5 v5.7.6 github.com/joho/godotenv v1.5.1 + github.com/robfig/cron/v3 v3.0.0 ) require ( - github.com/bwmarrin/discordgo v0.29.0 // indirect github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect @@ -29,7 +31,6 @@ require ( github.com/hirochachacha/go-smb2 v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.6 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect @@ -39,7 +40,6 @@ require ( github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/prometheus-community/pro-bing v0.7.0 // indirect github.com/robfig/cron v1.2.0 // indirect - github.com/robfig/cron/v3 v3.0.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect golang.org/x/arch v0.8.0 // indirect diff --git a/controller/index.html b/controller/index.html index 75bb008..a816eb4 100644 --- a/controller/index.html +++ b/controller/index.html @@ -180,22 +180,22 @@ { name: "Houston", server: "USHOU1VMS006", - location: "E$\\LST\\LST", + location: "E$\\LST", }, { name: "Sherman", server: "USSHE1VMS006", - location: "E$\\LST\\LST", + location: "E$\\LST", }, { name: "West Bend", server: "USWEB1VMS006", - location: "E$\\LST\\LST", + location: "E$\\LST", }, { name: "Jerfferson City", server: "USJCI1VMS006", - location: "E$\\LST\\LST", + location: "E$\\LST", }, ]; @@ -324,9 +324,7 @@ }); logMessage( "info", - `Copying to ${ - srv.name - } (drive ${srv.drive.toUpperCase()})` + `Copying to ${srv.name} (location ${srv.location})` ); }); @@ -364,15 +362,13 @@ currentServer = copyQueue.shift(); logMessage( "info", - `🚀 Copying to ${ - currentServer.name - } (drive ${currentServer.drive.toUpperCase()})` + `Copying to ${currentServer.name} (location ${currentServer.location})` ); socket.emit("update", { action: "copy", - target: currentServer.name, - drive: currentServer.drive, + target: currentServer.server, + location: currentServer.location, }); } @@ -381,7 +377,8 @@ // Only check queue progress if we're in All mode and have a currentServer if (isRunningAll && currentServer) { - const expected = `✅ Copy to ${currentServer.name} successful`; + //const expected = `✅ Copy to ${currentServer.name} successful`; + const expected = "done"; if (msg.includes(expected)) { logMessage( diff --git a/controller/load_env.go b/controller/load_env.go new file mode 100644 index 0000000..6610881 --- /dev/null +++ b/controller/load_env.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/joho/godotenv" +) + +func loadEnv() { + exePath, _ := os.Executable() + exeDir := filepath.Dir(exePath) + + // Normalize both to lowercase absolute paths for Windows safety + exePathLower := strings.ToLower(exePath) + tempDirLower := strings.ToLower(filepath.Clean(os.TempDir())) + + // Heuristic: if exe lives *inside* the system temp dir → assume go run + if strings.HasPrefix(exePathLower, tempDirLower) { + fmt.Println("Detected go run – loading ../.env") + err := godotenv.Load("../.env") + if err != nil { + fmt.Println("ERROR loading .env:", err) + } else { + fmt.Println(".env successfully loaded") + } + + return + } + + // Otherwise → normal compiled exe + fmt.Println("Detected compiled exe – loading exeDir/.env") + if err := godotenv.Load(filepath.Join(exeDir, ".env")); err != nil { + fmt.Println("Didn't find exeDir/.env – trying ../.env as fallback") + err := godotenv.Load("../.env") + if err != nil { + fmt.Println("ERROR loading .env:", err) + } else { + fmt.Println(".env successfully loaded") + } + } + +} diff --git a/controller/main.go b/controller/main.go index 31615c9..f67fadc 100644 --- a/controller/main.go +++ b/controller/main.go @@ -5,26 +5,18 @@ import ( "log" "net/http" "os" - "path/filepath" "strings" "time" "github.com/gin-gonic/gin" socketio "github.com/googollee/go-socket.io" - "github.com/joho/godotenv" "lst.net/internal/bot" "lst.net/pkg" ) func main() { - exePath, _ := os.Executable() - exeDir := filepath.Dir(exePath) - - if err := godotenv.Load(filepath.Join(exeDir, ".env")); err != nil { - // fallback dev path - _ = godotenv.Load("../.env") - } + loadEnv() // gin stuff basePath := "/api/controller" diff --git a/migrations/0010_watery_gravity.sql b/migrations/0010_watery_gravity.sql new file mode 100644 index 0000000..c871f4b --- /dev/null +++ b/migrations/0010_watery_gravity.sql @@ -0,0 +1,21 @@ +CREATE TABLE "serverData" ( + "server_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "name" text NOT NULL, + "serverDNS" text, + "plantToken" text, + "ipAddress" text, + "greatPlainsPlantCode" numeric, + "streetAddress" text, + "cityState" text, + "zipcode" numeric, + "contactEmail" text, + "contactPhone" text, + "customerTiAcc" text, + "lstServerPort" numeric, + "active" boolean DEFAULT true, + "serverLoc" text, + "lastUpdated" timestamp DEFAULT now(), + "isUpgrading" boolean DEFAULT false +); +--> statement-breakpoint +CREATE UNIQUE INDEX "plantToken" ON "serverData" USING btree ("plantToken"); \ No newline at end of file diff --git a/migrations/0011_careless_banshee.sql b/migrations/0011_careless_banshee.sql new file mode 100644 index 0000000..32b95cd --- /dev/null +++ b/migrations/0011_careless_banshee.sql @@ -0,0 +1,9 @@ +ALTER TABLE "serverData" ALTER COLUMN "serverDNS" SET NOT NULL;--> statement-breakpoint +ALTER TABLE "serverData" ALTER COLUMN "plantToken" SET NOT NULL;--> statement-breakpoint +ALTER TABLE "serverData" ALTER COLUMN "ipAddress" SET NOT NULL;--> statement-breakpoint +ALTER TABLE "serverData" ALTER COLUMN "greatPlainsPlantCode" SET DATA TYPE integer;--> statement-breakpoint +ALTER TABLE "serverData" ALTER COLUMN "greatPlainsPlantCode" SET NOT NULL;--> statement-breakpoint +ALTER TABLE "serverData" ALTER COLUMN "zipcode" SET DATA TYPE integer;--> statement-breakpoint +ALTER TABLE "serverData" ALTER COLUMN "lstServerPort" SET DATA TYPE integer;--> statement-breakpoint +ALTER TABLE "serverData" ALTER COLUMN "lstServerPort" SET NOT NULL;--> statement-breakpoint +ALTER TABLE "serverData" ALTER COLUMN "serverLoc" SET NOT NULL; \ No newline at end of file diff --git a/migrations/meta/0010_snapshot.json b/migrations/meta/0010_snapshot.json new file mode 100644 index 0000000..b2f333a --- /dev/null +++ b/migrations/meta/0010_snapshot.json @@ -0,0 +1,1056 @@ +{ + "id": "2953b8d4-267c-4f74-962c-2d8fbbb96837", + "prevId": "7f5da907-4bed-4584-b32b-1f7f2ce17455", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.apiHits": { + "name": "apiHits", + "schema": "", + "columns": { + "apiHit_id": { + "name": "apiHit_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "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": {}, + "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": {}, + "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 + } + }, + "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": {}, + "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 + }, + "last_login": { + "name": "last_login", + "type": "timestamp", + "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": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.logs": { + "name": "logs", + "schema": "", + "columns": { + "log_id": { + "name": "log_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 + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.serverData": { + "name": "serverData", + "schema": "", + "columns": { + "server_id": { + "name": "server_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverDNS": { + "name": "serverDNS", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plantToken": { + "name": "plantToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ipAddress": { + "name": "ipAddress", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "greatPlainsPlantCode": { + "name": "greatPlainsPlantCode", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "streetAddress": { + "name": "streetAddress", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cityState": { + "name": "cityState", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "zipcode": { + "name": "zipcode", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "contactEmail": { + "name": "contactEmail", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contactPhone": { + "name": "contactPhone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customerTiAcc": { + "name": "customerTiAcc", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "lstServerPort": { + "name": "lstServerPort", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "serverLoc": { + "name": "serverLoc", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "lastUpdated": { + "name": "lastUpdated", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "isUpgrading": { + "name": "isUpgrading", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": { + "plantToken": { + "name": "plantToken", + "columns": [ + { + "expression": "plantToken", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.serverStats": { + "name": "serverStats", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "default": "'serverStats'" + }, + "build": { + "name": "build", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "lastUpdate": { + "name": "lastUpdate", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "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" + }, + "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 + }, + "public.user_roles": { + "name": "user_roles", + "schema": "", + "columns": { + "user_role_id": { + "name": "user_role_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "unique_user_module": { + "name": "unique_user_module", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "module", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_roles_user_id_user_id_fk": { + "name": "user_roles_user_id_user_id_fk", + "tableFrom": "user_roles", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/migrations/meta/0011_snapshot.json b/migrations/meta/0011_snapshot.json new file mode 100644 index 0000000..30a5550 --- /dev/null +++ b/migrations/meta/0011_snapshot.json @@ -0,0 +1,1056 @@ +{ + "id": "9b37f7bd-ca18-43df-a9a7-00e23f986ace", + "prevId": "2953b8d4-267c-4f74-962c-2d8fbbb96837", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.apiHits": { + "name": "apiHits", + "schema": "", + "columns": { + "apiHit_id": { + "name": "apiHit_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "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": {}, + "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": {}, + "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 + } + }, + "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": {}, + "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 + }, + "last_login": { + "name": "last_login", + "type": "timestamp", + "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": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.logs": { + "name": "logs", + "schema": "", + "columns": { + "log_id": { + "name": "log_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 + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.serverData": { + "name": "serverData", + "schema": "", + "columns": { + "server_id": { + "name": "server_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serverDNS": { + "name": "serverDNS", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "plantToken": { + "name": "plantToken", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "ipAddress": { + "name": "ipAddress", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "greatPlainsPlantCode": { + "name": "greatPlainsPlantCode", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "streetAddress": { + "name": "streetAddress", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cityState": { + "name": "cityState", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "zipcode": { + "name": "zipcode", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "contactEmail": { + "name": "contactEmail", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contactPhone": { + "name": "contactPhone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "customerTiAcc": { + "name": "customerTiAcc", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "lstServerPort": { + "name": "lstServerPort", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "serverLoc": { + "name": "serverLoc", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "lastUpdated": { + "name": "lastUpdated", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "isUpgrading": { + "name": "isUpgrading", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": { + "plantToken": { + "name": "plantToken", + "columns": [ + { + "expression": "plantToken", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.serverStats": { + "name": "serverStats", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "default": "'serverStats'" + }, + "build": { + "name": "build", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "lastUpdate": { + "name": "lastUpdate", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "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" + }, + "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 + }, + "public.user_roles": { + "name": "user_roles", + "schema": "", + "columns": { + "user_role_id": { + "name": "user_role_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "unique_user_module": { + "name": "unique_user_module", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "module", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_roles_user_id_user_id_fk": { + "name": "user_roles_user_id_user_id_fk", + "tableFrom": "user_roles", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "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 d5e5648..5e86e34 100644 --- a/migrations/meta/_journal.json +++ b/migrations/meta/_journal.json @@ -71,6 +71,20 @@ "when": 1758891252758, "tag": "0009_cultured_slayback", "breakpoints": true + }, + { + "idx": 10, + "version": "7", + "when": 1759193957132, + "tag": "0010_watery_gravity", + "breakpoints": true + }, + { + "idx": 11, + "version": "7", + "when": 1759195276875, + "tag": "0011_careless_banshee", + "breakpoints": true } ] } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 29a44b7..e8b74c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@dotenvx/dotenvx": "^1.49.0", "@tanstack/react-table": "^8.21.3", "@types/cors": "^2.8.19", + "axios": "^1.12.2", "better-auth": "^1.3.9", "cors": "^2.8.5", "date-fns": "^4.1.0", @@ -3438,6 +3439,12 @@ "node": ">=12.0.0" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -3457,6 +3464,17 @@ "node": ">=8.0.0" } }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "dev": true, @@ -3892,6 +3910,18 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", @@ -4760,6 +4790,15 @@ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", "license": "MIT" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "license": "MIT", @@ -5184,6 +5223,21 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", @@ -5604,6 +5658,26 @@ "node": ">= 8" } }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -5634,6 +5708,43 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "license": "MIT", @@ -6072,6 +6183,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "license": "MIT", @@ -8294,6 +8420,12 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/pump": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", diff --git a/package.json b/package.json index e836490..1e84c3b 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@dotenvx/dotenvx": "^1.49.0", "@tanstack/react-table": "^8.21.3", "@types/cors": "^2.8.19", + "axios": "^1.12.2", "better-auth": "^1.3.9", "cors": "^2.8.5", "date-fns": "^4.1.0",