refactor(biome): more format changes
This commit is contained in:
109
app/src/pkg/prodSql/querys/scheduler/scheduler.ts
Normal file
109
app/src/pkg/prodSql/querys/scheduler/scheduler.ts
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
export const scheduler = `
|
||||||
|
use AlplaPROD_test1
|
||||||
|
/*
|
||||||
|
This query will combine both the incoming goods and the deliveries in 1 as it will be the query that populates into lst db then later updated
|
||||||
|
*/
|
||||||
|
DECLARE @checkDateString NVARCHAR(MAX) = '[dateCheck]' --'2025-10-14 08:00'; -- will be passed over to validate new updates.
|
||||||
|
DECLARE @checkDate DATETIME2 = CONVERT(datetime2, @checkDateString);
|
||||||
|
|
||||||
|
-- orders
|
||||||
|
select * from (select
|
||||||
|
type = 'orders'
|
||||||
|
,l.ArticleHumanReadableId as av
|
||||||
|
,l.ArticleDescription as description
|
||||||
|
,[ReleaseNumber] as orderNumber
|
||||||
|
,h.CustomerOrderNumber as header
|
||||||
|
,l.CustomerLineItemNumber as lineItemNumber
|
||||||
|
,CustomerReleaseNumber as customerReleaseNumber
|
||||||
|
,FORMAT(r.[Deliverydate], 'yyyy-MM-dd HH:mm') as deliveryDate
|
||||||
|
,FORMAT([LoadingDate], 'yyyy-MM-dd HH:mm') as loadingDate
|
||||||
|
,[Quantity] as orderQTY
|
||||||
|
,[LoadingUnits] as orderLu
|
||||||
|
,case when t.GelieferteMenge is null then 0 else t.GelieferteMenge end as deliveredQTY
|
||||||
|
,case when t.GelieferteMengeVPK is null then 0 else t.GelieferteMengeVPK end as deliveredLu
|
||||||
|
,r.Remark as remark
|
||||||
|
,h.CreatedByEdi as createdAsEDI -- if 1 then we run the new function to change this in true edi as well as lstdb.
|
||||||
|
,r.ReleaseState as currentState -- anything other than 0 should lock this and not allow for changes
|
||||||
|
--,lstDate = getdate() --'this is a place holder for date see edi comment'
|
||||||
|
--,dock = 'dock3' --another place holder for what dock we will go to'
|
||||||
|
--,orderType = 'maunal or prod' -- this is for if we manually add in the order from lst. this way the dates will be ignored if this is manual.
|
||||||
|
,h.CustomerHumanReadableId as addressId
|
||||||
|
,h.CustomerDescription as customer
|
||||||
|
,orderType = 20
|
||||||
|
,r.[Add_User]
|
||||||
|
,r.[Add_Date]
|
||||||
|
,r.[Upd_User]
|
||||||
|
,r.[Upd_Date]
|
||||||
|
FROM [test1_AlplaPROD2.0_Reporting].[reporting_order].[Release] as r
|
||||||
|
|
||||||
|
left join
|
||||||
|
[test1_AlplaPROD2.0_Reporting].[reporting_order].LineItem as l on
|
||||||
|
l.id = r.LineItemId
|
||||||
|
|
||||||
|
left join
|
||||||
|
[test1_AlplaPROD2.0_Read].[order].Header as h on
|
||||||
|
h.Id = l.HeaderId
|
||||||
|
|
||||||
|
left join
|
||||||
|
dbo.V_TrackerAuftragsAbrufe (nolock) as t on
|
||||||
|
t.IdAuftragsAbruf = r.ReleaseNumber
|
||||||
|
|
||||||
|
--where r.[Upd_Date] >= getdate() -@age
|
||||||
|
where CAST(r.[Upd_Date] AS datetime2) >= @checkDate
|
||||||
|
|
||||||
|
|
||||||
|
union all
|
||||||
|
-- incoming goods
|
||||||
|
select
|
||||||
|
type = 'incoming'
|
||||||
|
,inc.IdArtikelVarianten as av
|
||||||
|
,av.Bezeichnung as description
|
||||||
|
,IdBestellung as orderNumber
|
||||||
|
,case when inc.Bemerkung <> '' then case when CHARINDEX(',',inc.Bemerkung) = 0 then inc.Bemerkung else left(inc.Bemerkung, CHARINDEX(',',inc.Bemerkung) -1) end else 'Missing PO' end as header
|
||||||
|
,case when inc.Bemerkung <> '' then case when CHARINDEX(',',inc.Bemerkung) = 0 then inc.Bemerkung else left(inc.Bemerkung, CHARINDEX(',',inc.Bemerkung) -1) end else 'Missing PO' end as lineItemNumber
|
||||||
|
,case when inc.Bemerkung <> '' then case when CHARINDEX(',',inc.Bemerkung) = 0 then inc.Bemerkung else left(inc.Bemerkung, CHARINDEX(',',inc.Bemerkung) -1) end else 'Missing PO' end as customerReleaseNumber
|
||||||
|
,FORMAT(inc.Datum, 'yyyy-MM-dd HH:mm') as deliveryDate
|
||||||
|
,FORMAT(inc.Datum, 'yyyy-MM-dd HH:mm') as loadingDate
|
||||||
|
,sollMenge as orderQty
|
||||||
|
,sollmengevpk as orderLu
|
||||||
|
,case when l.EntladeMenge is null then 0 else l.EntladeMenge end as deliveredQTY
|
||||||
|
,case when l.EntladeMengeVPK is null then 0 else l.EntladeMengeVPK end as deliveredLu
|
||||||
|
,inc.Bemerkung as remark
|
||||||
|
,createdAsEDI = 0
|
||||||
|
,inc.Status as currentState -- anything other than 0 should lock this and not allow for changes
|
||||||
|
--,lstDate = getdate() --'this is a place holder for date see edi comment'
|
||||||
|
--,dock = 'dock3' --another place holder for what dock we will go to'
|
||||||
|
--,orderType = 'maunal or prod' -- this is for if we manually add in the order from lst. this way the dates will be ignored if this is manual.
|
||||||
|
,inc.IdAdresse as addressId
|
||||||
|
,a.Bezeichnung
|
||||||
|
,inc.Typ as orderType -- this is just the id
|
||||||
|
,inc.Add_User
|
||||||
|
,inc.Add_Date
|
||||||
|
,inc.Upd_User
|
||||||
|
,inc.Upd_Date
|
||||||
|
from T_Wareneingaenge (nolock) as inc
|
||||||
|
|
||||||
|
--article stuff
|
||||||
|
left join
|
||||||
|
T_Artikelvarianten (nolock) as av on
|
||||||
|
av.IdArtikelvarianten = inc.IdArtikelVarianten
|
||||||
|
|
||||||
|
left join
|
||||||
|
T_WareneingangAuftraege (nolock) as w on
|
||||||
|
w.Beleg = inc.Beleg
|
||||||
|
|
||||||
|
left join
|
||||||
|
T_WareneingangPlanungen (nolock) as l on
|
||||||
|
l.IdWareneingangAuftrag = w.IdWareneingangAuftrag
|
||||||
|
|
||||||
|
left join
|
||||||
|
T_adressen as a on
|
||||||
|
a.idadressen = inc.IdAdresse
|
||||||
|
|
||||||
|
--where inc.Upd_Date >= getdate() -@age
|
||||||
|
where inc.Upd_Date >= @checkDate
|
||||||
|
--and inc.Typ not in (40)
|
||||||
|
)a
|
||||||
|
|
||||||
|
order by upd_date desc
|
||||||
|
`;
|
||||||
15
app/src/pkg/utils/corsController.ts
Normal file
15
app/src/pkg/utils/corsController.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { validateEnv } from "./envValidator.js";
|
||||||
|
|
||||||
|
const env = validateEnv(process.env);
|
||||||
|
// export const allowedOrigins = [
|
||||||
|
// /^https?:\/\/localhost:(5173|5500|4200|3000|4000)$/, // all the allowed backend ports
|
||||||
|
// /^http?:\/\/localhost:(5173|5500|4200|3000|4000)$/,
|
||||||
|
// /^https?:\/\/.*\.alpla\.net$/,
|
||||||
|
// env.BETTER_AUTH_URL, // prod
|
||||||
|
// ];
|
||||||
|
|
||||||
|
export const allowedOrigins: (string | RegExp)[] = [
|
||||||
|
/^https?:\/\/localhost:(5173|5500|4200|3000|4000)$/, // all local dev ports
|
||||||
|
/^https?:\/\/.*\.alpla\.net$/, // any subdomain of alpla.net
|
||||||
|
env.BETTER_AUTH_URL, // production URL
|
||||||
|
];
|
||||||
0
app/src/ws/channels/labelLogs.ts
Normal file
0
app/src/ws/channels/labelLogs.ts
Normal file
43
app/src/ws/channels/logs.ts
Normal file
43
app/src/ws/channels/logs.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { Namespace, Socket } from "socket.io";
|
||||||
|
import { requireAuth } from "../../pkg/middleware/authMiddleware.js";
|
||||||
|
|
||||||
|
export const setupAllLogs = (io: Namespace) => {
|
||||||
|
// Wrap middleware for Socket.IO
|
||||||
|
io.use(async (socket: Socket, next) => {
|
||||||
|
try {
|
||||||
|
// Mock Express req/res object
|
||||||
|
const req = socket.request as any;
|
||||||
|
|
||||||
|
// Create a mini next function that throws an error if unauthorized
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
const fakeRes: any = {
|
||||||
|
status: () => ({
|
||||||
|
json: (obj: any) => reject(new Error(obj.error)),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
const nextFn = (err?: any) => (err ? reject(err) : resolve());
|
||||||
|
|
||||||
|
// Call your middleware
|
||||||
|
requireAuth("", ["systemAdmin", "admin"])(req, fakeRes, nextFn);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auth passed
|
||||||
|
next();
|
||||||
|
} catch (err: any) {
|
||||||
|
next(new Error(err.message || "Unauthorized"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
io.on("connection", (socket: Socket) => {
|
||||||
|
console.log(
|
||||||
|
"✅ Authenticated client connected to channel2:",
|
||||||
|
socket.id
|
||||||
|
);
|
||||||
|
|
||||||
|
socket.on("ping", () => socket.emit("pong"));
|
||||||
|
|
||||||
|
socket.on("disconnect", () => {
|
||||||
|
console.log("🔴 Client disconnected from channel2:", socket.id);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
59
app/src/ws/channels/scheduler.ts
Normal file
59
app/src/ws/channels/scheduler.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { formatDate } from "date-fns";
|
||||||
|
import type { Server, Socket } from "socket.io";
|
||||||
|
import { db } from "../../pkg/db/db.js";
|
||||||
|
import { orderScheduler } from "../../pkg/db/schema/orderScheduler.js";
|
||||||
|
import { tryCatch } from "../../pkg/utils/tryCatch.js";
|
||||||
|
|
||||||
|
let ioInstance: Server | null = null;
|
||||||
|
|
||||||
|
export const setupScheduler = (io: Server, socket: Socket) => {
|
||||||
|
ioInstance = io;
|
||||||
|
|
||||||
|
socket.on("joinScheduler", async () => {
|
||||||
|
socket.join("scheduler");
|
||||||
|
//console.log(`Socket ${socket.id} joined room "scheduler"`);
|
||||||
|
|
||||||
|
const { data, error } = await tryCatch(db.select().from(orderScheduler));
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
setTimeout(() => {
|
||||||
|
io.to("scheduler").emit("scheduler:update", {
|
||||||
|
type: "init",
|
||||||
|
error: error,
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initial push
|
||||||
|
setTimeout(() => {
|
||||||
|
io.to("scheduler").emit("scheduler:update", { type: "init", data: data });
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
// socket.on("ping", () => {
|
||||||
|
// io.to("scheduler").emit("pong", { from: socket.id });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// setInterval(() => {
|
||||||
|
// io.to("scheduler").emit("heartbeat", {
|
||||||
|
// ts: formatDate(Date.now(), "M/d/yyyy HH:mm"),
|
||||||
|
// });
|
||||||
|
// }, 60_000);
|
||||||
|
|
||||||
|
// add in listen for changes to the db with pg listen?
|
||||||
|
};
|
||||||
|
|
||||||
|
// --- Change Broadcast Function ---
|
||||||
|
export const schedulerChange = async (data: any) => {
|
||||||
|
if (!ioInstance) {
|
||||||
|
console.error("⚠️ schedulerChange called before setupScheduler initialized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ioInstance.to("scheduler").emit("scheduler:update", {
|
||||||
|
ts: formatDate(Date.now(), "M/d/yyyy HH:mm"),
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
console.log("📢 Scheduler update broadcasted:", data);
|
||||||
|
};
|
||||||
66
app/src/ws/server.ts
Normal file
66
app/src/ws/server.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { Server } from "socket.io";
|
||||||
|
import type { Server as HttpServer } from "http";
|
||||||
|
import { allowedOrigins } from "../pkg/utils/corsController.js";
|
||||||
|
import { setupScheduler } from "./channels/scheduler.js";
|
||||||
|
|
||||||
|
export const setupIoServer = async (server: HttpServer, basePath: string) => {
|
||||||
|
const io = new Server(server, {
|
||||||
|
path: `${basePath}/api/ws`,
|
||||||
|
cors: {
|
||||||
|
// origin: ["http://localhost:5500"],
|
||||||
|
origin: (origin, callback) => {
|
||||||
|
// Allow non-browser clients (Postman, direct websocket, etc.)
|
||||||
|
if (!origin) return callback(null, true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check if origin matches any allowed string or regex
|
||||||
|
const allowed = allowedOrigins.some((o) => {
|
||||||
|
if (typeof o === "string") return o === origin;
|
||||||
|
if (o instanceof RegExp) return o.test(origin);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (allowed) {
|
||||||
|
return callback(null, true);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Invalid Origin header:", origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deny all others
|
||||||
|
return callback(new Error("Not allowed by CORS: " + origin));
|
||||||
|
},
|
||||||
|
// methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
|
||||||
|
credentials: true,
|
||||||
|
},
|
||||||
|
pingInterval: 25_000, // send ping every 25s (default 25s)
|
||||||
|
pingTimeout: 60_000, // wait 60s before disconnecting (default 60s)
|
||||||
|
});
|
||||||
|
|
||||||
|
io.on("connection", (socket) => {
|
||||||
|
console.log("🟢 User connected:", socket.id);
|
||||||
|
|
||||||
|
// Join a room
|
||||||
|
socket.on("joinRoom", (room: string) => {
|
||||||
|
socket.join(room);
|
||||||
|
console.log(`Socket ${socket.id} joined room ${room}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Leave a room
|
||||||
|
socket.on("leaveRoom", (room: string) => {
|
||||||
|
socket.leave(room);
|
||||||
|
console.log(`Socket ${socket.id} left room ${room}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Example: broadcast a message to a room
|
||||||
|
socket.on("message", ({ room, payload }) => {
|
||||||
|
io.to(room).emit("message", payload);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("disconnect", (reason) => {
|
||||||
|
console.log("🔴 User disconnected:", socket.id, reason);
|
||||||
|
});
|
||||||
|
|
||||||
|
setupScheduler(io, socket);
|
||||||
|
});
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user