Services refactor

This commit is contained in:
Dominic Ferrando
2026-06-23 15:36:53 -04:00
parent 5bae0f067d
commit 720aa61c66
6 changed files with 502 additions and 638 deletions
+37 -22
View File
@@ -11,9 +11,9 @@ import {
import { cors } from "@elysiajs/cors";
import { Elysia, NotFoundError, status } from "elysia";
import {
PrintfulService,
SyncService,
WebflowService,
PrintfulClient,
ProductSyncer,
WebflowClient,
Printful,
Webflow,
FetchError,
@@ -21,10 +21,28 @@ import {
import zipcodesUs from "zipcodes-us";
import z from "zod";
// SERVICES
// -----------
const levelCalculator = new LevelCalculator(
new Standards(DEFAULT_STANDARDS_DATA),
);
const printful = new PrintfulClient({
token: Bun.env.PRINTFUL_AUTH!,
storeId: Bun.env.PRINTFUL_STORE_ID!,
});
const webflow = new WebflowClient({
siteId: Bun.env.WEBFLOW_SITE_ID!,
collectionsId: Bun.env.WEBFLOW_COLLECTION_ID!,
token: Bun.env.WEBFLOW_AUTH!,
webhookSecret: Bun.env.WEBFLOW_WEBHOOK_SECRET!,
});
const productSyncer = new ProductSyncer(printful, webflow);
// ELYSIA
// -----------
export const app = new Elysia()
.use(
cors({
@@ -105,42 +123,39 @@ export const app = new Elysia()
.group("/sync", (app) =>
app
// Sync status
.get("/", async ({ }) => await SyncService.getState())
.get("/", async ({ }) => await productSyncer.getState())
// Full sync
.post("/", async ({ }) => {
const syncState = await SyncService.getState();
const syncState = await productSyncer.getState();
if (syncState.isSyncing)
return status(409, { error: "Sync already in progress" });
await SyncService.sync();
await productSyncer.sync();
return { ok: true };
})
// Per-product sync
.post("/:printfulProductId", async ({ params }) => {
const syncState = await SyncService.getState();
const syncState = await productSyncer.getState();
if (syncState.isSyncing)
return status(409, { error: "Sync already in progress" });
await SyncService.sync(params.printfulProductId);
await productSyncer.sync(params.printfulProductId);
return { ok: true };
}, { params: z.object({ printfulProductId: z.number() }) }),
)
// TODO: add schema validation
.get("/:printfulProductId", async ({ params }) => {
const printfulProductId = +params.printfulProductId;
const printfulProduct =
await PrintfulService.Products.get(printfulProductId);
if (!printfulProduct) {
return new NotFoundError();
}
await printful.Products.get(printfulProductId);
if (!printfulProduct) return new NotFoundError();
const webflowProductId =
printfulProduct.sync_product.external_id.split("-")[0];
if (!webflowProductId) {
return new NotFoundError();
}
if (!webflowProductId) return new NotFoundError();
const webflowProduct =
await WebflowService.Products.get(webflowProductId);
await webflow.Products.get(webflowProductId);
return { printfulProduct, webflowProduct };
}),
@@ -153,11 +168,11 @@ export const app = new Elysia()
switch (payload.type) {
case Printful.Webhook.Event.ProductUpdated: {
const printfulProduct = payload.data.sync_product;
await SyncService.sync(printfulProduct.id);
await productSyncer.sync(printfulProduct.id);
break;
}
case Printful.Webhook.Event.ProductDeleted: {
await WebflowService.Products.remove(
await webflow.Products.remove(
payload.data.sync_product.external_id,
);
break;
@@ -166,12 +181,12 @@ export const app = new Elysia()
const webflowOrderId = payload.data.order.external_id;
const shipInfo = payload.data.shipment;
await WebflowService.Orders.update(webflowOrderId, {
await webflow.Orders.update(webflowOrderId, {
shippingTrackingURL: shipInfo.tracking_url,
shippingTracking: shipInfo.tracking_number,
shippingProvider: shipInfo.carrier,
});
await WebflowService.Orders.fulfill(webflowOrderId, {
await webflow.Orders.fulfill(webflowOrderId, {
sendOrderFulfilledEmail: true,
});
break;
@@ -181,7 +196,7 @@ export const app = new Elysia()
return { ok: true };
})
.post("/webhook/webflow", async ({ request, body, set }) => {
if (!WebflowService.Util.verifyWebflowSignature(request, body)) {
if (!webflow.Util.verifyWebflowSignature(request, body)) {
set.status = 400;
return "Invalid signature";
}
@@ -192,7 +207,7 @@ export const app = new Elysia()
case Webflow.Webhook.Event.OrderCreated: {
const webflowOrder = payload.payload;
await PrintfulService.Orders.create({
await printful.Orders.create({
external_id: webflowOrder.orderId,
// TODO: derive from webflow
shipping: "STANDARD",