Services
All business logic lives in src/lib/server/services/. Each service is a singleton class.
Product Service
Manages products and their variants. Returns ResolvedProduct with flat translated fields.
import { productService } from "$lib/server/services/products";
// Get by ID or slug — returns resolved flat fields
const product = await productService.getById(123);
const product = await productService.getBySlug("blue-shirt");
product.name; // "Blue Shirt" (resolved from translations)
// List with pagination
const { items, total } = await productService.list({
limit: 20
});
// Search
const results = await productService.list({ search: "shirt" });
// CRUD
await productService.create({ slug: "new-product" /* ... */ });
await productService.update(123, {
/* ... */
});
await productService.delete(123);Variant operations (stock, pricing, SKU management) are also handled through productService.
Order Service
Manages the full order lifecycle, including cart operations.
import { orderService } from "$lib/server/services/orders";
// Cart operations (orders in "created" state act as carts)
const cart = await orderService.getOrCreateActiveCart({ cartToken, customerId });
await orderService.addLine(orderId, { variantId, quantity });
await orderService.updateLineQuantity(orderId, lineId, quantity);
await orderService.removeLine(orderId, lineId);
// State transitions (all go through transitionState)
await orderService.transitionState(orderId, "payment_pending");
await orderService.transitionState(orderId, "paid");
await orderService.transitionState(orderId, "shipped");
await orderService.transitionState(orderId, "delivered");
await orderService.transitionState(orderId, "cancelled");
// Checkout
await orderService.setShippingAddress(orderId, address);
await orderService.setCustomerEmail(orderId, email);
await orderService.updateTotals(orderId);
// Query
const order = await orderService.getByCode("ORD-2024-001");Customer Service
import { customerService } from "$lib/server/services/customers";
// Create from auth user
const customer = await customerService.getOrCreateFromAuth(authUser);
// Query
const customer = await customerService.getByEmail("user@example.com");Translation Service
Manages translations for all 7 translatable entities. Uses Drizzle’s onConflictDoUpdate for upserts.
import { translationService } from "$lib/server/services/translations";
// Get translations for an entity
const rows = await translationService.getProductTranslations(productId);
// Upsert a translation (insert or update)
await translationService.upsertProductTranslation(productId, "fi", {
name: "Sininen paita",
slug: "sininen-paita",
description: "<p>Hieno paita</p>"
});
// Bulk methods for list pages
const allCategoryTranslations = await translationService.getAllCategoryTranslations();
const facetValueTranslations = await translationService.getAllFacetValueTranslations(facetId);See Localization for the full API and admin UI integration.
Other Services
See src/lib/server/services/ for all available services including:
taxService— Tax rate lookups and calculationspaymentService— Payment provider orchestrationshippingService— Shipping provider orchestrationcollectionService— Product collectionspromotionService— Discount and promotion rulesreservationService— Stock reservationscustomerGroupService— Customer group managementcontentPageService— CMS content pagestranslationService— Multi-language translations for all entitiesassetService— Image/file managementwishlistService— Customer wishlistsreviewService— Product reviews
Last updated on