Compare commits
3 Commits
083f38a079
...
4a1d95e818
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a1d95e818 | |||
| 80c0e1ec30 | |||
| 8fe1bcaef5 |
@@ -25,5 +25,13 @@ PROD_PLANT_TOKEN=test3
|
|||||||
PROD_USER=alplaprod
|
PROD_USER=alplaprod
|
||||||
PROD_PASSWORD=password
|
PROD_PASSWORD=password
|
||||||
|
|
||||||
|
# Docker Related
|
||||||
|
PROD_IP=10.193.0.56
|
||||||
|
LOGISTICS_NETWORK=10.193.14.0/24
|
||||||
|
LOGISTICS_GATEWAY=10.193.14.252
|
||||||
|
|
||||||
|
MLAN1_NETWORK=192.168.193.0/24
|
||||||
|
MLAN1_GATEWAY=192.168.193.252
|
||||||
|
|
||||||
# admin
|
# admin
|
||||||
WEBHOOK_URL
|
WEBHOOK_URL
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@ app/src/frontend
|
|||||||
lstWrapper/bin
|
lstWrapper/bin
|
||||||
lstWrapper/obj
|
lstWrapper/obj
|
||||||
lstWrapper/publish
|
lstWrapper/publish
|
||||||
|
testScripts
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
|||||||
@@ -7,15 +7,17 @@ import path, { dirname, join } from "path";
|
|||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
import { db } from "./pkg/db/db.js";
|
import { db } from "./pkg/db/db.js";
|
||||||
import { settings, type Setting } from "./pkg/db/schema/settings.js";
|
import { settings, type Setting } from "./pkg/db/schema/settings.js";
|
||||||
import { env } from "./pkg/utils/envValidator.js";
|
import { validateEnv } from "./pkg/utils/envValidator.js";
|
||||||
import { createLogger } from "./pkg/logger/logger.js";
|
import { createLogger } from "./pkg/logger/logger.js";
|
||||||
import { returnFunc } from "./pkg/utils/return.js";
|
import { returnFunc } from "./pkg/utils/return.js";
|
||||||
import { initializeProdPool } from "./pkg/prodSql/prodSqlConnect.js";
|
import { closePool, initializeProdPool } from "./pkg/prodSql/prodSqlConnect.js";
|
||||||
import { tryCatch } from "./pkg/utils/tryCatch.js";
|
import { tryCatch } from "./pkg/utils/tryCatch.js";
|
||||||
|
import os, { hostname } from "os";
|
||||||
const PORT = Number(env.VITE_PORT) || 4200;
|
import { sendNotify } from "./pkg/utils/notify.js";
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
|
const env = validateEnv(process.env);
|
||||||
|
const PORT = Number(env.VITE_PORT) || 4200;
|
||||||
//create the logger
|
//create the logger
|
||||||
const log = createLogger({ module: "system", subModule: "main start" });
|
const log = createLogger({ module: "system", subModule: "main start" });
|
||||||
|
|
||||||
@@ -94,28 +96,16 @@ const main = async () => {
|
|||||||
// start the server up
|
// start the server up
|
||||||
server.listen(PORT, "0.0.0.0", () =>
|
server.listen(PORT, "0.0.0.0", () =>
|
||||||
log.info(
|
log.info(
|
||||||
|
{ stack: { name: "test" } },
|
||||||
`Server running in ${
|
`Server running in ${
|
||||||
process.env.NODE_ENV ? process.env.NODE_ENV : "dev"
|
process.env.NODE_ENV ? process.env.NODE_ENV : "dev"
|
||||||
}, on http://0.0.0.0:${PORT}${basePath}`
|
}, on http://0.0.0.0:${PORT}${basePath}`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Handle app exit signals
|
|
||||||
process.on("SIGINT", async () => {
|
|
||||||
console.log("\nGracefully shutting down...");
|
|
||||||
//await closePool();
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
process.on("SIGTERM", async () => {
|
|
||||||
console.log("Received termination signal, closing database...");
|
|
||||||
//await closePool();
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
process.on("uncaughtException", async (err) => {
|
process.on("uncaughtException", async (err) => {
|
||||||
console.log("Uncaught Exception:", err);
|
//console.log("Uncaught Exception:", err);
|
||||||
//await closePool();
|
// await closePool();
|
||||||
// const emailData = {
|
// const emailData = {
|
||||||
// email: "blake.matthes@alpla.com", // should be moved to the db so it can be reused.
|
// email: "blake.matthes@alpla.com", // should be moved to the db so it can be reused.
|
||||||
// subject: `${os.hostname()} has just encountered a crash.`,
|
// subject: `${os.hostname()} has just encountered a crash.`,
|
||||||
@@ -126,15 +116,40 @@ const main = async () => {
|
|||||||
// },
|
// },
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// await sendEmail(emailData);
|
if (!process.env.WEBHOOK_URL) {
|
||||||
|
// await sendEmail(emailData);
|
||||||
|
} else {
|
||||||
|
await sendNotify({
|
||||||
|
module: "system",
|
||||||
|
subModule: "fatalCrash",
|
||||||
|
hostname: os.hostname(),
|
||||||
|
message: err.message,
|
||||||
|
stack: err?.stack,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on("beforeExit", async () => {
|
// setInterval(() => {
|
||||||
console.log("Process is about to exit...");
|
// const used = process.memoryUsage();
|
||||||
//await closePool();
|
// console.log(
|
||||||
process.exit(0);
|
// `Heap: ${(used.heapUsed / 1024 / 1024).toFixed(2)} MB / RSS: ${(
|
||||||
});
|
// used.rss /
|
||||||
|
// 1024 /
|
||||||
|
// 1024
|
||||||
|
// ).toFixed(2)} MB`
|
||||||
|
// );
|
||||||
|
// }, 10000);
|
||||||
};
|
};
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
||||||
|
// .catch((err) => {
|
||||||
|
// const log = createLogger({ module: "system", subModule: "main" });
|
||||||
|
// log.fatal(
|
||||||
|
// { notify: true },
|
||||||
|
// "There was a crash that occured and caused the app to restart."
|
||||||
|
// );
|
||||||
|
// process.exit(1);
|
||||||
|
// });
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { drizzle } from "drizzle-orm/postgres-js";
|
import { drizzle } from "drizzle-orm/postgres-js";
|
||||||
import postgres from "postgres";
|
import postgres from "postgres";
|
||||||
import { env } from "../utils/envValidator.js";
|
import { validateEnv } from "../utils/envValidator.js";
|
||||||
|
|
||||||
|
const env = validateEnv(process.env);
|
||||||
const dbURL = `postgres://${env.DATABASE_USER}:${env.DATABASE_PASSWORD}@${env.DATABASE_HOST}:${env.DATABASE_PORT}/${env.DATABASE_DB}`;
|
const dbURL = `postgres://${env.DATABASE_USER}:${env.DATABASE_PASSWORD}@${env.DATABASE_HOST}:${env.DATABASE_PORT}/${env.DATABASE_DB}`;
|
||||||
|
|
||||||
const queryClient = postgres(dbURL, {
|
const queryClient = postgres(dbURL, {
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
import { boolean, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
import {
|
||||||
|
boolean,
|
||||||
|
jsonb,
|
||||||
|
pgTable,
|
||||||
|
text,
|
||||||
|
timestamp,
|
||||||
|
uuid,
|
||||||
|
} from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -8,7 +15,7 @@ export const logs = pgTable("logs", {
|
|||||||
module: text("module").notNull(),
|
module: text("module").notNull(),
|
||||||
subModule: text("subModule"),
|
subModule: text("subModule"),
|
||||||
message: text("message").notNull(),
|
message: text("message").notNull(),
|
||||||
stack: text("stack"),
|
stack: jsonb("stack").default([]),
|
||||||
checked: boolean("checked").default(false),
|
checked: boolean("checked").default(false),
|
||||||
hostname: text("hostname"),
|
hostname: text("hostname"),
|
||||||
createdAt: timestamp("createdAt").defaultNow(),
|
createdAt: timestamp("createdAt").defaultNow(),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import build from "pino-abstract-transport";
|
import build from "pino-abstract-transport";
|
||||||
import { db } from "../db/db.js";
|
import { db } from "../db/db.js";
|
||||||
import { logs, type Log } from "../db/schema/logs.js";
|
import { logs, type Log } from "../db/schema/logs.js";
|
||||||
import { checkENV } from "../utils/envValidator.js";
|
import { tryCatch } from "../utils/tryCatch.js";
|
||||||
|
|
||||||
const pinoLogLevels: any = {
|
const pinoLogLevels: any = {
|
||||||
10: "trace",
|
10: "trace",
|
||||||
@@ -19,14 +19,21 @@ export default async function (log: Log) {
|
|||||||
for await (let obj of source) {
|
for await (let obj of source) {
|
||||||
// convert to the name to make it more easy to find later :P
|
// convert to the name to make it more easy to find later :P
|
||||||
const levelName = pinoLogLevels[obj.level] || "unknown";
|
const levelName = pinoLogLevels[obj.level] || "unknown";
|
||||||
await db.insert(logs).values({
|
|
||||||
level: levelName,
|
const res = await tryCatch(
|
||||||
module: obj?.module.toLowerCase(),
|
db.insert(logs).values({
|
||||||
subModule: obj?.subModule.toLowerCase(),
|
level: levelName,
|
||||||
hostname: obj?.hostname.toLowerCase(),
|
module: obj?.module?.toLowerCase(),
|
||||||
message: obj.msg,
|
subModule: obj?.subModule?.toLowerCase(),
|
||||||
stack: obj?.stack,
|
hostname: obj?.hostname?.toLowerCase(),
|
||||||
});
|
message: obj.msg,
|
||||||
|
stack: obj?.stack,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res.error) {
|
||||||
|
console.log(res.error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import pino, { type Logger } from "pino";
|
import pino, { type Logger } from "pino";
|
||||||
import { env } from "../utils/envValidator.js";
|
|
||||||
|
|
||||||
export let logLevel = process.env.LOG_LEVEL || "info";
|
export let logLevel = process.env.LOG_LEVEL || "info";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import build from "pino-abstract-transport";
|
import build from "pino-abstract-transport";
|
||||||
import { db } from "../db/db.js";
|
import { type Log } from "../db/schema/logs.js";
|
||||||
import { logs, type Log } from "../db/schema/logs.js";
|
import { validateEnv } from "../utils/envValidator.js";
|
||||||
import { env } from "../utils/envValidator.js";
|
import { sendNotify } from "../utils/notify.js";
|
||||||
|
const env = validateEnv(process.env);
|
||||||
|
|
||||||
const pinoLogLevels: any = {
|
const pinoLogLevels: any = {
|
||||||
10: "trace",
|
10: "trace",
|
||||||
@@ -12,49 +13,6 @@ const pinoLogLevels: any = {
|
|||||||
60: "fatal",
|
60: "fatal",
|
||||||
};
|
};
|
||||||
// discord function
|
// discord function
|
||||||
async function sendFatal(log: Log) {
|
|
||||||
const webhookUrl = process.env.WEBHOOK_URL!;
|
|
||||||
let payload = {
|
|
||||||
embeds: [
|
|
||||||
{
|
|
||||||
title: `🚨 ${env.PROD_PLANT_TOKEN}: encounter a critical error `,
|
|
||||||
description: `Where was the error: ${log.module}${
|
|
||||||
log.subModule ? `-${log.subModule}` : ""
|
|
||||||
}`,
|
|
||||||
color: 0xff0000, // red
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: "Message",
|
|
||||||
value: log.message,
|
|
||||||
inline: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Hostname",
|
|
||||||
value: log.hostname,
|
|
||||||
inline: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Stack",
|
|
||||||
value:
|
|
||||||
"```" +
|
|
||||||
(log.stack?.slice(0, 1000) ?? "no stack") +
|
|
||||||
"```",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
footer: {
|
|
||||||
text: "LST Logger 💀",
|
|
||||||
},
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
await fetch(webhookUrl, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify(payload),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function (log: Log) {
|
export default async function (log: Log) {
|
||||||
//const {username, service, level, msg, ...extra} = log;
|
//const {username, service, level, msg, ...extra} = log;
|
||||||
@@ -76,14 +34,15 @@ export default async function (log: Log) {
|
|||||||
? String(obj.hostname).toLowerCase()
|
? String(obj.hostname).toLowerCase()
|
||||||
: undefined,
|
: undefined,
|
||||||
message: obj.msg,
|
message: obj.msg,
|
||||||
|
stack: obj.stack ? obj.stack : undefined,
|
||||||
};
|
};
|
||||||
if (!process.env.WEBHOOK_URL) {
|
if (!process.env.WEBHOOK_URL) {
|
||||||
console.log("webhook missing?");
|
console.log("WebHook is missing we wont move foward.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.level >= 60 && obj.notify) {
|
if (obj.level >= 60 && obj.notify) {
|
||||||
sendFatal(newlog as Log);
|
sendNotify(newlog as Log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { env } from "../utils/envValidator.js";
|
|
||||||
import { returnFunc } from "../utils/return.js";
|
import { returnFunc } from "../utils/return.js";
|
||||||
import { connected, pool } from "./prodSqlConnect.js";
|
import { connected, pool } from "./prodSqlConnect.js";
|
||||||
|
import { validateEnv } from "../utils/envValidator.js";
|
||||||
|
|
||||||
|
const env = validateEnv(process.env);
|
||||||
/**
|
/**
|
||||||
* Run a prod query
|
* Run a prod query
|
||||||
* just pass over the query as a string and the name of the query.
|
* just pass over the query as a string and the name of the query.
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import sql from "mssql";
|
import sql from "mssql";
|
||||||
import { env } from "../utils/envValidator.js";
|
import { validateEnv } from "../utils/envValidator.js";
|
||||||
|
|
||||||
|
const env = validateEnv(process.env);
|
||||||
export const sqlConfig: sql.config = {
|
export const sqlConfig: sql.config = {
|
||||||
server: env.PROD_SERVER,
|
server: env.PROD_SERVER,
|
||||||
database: `AlplaPROD_${env.PROD_PLANT_TOKEN}_cus`,
|
database: `AlplaPROD_${env.PROD_PLANT_TOKEN}_cus`,
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import sql from "mssql";
|
import sql from "mssql";
|
||||||
import { checkHostnamePort } from "../utils/checkHostNamePort.js";
|
import { checkHostnamePort } from "../utils/checkHostNamePort.js";
|
||||||
import { sqlConfig } from "./prodSqlConfig.js";
|
import { sqlConfig } from "./prodSqlConfig.js";
|
||||||
import { env } from "../utils/envValidator.js";
|
|
||||||
import { createLogger } from "../logger/logger.js";
|
import { createLogger } from "../logger/logger.js";
|
||||||
import { returnFunc } from "../utils/return.js";
|
import { returnFunc } from "../utils/return.js";
|
||||||
|
import { validateEnv } from "../utils/envValidator.js";
|
||||||
|
|
||||||
|
const env = validateEnv(process.env);
|
||||||
|
|
||||||
export let pool: any;
|
export let pool: any;
|
||||||
export let connected: boolean = false;
|
export let connected: boolean = false;
|
||||||
|
|||||||
@@ -1,55 +1,37 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { createLogger } from "../logger/logger.js";
|
|
||||||
/**
|
|
||||||
* This is where we will validate the required ENV parapmeters.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const envSchema = z.object({
|
const envSchema = z.object({
|
||||||
//Server stuff
|
// server stuff
|
||||||
VITE_PORT: z.string().default("4200"),
|
VITE_PORT: z.string().default("4200"),
|
||||||
LOG_LEVEL: z.string().default("info"),
|
LOG_LEVEL: z.string().default("info"),
|
||||||
// app db stuff
|
|
||||||
|
// db stuff
|
||||||
DATABASE_HOST: z.string(),
|
DATABASE_HOST: z.string(),
|
||||||
DATABASE_PORT: z.string(),
|
DATABASE_PORT: z.string(),
|
||||||
DATABASE_USER: z.string(),
|
DATABASE_USER: z.string(),
|
||||||
DATABASE_PASSWORD: z.string(),
|
DATABASE_PASSWORD: z.string(),
|
||||||
DATABASE_DB: z.string().default("lst"),
|
DATABASE_DB: z.string().default("lst"),
|
||||||
// prod server checks
|
|
||||||
|
// prod stuff
|
||||||
PROD_SERVER: z.string(),
|
PROD_SERVER: z.string(),
|
||||||
PROD_PLANT_TOKEN: z.string(),
|
PROD_PLANT_TOKEN: z.string(),
|
||||||
PROD_USER: z.string(),
|
PROD_USER: z.string(),
|
||||||
PROD_PASSWORD: z.string(),
|
PROD_PASSWORD: z.string(),
|
||||||
|
|
||||||
|
// docker specifc
|
||||||
|
RUNNING_IN_DOCKER: z.string().default("false"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// use safeParse instead of parse
|
export type Env = z.infer<typeof envSchema>;
|
||||||
const parsed = envSchema.safeParse(process.env);
|
|
||||||
|
|
||||||
export const checkENV = () => {
|
export function validateEnv(raw: NodeJS.ProcessEnv): Env {
|
||||||
return envSchema.safeParse(process.env);
|
const parsed = envSchema.safeParse(raw);
|
||||||
};
|
if (!parsed.success) {
|
||||||
|
throw new Error(
|
||||||
const log = createLogger({ module: "envValidation" });
|
`Environment validation failed. Missing: ${parsed.error.issues
|
||||||
|
.map((e) => e.path[0])
|
||||||
if (!parsed.success) {
|
.join(", ")}`
|
||||||
log.fatal(
|
);
|
||||||
`Environment validation failed: Missing: ${parsed.error.issues
|
}
|
||||||
.map((e) => {
|
return parsed.data;
|
||||||
return e.path[0];
|
|
||||||
})
|
|
||||||
.join(", ")}`
|
|
||||||
);
|
|
||||||
// 🔔 Send a notification (e.g., email, webhook, Slack)
|
|
||||||
// sendNotification(parsed.error.format());
|
|
||||||
|
|
||||||
// gracefully exit if in production
|
|
||||||
//process.exit(1);
|
|
||||||
throw Error(
|
|
||||||
`Environment validation failed: Missing: ${parsed.error.issues
|
|
||||||
.map((e) => {
|
|
||||||
return e.path[0];
|
|
||||||
})
|
|
||||||
.join(", ")}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const env = parsed.data;
|
|
||||||
|
|||||||
45
app/src/pkg/utils/notify.ts
Normal file
45
app/src/pkg/utils/notify.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import type { Log } from "../db/schema/logs.js";
|
||||||
|
import { validateEnv } from "../utils/envValidator.js";
|
||||||
|
|
||||||
|
const env = validateEnv(process.env);
|
||||||
|
|
||||||
|
export async function sendNotify(log: any) {
|
||||||
|
const webhookUrl = process.env.WEBHOOK_URL!;
|
||||||
|
let payload = {
|
||||||
|
embeds: [
|
||||||
|
{
|
||||||
|
title: `🚨 ${env.PROD_PLANT_TOKEN}: encounter a critical error `,
|
||||||
|
description: `Where was the error: ${log.module}${
|
||||||
|
log.subModule ? `-${log.subModule}` : ""
|
||||||
|
}`,
|
||||||
|
color: 0xff0000, // red
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "Message",
|
||||||
|
value: log.message,
|
||||||
|
inline: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Hostname",
|
||||||
|
value: log.hostname,
|
||||||
|
inline: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Stack",
|
||||||
|
value: "```" + (log.stack ?? "no stack") + "```",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
footer: {
|
||||||
|
text: "LST Logger 💀",
|
||||||
|
},
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
await fetch(webhookUrl, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ services:
|
|||||||
- "${VITE_PORT:-4200}:4200"
|
- "${VITE_PORT:-4200}:4200"
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=devolpment
|
- NODE_ENV=devolpment
|
||||||
- DATABASE_HOST=${DATABASE_HOST}
|
- DATABASE_HOST=host.docker.internal
|
||||||
- DATABASE_PORT=${DATABASE_PORT}
|
- DATABASE_PORT=${DATABASE_PORT}
|
||||||
- DATABASE_USER=${DATABASE_USER}
|
- DATABASE_USER=${DATABASE_USER}
|
||||||
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
|
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
|
||||||
@@ -18,3 +18,29 @@ services:
|
|||||||
- PROD_USER=${PROD_USER}
|
- PROD_USER=${PROD_USER}
|
||||||
- PROD_PASSWORD=${PROD_PASSWORD}
|
- PROD_PASSWORD=${PROD_PASSWORD}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
# for all host including prod servers, plc's, printers, or other de
|
||||||
|
extra_hosts:
|
||||||
|
- "${PROD_SERVER}:${PROD_IP}"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- logisticsNetwork
|
||||||
|
- mlan1
|
||||||
|
networks:
|
||||||
|
logisticsNetwork:
|
||||||
|
driver: macvlan
|
||||||
|
driver_opts:
|
||||||
|
parent: eth0
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: ${LOGISTICS_NETWORK}
|
||||||
|
gateway: ${LOGISTICS_GATEWAY}
|
||||||
|
|
||||||
|
mlan1:
|
||||||
|
driver: macvlan
|
||||||
|
driver_opts:
|
||||||
|
parent: eth0
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: ${MLAN1_NETWORK}
|
||||||
|
gateway: ${MLAN1_GATEWAY}
|
||||||
|
|||||||
2
migrations/0002_mean_nuke.sql
Normal file
2
migrations/0002_mean_nuke.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE "logs" ALTER COLUMN "stack" SET DATA TYPE jsonb;--> statement-breakpoint
|
||||||
|
ALTER TABLE "logs" ALTER COLUMN "stack" SET DEFAULT '[]'::jsonb;
|
||||||
192
migrations/meta/0002_snapshot.json
Normal file
192
migrations/meta/0002_snapshot.json
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
{
|
||||||
|
"id": "922093ba-6949-4d30-9c17-007257754cf2",
|
||||||
|
"prevId": "5eac3348-eeab-4210-b686-29e570f87911",
|
||||||
|
"version": "7",
|
||||||
|
"dialect": "postgresql",
|
||||||
|
"tables": {
|
||||||
|
"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.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
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enums": {},
|
||||||
|
"schemas": {},
|
||||||
|
"sequences": {},
|
||||||
|
"roles": {},
|
||||||
|
"policies": {},
|
||||||
|
"views": {},
|
||||||
|
"_meta": {
|
||||||
|
"columns": {},
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,13 @@
|
|||||||
"when": 1756693049476,
|
"when": 1756693049476,
|
||||||
"tag": "0001_solid_kronos",
|
"tag": "0001_solid_kronos",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 2,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1756843987534,
|
||||||
|
"tag": "0002_mean_nuke",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user