import { fromPrice, paramsSchemaSchema, pricingSchema, slotConfigSchema, type CategoryCode, type ParamsSchema, type Pricing, type SlotConfig, } from '@barev/core'; import type { Db, Service, Tx } from '@barev/db'; import { DomainError } from './context.ts'; export interface ParsedService { id: string; code: string; category: CategoryCode; categoryDiscountPct: number; flow: Service['flow']; providerRole: Service['providerRole']; pricing: Pricing; paramsSchema: ParamsSchema; slotConfig: SlotConfig; lateCancelFeePct: number; isOnline: boolean; active: boolean; fromPrice: number; } type ServiceWithCategory = Service & { category: { code: CategoryCode; barevPlusDiscountPct: number } }; export function parseService(s: ServiceWithCategory): ParsedService { const pricing = pricingSchema.parse(s.pricing); return { id: s.id, code: s.code, category: s.category.code, categoryDiscountPct: s.category.barevPlusDiscountPct, flow: s.flow, providerRole: s.providerRole, pricing, paramsSchema: paramsSchemaSchema.parse(s.paramsSchema), slotConfig: slotConfigSchema.parse(s.slotConfig), lateCancelFeePct: s.lateCancelFeePct, isOnline: s.isOnline, active: s.active, fromPrice: fromPrice(pricing), }; } /** Каталог для лендинга и Mini App: все направления, у услуг — «от N ֏» и признак доступности */ export async function listCatalog(db: Db) { const categories = await db.category.findMany({ orderBy: { sortOrder: 'asc' }, include: { services: { orderBy: { sortOrder: 'asc' }, include: { category: true } } }, }); return categories.map((c) => ({ code: c.code, barevPlusDiscountPct: c.barevPlusDiscountPct, services: c.services.map((s) => { const p = parseService(s); return { code: p.code, flow: p.flow, fromPrice: p.fromPrice, active: p.active, isOnline: p.isOnline }; }), })); } export async function getServiceByCode(db: Db | Tx, code: string, opts: { activeOnly?: boolean } = {}): Promise { const s = await db.service.findUnique({ where: { code }, include: { category: true } }); if (!s) throw new DomainError('NOT_FOUND'); if (opts.activeOnly && !s.active) throw new DomainError('SERVICE_UNAVAILABLE'); return parseService(s); }