Compare commits
12 Commits
a73c63cefa
...
cb59f58926
| Author | SHA1 | Date | |
|---|---|---|---|
| cb59f58926 | |||
| 1a79a97929 | |||
| 4b92a28dfa | |||
| 4aae659ee4 | |||
| 7bfb48b81f | |||
| 7432decd3c | |||
| 04a607d3bc | |||
| d178e04362 | |||
| 020fdc83af | |||
| 33803a69a6 | |||
| 3ea6dc5bc4 | |||
| b484a0c5ea |
41
CHANGELOG.md
41
CHANGELOG.md
@@ -1,5 +1,46 @@
|
|||||||
# All CHanges to LST can be found below.
|
# All CHanges to LST can be found below.
|
||||||
|
|
||||||
|
## [2.7.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.6.0...v2.7.0) (2025-03-15)
|
||||||
|
|
||||||
|
|
||||||
|
### 📝 Chore
|
||||||
|
|
||||||
|
* bump build number to 10 ([245ba19](https://git.tuffraid.net/cowch/lstV2/commits/245ba19cdc7e67fec9343bb9eba90287d8951854))
|
||||||
|
* bump build number to 11 ([c9a5203](https://git.tuffraid.net/cowch/lstV2/commits/c9a520313160959ed929351f55bd18606b6500a9))
|
||||||
|
* bump build number to 12 ([b1d25c7](https://git.tuffraid.net/cowch/lstV2/commits/b1d25c7ba27a72c42803a3b482234c41670a07a2))
|
||||||
|
* bump build number to 13 ([bcd65b4](https://git.tuffraid.net/cowch/lstV2/commits/bcd65b4b91cf6cb24a32323ead5ff6a73d3c9d3d))
|
||||||
|
* bump build number to 14 ([a2fb845](https://git.tuffraid.net/cowch/lstV2/commits/a2fb845e2efbeb8becf91082343770b2d730330c))
|
||||||
|
* bump build number to 15 ([0b72ffa](https://git.tuffraid.net/cowch/lstV2/commits/0b72ffa935be81476a15166fd60ae8cabe29d297))
|
||||||
|
* bump build number to 16 ([44da09d](https://git.tuffraid.net/cowch/lstV2/commits/44da09d22c4d946c981d408d797ea121d26690b6))
|
||||||
|
* bump build number to 17 ([1ce5f9a](https://git.tuffraid.net/cowch/lstV2/commits/1ce5f9acf752f5f4bcb4b2ff1c71f54ffb9331f3))
|
||||||
|
* bump build number to 18 ([b6f1cfd](https://git.tuffraid.net/cowch/lstV2/commits/b6f1cfdc6c71e351fb90ec7729e0d0f89322174f))
|
||||||
|
|
||||||
|
|
||||||
|
### 🛠️ Code Refactor
|
||||||
|
|
||||||
|
* **frontend:** removed tanstack devTools ([3594278](https://git.tuffraid.net/cowch/lstV2/commits/359427824bae319b7f2f406eb52b8f9c43be198f))
|
||||||
|
* **frontend:** removed the caption from settings table ([35acd2b](https://git.tuffraid.net/cowch/lstV2/commits/35acd2b0b3af7b9d010cb8f78f088ab3a539c54b))
|
||||||
|
|
||||||
|
|
||||||
|
### 🌟 Enhancements
|
||||||
|
|
||||||
|
* **frontend:** added in proper links for settings and servers to the sidebar ([cbdd218](https://git.tuffraid.net/cowch/lstV2/commits/cbdd218fe454e38a7cf0c4d0ddf60d1f20e15ee2))
|
||||||
|
* **frontend:** added in update server page only for sysAdmin ([625d596](https://git.tuffraid.net/cowch/lstV2/commits/625d5969be2dbde9e97f6607c33c5e5b14e3d192))
|
||||||
|
* **new setting:** added in devDir ment for updating servers ([5b97d07](https://git.tuffraid.net/cowch/lstV2/commits/5b97d078c583f3e78d52dbc135da99a0175c8e54))
|
||||||
|
* **server upgrade:** added in a catch incase we try to upgrade again ([ab16059](https://git.tuffraid.net/cowch/lstV2/commits/ab16059387b7cb46e2a3d86f6da09a31899bd5d6))
|
||||||
|
* **server:** added in update server as well as get serverdata ([df252e7](https://git.tuffraid.net/cowch/lstV2/commits/df252e72b39d811ffbbb0af49aaf43ff22081f48))
|
||||||
|
* **serverdata:** added catch if we are not on localhost we cant actaully see the devDir in set ([f3fa617](https://git.tuffraid.net/cowch/lstV2/commits/f3fa617aa53ed35f461b71f5e479ea521412936e))
|
||||||
|
* **serverdata:** added in bowling green 2 ([7529cc5](https://git.tuffraid.net/cowch/lstV2/commits/7529cc5b0cc2c6542e8f4af07d465b6a9f4295b1))
|
||||||
|
* **sql query:** added 2 catches if not connected dont run ([cb7a406](https://git.tuffraid.net/cowch/lstV2/commits/cb7a4068fcffc7a1d85c2e04f2eeaebdc264705c))
|
||||||
|
* **sql server:** added in the ping check to not spam if we are not connected ([e4d15ef](https://git.tuffraid.net/cowch/lstV2/commits/e4d15ef051f6c72d2cca9bb9fb61ff78849db8c4))
|
||||||
|
|
||||||
|
|
||||||
|
### 🐛 Bug fixes
|
||||||
|
|
||||||
|
* **frontend:** if the modules returns and error we want to use an empty array ([2370d45](https://git.tuffraid.net/cowch/lstV2/commits/2370d45220c5e1c3215a3f2fce9582d8f2bbd3ed))
|
||||||
|
* **rfid:** correction to the params and incorrect naming ([a73c63c](https://git.tuffraid.net/cowch/lstV2/commits/a73c63cefa67f43300f4695f40f2248bcab8f40e))
|
||||||
|
* **zippaths:** corrected the paths to the src that were moved the the env ([246b5a1](https://git.tuffraid.net/cowch/lstV2/commits/246b5a17bd4ffe47654416fa4a1be446f8bffbd0))
|
||||||
|
|
||||||
## [2.6.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.5.1...v2.6.0) (2025-03-14)
|
## [2.6.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.5.1...v2.6.0) (2025-03-14)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1
database/migrations/0017_bitter_brood.sql
Normal file
1
database/migrations/0017_bitter_brood.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "rfidReaders" ADD COLUMN "lastTrigger" timestamp DEFAULT now();
|
||||||
1
database/migrations/0018_lovely_landau.sql
Normal file
1
database/migrations/0018_lovely_landau.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "rfidReaders" ADD COLUMN "active" boolean DEFAULT true;
|
||||||
2
database/migrations/0019_greedy_justice.sql
Normal file
2
database/migrations/0019_greedy_justice.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE "rfidTags" ADD COLUMN "antenna" numeric;--> statement-breakpoint
|
||||||
|
ALTER TABLE "rfidTags" ADD COLUMN "tagStrength" numeric;
|
||||||
2
database/migrations/0020_empty_thundra.sql
Normal file
2
database/migrations/0020_empty_thundra.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE "rfidTags" ALTER COLUMN "counts" SET DEFAULT '[]'::jsonb;--> statement-breakpoint
|
||||||
|
ALTER TABLE "rfidTags" ALTER COLUMN "counts" DROP NOT NULL;
|
||||||
4
database/migrations/0021_premium_albert_cleary.sql
Normal file
4
database/migrations/0021_premium_albert_cleary.sql
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE "rfidTags" ALTER COLUMN "runningNumber" SET DATA TYPE integer;--> statement-breakpoint
|
||||||
|
ALTER TABLE "rfidTags" ALTER COLUMN "runningNumber" DROP NOT NULL;--> statement-breakpoint
|
||||||
|
ALTER TABLE "rfidTags" ALTER COLUMN "antenna" SET DATA TYPE integer;--> statement-breakpoint
|
||||||
|
ALTER TABLE "rfidTags" ALTER COLUMN "tagStrength" SET DATA TYPE integer;
|
||||||
1
database/migrations/0022_amused_true_believers.sql
Normal file
1
database/migrations/0022_amused_true_believers.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "rfidReaders" ADD COLUMN "lastTiggerGood" boolean DEFAULT true;
|
||||||
1047
database/migrations/meta/0017_snapshot.json
Normal file
1047
database/migrations/meta/0017_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1054
database/migrations/meta/0018_snapshot.json
Normal file
1054
database/migrations/meta/0018_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1066
database/migrations/meta/0019_snapshot.json
Normal file
1066
database/migrations/meta/0019_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1067
database/migrations/meta/0020_snapshot.json
Normal file
1067
database/migrations/meta/0020_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1067
database/migrations/meta/0021_snapshot.json
Normal file
1067
database/migrations/meta/0021_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1074
database/migrations/meta/0022_snapshot.json
Normal file
1074
database/migrations/meta/0022_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -120,6 +120,48 @@
|
|||||||
"when": 1742051878587,
|
"when": 1742051878587,
|
||||||
"tag": "0016_wet_doctor_strange",
|
"tag": "0016_wet_doctor_strange",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 17,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1742133439717,
|
||||||
|
"tag": "0017_bitter_brood",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 18,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1742133828291,
|
||||||
|
"tag": "0018_lovely_landau",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 19,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1742139737945,
|
||||||
|
"tag": "0019_greedy_justice",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 20,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1742143798267,
|
||||||
|
"tag": "0020_empty_thundra",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 21,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1742144973347,
|
||||||
|
"tag": "0021_premium_albert_cleary",
|
||||||
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 22,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1742156466912,
|
||||||
|
"tag": "0022_amused_true_believers",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,9 @@ export const rfidReaders = pgTable(
|
|||||||
reader: text("reader"),
|
reader: text("reader"),
|
||||||
readerIP: text("readerIP"),
|
readerIP: text("readerIP"),
|
||||||
lastHeartBeat: timestamp("lastHeartBeat").defaultNow(),
|
lastHeartBeat: timestamp("lastHeartBeat").defaultNow(),
|
||||||
|
lastTrigger: timestamp("lastTrigger").defaultNow(),
|
||||||
|
lastTriggerGood: boolean("lastTiggerGood").default(true),
|
||||||
|
active: boolean("active").default(true),
|
||||||
},
|
},
|
||||||
(table) => [
|
(table) => [
|
||||||
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
|
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {text, pgTable, numeric, index, timestamp, boolean, uuid, uniqueIndex, jsonb} from "drizzle-orm/pg-core";
|
import {text, pgTable, timestamp, uuid, uniqueIndex, jsonb, integer} 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";
|
||||||
|
|
||||||
@@ -9,9 +9,11 @@ export const rfidTags = pgTable(
|
|||||||
tagHex: text("tagHex"),
|
tagHex: text("tagHex"),
|
||||||
tag: text("tag"),
|
tag: text("tag"),
|
||||||
lastRead: timestamp("timeStamp").defaultNow(),
|
lastRead: timestamp("timeStamp").defaultNow(),
|
||||||
counts: jsonb("counts").notNull(), //.default([{area: 1, timesHere: 5}]).notNull(),
|
counts: jsonb("counts").default([]), // example [{area: Line3.2, count: 1}, {area: line3.1, count: 6}]
|
||||||
lastareaIn: text("lastareaIn").notNull(),
|
lastareaIn: text("lastareaIn").notNull(),
|
||||||
runningNumber: numeric("runningNumber").notNull(),
|
runningNumber: integer("runningNumber"),
|
||||||
|
antenna: integer("antenna"),
|
||||||
|
tagStrength: integer("tagStrength"),
|
||||||
created_at: timestamp("created_at").defaultNow(),
|
created_at: timestamp("created_at").defaultNow(),
|
||||||
},
|
},
|
||||||
(table) => [
|
(table) => [
|
||||||
@@ -21,8 +23,8 @@ export const rfidTags = pgTable(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Schema for inserting a user - can be used to validate API requests
|
// Schema for inserting a user - can be used to validate API requests
|
||||||
// export const insertRolesSchema = createInsertSchema(roles, {
|
export const insertRolesSchema = createInsertSchema(rfidTags, {
|
||||||
// name: z.string().min(3, {message: "Role name must be more than 3 letters"}),
|
tagHex: z.string().min(3, {message: "Tag Should have more than 3 characters"}),
|
||||||
// });
|
});
|
||||||
// Schema for selecting a Expenses - can be used to validate API responses
|
// Schema for selecting a Expenses - can be used to validate API responses
|
||||||
export const selectRolesSchema = createSelectSchema(rfidTags);
|
export const selectRolesSchema = createSelectSchema(rfidTags);
|
||||||
|
|||||||
15
frontend/package-lock.json
generated
15
frontend/package-lock.json
generated
@@ -33,6 +33,7 @@
|
|||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"lucide-react": "^0.476.0",
|
"lucide-react": "^0.476.0",
|
||||||
"next-themes": "^0.4.4",
|
"next-themes": "^0.4.4",
|
||||||
|
"npm-check-updates": "^17.1.15",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-day-picker": "^8.10.1",
|
"react-day-picker": "^8.10.1",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
@@ -4901,6 +4902,20 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/npm-check-updates": {
|
||||||
|
"version": "17.1.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.1.15.tgz",
|
||||||
|
"integrity": "sha512-miATvKu5rjec/1wxc5TGDjpsucgtCHwRVZorZpDkS6NzdWXfnUWlN4abZddWb7XSijAuBNzzYglIdTm9SbgMVg==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"ncu": "build/cli.js",
|
||||||
|
"npm-check-updates": "build/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || >=20.0.0",
|
||||||
|
"npm": ">=8.12.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-assign": {
|
"node_modules/object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
"build": "rimraf dist && tsc -b && vite build",
|
"build": "rimraf dist && tsc -b && vite build",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"shad": "npx shadcn@canary add "
|
"shad": "npx shadcn@canary add ",
|
||||||
|
"checkupdates": "npm-check-updates"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^4.1.2",
|
"@hookform/resolvers": "^4.1.2",
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"lucide-react": "^0.476.0",
|
"lucide-react": "^0.476.0",
|
||||||
"next-themes": "^0.4.4",
|
"next-themes": "^0.4.4",
|
||||||
|
"npm-check-updates": "^17.1.15",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-day-picker": "^8.10.1",
|
"react-day-picker": "^8.10.1",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
|
|||||||
19
package-lock.json
generated
19
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "lstv2",
|
"name": "lstv2",
|
||||||
"version": "2.6.0",
|
"version": "2.7.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "lstv2",
|
"name": "lstv2",
|
||||||
"version": "2.6.0",
|
"version": "2.7.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dotenvx/dotenvx": "^1.38.3",
|
"@dotenvx/dotenvx": "^1.38.3",
|
||||||
"@hono/node-server": "^1.13.8",
|
"@hono/node-server": "^1.13.8",
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
"mssql": "^11.0.1",
|
"mssql": "^11.0.1",
|
||||||
"nodemailer": "^6.10.0",
|
"nodemailer": "^6.10.0",
|
||||||
"nodemailer-express-handlebars": "^7.0.0",
|
"nodemailer-express-handlebars": "^7.0.0",
|
||||||
|
"npm-check-updates": "^17.1.15",
|
||||||
"pg": "^8.13.3",
|
"pg": "^8.13.3",
|
||||||
"pino": "^9.6.0",
|
"pino": "^9.6.0",
|
||||||
"pino-abstract-transport": "^2.0.0",
|
"pino-abstract-transport": "^2.0.0",
|
||||||
@@ -8783,6 +8784,20 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/npm-check-updates": {
|
||||||
|
"version": "17.1.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.1.15.tgz",
|
||||||
|
"integrity": "sha512-miATvKu5rjec/1wxc5TGDjpsucgtCHwRVZorZpDkS6NzdWXfnUWlN4abZddWb7XSijAuBNzzYglIdTm9SbgMVg==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"ncu": "build/cli.js",
|
||||||
|
"npm-check-updates": "build/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || >=20.0.0",
|
||||||
|
"npm": ">=8.12.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/npm-run-path": {
|
"node_modules/npm-run-path": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lstv2",
|
"name": "lstv2",
|
||||||
"version": "2.6.0",
|
"version": "2.7.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently -n \"server,frontend\" -c \"#007755,#2f6da3\" \"npm run dev:server\" \"cd frontend && npm run dev\"",
|
"dev": "concurrently -n \"server,frontend\" -c \"#007755,#2f6da3\" \"npm run dev:server\" \"cd frontend && npm run dev\"",
|
||||||
@@ -15,11 +15,13 @@
|
|||||||
"start:server": "dotenvx run -f .env -- node dist/server/index.js",
|
"start:server": "dotenvx run -f .env -- node dist/server/index.js",
|
||||||
"db:generate": "npx drizzle-kit generate",
|
"db:generate": "npx drizzle-kit generate",
|
||||||
"db:migrate": "npx drizzle-kit push",
|
"db:migrate": "npx drizzle-kit push",
|
||||||
|
"db:dev": "npm run build && npm run db:generate && npm run db:migrate",
|
||||||
"deploy": "standard-version --conventional-commits && npm run prodBuild",
|
"deploy": "standard-version --conventional-commits && npm run prodBuild",
|
||||||
"zipServer": "dotenvx run -f .env -- tsx server/scripts/zipUpBuild.ts \"C:\\Users\\matthes01\\Documents\\lstv2\"",
|
"zipServer": "dotenvx run -f .env -- tsx server/scripts/zipUpBuild.ts \"C:\\Users\\matthes01\\Documents\\lstv2\"",
|
||||||
"prodBuild": "powershell -ExecutionPolicy Bypass -File server/scripts/build.ps1 -dir \"C:\\Users\\matthes01\\Documents\\lstv2\" && npm run zipServer",
|
"prodBuild": "powershell -ExecutionPolicy Bypass -File server/scripts/build.ps1 -dir \"C:\\Users\\matthes01\\Documents\\lstv2\" && npm run zipServer",
|
||||||
"commit": "cz",
|
"commit": "cz",
|
||||||
"prodinstall": "npm i --omit=dev && npm run db:migrate"
|
"prodinstall": "npm i --omit=dev && npm run db:migrate",
|
||||||
|
"checkupdates": "npm-check-updates"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dotenvx/dotenvx": "^1.38.3",
|
"@dotenvx/dotenvx": "^1.38.3",
|
||||||
@@ -69,7 +71,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"admConfig": {
|
"admConfig": {
|
||||||
"build": 18,
|
"build": 19,
|
||||||
"oldBuild": "backend-0.1.2-217.zip"
|
"oldBuild": "backend-0.1.2-217.zip"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
8
server/globalUtils/routeDefs/options.ts
Normal file
8
server/globalUtils/routeDefs/options.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export const apiOptions = () => {
|
||||||
|
return {
|
||||||
|
tags: ["rfid"],
|
||||||
|
summary: "Add new reader",
|
||||||
|
method: "post",
|
||||||
|
path: "/addreader",
|
||||||
|
};
|
||||||
|
};
|
||||||
45
server/globalUtils/routeDefs/responses.ts
Normal file
45
server/globalUtils/routeDefs/responses.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import {z} from "@hono/zod-openapi";
|
||||||
|
|
||||||
|
const responseSchema = z.object({
|
||||||
|
success: z.boolean().openapi({example: true}),
|
||||||
|
message: z.string().optional(),
|
||||||
|
data: z
|
||||||
|
.array(z.object({}).optional())
|
||||||
|
.optional()
|
||||||
|
.openapi({example: [{data: "hi"}]}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const responses = () => {
|
||||||
|
return {
|
||||||
|
200: {
|
||||||
|
content: {
|
||||||
|
"application/json": {schema: responseSchema},
|
||||||
|
},
|
||||||
|
description: "Response message",
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: "Internal Server Error",
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: "Unauthorized",
|
||||||
|
},
|
||||||
|
500: {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: "Internal Server Error",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -16,6 +16,7 @@ import ocme from "./services/ocme/ocmeService.js";
|
|||||||
import sqlService from "./services/sqlServer/sqlService.js";
|
import sqlService from "./services/sqlServer/sqlService.js";
|
||||||
import logistics from "./services/logistics/logisticsService.js";
|
import logistics from "./services/logistics/logisticsService.js";
|
||||||
import rfid from "./services/rfid/rfidService.js";
|
import rfid from "./services/rfid/rfidService.js";
|
||||||
|
import printers from "./services/printers/printerService.js";
|
||||||
|
|
||||||
import {db} from "../database/dbclient.js";
|
import {db} from "../database/dbclient.js";
|
||||||
import {settings} from "../database/schema/settings.js";
|
import {settings} from "../database/schema/settings.js";
|
||||||
@@ -83,6 +84,7 @@ const routes = [
|
|||||||
sqlService,
|
sqlService,
|
||||||
logistics,
|
logistics,
|
||||||
rfid,
|
rfid,
|
||||||
|
printers,
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
const appRoutes = routes.forEach((route) => {
|
const appRoutes = routes.forEach((route) => {
|
||||||
|
|||||||
14
server/services/printers/printerService.ts
Normal file
14
server/services/printers/printerService.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import {OpenAPIHono} from "@hono/zod-openapi";
|
||||||
|
|
||||||
|
import alerts from "./route/printerAlert.js";
|
||||||
|
const app = new OpenAPIHono();
|
||||||
|
const port = 4000;
|
||||||
|
|
||||||
|
const routes = [alerts] as const;
|
||||||
|
|
||||||
|
// app.route("/server", modules);
|
||||||
|
const appRoutes = routes.forEach((route) => {
|
||||||
|
app.route("/printers", route);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default app;
|
||||||
102
server/services/printers/route/printerAlert.ts
Normal file
102
server/services/printers/route/printerAlert.ts
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
//http://usday1vms006:4000/api/v1/zebra/wrapper1
|
||||||
|
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||||
|
|
||||||
|
// Define the response schema
|
||||||
|
const responseSchema = z.object({
|
||||||
|
success: z.boolean().openapi({example: true}),
|
||||||
|
message: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
|
const ParamsSchema = z.object({
|
||||||
|
printer: z
|
||||||
|
.string()
|
||||||
|
.min(3)
|
||||||
|
.openapi({
|
||||||
|
param: {
|
||||||
|
name: "printer",
|
||||||
|
in: "path",
|
||||||
|
},
|
||||||
|
example: "Line1",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
app.openapi(
|
||||||
|
createRoute({
|
||||||
|
tags: ["printer"],
|
||||||
|
summary: "Printer Alert",
|
||||||
|
method: "post",
|
||||||
|
path: "/{printer}",
|
||||||
|
request: {
|
||||||
|
params: ParamsSchema,
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
content: {
|
||||||
|
"application/json": {schema: responseSchema},
|
||||||
|
},
|
||||||
|
description: "Response message",
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: "Internal Server Error",
|
||||||
|
},
|
||||||
|
401: {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: "Unauthorized",
|
||||||
|
},
|
||||||
|
500: {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: "Internal Server Error",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const {printer} = c.req.valid("param");
|
||||||
|
|
||||||
|
const contentType = c.req.header("Content-Type") || "";
|
||||||
|
const boundaryMatch = contentType.match(/boundary=(.*)$/);
|
||||||
|
|
||||||
|
if (!boundaryMatch) {
|
||||||
|
return c.json({message: "No boundary found in Content-Type"}, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const boundary = boundaryMatch[1];
|
||||||
|
const body = await c.req.text(); // Get the body of the request
|
||||||
|
|
||||||
|
// Split the body by the boundary (adding extra dashes before the boundary)
|
||||||
|
const parts = body.split(`--${boundary}`);
|
||||||
|
console.log(parts);
|
||||||
|
// Remove the first and last empty parts (they are just before and after the boundaries)
|
||||||
|
const formDataParts = parts.slice(1, parts.length - 1);
|
||||||
|
|
||||||
|
// console.log(formDataParts);
|
||||||
|
|
||||||
|
// formDataParts.forEach((part, index) => {
|
||||||
|
// // Split the part into headers and body
|
||||||
|
// const [headers, data] = part.split("\r\n\r\n");
|
||||||
|
|
||||||
|
// // Log the part index and data for debugging
|
||||||
|
// console.log(`Part ${index + 1}:`);
|
||||||
|
// console.log("Headers:", headers);
|
||||||
|
// console.log("Data:", decodeURIComponent(data));
|
||||||
|
// });
|
||||||
|
|
||||||
|
return c.json({success: true, message: `New info from ${printer}`}, 200);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default app;
|
||||||
34
server/services/rfid/controller/addReader.ts
Normal file
34
server/services/rfid/controller/addReader.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import {z} from "zod";
|
||||||
|
import {createLog} from "../../logger/logger.js";
|
||||||
|
import {db} from "../../../../database/dbclient.js";
|
||||||
|
import {rfidReaders} from "../../../../database/schema/rfidReaders.js";
|
||||||
|
|
||||||
|
const ReaderData = z.object({
|
||||||
|
reader: z.string(),
|
||||||
|
readerIP: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type ReaderData = z.infer<typeof ReaderData>;
|
||||||
|
|
||||||
|
export const addReader = async (data: ReaderData, user: any) => {
|
||||||
|
/**
|
||||||
|
* add a new reader with name and ip.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ReaderData.parse(data);
|
||||||
|
|
||||||
|
if (!data.reader && !data.readerIP) {
|
||||||
|
createLog("error", user.username, "rfid", "Missing data please check that you have both a name and ip.");
|
||||||
|
return {success: false, message: "Missing data please check that you have both a name and ip."};
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to add the reader
|
||||||
|
try {
|
||||||
|
await db.insert(rfidReaders).values(data).onConflictDoUpdate({target: rfidReaders.reader, set: data});
|
||||||
|
createLog("info", user.username, "rfid", `Just added ${data.reader}.`);
|
||||||
|
return {success: true, message: `${data.reader} was just added.`};
|
||||||
|
} catch (error) {
|
||||||
|
createLog("error", user.username, "rfid", `there was an error adding ${data.reader}, ${error}`);
|
||||||
|
return {success: false, message: `${data.reader} encountered and error: ${error}`};
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
/**
|
|
||||||
* While in production we will monitor the readers if we have not gotten a heartbeat in the last 5 min we will send a reboot command along with an email.
|
|
||||||
*/
|
|
||||||
7
server/services/rfid/controller/noRead.ts
Normal file
7
server/services/rfid/controller/noRead.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* For a no read we just want to put up a notification to the rfid dashboard stating this reader did not respond with any tag data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const noRead = async (reader: string) => {
|
||||||
|
console.log(`${reader} just had a no read please check for a tag and manually trigger a read.`);
|
||||||
|
};
|
||||||
@@ -1,23 +1,47 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {createLog} from "../../logger/logger.js";
|
import {createLog} from "../../logger/logger.js";
|
||||||
|
import {db} from "../../../../database/dbclient.js";
|
||||||
|
import {rfidReaders} from "../../../../database/schema/rfidReaders.js";
|
||||||
|
import {eq} from "drizzle-orm";
|
||||||
|
|
||||||
|
const authData = btoa("admin:Zebra123!");
|
||||||
|
let token: string;
|
||||||
|
let ip: string;
|
||||||
|
|
||||||
export const readTags = async (reader: string) => {
|
export const readTags = async (reader: string) => {
|
||||||
/**
|
/**
|
||||||
* Start the read for x seconds then auto stop it
|
* Start the read for x seconds then auto stop it
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let token: string;
|
const readers = await db.select().from(rfidReaders).where(eq(rfidReaders.active, true));
|
||||||
|
if (readers.length === 0) {
|
||||||
const readers = [{reader: "reader1", readerIP: "10.10.1.222", lastHeartBeat: new Date()}];
|
createLog("error", "rfid", "rfid", `There are no active readers right now maybe one forgot to be activated`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// get the auth token
|
// get the auth token
|
||||||
const ip = readers.find((r) => r.reader === reader)?.readerIP;
|
ip = readers.find((r) => r.reader === reader)?.readerIP as string;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(`https://${ip}/cloud/localRestLogin`, {
|
const res = await axios.get(`https://${ip}/cloud/localRestLogin`, {
|
||||||
headers: {Authorization: `Basic ${btoa("admin:Zebra123!")}`},
|
headers: {Authorization: `Basic ${authData}`},
|
||||||
});
|
});
|
||||||
token = res.data.message;
|
token = res.data.message;
|
||||||
// start the read
|
// start the read
|
||||||
|
startRead();
|
||||||
|
} catch (error: any) {
|
||||||
|
console.log(error);
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"rfid",
|
||||||
|
"rfid",
|
||||||
|
`There was an error Getting the token the read: ${error.response?.data.message}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// start the read
|
||||||
|
};
|
||||||
|
|
||||||
|
const startRead = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await axios.put(
|
const res = await axios.put(
|
||||||
`https://${ip}/cloud/start`,
|
`https://${ip}/cloud/start`,
|
||||||
@@ -27,8 +51,26 @@ export const readTags = async (reader: string) => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// stop after 5 seconds
|
//console.log(res.data);
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
setTimeout(() => {
|
||||||
|
stopRead();
|
||||||
|
}, 5 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop after 5 seconds
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.response.data.code === 3) {
|
||||||
|
stopRead();
|
||||||
|
setTimeout(() => {
|
||||||
|
startRead();
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
createLog("error", "rfid", "rfid", `There was an error Starting the read: ${error.response.data.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const stopRead = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await axios.put(
|
const res = await axios.put(
|
||||||
`https://${ip}/cloud/stop`,
|
`https://${ip}/cloud/stop`,
|
||||||
@@ -37,15 +79,7 @@ export const readTags = async (reader: string) => {
|
|||||||
headers: {Authorization: `Bearer ${token}`},
|
headers: {Authorization: `Bearer ${token}`},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
createLog("error", "rfid", "rfid", `There was an error Stopping the read ${error}`);
|
createLog("error", "rfid", "rfid", `There was an error Stopping the read: ${error.response.data.message}`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
createLog("error", "rfid", "rfid", `There was an error Starting the read ${error}`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
createLog("error", "rfid", "rfid", `There was an error Getting the token the read ${error}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// start the read
|
|
||||||
};
|
};
|
||||||
|
|||||||
60
server/services/rfid/controller/readerControl.ts
Normal file
60
server/services/rfid/controller/readerControl.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* While in production we will monitor the readers if we have not gotten a heartbeat in the last 5 min we will send a reboot command along with an email.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {eq, sql} from "drizzle-orm";
|
||||||
|
import {db} from "../../../../database/dbclient.js";
|
||||||
|
import {rfidReaders} from "../../../../database/schema/rfidReaders.js";
|
||||||
|
import {createLog} from "../../logger/logger.js";
|
||||||
|
|
||||||
|
export const newHeartBeat = async (reader: string) => {
|
||||||
|
/**
|
||||||
|
* When a heat beat is sent over for a reader we want to update the reader.
|
||||||
|
*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
const heatBeat = await db
|
||||||
|
.update(rfidReaders)
|
||||||
|
.set({lastHeartBeat: sql`NOW()`})
|
||||||
|
.where(eq(rfidReaders.reader, reader));
|
||||||
|
createLog("info", "rfid", "rfid", `${reader} just updated its heatBeat.`);
|
||||||
|
return {success: true, message: `${reader} just updated its heatBeat.`};
|
||||||
|
} catch (error) {
|
||||||
|
createLog("error", "rfid", "rfid", `${reader} encountered an error while updating the heatbeat, ${error}`);
|
||||||
|
return {success: false, message: `${reader} encountered an error while updating the heatbeat, ${error}`};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const badRead = async (reader: string) => {
|
||||||
|
/**
|
||||||
|
* When we have a bad read we want to make sure the reader shows this was well.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
const badRead = await db
|
||||||
|
.update(rfidReaders)
|
||||||
|
.set({lastTrigger: sql`NOW()`, lastTriggerGood: false})
|
||||||
|
.where(eq(rfidReaders.reader, reader));
|
||||||
|
createLog("info", "rfid", "rfid", `${reader} just Triggered a bad read.`);
|
||||||
|
return {success: true, message: `${reader} just Triggered a bad read.`};
|
||||||
|
} catch (error) {
|
||||||
|
createLog("error", "rfid", "rfid", `${reader} encountered an error while updating the heatbeat, ${error}`);
|
||||||
|
return {success: false, message: `${reader} encountered an error while updating the heatbeat, ${error}`};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const goodRead = async (reader: string) => {
|
||||||
|
/**
|
||||||
|
* When we have a bad read we want to make sure the reader shows this was well.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
const goodRead = await db
|
||||||
|
.update(rfidReaders)
|
||||||
|
.set({lastTrigger: sql`NOW()`, lastTriggerGood: true})
|
||||||
|
.where(eq(rfidReaders.reader, reader));
|
||||||
|
createLog("info", "rfid", "rfid", `${reader} just Triggered a good read.`);
|
||||||
|
return {success: true, message: `${reader} just Triggered a good read.`};
|
||||||
|
} catch (error) {
|
||||||
|
createLog("error", "rfid", "rfid", `${reader} encountered an error while updating the heatbeat, ${error}`);
|
||||||
|
return {success: false, message: `${reader} encountered an error while updating the heatbeat, ${error}`};
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* Phase 1 we link the tag to the line only the line3.x where x is the line number
|
|
||||||
* Phase 2 we will generate a label to be reprinted at staion 4
|
|
||||||
*/
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* Phase 1 we will just follow the logic of printing a label when we are told requested to based on this tag.
|
|
||||||
* Phase 2 we will just reprint the tag that was generated at the line
|
|
||||||
*/
|
|
||||||
27
server/services/rfid/controller/stations/station3.ts
Normal file
27
server/services/rfid/controller/stations/station3.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Phase 1 we link the tag to the line only the line3.x where x is the line number
|
||||||
|
* Phase 2 we will generate a label to be reprinted at staion 4
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {createLog} from "../../../logger/logger.js";
|
||||||
|
import type {TagData} from "../tagData.js";
|
||||||
|
import {tagStuff} from "../tags/crudTag.js";
|
||||||
|
|
||||||
|
export const station3Tags = async (tagData: TagData[]) => {
|
||||||
|
// make sure we only have one tag or dont update
|
||||||
|
if (tagData.length != 1) {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"rfid",
|
||||||
|
"rfid",
|
||||||
|
`There are ${tagData.length} tags, and ${tagData[0].reader} only allows 1 tag to create a label.`
|
||||||
|
);
|
||||||
|
// get tag data
|
||||||
|
tagStuff(tagData);
|
||||||
|
} else {
|
||||||
|
//console.log("Generate the label and link it to the tag.");
|
||||||
|
const tagdata = await tagStuff(tagData);
|
||||||
|
|
||||||
|
createLog("info", "rfid", "rfid", "Generate a label and link it to this tag.");
|
||||||
|
}
|
||||||
|
};
|
||||||
43
server/services/rfid/controller/stations/wrappers.ts
Normal file
43
server/services/rfid/controller/stations/wrappers.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* Phase 1 we will just follow the logic of printing a label when we are told requested to based on this tag.
|
||||||
|
* Phase 2 we will just reprint the tag that was generated at the line
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {createLog} from "../../../logger/logger.js";
|
||||||
|
import type {TagData} from "../tagData.js";
|
||||||
|
import {tagStuff} from "../tags/crudTag.js";
|
||||||
|
|
||||||
|
export const wrapperStuff = async (tagData: TagData[]) => {
|
||||||
|
if (tagData.length != 1) {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"rfid",
|
||||||
|
"rfid",
|
||||||
|
`There are ${tagData.length} tags and this ${tagData[0].reader} only allows 1 tag to create a label.`
|
||||||
|
);
|
||||||
|
tagStuff(tagData);
|
||||||
|
} else {
|
||||||
|
const tagdata = await tagStuff(tagData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* we want to make sure this pallet came from a line as its last spot if not we need to have a manual check.
|
||||||
|
*/
|
||||||
|
const station3 = tagdata.some((n: any) => n.lastareaIn.includes("line3"));
|
||||||
|
|
||||||
|
if (!station3) {
|
||||||
|
createLog(
|
||||||
|
"error",
|
||||||
|
"rfid",
|
||||||
|
"rfid",
|
||||||
|
`${tagdata.tag}, Did not come from a line please check the pallet and manually print the label.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if a running number exists
|
||||||
|
if (station3.runningNumber) {
|
||||||
|
createLog("info", "rfid", "rfid", `Reprint label ${station3.runningNumber}`);
|
||||||
|
} else {
|
||||||
|
createLog("info", "rfid", "rfid", `A new labels will be created and linked to this ${tagdata.tag} tag`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,4 +1,14 @@
|
|||||||
type TagData = {tagHex: string; reader: string; tag: string; timeStamp: Date};
|
import {station3Tags} from "./stations/station3.js";
|
||||||
|
import {wrapperStuff} from "./stations/wrappers.js";
|
||||||
|
|
||||||
|
export type TagData = {
|
||||||
|
tagHex: string;
|
||||||
|
reader: string;
|
||||||
|
tag: string;
|
||||||
|
timeStamp: Date;
|
||||||
|
antenna: number;
|
||||||
|
tagStrength: number;
|
||||||
|
};
|
||||||
export const tagData = async (data: TagData[]) => {
|
export const tagData = async (data: TagData[]) => {
|
||||||
/**
|
/**
|
||||||
* We will always update a tag
|
* We will always update a tag
|
||||||
@@ -14,7 +24,7 @@ export const tagData = async (data: TagData[]) => {
|
|||||||
const station3 = data.some((n) => n.reader.includes("line3"));
|
const station3 = data.some((n) => n.reader.includes("line3"));
|
||||||
|
|
||||||
// at the wrapper
|
// at the wrapper
|
||||||
const station4 = data.some((n) => n.reader.includes("wrapper"));
|
const wrappers = data.some((n) => n.reader.includes("wrapper"));
|
||||||
|
|
||||||
// station checks
|
// station checks
|
||||||
if (station1 && data.length != 10) {
|
if (station1 && data.length != 10) {
|
||||||
@@ -26,23 +36,10 @@ export const tagData = async (data: TagData[]) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (station3) {
|
if (station3) {
|
||||||
// make sure we only have one tag or dont update
|
station3Tags(data);
|
||||||
if (data.length != 1) {
|
|
||||||
console.log(`There are ${data.length} tags, and ${data[0].reader} only allows 1 tag to create a label.`);
|
|
||||||
//throw new Error("There are more than 1 tag at this station and it is not allowed");
|
|
||||||
} else {
|
|
||||||
console.log("Generate the tag and link it to the tag.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (station4) {
|
if (wrappers) {
|
||||||
if (data.length != 1) {
|
wrapperStuff(data);
|
||||||
console.log(
|
|
||||||
`There are ${data.length} tags and this ${data[0].reader} only allows 1 tag to create a label.`
|
|
||||||
);
|
|
||||||
//throw new Error("There are more than 1 tag at this station and it is not allowed");
|
|
||||||
} else {
|
|
||||||
console.log("reprint the label linked to the tag.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
87
server/services/rfid/controller/tags/crudTag.ts
Normal file
87
server/services/rfid/controller/tags/crudTag.ts
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
import {eq} from "drizzle-orm";
|
||||||
|
import {db} from "../../../../../database/dbclient.js";
|
||||||
|
import {rfidTags} from "../../../../../database/schema/rfidTags.js";
|
||||||
|
import type {TagData} from "../tagData.js";
|
||||||
|
import {createLog} from "../../../logger/logger.js";
|
||||||
|
|
||||||
|
type ReturnTag = {
|
||||||
|
success: boolean;
|
||||||
|
tag: any;
|
||||||
|
error: any;
|
||||||
|
};
|
||||||
|
export const tagStuff = async (tagData: TagData[]): Promise<any> => {
|
||||||
|
const tags = await db.select().from(rfidTags);
|
||||||
|
|
||||||
|
// look through each tag and either add it to the db or update the area and other relevent data.
|
||||||
|
for (let i = 0; i < tagData.length; i++) {
|
||||||
|
// check if the tag already exists
|
||||||
|
const tag = tags.filter((n) => n.tagHex === tagData[i].tagHex);
|
||||||
|
if (tag.length === 0) {
|
||||||
|
// add new tag
|
||||||
|
const newTag = {
|
||||||
|
tagHex: tagData[i].tagHex,
|
||||||
|
tag: tagData[i].tag,
|
||||||
|
lastRead: new Date(tagData[i].timeStamp),
|
||||||
|
counts: [{area: tagData[i].reader, timesHere: 1}], //jsonb("counts").notNull(), //.default([{area: 1, timesHere: 5}]).notNull(),
|
||||||
|
lastareaIn: tagData[i].reader,
|
||||||
|
antenna: tagData[i].antenna,
|
||||||
|
tagStrength: tagData[i].tagStrength,
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
// insert the tag with the onConflict update the tag
|
||||||
|
const tag = await db.insert(rfidTags).values(newTag).returning({
|
||||||
|
tag: rfidTags.tag,
|
||||||
|
runningNumber: rfidTags.runningNumber,
|
||||||
|
counts: rfidTags.counts,
|
||||||
|
lastareaIn: rfidTags.lastareaIn,
|
||||||
|
});
|
||||||
|
createLog("info", "rfid", "rfid", `Tags were jusdt updated.`);
|
||||||
|
return {success: true, tag};
|
||||||
|
} catch (error) {
|
||||||
|
createLog("error", "rfid", "rfid", `${JSON.stringify(error)}`);
|
||||||
|
return {success: false, error};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// update tag
|
||||||
|
//console.log("Updating existing tag");
|
||||||
|
// make sure we actually have an array here
|
||||||
|
const countsArray = (tag[0]?.counts as {area: string; timesHere: number}[]) ?? [];
|
||||||
|
|
||||||
|
// check if the reader exists on the array
|
||||||
|
const areaExists = countsArray.some((t) => t.area === tagData[0].reader);
|
||||||
|
|
||||||
|
// run the update on the array
|
||||||
|
const updateCount = areaExists
|
||||||
|
? countsArray.map((t) => {
|
||||||
|
if (t.area === tagData[0].reader) {
|
||||||
|
return {...t, timesHere: t.timesHere + 1};
|
||||||
|
} else {
|
||||||
|
return {...t, area: tagData[i].reader, timesHere: 1};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
: [...countsArray, {area: tagData[i].reader, timesHere: 1}];
|
||||||
|
|
||||||
|
const updateTag = {
|
||||||
|
lastRead: new Date(tagData[i].timeStamp),
|
||||||
|
counts: updateCount, //jsonb("counts").notNull(), //.default([{area: 1, timesHere: 5}]).notNull(),
|
||||||
|
lastareaIn: tagData[i].reader,
|
||||||
|
antenna: tagData[i].antenna,
|
||||||
|
tagStrength: tagData[i].tagStrength,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await db.update(rfidTags).set(updateTag).where(eq(rfidTags.tagHex, tagData[0].tagHex)).returning({
|
||||||
|
tag: rfidTags.tag,
|
||||||
|
runningNumber: rfidTags.runningNumber,
|
||||||
|
counts: rfidTags.counts,
|
||||||
|
lastareaIn: rfidTags.lastareaIn,
|
||||||
|
});
|
||||||
|
createLog("info", "rfid", "rfid", `Tags were jusdt updated.`);
|
||||||
|
return {success: true, tag};
|
||||||
|
} catch (error) {
|
||||||
|
createLog("error", "rfid", "rfid", `${JSON.stringify(error)}`);
|
||||||
|
return {success: false, error};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -2,13 +2,12 @@ import {OpenAPIHono} from "@hono/zod-openapi";
|
|||||||
|
|
||||||
import mgtEvents from "./route/mgtEvents.js";
|
import mgtEvents from "./route/mgtEvents.js";
|
||||||
import tagInfo from "./route/tagInfo.js";
|
import tagInfo from "./route/tagInfo.js";
|
||||||
|
import addReader from "./route/addReader.js";
|
||||||
|
import updateReader from "./route/updateReader.js";
|
||||||
|
import manualTrigger from "./route/manualTagRead.js";
|
||||||
const app = new OpenAPIHono();
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
const routes = [
|
const routes = [mgtEvents, tagInfo, addReader, updateReader, manualTrigger] as const;
|
||||||
mgtEvents,
|
|
||||||
tagInfo,
|
|
||||||
// settings
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
// app.route("/server", modules);
|
// app.route("/server", modules);
|
||||||
const appRoutes = routes.forEach((route) => {
|
const appRoutes = routes.forEach((route) => {
|
||||||
|
|||||||
51
server/services/rfid/route/addReader.ts
Normal file
51
server/services/rfid/route/addReader.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||||
|
import {addReader} from "../controller/addReader.js";
|
||||||
|
import {authMiddleware} from "../../auth/middleware/authMiddleware.js";
|
||||||
|
import {responses} from "../../../globalUtils/routeDefs/responses.js";
|
||||||
|
import type {User} from "../../../types/users.js";
|
||||||
|
import {verify} from "hono/jwt";
|
||||||
|
|
||||||
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
|
export const ReaderBody = z.object({
|
||||||
|
reader: z.string().openapi({example: "wrapper1"}),
|
||||||
|
readerIP: z.string().openapi({example: "192.168.1.52"}),
|
||||||
|
});
|
||||||
|
|
||||||
|
app.openapi(
|
||||||
|
createRoute({
|
||||||
|
tags: ["rfid"],
|
||||||
|
summary: "Add new reader",
|
||||||
|
method: "post",
|
||||||
|
path: "/addreader",
|
||||||
|
middleware: authMiddleware,
|
||||||
|
description: "Adding in a new reader to add to the network.",
|
||||||
|
request: {
|
||||||
|
body: {content: {"application/json": {schema: ReaderBody}}},
|
||||||
|
},
|
||||||
|
responses: responses(),
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const body = await c.req.json();
|
||||||
|
const authHeader = c.req.header("Authorization");
|
||||||
|
|
||||||
|
const token = authHeader?.split("Bearer ")[1] || "";
|
||||||
|
let user: User;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const payload = await verify(token, process.env.JWT_SECRET!);
|
||||||
|
user = payload.user as User;
|
||||||
|
} catch (error) {
|
||||||
|
return c.json({message: "Unauthorized"}, 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const addingReader = await addReader(body, user);
|
||||||
|
return c.json({success: addingReader.success, message: addingReader.message}, 200);
|
||||||
|
} catch (error) {
|
||||||
|
return c.json({success: false, message: `${body.name} encountered an error while trying to be added`}, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default app;
|
||||||
40
server/services/rfid/route/manualTagRead.ts
Normal file
40
server/services/rfid/route/manualTagRead.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
//http://usday1vms006:4000/api/v1/zebra/wrapper1
|
||||||
|
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||||
|
import {responses} from "../../../globalUtils/routeDefs/responses.js";
|
||||||
|
import {readTags} from "../controller/readTags.js";
|
||||||
|
|
||||||
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
|
const ParamsSchema = z.object({
|
||||||
|
reader: z
|
||||||
|
.string()
|
||||||
|
.min(3)
|
||||||
|
.openapi({
|
||||||
|
param: {
|
||||||
|
name: "reader",
|
||||||
|
in: "path",
|
||||||
|
},
|
||||||
|
example: "1212121",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
app.openapi(
|
||||||
|
createRoute({
|
||||||
|
tags: ["rfid"],
|
||||||
|
summary: "Manual triggers the read function",
|
||||||
|
method: "post",
|
||||||
|
path: "/manualtrigger/{reader}",
|
||||||
|
request: {
|
||||||
|
params: ParamsSchema,
|
||||||
|
},
|
||||||
|
responses: responses(),
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const {reader} = c.req.valid("param");
|
||||||
|
const manualTrigger = await readTags(reader);
|
||||||
|
|
||||||
|
return c.json({success: true, message: `A Manaul trigger was done on ${reader}`}, 200);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default app;
|
||||||
@@ -2,12 +2,8 @@
|
|||||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||||
import {readTags} from "../controller/readTags.js";
|
import {readTags} from "../controller/readTags.js";
|
||||||
import {createLog} from "../../logger/logger.js";
|
import {createLog} from "../../logger/logger.js";
|
||||||
|
import {responses} from "../../../globalUtils/routeDefs/responses.js";
|
||||||
// Define the response schema
|
import {newHeartBeat} from "../controller/readerControl.js";
|
||||||
const responseSchema = z.object({
|
|
||||||
success: z.boolean().openapi({example: true}),
|
|
||||||
message: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const app = new OpenAPIHono();
|
const app = new OpenAPIHono();
|
||||||
let lastGpiTimestamp = 0;
|
let lastGpiTimestamp = 0;
|
||||||
@@ -28,64 +24,37 @@ const ParamsSchema = z.object({
|
|||||||
app.openapi(
|
app.openapi(
|
||||||
createRoute({
|
createRoute({
|
||||||
tags: ["rfid"],
|
tags: ["rfid"],
|
||||||
summary: "Adds a new module",
|
summary: "Post info from the reader",
|
||||||
method: "post",
|
method: "post",
|
||||||
path: "/mgtevents/{reader}",
|
path: "/mgtevents/{reader}",
|
||||||
request: {
|
request: {
|
||||||
params: ParamsSchema,
|
params: ParamsSchema,
|
||||||
},
|
},
|
||||||
responses: {
|
responses: responses(),
|
||||||
200: {
|
|
||||||
content: {
|
|
||||||
"application/json": {schema: responseSchema},
|
|
||||||
},
|
|
||||||
description: "Response message",
|
|
||||||
},
|
|
||||||
400: {
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: "Internal Server Error",
|
|
||||||
},
|
|
||||||
401: {
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: "Unauthorized",
|
|
||||||
},
|
|
||||||
500: {
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: "Internal Server Error",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
async (c) => {
|
async (c) => {
|
||||||
const {reader} = c.req.valid("param");
|
const {reader} = c.req.valid("param");
|
||||||
const body = await c.req.json();
|
const body = await c.req.json();
|
||||||
|
|
||||||
if (body.type === "heartbeat") {
|
if (body.type === "heartbeat") {
|
||||||
console.log("Heartbeat");
|
const heart = await newHeartBeat(reader);
|
||||||
|
return c.json({success: heart.success, message: heart.message}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body.type === "gpi" && body.data.state === "HIGH") {
|
if (body.type === "gpi" && body.data.state === "HIGH") {
|
||||||
const eventTimestamp = new Date(body.timestamp).getTime(); // Convert ISO timestamp to milliseconds
|
const eventTimestamp = new Date(body.timestamp).getTime(); // Convert ISO timestamp to milliseconds
|
||||||
|
if (eventTimestamp - lastGpiTimestamp > 5 * 1000) {
|
||||||
if (eventTimestamp - lastGpiTimestamp > 10) {
|
|
||||||
// Check if it's been more than 2ms
|
// Check if it's been more than 2ms
|
||||||
lastGpiTimestamp = eventTimestamp; // Update last seen timestamp
|
lastGpiTimestamp = eventTimestamp; // Update last seen timestamp
|
||||||
|
|
||||||
createLog("info", "rfid", "rfid", `${reader} is reading a tag.`);
|
createLog("info", "rfid", "rfid", `${reader} is reading a tag.`);
|
||||||
readTags(reader);
|
await readTags(reader);
|
||||||
} else {
|
} else {
|
||||||
console.log("Duplicate GPI event ignored.");
|
createLog("info", "rfid", "rfid", `A new trigger from ${reader} was to soon`);
|
||||||
|
lastGpiTimestamp = eventTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//console.log(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.json({success: true, message: `New info from ${reader}`}, 200);
|
return c.json({success: true, message: `New info from ${reader}`}, 200);
|
||||||
|
|||||||
@@ -2,12 +2,9 @@
|
|||||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||||
import {ConsoleLogWriter} from "drizzle-orm";
|
import {ConsoleLogWriter} from "drizzle-orm";
|
||||||
import {tagData} from "../controller/tagData.js";
|
import {tagData} from "../controller/tagData.js";
|
||||||
|
import {responses} from "../../../globalUtils/routeDefs/responses.js";
|
||||||
// Define the response schema
|
import {noRead} from "../controller/noRead.js";
|
||||||
const responseSchema = z.object({
|
import {badRead, goodRead} from "../controller/readerControl.js";
|
||||||
success: z.boolean().openapi({example: true}),
|
|
||||||
message: z.string().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const app = new OpenAPIHono();
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
@@ -27,44 +24,13 @@ const ParamsSchema = z.object({
|
|||||||
app.openapi(
|
app.openapi(
|
||||||
createRoute({
|
createRoute({
|
||||||
tags: ["rfid"],
|
tags: ["rfid"],
|
||||||
summary: "Adds a new module",
|
summary: "Tag info posted from the reader.",
|
||||||
method: "post",
|
method: "post",
|
||||||
path: "/taginfo/{reader}",
|
path: "/taginfo/{reader}",
|
||||||
request: {
|
request: {
|
||||||
params: ParamsSchema,
|
params: ParamsSchema,
|
||||||
},
|
},
|
||||||
responses: {
|
responses: responses(),
|
||||||
200: {
|
|
||||||
content: {
|
|
||||||
"application/json": {schema: responseSchema},
|
|
||||||
},
|
|
||||||
description: "Response message",
|
|
||||||
},
|
|
||||||
400: {
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: "Internal Server Error",
|
|
||||||
},
|
|
||||||
401: {
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: "Unauthorized",
|
|
||||||
},
|
|
||||||
500: {
|
|
||||||
content: {
|
|
||||||
"application/json": {
|
|
||||||
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: "Internal Server Error",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
async (c) => {
|
async (c) => {
|
||||||
const {reader} = c.req.valid("param");
|
const {reader} = c.req.valid("param");
|
||||||
@@ -74,18 +40,32 @@ app.openapi(
|
|||||||
|
|
||||||
for (let i = 0; i < body.length; i++) {
|
for (let i = 0; i < body.length; i++) {
|
||||||
const tag = Buffer.from(body[i].data.idHex, "hex").toString("utf-8");
|
const tag = Buffer.from(body[i].data.idHex, "hex").toString("utf-8");
|
||||||
if (tag.includes("ALPLA")) {
|
//console.log("Raw value:", body[i].data.peakRssi, "Parsed:", parseInt(body[i].data.peakRssi));
|
||||||
|
if (tag.includes("ALPLA") && parseInt(body[i].data.peakRssi) < -50) {
|
||||||
tagdata = [
|
tagdata = [
|
||||||
...tagdata,
|
...tagdata,
|
||||||
{tagHex: body[i].data.idHex, reader: reader, tag: tag, timeStamp: body[i].timestamp},
|
{
|
||||||
|
tagHex: body[i].data.idHex,
|
||||||
|
reader: reader,
|
||||||
|
tag: tag,
|
||||||
|
timeStamp: body[i].timestamp,
|
||||||
|
antenna: body[i].data.antenna,
|
||||||
|
tagStrength: body[i].data.peakRssi,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tagdata.length === 0) {
|
||||||
|
noRead(reader);
|
||||||
|
badRead(reader);
|
||||||
|
return c.json({success: false, message: `There were no tags scanned.`}, 200);
|
||||||
|
} else {
|
||||||
tagData(tagdata);
|
tagData(tagdata);
|
||||||
|
goodRead(reader);
|
||||||
return c.json({success: true, message: `New info from ${reader}`}, 200);
|
return c.json({success: true, message: `New info from ${reader}`}, 200);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export default app;
|
export default app;
|
||||||
|
|||||||
52
server/services/rfid/route/updateReader.ts
Normal file
52
server/services/rfid/route/updateReader.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||||
|
import {addReader} from "../controller/addReader.js";
|
||||||
|
import {authMiddleware} from "../../auth/middleware/authMiddleware.js";
|
||||||
|
import {responses} from "../../../globalUtils/routeDefs/responses.js";
|
||||||
|
import type {User} from "../../../types/users.js";
|
||||||
|
import {verify} from "hono/jwt";
|
||||||
|
|
||||||
|
const app = new OpenAPIHono();
|
||||||
|
|
||||||
|
export const ReaderBody = z.object({
|
||||||
|
reader: z.string().openapi({example: "wrapper1"}),
|
||||||
|
readerIP: z.string().openapi({example: "192.168.1.52"}),
|
||||||
|
active: z.boolean().optional().openapi({example: true}),
|
||||||
|
});
|
||||||
|
|
||||||
|
app.openapi(
|
||||||
|
createRoute({
|
||||||
|
tags: ["rfid"],
|
||||||
|
summary: "Add new reader",
|
||||||
|
method: "patch",
|
||||||
|
path: "/updatereader",
|
||||||
|
middleware: authMiddleware,
|
||||||
|
description: "Updates the reader data..",
|
||||||
|
request: {
|
||||||
|
body: {content: {"application/json": {schema: ReaderBody}}},
|
||||||
|
},
|
||||||
|
responses: responses(),
|
||||||
|
}),
|
||||||
|
async (c) => {
|
||||||
|
const body = await c.req.json();
|
||||||
|
const authHeader = c.req.header("Authorization");
|
||||||
|
|
||||||
|
const token = authHeader?.split("Bearer ")[1] || "";
|
||||||
|
let user: User;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const payload = await verify(token, process.env.JWT_SECRET!);
|
||||||
|
user = payload.user as User;
|
||||||
|
} catch (error) {
|
||||||
|
return c.json({message: "Unauthorized"}, 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const addingReader = await addReader(body, user);
|
||||||
|
return c.json({success: addingReader.success, message: addingReader.message}, 200);
|
||||||
|
} catch (error) {
|
||||||
|
return c.json({success: false, message: `${body.name} encountered an error while trying to be added`}, 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default app;
|
||||||
Reference in New Issue
Block a user