Compare commits

...

21 Commits

Author SHA1 Message Date
a73c63cefa fix(rfid): correction to the params and incorrect naming 2025-03-15 15:34:04 -05:00
5b97d078c5 feat(new setting): added in devDir ment for updating servers 2025-03-15 15:33:41 -05:00
7529cc5b0c feat(serverdata): added in bowling green 2 2025-03-15 15:33:04 -05:00
df252e72b3 feat(server): added in update server as well as get serverdata 2025-03-15 15:32:15 -05:00
359427824b refactor(frontend): removed tanstack devTools 2025-03-15 15:31:22 -05:00
cbdd218fe4 feat(frontend): added in proper links for settings and servers to the sidebar 2025-03-15 15:30:53 -05:00
35acd2b0b3 refactor(frontend): removed the caption from settings table 2025-03-15 15:30:19 -05:00
625d5969be feat(frontend): added in update server page only for sysAdmin 2025-03-15 15:29:53 -05:00
2370d45220 fix(frontend): if the modules returns and error we want to use an empty array 2025-03-15 15:29:25 -05:00
cb7a4068fc feat(sql query): added 2 catches if not connected dont run 2025-03-15 15:28:51 -05:00
e4d15ef051 feat(sql server): added in the ping check to not spam if we are not connected 2025-03-15 15:25:46 -05:00
f3fa617aa5 feat(serverdata): added catch if we are not on localhost we cant actaully see the devDir in set 2025-03-15 15:24:11 -05:00
ab16059387 feat(server upgrade): added in a catch incase we try to upgrade again 2025-03-15 15:22:38 -05:00
b6f1cfdc6c chore: bump build number to 18 2025-03-14 14:47:51 -05:00
1ce5f9acf7 chore: bump build number to 17 2025-03-14 14:42:36 -05:00
44da09d22c chore: bump build number to 16 2025-03-14 14:38:14 -05:00
0b72ffa935 chore: bump build number to 15 2025-03-14 14:35:19 -05:00
a2fb845e2e chore: bump build number to 14 2025-03-14 14:33:58 -05:00
bcd65b4b91 chore: bump build number to 13 2025-03-14 14:33:00 -05:00
b1d25c7ba2 chore: bump build number to 12 2025-03-14 14:31:11 -05:00
c9a5203131 chore: bump build number to 11 2025-03-14 14:08:07 -05:00
27 changed files with 1578 additions and 76 deletions

View File

@@ -0,0 +1 @@
ALTER TABLE "serverData" ADD COLUMN "isUpgrading" boolean DEFAULT false;

File diff suppressed because it is too large Load Diff

View File

@@ -113,6 +113,13 @@
"when": 1741952150913,
"tag": "0015_wonderful_lady_vermin",
"breakpoints": true
},
{
"idx": 16,
"version": "7",
"when": 1742051878587,
"tag": "0016_wet_doctor_strange",
"breakpoints": true
}
]
}

View File

