feat(app): order schdeuler

This commit is contained in:
2025-10-15 14:27:54 -05:00
parent dfff8fc166
commit 94e1198f63
7 changed files with 243 additions and 3 deletions

View File

@@ -19,10 +19,13 @@ import { sendNotify } from "./src/pkg/utils/notify.js";
import { toNodeHandler } from "better-auth/node";
import { auth } from "./src/pkg/auth/auth.js";
import { apiHitMiddleware } from "./src/pkg/middleware/apiHits.js";
import { setupIoServer } from "./src/ws/server.js";
import { schedulerManager } from "./src/internal/logistics/controller/schedulerManager.js";
const main = async () => {
const env = validateEnv(process.env);
const PORT = Number(env.VITE_PORT) || 4200;
//create the logger
const log = createLogger({ module: "system", subModule: "main start" });
@@ -130,16 +133,18 @@ const main = async () => {
express.static(join(__dirname, "../frontend/dist"))
);
// server setup
const server = createServer(app);
// register app
setupRoutes(app, basePath);
// ws stuff
// ws + server stuff
const server = createServer(app);
setupIoServer(server, basePath);
// sub systems
printers();
schedulerManager();
// start the server up
server.listen(PORT, "0.0.0.0", () =>

View File

@@ -0,0 +1,122 @@
import { subMinutes } from "date-fns";
import { format, formatInTimeZone } from "date-fns-tz";
import { sql } from "drizzle-orm";
import { db } from "../../../pkg/db/db.js";
import {
type OrderScheduler,
orderScheduler,
} from "../../../pkg/db/schema/orderScheduler.js";
import { createLogger } from "../../../pkg/logger/logger.js";
import { prodQuery } from "../../../pkg/prodSql/prodQuery.js";
import { scheduler } from "../../../pkg/prodSql/querys/scheduler/scheduler.js";
import { tryCatch } from "../../../pkg/utils/tryCatch.js";
/*
will monitor the incoming goods and the orders and update lst as they change or get updated.
*/
export const schedulerManager = async () => {
const log = createLogger({
module: "logistics",
subModule: "scheduleManager",
});
log.info({}, "Starting the scheduler manager up.");
setInterval(async () => {
const targetTimeZone = "America/New_York";
const now = new Date();
// console.log(formatInTimeZone(now, targetTimeZone, "yyyy-M-d HH:mm"));
// console.log(format(now, "yyyy-M-d HH:mm"));
const { data, error } = (await tryCatch(
prodQuery(
scheduler.replace(
"[dateCheck]",
formatInTimeZone(
subMinutes(now, 1), // dealing with the 1 min difference in case we have something missed.
targetTimeZone,
"yyyy-M-d HH:mm",
),
),
"scheduler",
),
)) as any;
// do the updates to the db so we can pull the info up to the frontend
if (error) {
log.error({ error: error }, "there was an error getting the data");
return;
}
const orderData = data.data || ([] as OrderScheduler);
//console.log(data);
if (orderData.length === 0) {
log.info({}, "There are no new orders or incoming to be updated");
return;
}
for (let i = 0; i < orderData.length; i++) {
const { data, error } = await tryCatch(
db
.insert(orderScheduler)
.values({
av: orderData[i].av,
description: orderData[i].description,
orderType: orderData[i].type, //orders || incoming
orderNumber: orderData[i].orderNumber,
header: orderData[i].av,
lineItemNumber: orderData[i].lineItemNumber,
customerReleaseNumber: orderData[i].customerReleaseNumber,
deliveryDate: new Date(orderData[i].deliveryDate),
loadingDate: new Date(orderData[i].loadingDate),
orderQTY: orderData[i].orderQTY,
orderLu: orderData[i].orderLu,
deliveredQTY: orderData[i].deliveredQTY,
deliveredLu: orderData[i].deliveredLu,
remark: orderData[i].remark,
createdAsEDI: orderData[i].createdAsEDI,
currentState: orderData[i].currentState,
lstDateCheck: new Date(orderData[i].deliveryDate), //this will match the delivery date to start
customerAddressId: orderData[i].customerAddressId,
customerDescription: orderData[i].customerDescription,
orderFrom: "prod", // manual or prod.
// being edited change to true so it will essential lock all others from editing
// carrier
// carrier email. -- when dropped we can email the carrier this could be considered there confirmation.
addDate: sql`NOW()`,
updDate: sql`NOW()`,
})
.onConflictDoUpdate({
target: orderScheduler.orderNumber,
set: {
deliveryDate: new Date(orderData[i].deliveryDate),
loadingDate: new Date(orderData[i].loadingDate),
orderQTY: orderData[i].orderQTY,
orderLu: orderData[i].orderLu,
remark: orderData[i].remark,
currentState: orderData[i].currentState,
deliveredQTY: orderData[i].deliveredQTY,
deliveredLu: orderData[i].deliveredLu,
lstDateCheck: new Date(orderData[i].deliveryDate),
updDate: sql`NOW()`,
},
}),
);
if (error) {
console.log(error);
log.error(
{ error: error },
`There was an error inserting/updating the order ${orderData[i].orderNumber}`,
);
continue;
}
log.info(
{ data: data },
`${orderData[i].orderNumber} was inserted or updated`,
);
//await delay
}
}, 60 * 1000);
};

View File

@@ -0,0 +1,16 @@
import type { Express, Request, Response } from "express";
import { requireAuth } from "../../pkg/middleware/authMiddleware.js";
import schedule from "./routes/scheduler/scheduleRoutes.js";
export const setupLogisticsRoutes = (app: Express, basePath: string) => {
app.use(basePath + "/api/logistics/schedule", schedule);
app.use(
basePath + "/api/admin/users",
requireAuth("user", ["systemAdmin"]) // will pass bc system admin but this is just telling us we need this
);
app.use(
basePath + "/api/admin",
requireAuth("user", ["systemAdmin", "admin"]) // will pass bc system admin but this is just telling us we need this
);
};

View File

@@ -0,0 +1,12 @@
import { Router } from "express";
import type { Request, Response } from "express";
import { schedulerChange } from "../../../../ws/channels/scheduler.js";
const router = Router();
router.get("/", async (req: Request, res: Response) => {
schedulerChange({ name: "something" });
res.status(200).json({ message: "Something " });
});
export default router;

View File

@@ -0,0 +1,32 @@
import { Router } from "express";
import getSchedule from "./getSchedule.js";
import { restrictToHosts } from "../../../../pkg/middleware/restrictToHosts.js";
import { requireAuth } from "../../../../pkg/middleware/authMiddleware.js";
const router = Router();
router.use("/", getSchedule);
// router.use(
// "/",
// requireAuth("user", ["systemAdmin", "admin"]),
// restrictToHosts([
// "usmcd1vms036.alpla.net",
// "USMCD1VMS036.alpla.net",
// "https://usmcd1vms036.alpla.net",
// ]),
// addServer
// );
// router.use(
// "/",
// requireAuth("user", ["systemAdmin", "admin"]),
// restrictToHosts([
// "usmcd1vms036.alpla.net",
// "USMCD1VMS036.alpla.net",
// "https://usmcd1vms036.alpla.net",
// ]),
// updateServer
// );
export default router;

View File

@@ -2,12 +2,14 @@ import type { Express, Request, Response } from "express";
import { setupAuthRoutes } from "../auth/routes/routes.js";
import { setupAdminRoutes } from "../admin/routes.js";
import { setupSystemRoutes } from "../system/routes.js";
import { setupLogisticsRoutes } from "../logistics/routes.js";
export const setupRoutes = (app: Express, basePath: string) => {
// all routes
setupAuthRoutes(app, basePath);
setupAdminRoutes(app, basePath);
setupSystemRoutes(app, basePath);
setupLogisticsRoutes(app, basePath);
// always try to go to the app weather we are in dev or in production.
app.get(basePath + "/", (req: Request, res: Response) => {

View File

@@ -0,0 +1,51 @@
import {
boolean,
date,
integer,
pgTable,
real,
text,
timestamp,
uniqueIndex,
uuid,
} from "drizzle-orm/pg-core";
import type z from "zod";
export const orderScheduler = pgTable(
"orderScheduler",
{
schedule_id: uuid("schedule_id").defaultRandom().primaryKey(),
av: integer("av"),
description: text("description"),
orderType: text("order_type").notNull(), //orders || incoming
orderNumber: integer("order_number").notNull(),
header: text("header").notNull(),
lineItemNumber: text("line_item_number"),
customerReleaseNumber: text("customer_release_number"),
deliveryDate: timestamp("delivery_date").notNull(),
loadingDate: timestamp("loading_date"),
orderQTY: real("order_qty").notNull(),
orderLu: real("order_lu").notNull(),
deliveredQTY: real("delivered_qty").default(0.0),
deliveredLu: real("delivered_lu").default(0.0),
remark: text("remark"),
createdAsEDI: boolean("created_as_EDI"),
currentState: integer("current_state"),
lstDateCheck: timestamp("lst_date_check"), //this will match the delivery date to start and when moved in the front end run a function to alert or update via api
customerAddressId: integer("customer_address_id"),
customerDescription: text("customer_description"),
dock: text("dock"),
orderFrom: text("order_from"), // manual or prod.
// being edited change to true so it will essential lock all others from editing
// carrier
// carrier email. -- when dropped we can email the carrier this could be considered there confirmation.
addDate: timestamp("add_date").defaultNow(),
updDate: timestamp("upd_date").defaultNow(),
},
(table) => [
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
uniqueIndex("orderNumber").on(table.orderNumber),
],
);
export type OrderScheduler = z.infer<typeof orderScheduler>;