Move domain models into domain package with schemas and validate with zod + elysia. Some maintenence as well

This commit is contained in:
Dominic Ferrando
2026-06-22 13:59:04 -04:00
parent ed5abac209
commit 6fa3d78571
16 changed files with 220 additions and 166 deletions
+38 -19
View File
@@ -2,9 +2,14 @@ import {
DEFAULT_STANDARDS_DATA,
LevelCalculator,
Standards,
} from "@blade-and-brawn/calculator";
import {
ActivityPerformanceSchema,
PlayerSchema,
type ActivityPerformance,
type Player,
} from "@blade-and-brawn/calculator";
} from "@blade-and-brawn/domain"
import { cors } from "@elysiajs/cors";
import { Elysia, NotFoundError } from "elysia";
import {
@@ -16,6 +21,7 @@ import {
FetchError,
} from "@blade-and-brawn/commerce";
import zipcodesUs from "zipcodes-us";
import z from "zod";
const levelCalculator = new LevelCalculator(
new Standards(DEFAULT_STANDARDS_DATA),
@@ -25,13 +31,18 @@ export const app = new Elysia()
.use(
cors({
origin: [
// bladeandbrawn.com (apex + any subdomain)
// WEBSITE
// -----------
// production
/^https?:\/\/([a-z0-9-]+\.)?bladeandbrawn\.com$/i,
// Webflow preview domains
// testing
/^https?:\/\/([a-z0-9-]+\.)?bladeandbrawn\.webflow\.io$/i,
// Fly app host (this one already works)
// PORTAL
// -----------
// production
/^https?:\/\/blade-and-brawn\.fly\.dev$/i,
// Local dev portal
// development
"http://localhost:5173",
],
}),
@@ -65,14 +76,9 @@ export const app = new Elysia()
// CALCULATOR
.post("/calculate", async ({ body, query }) => {
interface CalcRequest {
player: Player;
activityPerformances: ActivityPerformance[];
}
const { player, activityPerformances } = body as CalcRequest;
.post("/calculate", async ({ body }) => {
const output = {
levels: levelCalculator.calculate(player, activityPerformances),
levels: levelCalculator.calculate(body.player, body.activityPerformances),
};
// console.log({ log: query?.log });
@@ -85,6 +91,11 @@ export const app = new Elysia()
// }
return output;
}, {
body: z.object({
player: PlayerSchema,
activityPerformances: z.array(ActivityPerformanceSchema)
})
})
// COMMERCE
@@ -93,18 +104,26 @@ export const app = new Elysia()
app
.group("/sync", (app) =>
app
.get("/", async ({}) => SyncService.state)
.post("/:printfulProductId?", async ({ params, set }) => {
// Sync status
.get("/", async ({ }) => SyncService.state)
// Full sync
.post("/", async ({ set }) => {
if (SyncService.state.isSyncing) {
set.status = 409;
return { error: "Sync already in progress" };
}
const printfulProductId = params.printfulProductId
? +params.printfulProductId
: undefined;
await SyncService.sync(printfulProductId);
await SyncService.sync();
return { ok: true };
}),
})
// Per-product sync
.post("/:printfulProductId", async ({ params, set }) => {
if (SyncService.state.isSyncing) {
set.status = 409;
return { error: "Sync already in progress" };
}
await SyncService.sync(params.printfulProductId);
return { ok: true };
}, { params: z.object({ printfulProductId: z.number() }) }),
)
.get("/:printfulProductId", async ({ params }) => {
const printfulProductId = +params.printfulProductId;