@@ -24,6 +24,7 @@ export const serverData = pgTable(
shippingHours: text("shippingHours").default('[{"early": "06:30", "late": "23:00"}]'),
tiPostTime: text("tiPostTime").default('[{"from": "24", "to": "24"}]'),
otherSettings: jsonb("otherSettings").default([{specialInstructions: "something for ti", active: false}]),
isUpgrading: boolean("isUpgrading").default(false),
},
(table) => [

View File

@@ -0,0 +1,99 @@
import {LstCard} from "@/components/extendedUI/LstCard";
import {Skeleton} from "@/components/ui/skeleton";
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
import {useSessionStore} from "@/lib/store/sessionStore";
import {useModuleStore} from "@/lib/store/useModuleStore";
import {getServers} from "@/utils/querys/servers";
import {useQuery} from "@tanstack/react-query";
import {useRouter} from "@tanstack/react-router";
import {format} from "date-fns";
import UpdateServer from "./UpdateServer";
export type Servers = {
server_id?: string;
sName?: string;
serverDNS?: string;
plantToken?: string;
idAddress: string;
lastUpdated: string;
isUpgrading: boolean;
};
export default function ServerPage() {
const {user, token} = useSessionStore();
const {modules} = useModuleStore();
const router = useRouter();
const {data, isError, error, isLoading} = useQuery(getServers(token ?? ""));
const adminModule = modules.filter((n) => n.name === "admin");
const userLevel = user?.roles?.filter((r) => r.module_id === adminModule[0].module_id) || [];
if (!adminModule[0]?.roles?.includes(userLevel[0]?.role)) {
router.navigate({to: "/"});
}
if (isError) {
return <div>{JSON.stringify(error)}</div>;
}
return (
<LstCard className="m-2 flex place-content-center w-dvh">
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Server</TableHead>
<TableHead>PlantToken</TableHead>
<TableHead>IP Address</TableHead>
<TableHead>Date Last updated</TableHead>
<TableHead>Update Server</TableHead>
</TableRow>
</TableHeader>
{isLoading ? (
<>
<TableBody>
{Array(10)
.fill(0)
.map((_, i) => (
<TableRow key={i}>
<TableCell className="font-medium">
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
</TableRow>
))}
</TableBody>
</>
) : (
<TableBody>
{data?.map((server: Servers) => (
<TableRow key={server.server_id}>
<TableCell className="font-medium">{server.sName}</TableCell>
<TableCell className="font-medium">{server.serverDNS}</TableCell>
<TableCell className="font-medium">{server.plantToken}</TableCell>
<TableCell className="font-medium">{server.idAddress}</TableCell>
<TableCell className="font-medium">
{format(server.lastUpdated, "MM/dd/yyyy hh:mm")}
</TableCell>
<TableCell className="font-medium">
{window.location.host.split(":")[0] === "localhost" && (
<UpdateServer server={server} token={token as string} />
)}
</TableCell>
</TableRow>
))}
</TableBody>
)}
</Table>
</LstCard>
);
}

View File

@@ -0,0 +1,41 @@
import {Button} from "@/components/ui/button";
import {CircleFadingArrowUp} from "lucide-react";
import {toast} from "sonner";
import {Servers} from "./ServerPage";
import {useQuery} from "@tanstack/react-query";
import {getSettings} from "@/utils/querys/settings";
import axios from "axios";
export default function UpdateServer({server, token}: {server: Servers; token: string}) {
const {data} = useQuery(getSettings(token ?? ""));
const upgrade = async () => {
let devDir = data.filter((n: any) => n.name === "devDir");
toast.success("Server being upgraded in the background please wait.");
try {
const result = await axios.post(
`/api/server/update/${server.plantToken}`,
{devDir: devDir[0].value},
{
headers: {Authorization: `Bearer ${token}`},
}
);
if (result.data.success) {
toast.success(result.data.message);
}
if (!result.data.success) {
toast.success(result.data.message);
}
} catch (error: any) {
toast.error(`There was an error updating the server: ${error.data.message}`);
}
};
return (
<div>
<Button variant={"outline"} size={"icon"} onClick={upgrade} disabled={server.isUpgrading}>
<CircleFadingArrowUp />
</Button>
</div>
);
}

View File

@@ -1,5 +1,5 @@
import {LstCard} from "@/components/extendedUI/LstCard";
import {Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
import {useSessionStore} from "@/lib/store/sessionStore";
import {useModuleStore} from "@/lib/store/useModuleStore";
import {useQuery} from "@tanstack/react-query";
@@ -39,7 +39,6 @@ export default function SettingsPage() {
return (
<LstCard className="m-2 flex place-content-center w-dvh">
<Table>
<TableCaption>All Settings</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>

View File

@@ -15,7 +15,7 @@ import {Collapsible, CollapsibleContent, CollapsibleTrigger} from "../../ui/coll
const items = [
{
title: "Servers",
url: "#",
url: "/servers",
icon: Server,
isActive: false,
},
@@ -31,13 +31,19 @@ const data = {
title: "Settings",
url: "/settings",
icon: Settings,
isActive: true,
},
{
title: "Modules",
url: "/modules",
icon: Settings,
isActive: false,
},
{
title: "Swagger",
url: "#",
icon: Webhook,
isActive: false,
isActive: true,
},
{
title: "Logs",
@@ -91,12 +97,17 @@ export function AdminSideBar() {
<SidebarMenuSub>
{item.items.map((item) => (
<SidebarMenuSubItem key={item.title}>
<SidebarMenuSubButton asChild isActive={item.isActive}>
<a href={item.url} target={item.newWindow ? "_blank" : "_self"}>
<item.icon />
<span>{item.title}</span>
</a>
</SidebarMenuSubButton>
{item.isActive && (
<SidebarMenuSubButton asChild>
<a
href={item.url}
target={item.newWindow ? "_blank" : "_self"}
>
<item.icon />
<span>{item.title}</span>
</a>
</SidebarMenuSubButton>
)}
</SidebarMenuSubItem>
))}
</SidebarMenuSub>

View File

@@ -29,6 +29,7 @@ export const useModuleStore = create<SettingState>()((set) => ({
set({modules: data.data});
} catch (error) {
console.error("Failed to fetch settings:", error);
set({modules: []});
}
},
}));

View File

@@ -22,6 +22,7 @@ import { Route as OcpLotsImport } from './routes/ocp/lots'
import { Route as EomEomImport } from './routes/_eom/eom'
import { Route as AuthProfileImport } from './routes/_auth/profile'
import { Route as AdminSettingsImport } from './routes/_admin/settings'
import { Route as AdminServersImport } from './routes/_admin/servers'
import { Route as AdminModulesImport } from './routes/_admin/modules'
import { Route as logisticsMaterialHelperIndexImport } from './routes/(logistics)/materialHelper/index'
import { Route as EomArticleAvImport } from './routes/_eom/article/$av'
@@ -93,6 +94,12 @@ const AdminSettingsRoute = AdminSettingsImport.update({
getParentRoute: () => AdminRoute,
} as any)
const AdminServersRoute = AdminServersImport.update({
id: '/servers',
path: '/servers',
getParentRoute: () => AdminRoute,
} as any)
const AdminModulesRoute = AdminModulesImport.update({
id: '/modules',
path: '/modules',
@@ -179,6 +186,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof AdminModulesImport
parentRoute: typeof AdminImport
}
'/_admin/servers': {
id: '/_admin/servers'
path: '/servers'
fullPath: '/servers'
preLoaderRoute: typeof AdminServersImport
parentRoute: typeof AdminImport
}
'/_admin/settings': {
id: '/_admin/settings'
path: '/settings'
@@ -249,11 +263,13 @@ declare module '@tanstack/react-router' {
interface AdminRouteChildren {
AdminModulesRoute: typeof AdminModulesRoute
AdminServersRoute: typeof AdminServersRoute
AdminSettingsRoute: typeof AdminSettingsRoute
}
const AdminRouteChildren: AdminRouteChildren = {
AdminModulesRoute: AdminModulesRoute,
AdminServersRoute: AdminServersRoute,
AdminSettingsRoute: AdminSettingsRoute,
}
@@ -287,6 +303,7 @@ export interface FileRoutesByFullPath {
'/about': typeof AboutRoute
'/login': typeof LoginRoute
'/modules': typeof AdminModulesRoute
'/servers': typeof AdminServersRoute
'/settings': typeof AdminSettingsRoute
'/profile': typeof AuthProfileRoute
'/eom': typeof EomEomRoute
@@ -304,6 +321,7 @@ export interface FileRoutesByTo {
'/about': typeof AboutRoute
'/login': typeof LoginRoute
'/modules': typeof AdminModulesRoute
'/servers': typeof AdminServersRoute
'/settings': typeof AdminSettingsRoute
'/profile': typeof AuthProfileRoute
'/eom': typeof EomEomRoute
@@ -324,6 +342,7 @@ export interface FileRoutesById {
'/about': typeof AboutRoute
'/login': typeof LoginRoute
'/_admin/modules': typeof AdminModulesRoute
'/_admin/servers': typeof AdminServersRoute
'/_admin/settings': typeof AdminSettingsRoute
'/_auth/profile': typeof AuthProfileRoute
'/_eom/eom': typeof EomEomRoute
@@ -343,6 +362,7 @@ export interface FileRouteTypes {
| '/about'
| '/login'
| '/modules'
| '/servers'
| '/settings'
| '/profile'
| '/eom'
@@ -359,6 +379,7 @@ export interface FileRouteTypes {
| '/about'
| '/login'
| '/modules'
| '/servers'
| '/settings'
| '/profile'
| '/eom'
@@ -377,6 +398,7 @@ export interface FileRouteTypes {
| '/about'
| '/login'
| '/_admin/modules'
| '/_admin/servers'
| '/_admin/settings'
| '/_auth/profile'
| '/_eom/eom'
@@ -449,6 +471,7 @@ export const routeTree = rootRoute
"filePath": "_admin.tsx",
"children": [
"/_admin/modules",
"/_admin/servers",
"/_admin/settings"
]
},
@@ -475,6 +498,10 @@ export const routeTree = rootRoute
"filePath": "_admin/modules.tsx",
"parent": "/_admin"
},
"/_admin/servers": {
"filePath": "_admin/servers.tsx",
"parent": "/_admin"
},
"/_admin/settings": {
"filePath": "_admin/settings.tsx",
"parent": "/_admin"

View File

@@ -1,5 +1,5 @@
import {createRootRoute, Link, Outlet} from "@tanstack/react-router";
import {TanStackRouterDevtools} from "@tanstack/router-devtools";
//import {TanStackRouterDevtools} from "@tanstack/router-devtools";
import Cookies from "js-cookie";
import {SidebarProvider} from "../components/ui/sidebar";
import {ThemeProvider} from "../components/layout/theme-provider";
@@ -84,7 +84,7 @@ export const Route = createRootRoute({
</ThemeProvider>
</SessionProvider>
<TanStackRouterDevtools position="bottom-right" />
{/* <TanStackRouterDevtools position="bottom-right" /> */}
</>
);
},

View File

@@ -0,0 +1,14 @@
import ServerPage from "@/components/admin/servers/ServerPage";
import {createFileRoute} from "@tanstack/react-router";
export const Route = createFileRoute("/_admin/servers")({
component: RouteComponent,
});
function RouteComponent() {
return (
<div>
<ServerPage />
</div>
);
}

View File

@@ -0,0 +1,19 @@
import {queryOptions} from "@tanstack/react-query";
import axios from "axios";
export function getServers(token: string) {
return queryOptions({
queryKey: ["servers"],
queryFn: () => fetchSettings(token),
enabled: !!token,
staleTime: 1000,
refetchInterval: 500,
refetchOnWindowFocus: true,
});
}
const fetchSettings = async (token: string) => {
const {data} = await axios.get("/api/server/servers", {headers: {Authorization: `Bearer ${token}`}});
return data.data;
};

View File

@@ -13,6 +13,11 @@ export function getSettings(token: string) {
const fetchSettings = async (token: string) => {
const {data} = await axios.get("/api/server/settings", {headers: {Authorization: `Bearer ${token}`}});
return data.data;
// if we are not localhost ignore the devDir setting.
const url: string = window.location.host.split(":")[0];
let settingsData = data.data;
if (url != "localhost") {
settingsData.filter((n: any) => n.name === "devDir");
}
return settingsData;
};

View File

@@ -9,7 +9,7 @@
"dev:dbgen": " drizzle-kit generate --config=drizzle-dev.config.ts",
"dev:dbmigrate": " drizzle-kit migrate --config=drizzle-dev.config.ts",
"build": "npm run build:server && npm run build:frontend",
"build:server": "rimraf build && tsc --build && xcopy server\\scripts dist\\server\\scripts /E /I /Y",
"build:server": "rimraf build && tsc --build && xcopy server\\scripts dist\\server\\scripts /E /I /Y && xcopy server\\services\\server\\utils\\serverData.json dist\\server\\services\\server\\utils /E /I /Y ",
"build:frontend": "cd frontend && npm run build",
"start": "set NODE_ENV=production && npm run start:server",
"start:server": "dotenvx run -f .env -- node dist/server/index.js",
@@ -69,7 +69,7 @@
}
},
"admConfig": {
"build": 10,
"build": 18,
"oldBuild": "backend-0.1.2-217.zip"
}
}

View File

@@ -5,9 +5,43 @@ import {serverData} from "../../database/schema/serverData.js";
import {eq, sql} from "drizzle-orm";
import {createLog} from "../services/logger/logger.js";
const updateServer = async (devApp: string, server: string) => {
type UpdateServerResponse = {
success: boolean;
message: string;
};
export const updateServer = async (devApp: string, server: string | null): Promise<UpdateServerResponse> => {
const app = await getAppInfo(devApp);
const serverInfo = await db.select().from(serverData).where(eq(serverData.sName, server.toLowerCase()));
const serverInfo = await db
.select()
.from(serverData)
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
if (serverInfo.length === 0) {
createLog(
"error",
"lst",
"serverUpdater",
`Looks like you are missing the plant token or have entered an incorrect one please try again.`
);
return {
success: false,
message: "Looks like you are missing the plant token or have entered an incorrect one please try again.",
};
}
if (serverInfo[0].isUpgrading) {
createLog(
"error",
"lst",
"serverUpdater",
`Looks like ${serverInfo[0].plantToken} is upgrading already you cant do this again.`
);
return {
success: false,
message: `Looks like ${serverInfo[0].plantToken} is upgrading already you cant do this again.`,
};
}
const scriptPath = `${process.env.DEVFOLDER}\\server\\scripts\\update.ps1 `;
const args = [
@@ -39,9 +73,13 @@ const updateServer = async (devApp: string, server: string) => {
,
];
return new Promise((resolve, reject) => {
return new Promise(async (resolve, reject) => {
const process = spawn("powershell", args);
// change the server to upgradeing
await db
.update(serverData)
.set({isUpgrading: true})
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
//let stdout = "";
//let stderr = "";
@@ -69,7 +107,16 @@ const updateServer = async (devApp: string, server: string) => {
//update the last build.
try {
await db.update(serverData).set({lastUpdated: sql`NOW()`});
await db
.update(serverData)
.set({lastUpdated: sql`NOW()`, isUpgrading: false})
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
createLog(
"info",
"lst",
"serverUpdater",
`${server?.toLowerCase()}, has been updated and can now be used again.`
);
} catch (error) {
createLog(
"error",
@@ -79,7 +126,10 @@ const updateServer = async (devApp: string, server: string) => {
);
}
resolve({success: true, code});
resolve({
success: true,
message: `${server?.toLowerCase()}, has been updated and can now be used again.`,
});
} else {
const errorMessage = `Process exited with code ${code}`;
@@ -87,7 +137,10 @@ const updateServer = async (devApp: string, server: string) => {
// //onClose(code);
// }
reject(new Error(errorMessage));
reject({
success: false,
message: `${server?.toLowerCase()}, Has encounted an error while updating.`,
});
}
});
@@ -107,7 +160,7 @@ export async function processAllServers(devApp: string) {
let count = 1;
for (const server of servers) {
try {
const updateToServer = await updateServer(devApp, server.sName);
const updateToServer = await updateServer(devApp, server.plantToken);
createLog("info", "lst", "serverUpdater", `${server.sName} was updated.`);
count = count + 1;
@@ -118,5 +171,3 @@ export async function processAllServers(devApp: string) {
}
}
}
updateServer("C:\\Users\\matthes01\\Documents\\lstv2", "test");

View File

@@ -9,6 +9,7 @@ import {getAppInfo} from "../globalUtils/appInfo.js";
const ignoreList = [
".git",
"builds",
"server",
"node_modules",
"apiDocsLSTV2",
"testFiles",
@@ -19,7 +20,7 @@ const ignoreList = [
"nssm.exe",
"postgresql-17.2-3-windows-x64.exe",
// front end ignore
"/frontend/node_modules",
"frontend/node_modules",
"fonrtend/.env",
"frontend/public",
"frontend/src",
@@ -33,6 +34,7 @@ const ignoreList = [
"frontend/tsconfig.app.json",
"frontend/tsconfig.node.json",
"frontend/vite.config.ts",
"frontend/components.json",
];
const shouldIgnore = (itemPath: any) => {
@@ -40,7 +42,10 @@ const shouldIgnore = (itemPath: any) => {
return ignoreList.some((ignorePattern) => {
const normalizedIgnorePatther = ignorePattern.replace(/\\/g, "/");
return normalizedItemPath.includes(normalizedIgnorePatther);
return (
normalizedItemPath === normalizedIgnorePatther ||
normalizedItemPath.startsWith(`${normalizedIgnorePatther}/`)
);
});
};

View File

@@ -18,7 +18,7 @@ const ParamsSchema = z.object({
.min(3)
.openapi({
param: {
name: "id",
name: "reader",
in: "path",
},
example: "1212121",
@@ -27,7 +27,7 @@ const ParamsSchema = z.object({
app.openapi(
createRoute({
tags: ["server"],
tags: ["rfid"],
summary: "Adds a new module",
method: "post",
path: "/mgtevents/{reader}",

View File

@@ -17,7 +17,7 @@ const ParamsSchema = z.object({
.min(3)
.openapi({
param: {
name: "id",
name: "reader",
in: "path",
},
example: "1212121",
@@ -26,7 +26,7 @@ const ParamsSchema = z.object({
app.openapi(
createRoute({
tags: ["server"],
tags: ["rfid"],
summary: "Adds a new module",
method: "post",
path: "/taginfo/{reader}",

View File

@@ -0,0 +1,64 @@
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
import {db} from "../../../../../database/dbclient.js";
import {authMiddleware} from "../../../auth/middleware/authMiddleware.js";
import {serverData} from "../../../../../database/schema/serverData.js";
import {eq} from "drizzle-orm";
// Define the request body schema
const requestSchema = z.object({
ip: z.string().optional(),
endpoint: z.string().optional(),
action: z.string().optional(),
stats: z.string().optional(),
});
// Define the response schema
const responseSchema = z.object({
message: z.string().optional(),
module_id: z.string().openapi({example: "6c922c6c-7de3-4ec4-acb0-f068abdc"}).optional(),
name: z.string().openapi({example: "Production"}).optional(),
active: z.boolean().openapi({example: true}).optional(),
roles: z.string().openapi({example: `["viewer","technician"]`}).optional(),
});
const app = new OpenAPIHono();
app.openapi(
createRoute({
tags: ["server"],
summary: "Returns all serverData on the server",
method: "get",
path: "/servers",
middleware: authMiddleware,
responses: {
200: {
content: {
"application/json": {schema: responseSchema},
},
description: "Response message",
},
},
}),
async (c) => {
//console.log("system modules");
let servers: any = [];
try {
servers = await db.select().from(serverData).where(eq(serverData.active, true));
} catch (error) {
console.log(error);
servers = [];
}
// sort the servers by there name
servers = servers.sort((a: any, b: any) => a.sName.localeCompare(b.sName));
// Return response with the received data
return c.json({
message: `All active modules`,
data: servers,
});
}
);
export default app;

View File

@@ -0,0 +1,93 @@
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
import {authMiddleware} from "../../../auth/middleware/authMiddleware.js";
import {updateServer} from "../../../../scripts/updateServers.js";
// Define the request body schema
const requestSchema = z.object({
ip: z.string().optional(),
endpoint: z.string().optional(),
action: z.string().optional(),
stats: z.string().optional(),
});
// Define the response schema
const responseSchema = z.object({
message: z.string().optional(),
module_id: z.string().openapi({example: "6c922c6c-7de3-4ec4-acb0-f068abdc"}).optional(),
name: z.string().openapi({example: "Production"}).optional(),
active: z.boolean().openapi({example: true}).optional(),
roles: z.string().openapi({example: `["viewer","technician"]`}).optional(),
});
const ParamsSchema = z.object({
server: z
.string()
.min(3)
.openapi({
param: {
name: "server",
in: "path",
},
example: "usbow1",
}),
});
const UpdateServer = z.object({
devDir: z.string().openapi({example: "C:\\something\\Something"}),
});
const app = new OpenAPIHono();
app.openapi(
createRoute({
tags: ["server"],
summary: "Updates server(s)",
method: "post",
path: "/update/:server",
middleware: authMiddleware,
request: {
params: ParamsSchema,
body: {
content: {
"application/json": {schema: UpdateServer},
},
},
},
responses: {
200: {
content: {
"application/json": {schema: responseSchema},
},
description: "Response message",
},
400: {
content: {
"application/json": {schema: responseSchema},
},
description: "Response message",
},
},
}),
async (c) => {
const {server} = c.req.valid("param");
const body = await c.req.json();
// fire off the update we wont make this way
try {
const update = await updateServer(body.devDir, server);
return c.json({
success: update?.success ?? false,
message: update?.message,
data: [],
});
} catch (error) {
return c.json({
success: false,
message: `${server} Encountered an ${error}`,
data: [],
});
}
}
);
export default app;

View File

@@ -10,6 +10,8 @@ import getSettings from "./route/settings/getSettings.js";
import updateSetting from "./route/settings/updateSetting.js";
import {areSettingsIn} from "./utils/settingsCheck.js";
import {serversCheckPoint} from "./utils/serverData.js";
import getServers from "./route/servers/getServers.js";
import updateServer from "./route/updates/updateServer.js";
// making sure all modules are in properly
setTimeout(() => {
@@ -28,6 +30,9 @@ const routes = [
addSetting,
getSettings,
updateSetting,
// serverData
getServers,
updateServer,
] as const;
// app.route("/server", modules);

View File

@@ -133,7 +133,7 @@
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01BG2INT",
"lstServerPort": "4000",
"active": false,
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "C:\\Users\\adm_matthes01\\Desktop\\lst_backend",
"shippingHours": "[{\"early\": \"06:30\", \"late\": \"23:00\"}]",
@@ -313,7 +313,7 @@
"contactPhone": "6366970253",
"customerTiAcc": "ALPL01WBINT",
"lstServerPort": "4000",
"active": false,
"active": true,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "C:\\Users\\adm_matthes01\\Desktop\\lst_backend",
"shippingHours": "[{\"early\": \"06:30\", \"late\": \"23:00\"}]",

View File

@@ -14,44 +14,40 @@ export const serversCheckPoint = async () => {
} else {
filePath = "./dist/server/services/server/utils/serverData.json";
}
fs.readFile(filePath, "utf8", (err, data) => {
if (err) {
console.error("Error reading JSON file:", err);
return;
}
servers = JSON.parse(data);
});
try {
const data = fs.readFileSync(filePath, "utf8");
const serverData = JSON.parse(data);
servers = serverData.servers;
} catch (err) {
console.error("Error reading JSON file:", err);
}
// get the roles
try {
const settingsCheck = await db.select().from(serverData);
try {
for (let i = 0; i < servers.length; i++) {
const newRole = await db
.insert(serverData)
.values(servers[i])
.onConflictDoUpdate({
target: serverData.plantToken,
set: {
sName: servers[i].sName,
serverDNS: servers[i].serverDNS,
active: servers[i].active,
contactEmail: servers[i].contactEmail,
contactPhone: servers[i].contactPhone,
shippingHours: servers[i].shippingHours,
customerTiAcc: servers[i].customerTiAcc,
tiPostTime: servers[i].tiPostTime,
otherSettings: servers[i].otherSettings,
},
}) // this will only update the ones that are new :D
.returning({name: serverData.sName});
}
createLog("info", "lst", "server", "Servers were just added/updated due to server startup");
} catch (error) {
createLog("error", "lst", "server", `There was an error adding/updating serverData to the db, ${error}`);
try {
for (let i = 0; i < servers.length; i++) {
const serverUpdate = await db
.insert(serverData)
.values(servers[i])
.onConflictDoUpdate({
target: serverData.plantToken,
set: {
sName: servers[i].sName,
serverDNS: servers[i].serverDNS,
active: servers[i].active,
contactEmail: servers[i].contactEmail,
contactPhone: servers[i].contactPhone,
shippingHours: servers[i].shippingHours,
customerTiAcc: servers[i].customerTiAcc,
tiPostTime: servers[i].tiPostTime,
otherSettings: servers[i].otherSettings,
},
}) // this will only update the ones that are new :D
.returning({name: serverData.sName});
}
createLog("info", "lst", "server", "Servers were just added/updated due to server startup");
} catch (error) {
createLog("error", "lst", "server", `There was an error adding serverData to the db, ${error}`);
createLog("error", "lst", "server", `There was an error adding/updating serverData to the db, ${error}`);
}
};

View File

@@ -80,6 +80,12 @@ const newSettings = [
description: "What address is monitored to be limited to the amount of lots that can be added to a truck.",
moduleName: "ocme",
},
{
name: "devDir",
value: "C:\\Users\\matthes01\\Documents\\lstv2",
description: "This is the dev dir and strictly only for updating the servers.",
moduleName: "server",
},
];
export const areSettingsIn = async () => {
// get the roles

View File

@@ -10,13 +10,6 @@ import {checkHostnamePort} from "../../globalUtils/pingServer.js";
let pool: any;
let connected: boolean = false;
export const initializeProdPool = async () => {
const dbServer = await db.select().from(settings).where(eq(settings.name, "dbServer"));
const serverUp = await checkHostnamePort(`${dbServer[0].value}:1433`);
if (!serverUp) {
createLog("error", "lst", "server", `The sql ${dbServer[0].value} is not reachable`);
return {success: false, message: `The sql ${dbServer[0].value} is not reachable`};
}
if (!installed) {
createLog("info", "lst", "sqlProd", "The server was not installed will reconnect in 5 seconds");
setTimeout(() => {
@@ -25,6 +18,13 @@ export const initializeProdPool = async () => {
return {success: false, message: "The server is not installed."};
}
const dbServer = await db.select().from(settings).where(eq(settings.name, "dbServer"));
const serverUp = await checkHostnamePort(`${dbServer[0].value}:1433`);
if (!serverUp) {
createLog("error", "lst", "server", `The sql ${dbServer[0].value} is not reachable`);
return {success: false, message: `The sql ${dbServer[0].value} is not reachable`};
}
// make sure the server is not set to localhost this will prevent some weird issues later but can be localhost on the dev
const serverLoc = await db.select().from(settings).where(eq(settings.name, "dbServer"));
@@ -69,11 +69,27 @@ export const closePool = async () => {
};
export async function query(queryToRun: string, name: string) {
/**
* Just an extra catch incase someone tried to run a query while we were not connected to the server or sql server
*/
const dbServer = await db.select().from(settings).where(eq(settings.name, "dbServer"));
const serverUp = await checkHostnamePort(`${dbServer[0].value}:1433`);
if (!serverUp) {
createLog("error", "lst", "server", `The sql ${dbServer[0].value} is not reachable`);
return {success: false, message: `The sql ${dbServer[0].value} is not reachable`};
}
if (!connected) {
createLog("error", "lst", "server", `The sql ${dbServer[0].value} is not connected`);
return {success: false, message: `The sql ${dbServer[0].value} is not not connected`};
}
/**
* We no longer need to send over the plant token change as we do it inside the query function.
*/
const plantToken = await db.select().from(settings).where(eq(settings.name, "plantToken"));
const query = queryToRun.replaceAll("test1", plantToken[0].value);
try {
const result = await pool.request().query(query);

View File

@@ -15,5 +15,6 @@
"esModuleInterop": true,
"resolveJsonModule": true
},
"exclude": ["node_modules", "frontend", "dist"]
"exclude": ["node_modules", "frontend", "dist", "testFiles"]
}