diff --git a/apps/api/package.json b/apps/api/package.json index ab014fc..20bad3c 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -8,11 +8,13 @@ "start": "bun run src/index.ts" }, "dependencies": { - "@elysiajs/cors": "^1.4.2", - "elysia": "^1.4.28", - "zipcodes-us": "^1.1.3", "@blade-and-brawn/calculator": "workspace:*", "@blade-and-brawn/commerce": "workspace:*", - "ml-levenberg-marquardt": "^5.0.1" + "@blade-and-brawn/domain": "workspace:*", + "@elysiajs/cors": "^1.4.2", + "elysia": "^1.4.29", + "ml-levenberg-marquardt": "^5.0.1", + "zipcodes-us": "^1.1.3", + "zod": "^4.4.3" } } diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index af52bec..5b850a4 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -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; diff --git a/apps/portal/package.json b/apps/portal/package.json index 9caa47c..8ce31d7 100644 --- a/apps/portal/package.json +++ b/apps/portal/package.json @@ -2,7 +2,7 @@ "name": "@blade-and-brawn/portal", "type": "module", "devDependencies": { - "@sveltejs/kit": "^2.65.1", + "@sveltejs/kit": "^2.66.0", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@types/bun": "^1.3.14", "svelte": "^5.56.3", @@ -22,9 +22,9 @@ "dependencies": { "@tailwindcss/vite": "^4.3.1", "daisyui": "^5.5.23", - "memoirist": "^0.4.0", "tailwindcss": "^4.3.1", "@blade-and-brawn/calculator": "workspace:*", - "@blade-and-brawn/commerce": "workspace:*" + "@blade-and-brawn/commerce": "workspace:*", + "@blade-and-brawn/domain": "workspace:*" } } diff --git a/apps/portal/src/lib/components/PlayersTable.svelte b/apps/portal/src/lib/components/PlayersTable.svelte index 3557404..46b9dff 100644 --- a/apps/portal/src/lib/components/PlayersTable.svelte +++ b/apps/portal/src/lib/components/PlayersTable.svelte @@ -1,16 +1,18 @@