@infuro/cms-core 1.0.23 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugins/erp/erp-queue.ts","../src/plugins/erp/erp-config-enabled.ts","../src/plugins/email/email-queue.ts","../src/plugins/erp/erp-response-map.ts","../src/plugins/erp/erp-order-invoice.ts","../src/plugins/erp/paid-order-erp.ts","../src/api/crud.ts","../src/plugins/erp/erp-contact-sync.ts","../src/plugins/erp/erp-product-sync.ts","../src/lib/link-contact-to-user.ts","../src/api/auth-handlers.ts","../src/api/cms-handlers.ts","../src/plugins/captcha/assert.ts","../src/entities/llm-agent.entity.ts","../src/lib/media-folder-path.ts","../src/lib/media-parent-path.ts","../src/lib/media-zip-extract.ts","../src/api/llm-agent-knowledge-handlers.ts","../src/message-templates/sms-defaults.ts","../src/api/message-template-admin-handlers.ts","../src/auth/permission-entities.ts","../src/auth/helpers.ts","../src/api/admin-roles-handlers.ts","../src/entities/user.entity.ts","../src/entities/user-group.entity.ts","../src/entities/permission.entity.ts","../src/entities/otp-challenge.entity.ts","../src/entities/password-reset-token.entity.ts","../src/entities/blog.entity.ts","../src/entities/category.entity.ts","../src/entities/seo.entity.ts","../src/entities/comment.entity.ts","../src/entities/tag.entity.ts","../src/entities/contact.entity.ts","../src/entities/form-submission.entity.ts","../src/entities/form.entity.ts","../src/entities/form-field.entity.ts","../src/entities/address.entity.ts","../src/entities/order.entity.ts","../src/entities/payment.entity.ts","../src/entities/chat-conversation.entity.ts","../src/entities/chat-message.entity.ts","../src/entities/config.entity.ts","../src/entities/message-template.entity.ts","../src/entities/media.entity.ts","../src/entities/page.entity.ts","../src/entities/product-category.entity.ts","../src/entities/collection.entity.ts","../src/entities/brand.entity.ts","../src/entities/product.entity.ts","../src/entities/attribute.entity.ts","../src/entities/product-attribute.entity.ts","../src/entities/tax.entity.ts","../src/entities/product-tax.entity.ts","../src/entities/order-item.entity.ts","../src/entities/knowledge-base-document.entity.ts","../src/entities/knowledge-base-chunk.entity.ts","../src/entities/cart.entity.ts","../src/entities/cart-item.entity.ts","../src/entities/wishlist.entity.ts","../src/entities/wishlist-item.entity.ts","../src/entities/llm-agent-knowledge-document.entity.ts","../src/entities/index.ts","../src/api/cms-api-handler.ts","../src/api/storefront-handlers.ts","../src/lib/is-valid-signup-email.ts","../src/lib/order-number.ts","../src/lib/order-storefront-metadata.ts","../src/plugins/erp/erp-order-status-map.ts","../src/plugins/erp/erp-order-sync.ts","../src/plugins/sms/sms-queue.ts","../src/lib/otp-challenge.ts"],"sourcesContent":["import type { ERPSubmissionService } from './erp-submission';\r\nimport type { ContactFormData, ErpCreateContactPayload } from './erp-submission';\r\n\r\nexport interface CmsAppLike {\r\n getPlugin(name: string): unknown;\r\n}\r\n\r\nconst ERP_QUEUE_NAME = 'erp';\r\n\r\nexport type ErpJobPayload =\r\n | { kind: 'lead'; contact: ContactFormData }\r\n | { kind: 'formOpportunity'; contact: ContactFormData }\r\n | { kind: 'createContact'; contact: ErpCreateContactPayload }\r\n | { kind: 'order'; order: Record<string, unknown> }\r\n | { kind: 'productUpsert'; product: Record<string, unknown> };\r\n\r\nexport async function queueErp(cms: CmsAppLike, payload: ErpJobPayload): Promise<void> {\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void> } | undefined;\r\n if (!queue) return;\r\n await queue.add(ERP_QUEUE_NAME, payload as object);\r\n}\r\n\r\nexport function registerErpQueueProcessor(cms: CmsAppLike): void {\r\n const queue = cms.getPlugin('queue') as\r\n | { registerProcessor: (name: string, fn: (data: object) => Promise<void>) => void }\r\n | undefined;\r\n if (!queue) return;\r\n queue.registerProcessor(ERP_QUEUE_NAME, async (data: object) => {\r\n const erp = cms.getPlugin('erp') as { submission: ERPSubmissionService } | undefined;\r\n if (!erp) return;\r\n const payload = data as ErpJobPayload;\r\n if (payload.kind === 'lead') {\r\n await erp.submission.submitContact(payload.contact);\r\n } else if (payload.kind === 'formOpportunity') {\r\n await erp.submission.submitFormOpportunity(payload.contact);\r\n } else if (payload.kind === 'createContact') {\r\n await erp.submission.submitCreateContact(payload.contact);\r\n } else if (payload.kind === 'order') {\r\n await erp.submission.submitOrder(payload.order);\r\n } else if (payload.kind === 'productUpsert') {\r\n await erp.submission.submitProductUpsert(payload.product);\r\n }\r\n });\r\n}\r\n","import type { ObjectLiteral } from 'typeorm';\r\n\r\nexport type CmsAppLike = { getPlugin(name: string): unknown };\r\n\r\nexport type ErpConfigDataSource = {\r\n getRepository(entity: unknown): {\r\n find(options?: object): Promise<unknown[]>;\r\n };\r\n};\r\n\r\n/** True when ERP plugin is loaded and config `erp.enabled` is not `'false'`. */\r\nexport async function isErpIntegrationEnabled(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>\r\n): Promise<boolean> {\r\n if (!cms.getPlugin('erp')) return false;\r\n const configRepo = dataSource.getRepository(entityMap.configs);\r\n const cfgRows = await configRepo.find({ where: { settings: 'erp', deleted: false } as ObjectLiteral });\r\n for (const row of cfgRows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'enabled' && r.value === 'false') return false;\r\n }\r\n return true;\r\n}\r\n","import type { CompanyDetails, EmailTemplateName, OrderPlacedLineItem } from './templates/types';\r\n\r\nexport interface CmsAppLike {\r\n getPlugin(name: string): unknown;\r\n}\r\n\r\n/** Context for template rendering: at least companyDetails; template-specific fields (formName, etc.) are allowed. */\r\nexport interface EmailJobPayload {\r\n to: string;\r\n templateName?: EmailTemplateName;\r\n ctx?: Record<string, unknown> & { companyDetails: CompanyDetails };\r\n subject?: string;\r\n html?: string;\r\n text?: string;\r\n}\r\n\r\nconst EMAIL_QUEUE_NAME = 'email';\r\n\r\nexport function registerEmailQueueProcessor(cms: CmsAppLike): void {\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void>; registerProcessor: (name: string, fn: (data: object) => Promise<void>) => void } | undefined;\r\n const email = cms.getPlugin('email') as { send: (opts: { to: string; subject: string; html: string; text?: string }) => Promise<boolean>; renderTemplate: (name: string, ctx: unknown) => { subject: string; html: string; text?: string } } | undefined;\r\n if (!queue || !email) return;\r\n queue.registerProcessor(EMAIL_QUEUE_NAME, async (data: object) => {\r\n const payload = data as EmailJobPayload;\r\n const { to, templateName, ctx, subject, html, text } = payload;\r\n if (!to) return;\r\n if (templateName && ctx) {\r\n const rendered = email.renderTemplate(templateName, ctx);\r\n await email.send({ to, subject: rendered.subject, html: rendered.html, text: rendered.text });\r\n } else if (subject != null && html != null) {\r\n await email.send({ to, subject, html, text });\r\n }\r\n });\r\n}\r\n\r\nexport async function queueEmail(cms: CmsAppLike, payload: EmailJobPayload): Promise<void> {\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void> } | undefined;\r\n if (queue) {\r\n await queue.add(EMAIL_QUEUE_NAME, payload);\r\n return;\r\n }\r\n const email = cms.getPlugin('email') as { send: (opts: { to: string; subject: string; html: string; text?: string }) => Promise<boolean>; renderTemplate: (name: string, ctx: unknown) => { subject: string; html: string; text?: string } } | undefined;\r\n if (email && payload.templateName && payload.ctx) {\r\n const rendered = email.renderTemplate(payload.templateName, payload.ctx);\r\n await email.send({ to: payload.to, subject: rendered.subject, html: rendered.html, text: rendered.text });\r\n } else if (email && payload.subject != null && payload.html != null) {\r\n await email.send({ to: payload.to, subject: payload.subject, html: payload.html, text: payload.text });\r\n }\r\n}\r\n\r\nexport interface OrderPlacedEmailPayload {\r\n orderNumber: string;\r\n total?: string | number;\r\n subtotal?: string | number;\r\n tax?: string | number;\r\n currency?: string;\r\n customerName?: string;\r\n /** Customer receipt; omitted if empty */\r\n customerEmail?: string | null;\r\n /** Parsed list from email plugin “Sales team” settings */\r\n salesTeamEmails: string[];\r\n companyDetails: CompanyDetails;\r\n lineItems: OrderPlacedLineItem[];\r\n billingAddress?: Record<string, string>;\r\n shippingAddress?: Record<string, string>;\r\n}\r\n\r\n/** Queues one `orderPlaced` email per recipient (customer + each unique sales address; skips sales if same as customer). */\r\nexport async function queueOrderPlacedEmails(cms: CmsAppLike, payload: OrderPlacedEmailPayload): Promise<void> {\r\n const {\r\n orderNumber,\r\n total,\r\n subtotal,\r\n tax,\r\n currency,\r\n customerName,\r\n customerEmail,\r\n salesTeamEmails,\r\n companyDetails,\r\n lineItems,\r\n billingAddress,\r\n shippingAddress,\r\n } = payload;\r\n const base = {\r\n orderNumber,\r\n total: total != null ? String(total) : undefined,\r\n subtotal: subtotal != null ? String(subtotal) : undefined,\r\n tax: tax != null ? String(tax) : undefined,\r\n currency,\r\n customerName,\r\n companyDetails: companyDetails ?? {},\r\n lineItems: lineItems ?? [],\r\n billingAddress,\r\n shippingAddress,\r\n };\r\n const customerLower = customerEmail?.trim().toLowerCase() ?? '';\r\n const jobs: Promise<void>[] = [];\r\n if (customerEmail?.trim()) {\r\n jobs.push(\r\n queueEmail(cms, {\r\n to: customerEmail.trim(),\r\n templateName: 'orderPlaced',\r\n ctx: { ...base, audience: 'customer' as const },\r\n })\r\n );\r\n }\r\n const seen = new Set<string>();\r\n for (const raw of salesTeamEmails) {\r\n const to = raw.trim();\r\n if (!to) continue;\r\n const key = to.toLowerCase();\r\n if (seen.has(key)) continue;\r\n seen.add(key);\r\n if (customerLower && key === customerLower) continue;\r\n jobs.push(\r\n queueEmail(cms, {\r\n to,\r\n templateName: 'orderPlaced',\r\n ctx: {\r\n ...base,\r\n audience: 'sales' as const,\r\n internalCustomerEmail: customerEmail?.trim() || undefined,\r\n },\r\n })\r\n );\r\n }\r\n await Promise.all(jobs);\r\n}\r\n","import type { OrderFulfillmentEvent, OrderFulfillmentMetadata } from '../../lib/order-storefront-metadata';\r\n\r\nfunction pickString(o: Record<string, unknown>, keys: string[]): string | undefined {\r\n for (const k of keys) {\r\n const v = o[k];\r\n if (typeof v === 'string' && v.trim()) return v.trim();\r\n }\r\n return undefined;\r\n}\r\n\r\nexport function unwrapErpReadData(json: unknown): Record<string, unknown> | null {\r\n if (!json || typeof json !== 'object') return null;\r\n const o = json as Record<string, unknown>;\r\n const d = o.data;\r\n if (d && typeof d === 'object' && !Array.isArray(d)) return d as Record<string, unknown>;\r\n return o;\r\n}\r\n\r\nfunction firstObject(\r\n data: Record<string, unknown>,\r\n keys: string[]\r\n): Record<string, unknown> | null {\r\n for (const k of keys) {\r\n const v = data[k];\r\n if (v && typeof v === 'object' && !Array.isArray(v)) return v as Record<string, unknown>;\r\n }\r\n return null;\r\n}\r\n\r\nfunction extractEvents(src: Record<string, unknown>): OrderFulfillmentEvent[] | undefined {\r\n const timeline = src.timeline ?? src.events ?? src.history ?? src.trackingEvents;\r\n if (!Array.isArray(timeline) || !timeline.length) return undefined;\r\n const events: OrderFulfillmentEvent[] = [];\r\n for (const row of timeline) {\r\n if (!row || typeof row !== 'object') continue;\r\n const r = row as Record<string, unknown>;\r\n const at =\r\n pickString(r, ['at', 'timestamp', 'date', 'occurredAt']) ??\r\n (r.at instanceof Date ? (r.at as Date).toISOString() : undefined);\r\n const label = pickString(r, ['label', 'status', 'title', 'message', 'description']);\r\n const detail = pickString(r, ['detail', 'notes', 'description']);\r\n if (at || label || detail) events.push({ at, label, detail });\r\n }\r\n return events.length ? events : undefined;\r\n}\r\n\r\nexport function mapErpPayloadToFulfillment(data: Record<string, unknown>): OrderFulfillmentMetadata | undefined {\r\n const nested = firstObject(data, ['fulfillment', 'packaging', 'shipment', 'shipping', 'delivery']);\r\n const src = nested || data;\r\n const status = pickString(src, ['status', 'fulfillmentStatus', 'state', 'label', 'packagingStatus']);\r\n const trackingId = pickString(src, ['trackingId', 'tracking_id', 'trackingNumber', 'awb', 'trackingUrl']);\r\n const events = extractEvents(src);\r\n if (!status && !trackingId && !(events && events.length)) return undefined;\r\n return { status, trackingId, events };\r\n}\r\n\r\nexport function mapErpPayloadToInvoiceNumber(data: Record<string, unknown>): string | undefined {\r\n const nested = firstObject(data, ['invoice', 'latestInvoice', 'postedInvoice']);\r\n const src = nested || data;\r\n return pickString(src, ['invoiceNumber', 'invoice_number', 'number', 'name', 'id']);\r\n}\r\n\r\nexport type ErpChildOrderRef = { ref: string; orderKind: 'return' | 'replacement' };\r\n\r\nexport function extractChildOrderRefsFromSalePayload(data: Record<string, unknown>): ErpChildOrderRef[] {\r\n const lists = [data.returns, data.returnOrders, data.relatedReturns, data.childOrders, data.children];\r\n const seen = new Set<string>();\r\n const out: ErpChildOrderRef[] = [];\r\n for (const list of lists) {\r\n if (!Array.isArray(list)) continue;\r\n for (const item of list) {\r\n if (!item || typeof item !== 'object') continue;\r\n const o = item as Record<string, unknown>;\r\n const ref =\r\n pickString(o, ['platformReturnId', 'platform_return_id', 'refId', 'ref_id']) ??\r\n (typeof o.id === 'string' ? o.id : undefined);\r\n if (!ref || seen.has(ref)) continue;\r\n seen.add(ref);\r\n const t = (pickString(o, ['kind', 'type', 'orderKind']) || '').toLowerCase();\r\n const orderKind: 'return' | 'replacement' = /replac/.test(t) ? 'replacement' : 'return';\r\n out.push({ ref, orderKind });\r\n }\r\n }\r\n return out;\r\n}\r\n","import type { ObjectLiteral, Repository } from 'typeorm';\r\nimport { unwrapErpReadData } from './erp-response-map';\r\nimport type { ERPSubmissionService } from './erp-submission';\r\nimport { isErpIntegrationEnabled, type CmsAppLike, type ErpConfigDataSource } from './erp-config-enabled';\r\n\r\nfunction pickInvoiceId(data: Record<string, unknown>): string | undefined {\r\n const nested =\r\n data.invoice && typeof data.invoice === 'object' && !Array.isArray(data.invoice)\r\n ? (data.invoice as Record<string, unknown>)\r\n : null;\r\n const src = nested || data;\r\n for (const k of ['invoiceId', 'invoice_id', 'id']) {\r\n const v = src[k];\r\n if (typeof v === 'string' && v.trim()) return v.trim();\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Streams invoice PDF for a **sale** order. Resolves `invoiceId` from order metadata or `get-invoice`.\r\n */\r\nexport async function streamOrderInvoicePdf(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>,\r\n orderId: number,\r\n options: { ownerContactId?: number }\r\n): Promise<Response> {\r\n const jsonErr = (msg: string, status: number) =>\r\n new Response(JSON.stringify({ error: msg }), {\r\n status,\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n\r\n const on = await isErpIntegrationEnabled(cms, dataSource, entityMap);\r\n if (!on) return jsonErr('Invoice not available', 503);\r\n\r\n const erp = cms.getPlugin('erp') as { submission: ERPSubmissionService } | undefined;\r\n if (!erp?.submission) return jsonErr('Invoice not available', 503);\r\n\r\n const orderRepo = dataSource.getRepository(entityMap.orders) as Repository<ObjectLiteral>;\r\n const order = await orderRepo.findOne({ where: { id: orderId, deleted: false } as ObjectLiteral });\r\n if (!order) return jsonErr('Not found', 404);\r\n\r\n const kind = (order.orderKind as string) || 'sale';\r\n if (kind !== 'sale') return jsonErr('Invoice only for sale orders', 400);\r\n\r\n if (options.ownerContactId != null && order.contactId !== options.ownerContactId) {\r\n return jsonErr('Not found', 404);\r\n }\r\n\r\n const meta =\r\n order.metadata && typeof order.metadata === 'object' && !Array.isArray(order.metadata)\r\n ? (order.metadata as Record<string, unknown>)\r\n : {};\r\n const inv = meta.invoice && typeof meta.invoice === 'object' && !Array.isArray(meta.invoice)\r\n ? (meta.invoice as Record<string, unknown>)\r\n : {};\r\n let invoiceId = typeof inv.invoiceId === 'string' ? inv.invoiceId.trim() : '';\r\n\r\n if (!invoiceId) {\r\n const refId = String(order.orderNumber || '');\r\n const r = await erp.submission.postErpReadAction('get-invoice', { platformOrderId: refId });\r\n const d = r.ok ? unwrapErpReadData(r.json) : null;\r\n invoiceId = d ? pickInvoiceId(d) || '' : '';\r\n }\r\n\r\n if (!invoiceId) return jsonErr('Invoice not ready', 404);\r\n\r\n const pdf = await erp.submission.fetchInvoicePdf(invoiceId);\r\n if (!pdf.ok || !pdf.buffer) return jsonErr(pdf.error || 'PDF fetch failed', 502);\r\n\r\n const filename = `invoice-${orderId}.pdf`;\r\n return new Response(pdf.buffer, {\r\n status: 200,\r\n headers: {\r\n 'Content-Type': pdf.contentType || 'application/pdf',\r\n 'Content-Disposition': `attachment; filename=\"${filename}\"`,\r\n },\r\n });\r\n}\r\n","import type { ObjectLiteral } from 'typeorm';\r\nimport { queueErp, type CmsAppLike } from './erp-queue';\r\n\r\n/**\r\n * Duck-typed DataSource so host apps (e.g. Next) can pass their own TypeORM instance\r\n * without duplicate-package type errors vs core’s node_modules/typeorm.\r\n */\r\nexport type ErpPaidOrderDataSource = {\r\n getRepository(entity: unknown): {\r\n find(options?: object): Promise<unknown[]>;\r\n findOne(options?: object): Promise<unknown | null>;\r\n };\r\n};\r\n\r\n/**\r\n * Entity map with `configs` and `orders` entries (e.g. ENTITY_MAP).\r\n * Typed as `Record<string, unknown>` so apps that cast their map to `Record<string, EntityTarget<…>>` still pass.\r\n */\r\nexport type ErpPaidOrderEntityMap = Record<string, unknown>;\r\n\r\nfunction roundMoney(major: number): number {\r\n return Math.round(major * 100) / 100;\r\n}\r\n\r\nfunction addressToWebhookDto(a: ObjectLiteral | null | undefined): Record<string, unknown> {\r\n if (!a) return {};\r\n return {\r\n line1: a.line1 ?? '',\r\n line2: a.line2 ?? '',\r\n city: a.city ?? '',\r\n state: a.state ?? '',\r\n postalCode: a.postalCode ?? '',\r\n country: a.country ?? '',\r\n };\r\n}\r\n\r\nfunction orderStatusLabel(status: string | undefined): string {\r\n const s = (status || '').toLowerCase();\r\n if (s === 'confirmed') return 'Confirmed';\r\n if (s === 'pending') return 'Pending';\r\n if (!status) return 'Pending';\r\n return status.charAt(0).toUpperCase() + status.slice(1);\r\n}\r\n\r\nfunction paymentRowToWebhookDto(p: ObjectLiteral, amountMajorOverride?: number): Record<string, unknown> {\r\n const currency = String(p.currency || 'INR');\r\n const amountMajor =\r\n amountMajorOverride != null && Number.isFinite(amountMajorOverride)\r\n ? amountMajorOverride\r\n : Number(p.amount);\r\n const meta = { ...((p.metadata as Record<string, unknown>) || {}) };\r\n delete meta.amount;\r\n delete meta.currency;\r\n return {\r\n id: String(p.externalReference || `payment_${p.id}`),\r\n amount: roundMoney(amountMajor),\r\n currency_code: currency,\r\n captured_at: p.paidAt\r\n ? new Date(p.paidAt as Date | string).toISOString()\r\n : new Date().toISOString(),\r\n provider_id: String(p.method || 'unknown'),\r\n data: { status: 'captured', ...meta },\r\n };\r\n}\r\n\r\n/**\r\n * Enqueues ERP `order.created` only when the order has at least one **completed** payment.\r\n * Include `payments` in the payload.\r\n */\r\nexport async function queueErpPaidOrderForOrderId(\r\n cms: CmsAppLike,\r\n dataSource: ErpPaidOrderDataSource,\r\n entityMap: ErpPaidOrderEntityMap,\r\n orderId: number\r\n): Promise<void> {\r\n try {\r\n const configRepo = dataSource.getRepository(entityMap.configs);\r\n const cfgRows = await configRepo.find({ where: { settings: 'erp', deleted: false } as ObjectLiteral });\r\n for (const row of cfgRows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'enabled' && r.value === 'false') return;\r\n }\r\n if (!cms.getPlugin('erp')) return;\r\n\r\n const orderRepo = dataSource.getRepository(entityMap.orders);\r\n const ord = await orderRepo.findOne({\r\n where: { id: orderId } as ObjectLiteral,\r\n relations: ['items', 'items.product', 'contact', 'billingAddress', 'shippingAddress', 'payments'],\r\n });\r\n if (!ord) return;\r\n const o = ord as ObjectLiteral;\r\n const okKind = o.orderKind === undefined || o.orderKind === null || o.orderKind === 'sale';\r\n if (!okKind) return;\r\n const rawPayments = (o.payments as ObjectLiteral[]) ?? [];\r\n const completedPayments = rawPayments.filter((pay) => pay.status === 'completed' && pay.deleted !== true);\r\n if (!completedPayments.length) return;\r\n\r\n const rawItems = (o.items as ObjectLiteral[]) ?? [];\r\n const lines = rawItems\r\n .filter((it) => it.product)\r\n .map((it) => {\r\n const p = it.product as ObjectLiteral;\r\n const sku = (p.sku as string) || `SKU-${p.id}`;\r\n const itemType =\r\n typeof it.productType === 'string' && it.productType.trim()\r\n ? String(it.productType).trim()\r\n : p.type === 'service'\r\n ? 'service'\r\n : 'product';\r\n return {\r\n sku,\r\n quantity: Number(it.quantity) || 1,\r\n unitPrice: Number(it.unitPrice),\r\n title: (p.name as string) || sku,\r\n discount: 0,\r\n tax: Number(it.tax) || 0,\r\n uom: (typeof it.uom === 'string' && it.uom.trim() ? it.uom : p.uom) || undefined,\r\n tax_code:\r\n typeof it.taxCode === 'string' && it.taxCode.trim() ? String(it.taxCode).trim() : undefined,\r\n hsn_number:\r\n (typeof it.hsn === 'string' && it.hsn.trim() ? it.hsn : p.hsn) || undefined,\r\n type: itemType,\r\n };\r\n });\r\n if (!lines.length) return;\r\n\r\n const contact = o.contact as ObjectLiteral | undefined;\r\n const orderTotalMajor = Number(o.total);\r\n const paymentDtos =\r\n completedPayments.length === 1 && Number.isFinite(orderTotalMajor)\r\n ? [paymentRowToWebhookDto(completedPayments[0]!, orderTotalMajor)]\r\n : completedPayments.map((pay) => paymentRowToWebhookDto(pay));\r\n const baseMeta =\r\n o.metadata && typeof o.metadata === 'object' && !Array.isArray(o.metadata)\r\n ? { ...(o.metadata as Record<string, unknown>) }\r\n : {};\r\n\r\n const orderDto: Record<string, unknown> = {\r\n platformType: 'website',\r\n platformOrderId: String(o.orderNumber),\r\n platformOrderNumber: String(o.orderNumber),\r\n order_date: o.createdAt ? new Date(o.createdAt as Date | string).toISOString() : undefined,\r\n status: orderStatusLabel(o.status as string | undefined),\r\n customer: {\r\n name: (contact?.name as string) || '',\r\n email: (contact?.email as string) || '',\r\n phone: (contact?.phone as string) || '',\r\n },\r\n shippingAddress: addressToWebhookDto(o.shippingAddress as ObjectLiteral),\r\n billingAddress: addressToWebhookDto(o.billingAddress as ObjectLiteral),\r\n items: lines,\r\n payments: paymentDtos,\r\n metadata: { ...baseMeta, source: 'storefront' },\r\n };\r\n\r\n await queueErp(cms, { kind: 'order', order: orderDto });\r\n } catch {\r\n /* non-fatal */\r\n }\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport { Brackets, ILike, MoreThan, Not } from 'typeorm';\r\nimport type { EntityMetadata, Repository } from 'typeorm';\r\nimport type { EntityCrudAction } from '../auth/permission-entities';\r\nimport { queueErpCreateContactIfEnabled } from '../plugins/erp/erp-contact-sync';\r\nimport { queueErpProductUpsertIfEnabled } from '../plugins/erp/erp-product-sync';\r\n\r\nexport type EntityMap = Record<string, import('typeorm').EntityTarget<import('typeorm').ObjectLiteral>>;\r\n\r\nexport interface CrudHandlerOptions {\r\n requireAuth: (req: Request) => Promise<Response | null>;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n requireEntityPermission?: (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;\r\n /** When set, contact create/update enqueues ERP `create-contact` (non-fatal). */\r\n getCms?: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n /** When set, soft-delete sets `deletedBy` from the current admin user. */\r\n getDeletedByUserId?: (req: Request) => Promise<number | null>;\r\n}\r\n\r\nconst CRUD_LOG = '[cms-crud]';\r\n\r\nfunction logCrudClientError(op: string, detail: Record<string, unknown>): void {\r\n console.warn(CRUD_LOG, op, detail);\r\n}\r\n\r\nfunction logCrudServerError(op: string, detail: Record<string, unknown>): void {\r\n console.error(CRUD_LOG, op, detail);\r\n}\r\n\r\n/** Recursive sum of `size` for all `file` descendants under each folder id (Postgres). */\r\nasync function aggregateMediaFolderFileSizes(dataSource: DataSource, folderIds: number[]): Promise<Map<number, number>> {\r\n const map = new Map<number, number>();\r\n if (folderIds.length === 0) return map;\r\n try {\r\n const rows = (await dataSource.query(\r\n `\r\n WITH RECURSIVE walk AS (\r\n SELECT m.\"parentId\" AS root_id, m.id, m.kind, m.size\r\n FROM media m\r\n WHERE m.\"parentId\" = ANY($1) AND m.deleted = false\r\n UNION ALL\r\n SELECT w.root_id, m.id, m.kind, m.size\r\n FROM walk w\r\n INNER JOIN media m ON m.\"parentId\" = w.id AND m.deleted = false\r\n )\r\n SELECT root_id AS \"rootId\", COALESCE(SUM(size) FILTER (WHERE kind = 'file'), 0)::bigint AS \"totalSize\"\r\n FROM walk\r\n GROUP BY root_id\r\n `,\r\n [folderIds]\r\n )) as { rootId: number; totalSize: string | number }[];\r\n for (const r of rows) {\r\n map.set(Number(r.rootId), Number(r.totalSize));\r\n }\r\n for (const id of folderIds) {\r\n if (!map.has(id)) map.set(id, 0);\r\n }\r\n } catch (err) {\r\n logCrudServerError('media folder size aggregate failed', {\r\n message: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n return map;\r\n}\r\n\r\nconst DATE_COLUMN_TYPES = new Set([\r\n 'date', 'datetime', 'datetime2', 'timestamp', 'timestamptz', 'timetz', 'smalldatetime', 'timestamp with time zone', 'timestamp without time zone',\r\n]);\r\n\r\nconst TIMESTAMP_PROP_NAMES = new Set(['createdAt', 'updatedAt', 'deletedAt']);\r\n\r\nfunction isInvalidDateValue(v: unknown): boolean {\r\n if (v === '' || v == null) return true;\r\n if (typeof v === 'string') return isNaN(Date.parse(v)) || /NaN|Invalid/i.test(v);\r\n if (v instanceof Date) return isNaN(v.getTime());\r\n return false;\r\n}\r\n\r\n/** Strip empty/invalid values for boolean, number, and date columns so DB defaults apply. */\r\nfunction sanitizeBodyForEntity(repo: Repository<import('typeorm').ObjectLiteral>, body: Record<string, unknown>): void {\r\n const meta = repo.metadata;\r\n for (const col of meta.columns) {\r\n if (!(col.propertyName in body)) continue;\r\n const v = body[col.propertyName];\r\n const t = typeof col.type === 'string' ? col.type : (col.type as Function)?.name ?? '';\r\n const isBoolean = t === 'boolean' || t === 'bool' || col.type === Boolean;\r\n const isNumber = ['int', 'integer', 'int2', 'int4', 'int8', 'smallint', 'bigint', 'number', 'Number'].includes(t) || col.type === Number;\r\n const isDate = DATE_COLUMN_TYPES.has(t) || col.type === Date || TIMESTAMP_PROP_NAMES.has(col.propertyName);\r\n if (v === '' && (isBoolean || isNumber)) {\r\n delete body[col.propertyName];\r\n } else if (isDate && isInvalidDateValue(v)) {\r\n delete body[col.propertyName];\r\n }\r\n }\r\n}\r\n\r\n/** Keep only scalar columns (excludes relations like tags) so repo.update() does not throw. */\r\nfunction pickColumnUpdates(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n body: Record<string, unknown>\r\n): Record<string, unknown> {\r\n const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));\r\n const out: Record<string, unknown> = {};\r\n for (const k of Object.keys(body)) {\r\n if (cols.has(k)) out[k] = body[k];\r\n }\r\n return out;\r\n}\r\n\r\n/** OR search on columns that exist on the entity (avoids Tag/Category etc. without `title`). */\r\nfunction buildSearchWhereClause(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n search: string\r\n): Record<string, unknown>[] | Record<string, unknown> {\r\n const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));\r\n const term = ILike(`%${search}%`);\r\n const ors: Record<string, unknown>[] = [];\r\n for (const field of ['name', 'title', 'slug', 'email', 'filename'] as const) {\r\n if (cols.has(field)) ors.push({ [field]: term });\r\n }\r\n if (ors.length === 0) return {};\r\n return ors.length === 1 ? ors[0]! : ors;\r\n}\r\n\r\nfunction entityHasSoftDelete(repo: Repository<import('typeorm').ObjectLiteral>): boolean {\r\n return repo.metadata.columns.some((c) => c.propertyName === 'deleted');\r\n}\r\n\r\nfunction mergeDeletedFalseWhere(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n where: Record<string, unknown>[] | Record<string, unknown>\r\n): Record<string, unknown>[] | Record<string, unknown> {\r\n if (!entityHasSoftDelete(repo)) return where;\r\n const d = { deleted: false };\r\n if (Array.isArray(where)) {\r\n if (where.length === 0) return [d];\r\n return where.map((w) => ({ ...w, ...d }));\r\n }\r\n return Object.keys(where).length > 0 ? { ...where, ...d } : d;\r\n}\r\n\r\nfunction normalizeProductSku(value: unknown): string | null {\r\n if (value == null) return null;\r\n const s = String(value).trim();\r\n return s === '' ? null : s;\r\n}\r\n\r\nasync function assertProductSkuUnique(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n sku: string,\r\n excludeId?: number\r\n): Promise<boolean> {\r\n const where: import('typeorm').ObjectLiteral =\r\n excludeId != null\r\n ? ({ sku, deleted: false, id: Not(excludeId) } as import('typeorm').ObjectLiteral)\r\n : ({ sku, deleted: false } as import('typeorm').ObjectLiteral);\r\n const row = await repo.findOne({ where });\r\n return row == null;\r\n}\r\n\r\nfunction buildSoftDeletePayload(meta: EntityMetadata, deletedBy: number | null): Record<string, unknown> {\r\n const payload: Record<string, unknown> = { deleted: true };\r\n if (meta.columns.some((c) => c.propertyName === 'deletedAt')) {\r\n payload.deletedAt = new Date();\r\n }\r\n if (deletedBy != null && meta.columns.some((c) => c.propertyName === 'deletedBy')) {\r\n payload.deletedBy = deletedBy;\r\n }\r\n return payload;\r\n}\r\n\r\nfunction makeContactErpSync(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n getCms: CrudHandlerOptions['getCms']\r\n): (row: import('typeorm').ObjectLiteral) => Promise<void> {\r\n return async function syncContactRowToErp(row: import('typeorm').ObjectLiteral): Promise<void> {\r\n if (!getCms) return;\r\n try {\r\n const cms = await getCms();\r\n const c = row as {\r\n name: string;\r\n email: string;\r\n phone?: string | null;\r\n type?: string | null;\r\n company?: string | null;\r\n notes?: string | null;\r\n };\r\n await queueErpCreateContactIfEnabled(cms, dataSource, entityMap, {\r\n name: c.name,\r\n email: c.email,\r\n phone: c.phone,\r\n type: c.type,\r\n company: c.company,\r\n notes: c.notes,\r\n });\r\n } catch {\r\n /* ignore */\r\n }\r\n };\r\n}\r\n\r\nexport function createCrudHandler(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n options: CrudHandlerOptions\r\n) {\r\n const { requireAuth, json, requireEntityPermission: reqPerm, getCms } = options;\r\n const syncContactRowToErp = makeContactErpSync(dataSource, entityMap, getCms);\r\n\r\n async function authz(req: Request, resource: string, action: EntityCrudAction): Promise<Response | null> {\r\n const authError = await requireAuth(req);\r\n if (authError) return authError;\r\n if (!reqPerm) {\r\n return json({ error: 'Forbidden', reason: 'entity_rbac_required', entity: resource, action }, { status: 403 });\r\n }\r\n const pe = await reqPerm(req, resource, action);\r\n if (pe) return pe;\r\n return null;\r\n }\r\n\r\n return {\r\n async GET(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'read');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('GET list', {\r\n reason: 'invalid_resource',\r\n resource,\r\n hasEntity: Boolean(entity),\r\n entityMapHasLlmAgents: Boolean(entityMap.llm_agents),\r\n entityMapKeyCount: Object.keys(entityMap).length,\r\n });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const { searchParams } = new URL(req.url);\r\n const page = Number(searchParams.get('page')) || 1;\r\n const limit = Math.min(Number(searchParams.get('limit')) || 10, 100);\r\n const skip = (page - 1) * limit;\r\n const sortFieldRaw = searchParams.get('sortField') || 'createdAt';\r\n const sortOrder = searchParams.get('sortOrder') === 'desc' ? 'DESC' : 'ASC';\r\n const search = searchParams.get('search');\r\n\r\n // Orders list: include contact + itemsSummary; search (order# + customer), status, date, paymentRef\r\n if (resource === 'orders') {\r\n const repo = dataSource.getRepository(entity);\r\n const allowedSort = ['id', 'orderNumber', 'contactId', 'status', 'total', 'currency', 'createdAt', 'updatedAt'];\r\n const sortField = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : 'createdAt';\r\n const sortOrderOrders = searchParams.get('sortOrder') === 'asc' ? 'ASC' : 'DESC';\r\n const statusFilter = searchParams.get('status')?.trim();\r\n const dateFrom = searchParams.get('dateFrom')?.trim();\r\n const dateTo = searchParams.get('dateTo')?.trim();\r\n const paymentRef = searchParams.get('paymentRef')?.trim();\r\n\r\n let orderIdsFromPayment: number[] | null = null;\r\n if (paymentRef && entityMap['payments']) {\r\n const paymentRepo = dataSource.getRepository(entityMap['payments']);\r\n const payments = await paymentRepo\r\n .createQueryBuilder('p')\r\n .select('p.orderId')\r\n .where('p.externalReference = :ref', { ref: paymentRef })\r\n .orWhere(\"p.metadata->>'razorpayPaymentId' = :ref\", { ref: paymentRef })\r\n .getRawMany<{ orderId: number }>();\r\n orderIdsFromPayment = payments.map((r) => r.orderId);\r\n if (orderIdsFromPayment.length === 0) {\r\n return json({ total: 0, page, limit, totalPages: 0, data: [] });\r\n }\r\n }\r\n\r\n const qb = repo\r\n .createQueryBuilder('order')\r\n .leftJoinAndSelect('order.contact', 'contact')\r\n .leftJoinAndSelect('order.items', 'items')\r\n .leftJoinAndSelect('items.product', 'product')\r\n .leftJoinAndSelect('product.collection', 'collection')\r\n .andWhere('order.deleted = :orderDel', { orderDel: false })\r\n .orderBy(`order.${sortField}`, sortOrderOrders)\r\n .skip(skip)\r\n .take(limit);\r\n\r\n if (search && typeof search === 'string' && search.trim()) {\r\n const term = `%${search.trim()}%`;\r\n qb.andWhere(\r\n '(order.orderNumber ILIKE :term OR contact.name ILIKE :term OR contact.email ILIKE :term)',\r\n { term }\r\n );\r\n }\r\n if (statusFilter) qb.andWhere('order.status = :status', { status: statusFilter });\r\n if (dateFrom) qb.andWhere('order.createdAt >= :dateFrom', { dateFrom: new Date(dateFrom + 'T00:00:00.000Z') });\r\n if (dateTo) qb.andWhere('order.createdAt <= :dateTo', { dateTo: new Date(dateTo + 'T23:59:59.999Z') });\r\n if (orderIdsFromPayment && orderIdsFromPayment.length) qb.andWhere('order.id IN (:...orderIds)', { orderIds: orderIdsFromPayment });\r\n\r\n const [rows, total] = await qb.getManyAndCount();\r\n const data = (rows as Record<string, unknown>[]).map((order: Record<string, unknown>) => {\r\n const contact = order.contact as Record<string, unknown> | undefined;\r\n const items = (order.items as Array<{ product?: { name?: string; collection?: { name?: string } }; quantity: number }>) ?? [];\r\n const itemsSummary = items\r\n .map((i) => {\r\n const label = i.product?.collection?.name ?? i.product?.name ?? 'Product';\r\n return `${label} × ${i.quantity}`;\r\n })\r\n .join(', ') || '—';\r\n return {\r\n ...order,\r\n contact: contact ? { id: contact.id, name: contact.name, email: contact.email, phone: contact.phone } : null,\r\n itemsSummary,\r\n };\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n // Payments list: include order + contact; search (customer), status, date, method, orderNumber\r\n if (resource === 'payments') {\r\n const repo = dataSource.getRepository(entity);\r\n const allowedSort = ['id', 'orderId', 'amount', 'currency', 'status', 'method', 'paidAt', 'createdAt', 'updatedAt'];\r\n const sortField = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : 'createdAt';\r\n const sortOrderPayments = searchParams.get('sortOrder') === 'asc' ? 'ASC' : 'DESC';\r\n const statusFilter = searchParams.get('status')?.trim();\r\n const dateFrom = searchParams.get('dateFrom')?.trim();\r\n const dateTo = searchParams.get('dateTo')?.trim();\r\n const methodFilter = searchParams.get('method')?.trim();\r\n const orderNumberParam = searchParams.get('orderNumber')?.trim();\r\n\r\n const qb = repo\r\n .createQueryBuilder('payment')\r\n .leftJoinAndSelect('payment.order', 'ord')\r\n .leftJoinAndSelect('ord.contact', 'orderContact')\r\n .leftJoinAndSelect('payment.contact', 'contact')\r\n .andWhere('payment.deleted = :payDel', { payDel: false })\r\n .orderBy(`payment.${sortField}`, sortOrderPayments)\r\n .skip(skip)\r\n .take(limit);\r\n\r\n if (search && typeof search === 'string' && search.trim()) {\r\n const term = `%${search.trim()}%`;\r\n qb.andWhere(\r\n '(orderContact.name ILIKE :term OR orderContact.email ILIKE :term OR contact.name ILIKE :term OR contact.email ILIKE :term)',\r\n { term }\r\n );\r\n }\r\n if (statusFilter) qb.andWhere('payment.status = :status', { status: statusFilter });\r\n if (dateFrom) qb.andWhere('payment.createdAt >= :dateFrom', { dateFrom: new Date(dateFrom + 'T00:00:00.000Z') });\r\n if (dateTo) qb.andWhere('payment.createdAt <= :dateTo', { dateTo: new Date(dateTo + 'T23:59:59.999Z') });\r\n if (methodFilter) qb.andWhere('payment.method = :method', { method: methodFilter });\r\n if (orderNumberParam) qb.andWhere('ord.orderNumber ILIKE :orderNumber', { orderNumber: `%${orderNumberParam}%` });\r\n\r\n const [rows, total] = await qb.getManyAndCount();\r\n const data = (rows as Record<string, unknown>[]).map((payment: Record<string, unknown>) => {\r\n const order = payment.order as Record<string, unknown> | undefined;\r\n const orderContact = order?.contact as Record<string, unknown> | undefined;\r\n const contact = payment.contact as Record<string, unknown> | undefined;\r\n const customer = orderContact ?? contact;\r\n return {\r\n ...payment,\r\n order: order ? { id: order.id, orderNumber: order.orderNumber, contact: orderContact ? { name: orderContact.name, email: orderContact.email } : null } : null,\r\n contact: customer ? { id: customer.id, name: customer.name, email: customer.email } : null,\r\n };\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n // Products list: status and inventory filters\r\n if (resource === 'products') {\r\n const repo = dataSource.getRepository(entity);\r\n const statusFilter = searchParams.get('status')?.trim();\r\n const inventory = searchParams.get('inventory')?.trim();\r\n const productWhere: Record<string, unknown> = { deleted: false };\r\n if (statusFilter) productWhere.status = statusFilter;\r\n if (inventory === 'in_stock') productWhere.quantity = MoreThan(0);\r\n if (inventory === 'out_of_stock') productWhere.quantity = 0;\r\n if (search && typeof search === 'string' && search.trim()) {\r\n productWhere.name = ILike(`%${search.trim()}%`);\r\n }\r\n const [data, total] = await repo.findAndCount({\r\n where: Object.keys(productWhere).length ? productWhere : undefined,\r\n skip,\r\n take: limit,\r\n order: { [sortFieldRaw]: sortOrder },\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n // Contacts list: filters (type, orderId), optional includeSummary (orderCount, totalPaid)\r\n if (resource === 'contacts') {\r\n const repo = dataSource.getRepository(entity);\r\n const allowedSort = ['id', 'name', 'email', 'createdAt', 'type'];\r\n const sortField = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : 'createdAt';\r\n const sortOrderContacts = searchParams.get('sortOrder') === 'asc' ? 'ASC' : 'DESC';\r\n const typeFilter = searchParams.get('type')?.trim();\r\n const orderIdParam = searchParams.get('orderId')?.trim();\r\n const includeSummary = searchParams.get('includeSummary') === '1';\r\n\r\n const qb = repo\r\n .createQueryBuilder('contact')\r\n .andWhere('contact.deleted = :contactDel', { contactDel: false })\r\n .orderBy(`contact.${sortField}`, sortOrderContacts)\r\n .skip(skip)\r\n .take(limit);\r\n\r\n if (search && typeof search === 'string' && search.trim()) {\r\n const term = `%${search.trim()}%`;\r\n qb.andWhere('(contact.name ILIKE :term OR contact.email ILIKE :term OR contact.phone ILIKE :term)', { term });\r\n }\r\n if (typeFilter) qb.andWhere('contact.type = :type', { type: typeFilter });\r\n if (orderIdParam) {\r\n const orderId = Number(orderIdParam);\r\n if (!Number.isNaN(orderId)) {\r\n qb.andWhere('contact.id IN (SELECT \"contactId\" FROM orders WHERE id = :orderId)', { orderId });\r\n }\r\n }\r\n\r\n if (includeSummary && entityMap['orders'] && entityMap['payments']) {\r\n qb.loadRelationCountAndMap('contact._orderCount', 'contact.orders');\r\n const [rows, total] = await qb.getManyAndCount();\r\n const contactIds = (rows as { id: number }[]).map((c) => c.id);\r\n const paymentRepo = dataSource.getRepository(entityMap['payments']);\r\n const paidByContact = await paymentRepo\r\n .createQueryBuilder('p')\r\n .select('p.contactId', 'contactId')\r\n .addSelect('COALESCE(SUM(CAST(p.amount AS DECIMAL)), 0)', 'total')\r\n .where('p.contactId IN (:...ids)', { ids: contactIds.length ? contactIds : [0] })\r\n .andWhere('p.status = :status', { status: 'completed' })\r\n .groupBy('p.contactId')\r\n .getRawMany<{ contactId: number; total: string }>();\r\n const totalPaidMap = new Map<number, number>(paidByContact.map((r) => [r.contactId, Number(r.total)]));\r\n const data = (rows as Record<string, unknown>[]).map((c) => {\r\n const { _orderCount, ...rest } = c as { _orderCount?: number; id: number };\r\n return {\r\n ...rest,\r\n orderCount: _orderCount ?? 0,\r\n totalPaid: totalPaidMap.get((rest as { id: number }).id) ?? 0,\r\n };\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n const [data, total] = await qb.getManyAndCount();\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n const repo = dataSource.getRepository(entity);\r\n const typeFilter = searchParams.get('type');\r\n const columnNames = new Set(repo.metadata.columns.map((c) => c.propertyName));\r\n\r\n if (resource === 'media') {\r\n const qb = repo.createQueryBuilder('m');\r\n const parentIdParam = searchParams.get('parentId');\r\n if (parentIdParam != null && parentIdParam !== '') {\r\n const n = Number(parentIdParam);\r\n if (!Number.isFinite(n)) return json({ error: 'Invalid parentId' }, { status: 400 });\r\n qb.where('m.deleted = :mediaDel AND m.parentId = :pid', { mediaDel: false, pid: n });\r\n } else {\r\n qb.where('m.deleted = :mediaDel AND m.parentId IS NULL', { mediaDel: false });\r\n }\r\n if (search && typeof search === 'string' && search.trim()) {\r\n qb.andWhere('m.filename ILIKE :search', { search: `%${search.trim()}%` });\r\n }\r\n if (typeFilter) {\r\n if (typeFilter === 'folder') {\r\n qb.andWhere('m.kind = :folderKind', { folderKind: 'folder' });\r\n }\r\n else if (typeFilter === 'file') {\r\n qb.andWhere('m.kind = :fileKind', { fileKind: 'file' });\r\n }\r\n else if (typeFilter === 'image') {\r\n qb.andWhere('m.mimeType LIKE :imageMimeType', { imageMimeType: 'image/%' });\r\n }\r\n else if (typeFilter === 'video') {\r\n qb.andWhere('m.mimeType LIKE :videoMimeType', { videoMimeType: 'video/%' });\r\n }\r\n else if (typeFilter === 'audio') {\r\n qb.andWhere('m.mimeType LIKE :audioMimeType', { audioMimeType: 'audio/%' });\r\n }\r\n else if (typeFilter === 'Document') {\r\n qb.andWhere('m.mimeType LIKE :documentMimeType', { documentMimeType: 'application/pdf' });\r\n }\r\n else if (typeFilter === 'application') {\r\n qb.andWhere('m.kind = :folderKind', { folderKind: 'folder' });\r\n }\r\n }\r\n const allowedSort = ['filename', 'createdAt', 'id'];\r\n const sf = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : 'filename';\r\n const so = sortOrder === 'DESC' ? 'DESC' : 'ASC';\r\n // qb.orderBy('CASE WHEN m.kind = :fk THEN 0 ELSE 1 END', 'ASC')\r\n // .addOrderBy(`m.${sf}`, so)\r\n // .setParameter('fk', 'folder')\r\n qb.orderBy(`m.${sf}`, so)\r\n .skip(skip)\r\n .take(limit);\r\n const [rows, total] = await qb.getManyAndCount();\r\n const mediaRows = rows as { id: number; kind?: string; size?: number }[];\r\n const folderIds = mediaRows.filter((m) => m.kind === 'folder').map((m) => m.id);\r\n let data: typeof rows = rows;\r\n if (folderIds.length > 0) {\r\n const sizeMap = await aggregateMediaFolderFileSizes(dataSource, folderIds);\r\n data = mediaRows.map((m) =>\r\n m.kind === 'folder' ? { ...m, size: sizeMap.get(m.id) ?? 0 } : m\r\n ) as typeof rows;\r\n }\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n const sortField = columnNames.has(sortFieldRaw) ? sortFieldRaw : 'createdAt';\r\n let where: Record<string, unknown>[] | Record<string, unknown> = {};\r\n if (search) {\r\n where = buildSearchWhereClause(repo, search);\r\n }\r\n // Exact-match filters for common FK query params (e.g. product_attributes?productId=1)\r\n const intFilterKeys = ['productId', 'attributeId', 'taxId'] as const;\r\n const extraWhere: Record<string, unknown> = {};\r\n for (const key of intFilterKeys) {\r\n const v = searchParams.get(key);\r\n if (v != null && v !== '' && columnNames.has(key)) {\r\n const n = Number(v);\r\n if (Number.isFinite(n)) extraWhere[key] = n;\r\n }\r\n }\r\n if (Object.keys(extraWhere).length > 0) {\r\n if (Array.isArray(where)) {\r\n where = where.map((w) => ({ ...w, ...extraWhere }));\r\n } else if (where && typeof where === 'object' && Object.keys(where).length > 0) {\r\n where = { ...where, ...extraWhere };\r\n } else {\r\n where = extraWhere;\r\n }\r\n }\r\n where = mergeDeletedFalseWhere(repo, where);\r\n let data: import('typeorm').ObjectLiteral[];\r\n let total: number;\r\n try {\r\n const r = await repo.findAndCount({\r\n skip,\r\n take: limit,\r\n order: { [sortField]: sortOrder },\r\n where,\r\n });\r\n data = r[0];\r\n total = r[1];\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : String(err);\r\n logCrudServerError('GET list query failed', { resource, sortField, sortOrder, message });\r\n throw err;\r\n }\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n },\r\n\r\n async POST(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'create');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('POST create', {\r\n reason: 'invalid_resource',\r\n resource,\r\n hasEntity: Boolean(entity),\r\n entityMapHasLlmAgents: Boolean(entityMap.llm_agents),\r\n });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const rawPostBody = await req.json();\r\n if (!rawPostBody || typeof rawPostBody !== 'object' || Object.keys(rawPostBody).length === 0) {\r\n logCrudClientError('POST create', {\r\n reason: 'invalid_request_payload',\r\n resource,\r\n rawType: rawPostBody == null ? 'nullish' : typeof rawPostBody,\r\n keyCount: rawPostBody && typeof rawPostBody === 'object' ? Object.keys(rawPostBody).length : 0,\r\n });\r\n return json({ error: 'Invalid request payload' }, { status: 400 });\r\n }\r\n const body = rawPostBody as Record<string, unknown>;\r\n if (resource === 'media') {\r\n const b = body;\r\n const kind = b.kind === 'folder' ? 'folder' : 'file';\r\n b.kind = kind;\r\n const fn = String(b.filename ?? '').trim().slice(0, 255);\r\n if (!fn) return json({ error: 'filename required' }, { status: 400 });\r\n b.filename = fn;\r\n let pid: number | null = null;\r\n if (b.parentId != null && b.parentId !== '') {\r\n const n = Number(b.parentId);\r\n if (!Number.isFinite(n)) return json({ error: 'Invalid parentId' }, { status: 400 });\r\n pid = n;\r\n }\r\n b.parentId = pid;\r\n const mediaRepo = dataSource.getRepository(entityMap.media);\r\n if (pid != null) {\r\n const parent = await mediaRepo.findOne({ where: { id: pid } });\r\n if (!parent || (parent as { kind: string }).kind !== 'folder') {\r\n return json({ error: 'parent must be a folder' }, { status: 400 });\r\n }\r\n }\r\n if (kind === 'folder') {\r\n b.url = null;\r\n b.mimeType = 'inode/directory';\r\n b.size = 0;\r\n } else {\r\n if (!b.url || typeof b.url !== 'string') return json({ error: 'url required for files' }, { status: 400 });\r\n if (!b.mimeType || typeof b.mimeType !== 'string') {\r\n b.mimeType = 'application/octet-stream';\r\n }\r\n }\r\n }\r\n const repo = dataSource.getRepository(entity);\r\n const persistBody = resource === 'media' ? body : pickColumnUpdates(repo, body);\r\n if (resource !== 'media' && Object.keys(persistBody).length === 0) {\r\n logCrudClientError('POST create', {\r\n reason: 'no_scalar_columns_after_pick',\r\n resource,\r\n incomingKeys: Object.keys(body),\r\n });\r\n return json({ error: 'Invalid request payload' }, { status: 400 });\r\n }\r\n if (resource === 'products') {\r\n if ('sku' in persistBody) {\r\n const skuNorm = normalizeProductSku(persistBody.sku);\r\n if (skuNorm) {\r\n const ok = await assertProductSkuUnique(repo, skuNorm);\r\n if (!ok) {\r\n return json({ error: 'SKU already exists. Please use a unique SKU.' }, { status: 400 });\r\n }\r\n persistBody.sku = skuNorm;\r\n } else {\r\n persistBody.sku = null;\r\n }\r\n }\r\n }\r\n sanitizeBodyForEntity(repo, persistBody);\r\n let created: import('typeorm').ObjectLiteral;\r\n try {\r\n created = await repo.save(repo.create(persistBody as object));\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : String(err);\r\n logCrudServerError('POST create save failed', { resource, message, persistKeys: Object.keys(persistBody) });\r\n throw err;\r\n }\r\n if (resource === 'contacts') {\r\n await syncContactRowToErp(created as import('typeorm').ObjectLiteral);\r\n }\r\n if (resource === 'products' && getCms) {\r\n const cms = await getCms();\r\n await queueErpProductUpsertIfEnabled(cms, dataSource, entityMap, created as import('typeorm').ObjectLiteral);\r\n }\r\n return json(created, { status: 201 });\r\n },\r\n\r\n async GET_METADATA(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'read');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('GET_METADATA', { reason: 'invalid_resource', resource });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const repo = dataSource.getRepository(entity);\r\n const meta = repo.metadata;\r\n\r\n // Collect unique column names from indices\r\n const uniqueFromIndices = new Set<string>();\r\n for (const idx of meta.indices) {\r\n if (idx.isUnique && idx.columns.length === 1) {\r\n uniqueFromIndices.add(idx.columns[0].propertyName);\r\n }\r\n }\r\n for (const uniq of meta.uniques) {\r\n if (uniq.columns.length === 1) {\r\n uniqueFromIndices.add(uniq.columns[0].propertyName);\r\n }\r\n }\r\n\r\n const columns = meta.columns.map((col) => ({\r\n name: col.propertyName,\r\n type: typeof col.type === 'string' ? col.type : (col.type as { name?: string })?.name ?? 'unknown',\r\n nullable: col.isNullable,\r\n isUnique: uniqueFromIndices.has(col.propertyName),\r\n isPrimary: col.isPrimary,\r\n default: col.default,\r\n }));\r\n\r\n const uniqueColumns = [...uniqueFromIndices];\r\n\r\n return json({ columns, uniqueColumns });\r\n },\r\n\r\n async BULK_POST(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'update');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('BULK_POST', { reason: 'invalid_resource', resource });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const body = await req.json();\r\n const { records, upsertKey = 'id' } = body as { records: object[]; upsertKey?: string };\r\n\r\n if (!Array.isArray(records) || records.length === 0) {\r\n logCrudClientError('BULK_POST', {\r\n reason: 'records_required',\r\n resource,\r\n recordsIsArray: Array.isArray(records),\r\n recordCount: Array.isArray(records) ? records.length : 0,\r\n });\r\n return json({ error: 'Records array is required' }, { status: 400 });\r\n }\r\n\r\n const repo = dataSource.getRepository(entity);\r\n\r\n // Sanitize each record\r\n for (const record of records) {\r\n sanitizeBodyForEntity(repo, record as Record<string, unknown>);\r\n }\r\n\r\n try {\r\n const result = await repo.upsert(records, {\r\n conflictPaths: [upsertKey],\r\n skipUpdateIfNoValuesChanged: true,\r\n });\r\n return json({\r\n success: true,\r\n imported: result.identifiers.length,\r\n identifiers: result.identifiers,\r\n });\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : 'Bulk import failed';\r\n logCrudClientError('BULK_POST upsert failed', { resource, upsertKey, message });\r\n return json({ error: message }, { status: 400 });\r\n }\r\n },\r\n\r\n async GET_EXPORT(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'read');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('GET_EXPORT', { reason: 'invalid_resource', resource });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n\r\n const { searchParams } = new URL(req.url);\r\n const format = searchParams.get('format') || 'csv';\r\n\r\n const repo = dataSource.getRepository(entity);\r\n const meta = repo.metadata;\r\n\r\n // Check if entity has 'deleted' column\r\n const hasDeleted = meta.columns.some((c) => c.propertyName === 'deleted');\r\n const where = hasDeleted ? { deleted: false } : {};\r\n\r\n const data = await repo.find({ where });\r\n\r\n // Get exportable columns (exclude soft-delete related)\r\n const excludeCols = new Set(['deletedAt', 'deletedBy', 'deleted']);\r\n const columns = meta.columns\r\n .filter((c) => !excludeCols.has(c.propertyName))\r\n .map((c) => c.propertyName);\r\n\r\n if (format === 'json') {\r\n return json(data);\r\n }\r\n\r\n // CSV format\r\n const escapeCSV = (val: unknown): string => {\r\n if (val === null || val === undefined) return '';\r\n const str = typeof val === 'object' ? JSON.stringify(val) : String(val);\r\n if (str.includes(',') || str.includes('\"') || str.includes('\\n')) {\r\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\r\n }\r\n return str;\r\n };\r\n\r\n const header = columns.join(',');\r\n const rows = data.map((row) =>\r\n columns.map((col) => escapeCSV((row as Record<string, unknown>)[col])).join(',')\r\n );\r\n const csv = [header, ...rows].join('\\n');\r\n\r\n return new Response(csv, {\r\n headers: {\r\n 'Content-Type': 'text/csv; charset=utf-8',\r\n 'Content-Disposition': `attachment; filename=\"${resource}.csv\"`,\r\n },\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport function createCrudByIdHandler(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n options: CrudHandlerOptions\r\n) {\r\n const { requireAuth, json, requireEntityPermission: reqPerm, getCms, getDeletedByUserId } = options;\r\n const syncContactRowToErp = makeContactErpSync(dataSource, entityMap, getCms);\r\n\r\n async function authz(req: Request, resource: string, action: EntityCrudAction): Promise<Response | null> {\r\n const authError = await requireAuth(req);\r\n if (authError) return authError;\r\n if (!reqPerm) {\r\n return json({ error: 'Forbidden', reason: 'entity_rbac_required', entity: resource, action }, { status: 403 });\r\n }\r\n const pe = await reqPerm(req, resource, action);\r\n if (pe) return pe;\r\n return null;\r\n }\r\n\r\n return {\r\n async GET(req: Request, resource: string, id: string) {\r\n const authError = await authz(req, resource, 'read');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!entity) {\r\n logCrudClientError('GET by id', { reason: 'invalid_resource', resource, id });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const repo = dataSource.getRepository(entity);\r\n\r\n if (resource === 'orders') {\r\n const order = await repo.findOne({\r\n where: { id: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n relations: ['contact', 'billingAddress', 'shippingAddress', 'items', 'items.product', 'items.product.collection', 'payments'],\r\n });\r\n if (!order) return json({ message: 'Not found' }, { status: 404 });\r\n const relatedOrders = await repo.find({\r\n where: { parentOrderId: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n order: { id: 'ASC' },\r\n });\r\n return json({ ...order, relatedOrders });\r\n }\r\n\r\n if (resource === 'contacts') {\r\n const contact = await repo.findOne({\r\n where: { id: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n relations: ['form_submissions', 'form_submissions.form', 'orders', 'payments', 'addresses'],\r\n });\r\n if (!contact) return json({ message: 'Not found' }, { status: 404 });\r\n const orders = (contact as { orders?: { total?: unknown; createdAt?: string }[] }).orders ?? [];\r\n const payments = (contact as { payments?: { status: string; amount?: number }[] }).payments ?? [];\r\n const totalPaid = payments\r\n .filter((p) => p.status === 'completed')\r\n .reduce((sum, p) => sum + Number(p.amount ?? 0), 0);\r\n const lastOrderAt =\r\n orders.length > 0\r\n ? orders.reduce((latest, o) => {\r\n const t = o.createdAt ? new Date(o.createdAt).getTime() : 0;\r\n return t > latest ? t : latest;\r\n }, 0)\r\n : null;\r\n return json({\r\n ...contact,\r\n summary: {\r\n totalOrders: orders.length,\r\n totalPaid,\r\n lastOrderAt: lastOrderAt ? new Date(lastOrderAt).toISOString() : null,\r\n },\r\n });\r\n }\r\n\r\n if (resource === 'payments') {\r\n const payment = await repo.findOne({\r\n where: { id: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n relations: ['order', 'order.contact', 'contact'],\r\n });\r\n if (!payment) return json({ message: 'Not found' }, { status: 404 });\r\n const p = payment as Record<string, unknown>;\r\n const order = p.order as Record<string, unknown> | undefined;\r\n const orderContact = order?.contact as Record<string, unknown> | undefined;\r\n const contact = p.contact as Record<string, unknown> | undefined;\r\n const customer = orderContact ?? contact;\r\n return json({\r\n ...p,\r\n order: order\r\n ? {\r\n id: order.id,\r\n orderNumber: order.orderNumber,\r\n contact: orderContact ? { name: orderContact.name, email: orderContact.email } : null,\r\n }\r\n : null,\r\n contact: customer\r\n ? { id: customer.id, name: customer.name, email: customer.email }\r\n : null,\r\n });\r\n }\r\n\r\n if (resource === 'blogs') {\r\n const blog = await repo.findOne({\r\n where: { id: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n relations: ['category', 'seo', 'tags'],\r\n });\r\n return blog ? json(blog) : json({ message: 'Not found' }, { status: 404 });\r\n }\r\n\r\n const idWhere: import('typeorm').ObjectLiteral = entityHasSoftDelete(repo)\r\n ? ({ id: Number(id), deleted: false } as import('typeorm').ObjectLiteral)\r\n : ({ id: Number(id) } as import('typeorm').ObjectLiteral);\r\n const item = await repo.findOne({ where: idWhere });\r\n return item ? json(item) : json({ message: 'Not found' }, { status: 404 });\r\n },\r\n\r\n async PUT(req: Request, resource: string, id: string) {\r\n const authError = await authz(req, resource, 'update');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!entity) {\r\n logCrudClientError('PUT by id', { reason: 'invalid_resource', resource, id });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const rawBody = (await req.json()) as Record<string, unknown> | null;\r\n const repo = dataSource.getRepository(entity);\r\n const numericId = Number(id);\r\n\r\n if (\r\n resource === 'blogs' &&\r\n rawBody &&\r\n typeof rawBody === 'object' &&\r\n entityMap.categories &&\r\n entityMap.seos &&\r\n entityMap.tags\r\n ) {\r\n const existing = await repo.findOne({\r\n where: { id: numericId, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!existing) return json({ message: 'Not found' }, { status: 404 });\r\n\r\n const updatePayload = pickColumnUpdates(repo, rawBody);\r\n\r\n if ('category' in rawBody) {\r\n const c = rawBody.category;\r\n if (typeof c === 'string' && c.trim()) {\r\n const cat = await dataSource\r\n .getRepository(entityMap.categories)\r\n .findOne({ where: { name: c.trim() } });\r\n updatePayload.categoryId = cat?.id ?? null;\r\n } else {\r\n updatePayload.categoryId = null;\r\n }\r\n }\r\n\r\n const blogSlug =\r\n (typeof updatePayload.slug === 'string' && updatePayload.slug) ||\r\n (existing as { slug: string }).slug;\r\n const seoRepo = dataSource.getRepository(entityMap.seos);\r\n const seoField = (k: string): string | null | undefined => {\r\n if (!(k in rawBody)) return undefined;\r\n const v = rawBody[k];\r\n if (v == null || v === '') return null;\r\n return String(v);\r\n };\r\n if (\r\n 'metaTitle' in rawBody ||\r\n 'metaDescription' in rawBody ||\r\n 'metaKeywords' in rawBody ||\r\n 'ogImage' in rawBody\r\n ) {\r\n const title = seoField('metaTitle');\r\n const description = seoField('metaDescription');\r\n const keywords = seoField('metaKeywords');\r\n const ogImage = seoField('ogImage');\r\n const exSeoId = (existing as { seoId: number | null }).seoId;\r\n if (exSeoId) {\r\n const seo = await seoRepo.findOne({ where: { id: exSeoId } });\r\n if (seo) {\r\n const s = seo as Record<string, unknown>;\r\n if (title !== undefined) s.title = title;\r\n if (description !== undefined) s.description = description;\r\n if (keywords !== undefined) s.keywords = keywords;\r\n if (ogImage !== undefined) s.ogImage = ogImage;\r\n s.slug = blogSlug;\r\n await seoRepo.save(seo);\r\n }\r\n } else {\r\n let seoSlug = blogSlug;\r\n const taken = await seoRepo.findOne({ where: { slug: seoSlug } });\r\n if (taken) seoSlug = `blog-${numericId}-${blogSlug}`;\r\n const seo = await seoRepo.save(\r\n seoRepo.create({\r\n slug: seoSlug,\r\n title: title ?? null,\r\n description: description ?? null,\r\n keywords: keywords ?? null,\r\n ogImage: ogImage ?? null,\r\n })\r\n );\r\n updatePayload.seoId = (seo as { id: number }).id;\r\n }\r\n }\r\n\r\n sanitizeBodyForEntity(repo, updatePayload);\r\n await repo.update(numericId, updatePayload as object);\r\n\r\n if (Array.isArray(rawBody.tags)) {\r\n const tagNames = (rawBody.tags as unknown[]).map((t) => String(t).trim()).filter(Boolean);\r\n const tagRepo = dataSource.getRepository(entityMap.tags);\r\n const tagEntities: import('typeorm').ObjectLiteral[] = [];\r\n for (const name of tagNames) {\r\n let tag = await tagRepo.findOne({ where: { name } });\r\n if (!tag) tag = await tagRepo.save(tagRepo.create({ name }));\r\n tagEntities.push(tag);\r\n }\r\n const blog = await repo.findOne({ where: { id: numericId }, relations: ['tags'] });\r\n if (blog) {\r\n (blog as Record<string, unknown>).tags = tagEntities;\r\n await repo.save(blog);\r\n }\r\n }\r\n\r\n const updated = await repo.findOne({\r\n where: { id: numericId },\r\n relations: ['tags', 'category', 'seo'],\r\n });\r\n return updated ? json(updated) : json({ message: 'Not found' }, { status: 404 });\r\n }\r\n\r\n if (entityHasSoftDelete(repo)) {\r\n const cur = await repo.findOne({\r\n where: { id: numericId, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!cur) return json({ message: 'Not found' }, { status: 404 });\r\n }\r\n\r\n const updatePayload = rawBody && typeof rawBody === 'object' ? pickColumnUpdates(repo, rawBody) : {};\r\n if (resource === 'media') {\r\n const u = updatePayload as Record<string, unknown>;\r\n delete u.parentId;\r\n delete u.kind;\r\n }\r\n if (resource === 'products') {\r\n const currentRow = await repo.findOne({\r\n where: { id: numericId, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!currentRow) return json({ message: 'Not found' }, { status: 404 });\r\n const merged: Record<string, unknown> = { ...(currentRow as Record<string, unknown>), ...updatePayload };\r\n const effSku = normalizeProductSku(merged.sku);\r\n if (effSku) {\r\n const ok = await assertProductSkuUnique(repo, effSku, numericId);\r\n if (!ok) {\r\n return json({ error: 'SKU already exists. Please use a unique SKU.' }, { status: 400 });\r\n }\r\n }\r\n if ('sku' in updatePayload) {\r\n updatePayload.sku = effSku;\r\n }\r\n }\r\n if (Object.keys(updatePayload).length > 0) {\r\n sanitizeBodyForEntity(repo, updatePayload);\r\n await repo.update(numericId, updatePayload as object);\r\n }\r\n const updated = await repo.findOne({ where: { id: numericId } });\r\n if (resource === 'contacts' && updated) {\r\n await syncContactRowToErp(updated as import('typeorm').ObjectLiteral);\r\n }\r\n if (resource === 'products' && updated && getCms) {\r\n const cms = await getCms();\r\n await queueErpProductUpsertIfEnabled(cms, dataSource, entityMap, updated as import('typeorm').ObjectLiteral);\r\n }\r\n return updated ? json(updated) : json({ message: 'Not found' }, { status: 404 });\r\n },\r\n\r\n async DELETE(req: Request, resource: string, id: string) {\r\n const authError = await authz(req, resource, 'delete');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!entity) {\r\n logCrudClientError('DELETE by id', { reason: 'invalid_resource', resource, id });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const repo = dataSource.getRepository(entity);\r\n const numericId = Number(id);\r\n if (entityHasSoftDelete(repo)) {\r\n const existing = await repo.findOne({\r\n where: { id: numericId, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!existing) return json({ message: 'Not found' }, { status: 404 });\r\n if (resource === 'contacts') {\r\n const result = await repo.delete(numericId);\r\n if (result.affected === 0) return json({ message: 'Not found' }, { status: 404 });\r\n return json({ message: 'Deleted successfully' }, { status: 200 });\r\n }\r\n let deletedBy: number | null = null;\r\n if (getDeletedByUserId) {\r\n try {\r\n deletedBy = await getDeletedByUserId(req);\r\n } catch {\r\n deletedBy = null;\r\n }\r\n }\r\n await repo.update(numericId, buildSoftDeletePayload(repo.metadata, deletedBy) as object);\r\n return json({ message: 'Deleted successfully' }, { status: 200 });\r\n }\r\n const result = await repo.delete(numericId);\r\n if (result.affected === 0) return json({ message: 'Not found' }, { status: 404 });\r\n return json({ message: 'Deleted successfully' }, { status: 200 });\r\n },\r\n };\r\n}\r\n","import type { ObjectLiteral } from 'typeorm';\r\nimport { queueErp, type CmsAppLike } from './erp-queue';\r\nimport type { ErpPaidOrderDataSource, ErpPaidOrderEntityMap } from './paid-order-erp';\r\n\r\nexport interface ErpContactSyncInput {\r\n name: string;\r\n email: string;\r\n phone?: string | null;\r\n type?: string | null;\r\n company?: string | null;\r\n notes?: string | null;\r\n /** Passed to ERP as `tags` when non-empty (§7c). */\r\n tags?: string[];\r\n}\r\n\r\nfunction splitName(full: string): { firstName: string; lastName: string } {\r\n const t = (full || '').trim();\r\n if (!t) return { firstName: 'Contact', lastName: '' };\r\n const parts = t.split(/\\s+/);\r\n if (parts.length === 1) return { firstName: parts[0]!, lastName: '' };\r\n return { firstName: parts[0]!, lastName: parts.slice(1).join(' ') };\r\n}\r\n\r\n/**\r\n * When ERP is enabled and plugin loaded, enqueue `create-contact` (non-fatal on failure).\r\n * Used for admin CRUD and storefront contact paths — not form submissions (those use lead/opportunity).\r\n */\r\nexport async function queueErpCreateContactIfEnabled(\r\n cms: CmsAppLike,\r\n dataSource: ErpPaidOrderDataSource,\r\n entityMap: ErpPaidOrderEntityMap,\r\n input: ErpContactSyncInput\r\n): Promise<void> {\r\n try {\r\n const configRepo = dataSource.getRepository(entityMap.configs);\r\n const cfgRows = await configRepo.find({ where: { settings: 'erp', deleted: false } as ObjectLiteral });\r\n for (const row of cfgRows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'enabled' && r.value === 'false') return;\r\n }\r\n if (!cms.getPlugin('erp')) return;\r\n\r\n const email = (input.email ?? '').trim();\r\n if (!email) return;\r\n\r\n const { firstName, lastName } = splitName(input.name);\r\n\r\n await queueErp(cms, {\r\n kind: 'createContact',\r\n contact: {\r\n email,\r\n firstName,\r\n lastName,\r\n phone: input.phone?.trim() || undefined,\r\n companyName: input.company?.trim() || undefined,\r\n type: input.type?.trim() || undefined,\r\n notes: input.notes?.trim() || undefined,\r\n tags: input.tags?.length ? [...input.tags] : undefined,\r\n },\r\n });\r\n } catch {\r\n /* non-fatal */\r\n }\r\n}\r\n","import type { ObjectLiteral } from 'typeorm';\r\nimport { queueErp } from './erp-queue';\r\nimport { isErpIntegrationEnabled, type CmsAppLike, type ErpConfigDataSource } from './erp-config-enabled';\r\n\r\nexport async function queueErpProductUpsertIfEnabled(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>,\r\n product: ObjectLiteral\r\n): Promise<void> {\r\n try {\r\n const sku = typeof product.sku === 'string' ? product.sku.trim() : '';\r\n if (!sku) return;\r\n const on = await isErpIntegrationEnabled(cms, dataSource, entityMap);\r\n if (!on) return;\r\n const rawMeta = product.metadata;\r\n let metadata: Record<string, unknown> | undefined;\r\n if (rawMeta && typeof rawMeta === 'object' && !Array.isArray(rawMeta)) {\r\n const { description: _d, ...rest } = rawMeta as Record<string, unknown>;\r\n metadata = Object.keys(rest).length ? rest : undefined;\r\n }\r\n const payload: Record<string, unknown> = {\r\n sku,\r\n title: (product.name as string) || sku,\r\n name: product.name,\r\n hsn_number: product.hsn,\r\n uom: product.uom != null && String(product.uom).trim() ? String(product.uom).trim() : undefined,\r\n type: product.type === 'service' ? 'service' : 'product',\r\n is_active: product.status === 'available',\r\n metadata,\r\n };\r\n await queueErp(cms, { kind: 'productUpsert', product: payload });\r\n } catch {\r\n /* non-fatal */\r\n }\r\n}\r\n","import type { DataSource, EntityTarget, ObjectLiteral } from 'typeorm';\r\nimport { IsNull } from 'typeorm';\r\n\r\n/** Links an unclaimed contact (same email, no userId) to the new user after signup or invite. */\r\nexport async function linkUnclaimedContactToUser(\r\n dataSource: DataSource,\r\n contactsEntity: EntityTarget<ObjectLiteral>,\r\n userId: number,\r\n email: string\r\n): Promise<void> {\r\n const repo = dataSource.getRepository(contactsEntity);\r\n const found = await repo.findOne({\r\n where: { email, userId: IsNull(), deleted: false } as ObjectLiteral,\r\n });\r\n if (found) await repo.update((found as { id: number }).id, { userId });\r\n}\r\n","/**\r\n * Auth API handler factories. Inject dataSource + entityMap, sendEmail, hash/compare; optional hooks to customize.\r\n */\r\nimport type { DataSource } from 'typeorm';\r\nimport { linkUnclaimedContactToUser } from '../lib/link-contact-to-user';\r\nimport type { EntityMap } from './crud';\r\n\r\nexport interface AuthHandlersConfig {\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n baseUrl: string;\r\n hashPassword: (plain: string) => Promise<string>;\r\n comparePassword: (plain: string, hash: string) => Promise<boolean>;\r\n}\r\n\r\nexport interface ForgotPasswordConfig extends AuthHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n sendEmail?: (opts: {\r\n to: string;\r\n subject: string;\r\n html: string;\r\n text?: string;\r\n /** Plain reset URL for templated emails (preferred over parsing html). */\r\n resetLink?: string;\r\n }) => Promise<void>;\r\n resetExpiryHours?: number;\r\n afterCreateToken?: (email: string, resetLink: string) => Promise<void>;\r\n}\r\n\r\nexport function createForgotPasswordHandler(config: ForgotPasswordConfig) {\r\n const { dataSource, entityMap, json, baseUrl, sendEmail, resetExpiryHours = 1, afterCreateToken } = config;\r\n return async function POST(request: Request): Promise<Response> {\r\n try {\r\n const body = await request.json().catch(() => ({})) as { email?: string };\r\n const email = typeof body?.email === 'string' ? body.email.trim().toLowerCase() : '';\r\n if (!email) return json({ error: 'Email is required' }, { status: 400 });\r\n\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n const user = await userRepo.findOne({ where: { email }, select: ['email'] });\r\n const msg = 'If an account exists with this email, you will receive a reset link shortly.';\r\n if (!user) return json({ message: msg }, { status: 200 });\r\n\r\n const crypto = await import('crypto');\r\n const token = crypto.randomBytes(32).toString('hex');\r\n const expiresAt = new Date(Date.now() + (resetExpiryHours * 60 * 60 * 1000));\r\n const tokenRepo = dataSource.getRepository(entityMap.password_reset_tokens);\r\n await tokenRepo.save(tokenRepo.create({ email: user.email, token, expiresAt }));\r\n const resetLink = `${baseUrl}/admin/reset-password?token=${token}`;\r\n\r\n if (sendEmail)\r\n await sendEmail({\r\n to: user.email,\r\n subject: 'Password reset',\r\n html: `<a href=\"${resetLink}\">Reset password</a>`,\r\n text: resetLink,\r\n resetLink,\r\n });\r\n if (afterCreateToken) await afterCreateToken(user.email, resetLink);\r\n return json({ message: msg }, { status: 200 });\r\n } catch (err) {\r\n return json({ error: 'Something went wrong. Please try again.' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface SetPasswordConfig extends AuthHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n minPasswordLength?: number;\r\n beforeUpdate?: (email: string, userId: number) => Promise<void>;\r\n}\r\n\r\nexport function createSetPasswordHandler(config: SetPasswordConfig) {\r\n const { dataSource, entityMap, json, hashPassword, minPasswordLength = 6, beforeUpdate } = config;\r\n return async function POST(request: Request): Promise<Response> {\r\n try {\r\n const body = await request.json().catch(() => ({})) as { token?: string; newPassword?: string };\r\n const { token, newPassword } = body;\r\n if (!token || !newPassword) return json({ error: 'Token and new password are required' }, { status: 400 });\r\n if (newPassword.length < minPasswordLength) return json({ error: 'Password must be at least 6 characters' }, { status: 400 });\r\n\r\n const tokenRepo = dataSource.getRepository(entityMap.password_reset_tokens);\r\n const record = await tokenRepo.findOne({ where: { token } });\r\n if (!record || record.expiresAt < new Date()) return json({ error: 'Invalid or expired reset link. Please request a new one.' }, { status: 400 });\r\n\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n const user = await userRepo.findOne({ where: { email: record.email }, select: ['id'] });\r\n if (!user) return json({ error: 'User not found' }, { status: 400 });\r\n\r\n if (beforeUpdate) await beforeUpdate(record.email, user.id);\r\n const hashedPassword = await hashPassword(newPassword);\r\n await userRepo.update(user.id, { password: hashedPassword, updatedAt: new Date() });\r\n await tokenRepo.delete({ email: record.email });\r\n return json({ message: 'Password updated successfully. You can now sign in.' });\r\n } catch {\r\n return json({ error: 'Something went wrong. Please try again.' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface InviteAcceptConfig extends AuthHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n beforeActivate?: (email: string, userId: number) => Promise<void>;\r\n}\r\n\r\n/** Decode invite token (base64 email) and set password + unblock user */\r\nexport function createInviteAcceptHandler(config: InviteAcceptConfig) {\r\n const { dataSource, entityMap, json, hashPassword, beforeActivate } = config;\r\n return async function POST(request: Request): Promise<Response> {\r\n try {\r\n const body = await request.json().catch(() => ({})) as { token?: string; password?: string };\r\n const { token, password } = body;\r\n if (!token || !password) return json({ error: 'Missing required fields: token, password' }, { status: 400 });\r\n\r\n let email: string;\r\n try {\r\n email = Buffer.from(token, 'base64').toString('utf8');\r\n } catch {\r\n return json({ error: 'Invalid or expired invite token' }, { status: 400 });\r\n }\r\n\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n const user = await userRepo.findOne({ where: { email }, select: ['id', 'blocked'] });\r\n if (!user) return json({ error: 'User not found' }, { status: 400 });\r\n if (!user.blocked) return json({ error: 'User is already active' }, { status: 400 });\r\n\r\n if (entityMap.contacts) {\r\n await linkUnclaimedContactToUser(dataSource, entityMap.contacts, user.id, email);\r\n }\r\n if (beforeActivate) await beforeActivate(email, user.id);\r\n const hashedPassword = await hashPassword(password);\r\n await userRepo.update(user.id, { password: hashedPassword, blocked: false });\r\n return json({ message: 'User account activated successfully' }, { status: 200 });\r\n } catch (err) {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface ChangePasswordConfig extends AuthHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n getSession: () => Promise<{ user?: { email?: string | null } } | null>;\r\n minPasswordLength?: number;\r\n beforeUpdate?: (email: string) => Promise<void>;\r\n}\r\n\r\nexport function createChangePasswordHandler(config: ChangePasswordConfig) {\r\n const { dataSource, entityMap, json, comparePassword, hashPassword, getSession, minPasswordLength = 6, beforeUpdate } = config;\r\n return async function POST(request: Request): Promise<Response> {\r\n try {\r\n const session = await getSession();\r\n if (!session?.user?.email) return json({ error: 'Unauthorized' }, { status: 401 });\r\n\r\n const body = await request.json().catch(() => ({})) as { currentPassword?: string; newPassword?: string };\r\n const { currentPassword, newPassword } = body;\r\n if (!currentPassword || !newPassword) return json({ error: 'Current password and new password are required' }, { status: 400 });\r\n if (newPassword.length < minPasswordLength) return json({ error: 'New password must be at least 6 characters long' }, { status: 400 });\r\n\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n const user = await userRepo.findOne({ where: { email: session.user.email }, select: ['password'] });\r\n if (!user) return json({ error: 'User not found' }, { status: 404 });\r\n if (!user.password) return json({ error: 'Current password is incorrect' }, { status: 400 });\r\n const valid = await comparePassword(currentPassword, user.password);\r\n if (!valid) return json({ error: 'Current password is incorrect' }, { status: 400 });\r\n\r\n if (beforeUpdate) await beforeUpdate(session.user.email);\r\n const hashedPassword = await hashPassword(newPassword);\r\n await userRepo.update({ email: session.user.email }, { password: hashedPassword, updatedAt: new Date() });\r\n return json({ message: 'Password updated successfully' });\r\n } catch {\r\n return json({ error: 'Internal server error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface UserAuthApiConfig\r\n extends ForgotPasswordConfig,\r\n Omit<SetPasswordConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword'>,\r\n Omit<InviteAcceptConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword'>,\r\n Omit<ChangePasswordConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword' | 'beforeUpdate' | 'getSession'> {\r\n getSession?: () => Promise<{ user?: { email?: string | null } } | null>;\r\n beforeChangePasswordUpdate?: (email: string) => Promise<void>;\r\n}\r\n\r\nconst USER_AUTH_PATHS = ['forgot-password', 'invite', 'set-password', 'reset-password'] as const;\r\n\r\n/**\r\n * Single router for all user-auth APIs. Mount in the app once.\r\n * Use when you have no users/[id] route (else Next.js gives [id] precedence and \"forgot-password\" would match as id).\r\n * Path is the segment after the mount (e.g. \"forgot-password\"). Returns 404 for unknown paths.\r\n */\r\nexport function createUserAuthApiRouter(config: UserAuthApiConfig) {\r\n const forgot = createForgotPasswordHandler(config);\r\n const setPass = createSetPasswordHandler(config);\r\n const invite = createInviteAcceptHandler(config);\r\n const changePass = config.getSession\r\n ? createChangePasswordHandler({\r\n ...config,\r\n getSession: config.getSession,\r\n beforeUpdate: config.beforeChangePasswordUpdate,\r\n })\r\n : null;\r\n\r\n return {\r\n async POST(req: Request, pathname: string): Promise<Response> {\r\n const path = pathname.replace(/\\/$/, '');\r\n if (!USER_AUTH_PATHS.includes(path as (typeof USER_AUTH_PATHS)[number])) {\r\n return config.json({ error: 'Not found' }, { status: 404 });\r\n }\r\n if (path === 'forgot-password') return forgot(req);\r\n if (path === 'set-password') return setPass(req);\r\n if (path === 'invite') return invite(req);\r\n if (path === 'reset-password' && changePass) return changePass(req);\r\n return config.json({ error: 'Not found' }, { status: 404 });\r\n },\r\n };\r\n}\r\n","/**\r\n * CMS API handlers: dashboard, analytics, upload, blog/form by slug, users (list/create/get/update/delete/regenerate-invite/avatar/profile).\r\n * All accept injectable deps; upload supports S3 or local.\r\n */\r\nimport type { DataSource, EntityTarget } from 'typeorm';\r\nimport { linkUnclaimedContactToUser } from '../lib/link-contact-to-user';\r\nimport { MoreThanOrEqual, ILike, In } from 'typeorm';\r\nimport type { EntityMap } from './crud';\r\nimport type { EntityCrudAction } from '../auth/permission-entities';\r\nimport type { SessionUser } from '../auth/helpers';\r\nimport { queueEmail } from '../plugins/email/email-queue';\r\nimport type { CompanyDetails } from '../plugins/email/templates/types';\r\nimport { queueErp } from '../plugins/erp/erp-queue';\r\nimport type { ERPSubmissionService } from '../plugins/erp/erp-submission';\r\nimport { assertCaptchaOk } from '../plugins/captcha/assert';\r\nimport { llmAgentToChatAgentOptions, type LlmAgent } from '../entities/llm-agent.entity';\r\nimport type { LlmAgentOptions, LlmMessage } from '../plugins/llm/llm-service';\r\n\r\nexport type RequireEntityPermissionFn = (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;\r\n\r\n/** Avoid duplicating the current user turn when the DB already includes it (see postMessage flow). */\r\nfunction historyBeforeCurrentUser(history: LlmMessage[], currentUserContent: string): LlmMessage[] {\r\n const last = history[history.length - 1];\r\n if (last?.role === 'user' && last.content === currentUserContent) {\r\n return history.slice(0, -1);\r\n }\r\n return [...history];\r\n}\r\n\r\n/**\r\n * Optional JSON in `LlmAgent.validationRules`. Used for programmatic checks before the LLM call.\r\n * For natural-language output rules, use `guardrails` / `outputRules` / `outputInstructions` (merged into system prompt).\r\n */\r\nexport type LlmAgentValidationRulesJson = {\r\n maxUserChars?: number;\r\n maxMessageLength?: number;\r\n minUserChars?: number;\r\n minMessageLength?: number;\r\n blockedSubstrings?: string[];\r\n /** Shown to the model as output guardrails (first non-empty of guardrails | outputRules | outputInstructions wins). */\r\n guardrails?: string;\r\n outputRules?: string;\r\n outputInstructions?: string;\r\n};\r\n\r\nexport type ParsedLlmAgentValidation = {\r\n /** Subset used for length / substring checks only. */\r\n structured: Pick<\r\n LlmAgentValidationRulesJson,\r\n 'maxUserChars' | 'maxMessageLength' | 'minUserChars' | 'minMessageLength' | 'blockedSubstrings'\r\n >;\r\n /** Appended to system prompt so the model follows output guardrails. */\r\n guardrailsForPrompt: string | null;\r\n};\r\n\r\nfunction pickStructuredRules(rules: LlmAgentValidationRulesJson): ParsedLlmAgentValidation['structured'] {\r\n return {\r\n maxUserChars: rules.maxUserChars,\r\n maxMessageLength: rules.maxMessageLength,\r\n minUserChars: rules.minUserChars,\r\n minMessageLength: rules.minMessageLength,\r\n blockedSubstrings: rules.blockedSubstrings,\r\n };\r\n}\r\n\r\nfunction guardrailsTextFromJsonObject(rules: LlmAgentValidationRulesJson): string | null {\r\n const g =\r\n (typeof rules.guardrails === 'string' && rules.guardrails.trim()) ||\r\n (typeof rules.outputRules === 'string' && rules.outputRules.trim()) ||\r\n (typeof rules.outputInstructions === 'string' && rules.outputInstructions.trim()) ||\r\n '';\r\n return g || null;\r\n}\r\n\r\n/**\r\n * - Valid JSON object: structural keys → validation; `guardrails` / `outputRules` / `outputInstructions` → prompt suffix.\r\n * - Not JSON: entire string is treated as prose guardrails for the prompt (no programmatic rules unless you use JSON).\r\n */\r\nexport function parseLlmAgentValidationRules(\r\n validationRulesText: string | null | undefined\r\n): ParsedLlmAgentValidation {\r\n const raw = validationRulesText?.trim();\r\n if (!raw) return { structured: {}, guardrailsForPrompt: null };\r\n try {\r\n const parsed = JSON.parse(raw) as unknown;\r\n if (typeof parsed === 'string') {\r\n const s = parsed.trim();\r\n return { structured: {}, guardrailsForPrompt: s || null };\r\n }\r\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\r\n return { structured: {}, guardrailsForPrompt: raw };\r\n }\r\n const rules = parsed as LlmAgentValidationRulesJson;\r\n return {\r\n structured: pickStructuredRules(rules),\r\n guardrailsForPrompt: guardrailsTextFromJsonObject(rules),\r\n };\r\n } catch {\r\n return { structured: {}, guardrailsForPrompt: raw };\r\n }\r\n}\r\n\r\nexport function validateUserMessageAgainstStructuredRules(\r\n message: string,\r\n structured: ParsedLlmAgentValidation['structured']\r\n): { ok: true } | { ok: false; error: string } {\r\n const maxLen = structured.maxUserChars ?? structured.maxMessageLength;\r\n if (typeof maxLen === 'number' && Number.isFinite(maxLen) && maxLen >= 0 && message.length > maxLen) {\r\n return { ok: false, error: `Message exceeds maximum length (${maxLen} characters)` };\r\n }\r\n\r\n const minLen = structured.minUserChars ?? structured.minMessageLength;\r\n if (typeof minLen === 'number' && Number.isFinite(minLen) && minLen > 0 && message.length < minLen) {\r\n return { ok: false, error: `Message is shorter than minimum length (${minLen} characters)` };\r\n }\r\n\r\n const blocked = structured.blockedSubstrings;\r\n if (Array.isArray(blocked) && blocked.length > 0) {\r\n const lower = message.toLowerCase();\r\n for (const s of blocked) {\r\n if (typeof s !== 'string' || !s.trim()) continue;\r\n if (lower.includes(s.toLowerCase())) {\r\n return { ok: false, error: 'Message contains disallowed content' };\r\n }\r\n }\r\n }\r\n\r\n return { ok: true };\r\n}\r\n\r\n/** Parses `validationRules` then runs programmatic checks only. */\r\nexport function validateUserMessageAgainstAgentRules(\r\n message: string,\r\n validationRulesText: string | null | undefined\r\n): { ok: true } | { ok: false; error: string } {\r\n const { structured } = parseLlmAgentValidationRules(validationRulesText);\r\n return validateUserMessageAgainstStructuredRules(message, structured);\r\n}\r\n\r\n/** Merges guardrails prose into the system instruction sent to the model. */\r\nexport function mergeGuardrailsIntoSystemPrompt(\r\n baseSystem: string | undefined,\r\n guardrailsForPrompt: string | null\r\n): string {\r\n const g = guardrailsForPrompt?.trim();\r\n const b = (baseSystem ?? '').trim();\r\n if (!g) return b;\r\n const block = `### Output guardrails (follow in every reply)\\n${g}`;\r\n return b ? `${b}\\n\\n${block}` : block;\r\n}\r\n\r\nexport interface CmsHandlersBase {\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n requireAuth: (req: Request) => Promise<Response | null>;\r\n requireEntityPermission?: RequireEntityPermissionFn;\r\n}\r\n\r\nexport interface DashboardStatsConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n requirePermission?: (req: Request, permission: string) => Promise<Response | null>;\r\n}\r\n\r\nexport function createDashboardStatsHandler(config: DashboardStatsConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requirePermission, requireEntityPermission } = config;\r\n return async function GET(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'dashboard', 'read');\r\n if (pe) return pe;\r\n }\r\n if (requirePermission) {\r\n const permErr = await requirePermission(req, 'view_dashboard');\r\n if (permErr) return permErr;\r\n }\r\n try {\r\n const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);\r\n const repo = (name: string) => entityMap[name] ? dataSource.getRepository(entityMap[name]) : undefined;\r\n const [contactsCount, formsCount, formSubmissionsCount, usersCount, blogsCount, recentContacts, recentSubmissions, contactTypeRows] = await Promise.all([\r\n repo('contacts')?.count({ where: { deleted: false } }) ?? 0,\r\n repo('forms')?.count({ where: { deleted: false } }) ?? 0,\r\n repo('form_submissions')?.count() ?? 0,\r\n repo('users')?.count({ where: { deleted: false } }) ?? 0,\r\n repo('blogs')?.count({ where: { deleted: false } }) ?? 0,\r\n repo('contacts')?.count({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(sevenDaysAgo) },\r\n }) ?? 0,\r\n repo('form_submissions')?.count({ where: { createdAt: MoreThanOrEqual(sevenDaysAgo) } }) ?? 0,\r\n repo('contacts')\r\n ?.createQueryBuilder('c')\r\n .select(\"COALESCE(NULLIF(TRIM(c.type), ''), 'unknown')\", 'type')\r\n .addSelect('COUNT(*)', 'count')\r\n .where('c.deleted = :deleted', { deleted: false })\r\n .groupBy(\"COALESCE(NULLIF(TRIM(c.type), ''), 'unknown')\")\r\n .getRawMany<{ type: string; count: string }>() ?? [],\r\n ]);\r\n return json({\r\n contacts: { total: contactsCount, recent: recentContacts },\r\n forms: { total: formsCount, submissions: formSubmissionsCount, recentSubmissions },\r\n users: usersCount,\r\n blogs: blogsCount,\r\n contactTypes: (contactTypeRows ?? []).map((row) => ({\r\n type: row.type || 'unknown',\r\n count: Number(row.count || 0),\r\n })),\r\n });\r\n } catch (err) {\r\n return json({ error: 'Failed to fetch dashboard stats' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface EcommerceAnalyticsConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n}\r\n\r\ntype SalesTrendPoint = { date: string; value: number; orders: number };\r\ntype ReturnsTrendPoint = { date: string; value: number; count: number };\r\n\r\nfunction toNum(v: unknown): number {\r\n const n = typeof v === 'number' ? v : Number(v ?? 0);\r\n return Number.isFinite(n) ? n : 0;\r\n}\r\n\r\nfunction toIsoDate(d: Date): string {\r\n return d.toISOString().slice(0, 10);\r\n}\r\n\r\nexport function createEcommerceAnalyticsHandler(config: EcommerceAnalyticsConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n return async function GET(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'analytics', 'read');\r\n if (pe) return pe;\r\n }\r\n if (!entityMap.orders || !entityMap.order_items || !entityMap.payments || !entityMap.products) {\r\n return json({ error: 'Store analytics unavailable' }, { status: 404 });\r\n }\r\n try {\r\n const url = new URL(req.url);\r\n const rawDays = parseInt(url.searchParams.get('days') || '30', 10);\r\n const days = Number.isFinite(rawDays) ? Math.min(365, Math.max(7, rawDays)) : 30;\r\n const end = new Date();\r\n const start = new Date(end.getTime() - days * 24 * 60 * 60 * 1000);\r\n\r\n const orderRepo = dataSource.getRepository(entityMap.orders);\r\n const paymentRepo = dataSource.getRepository(entityMap.payments);\r\n const itemRepo = dataSource.getRepository(entityMap.order_items);\r\n const productRepo = dataSource.getRepository(entityMap.products);\r\n\r\n const [salesOrders, returnOrders, replacementOrders, payments, products] = await Promise.all([\r\n orderRepo.find({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(start), orderKind: 'sale', status: In(['confirmed', 'processing', 'completed']) } as object,\r\n select: ['id', 'contactId', 'createdAt', 'subtotal', 'discount', 'tax', 'total', 'status'],\r\n }),\r\n orderRepo.find({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(start), orderKind: 'return' } as object,\r\n select: ['id', 'createdAt', 'total'],\r\n }),\r\n orderRepo.find({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(start), orderKind: 'replacement' } as object,\r\n select: ['id', 'createdAt', 'total'],\r\n }),\r\n paymentRepo.find({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(start) } as object,\r\n select: ['id', 'status', 'method', 'amount', 'createdAt'],\r\n }),\r\n productRepo.find({\r\n where: { deleted: false } as object,\r\n select: ['id', 'name', 'quantity'],\r\n }),\r\n ]);\r\n\r\n const saleOrderIds = salesOrders.map((o) => o.id);\r\n const orderItems = saleOrderIds.length\r\n ? await itemRepo.find({\r\n where: { orderId: In(saleOrderIds) } as object,\r\n select: ['id', 'orderId', 'productId', 'quantity', 'total'],\r\n })\r\n : [];\r\n\r\n const grossSales = salesOrders.reduce((sum, o) => sum + toNum(o.subtotal), 0);\r\n const discounts = salesOrders.reduce((sum, o) => sum + toNum(o.discount), 0);\r\n const taxes = salesOrders.reduce((sum, o) => sum + toNum(o.tax), 0);\r\n const returnsValue = returnOrders.reduce((sum, o) => sum + toNum(o.total), 0);\r\n const replacementsValue = replacementOrders.reduce((sum, o) => sum + toNum(o.total), 0);\r\n const netSales = grossSales - discounts - returnsValue;\r\n const ordersCount = salesOrders.length;\r\n const aov = ordersCount > 0 ? netSales / ordersCount : 0;\r\n const returnRate = ordersCount > 0 ? (returnOrders.length / ordersCount) * 100 : 0;\r\n\r\n const salesByDate = new Map<string, { value: number; orders: number }>();\r\n const returnsByDate = new Map<string, { value: number; count: number }>();\r\n for (const o of salesOrders) {\r\n const key = toIsoDate(new Date(o.createdAt));\r\n const row = salesByDate.get(key) ?? { value: 0, orders: 0 };\r\n row.value += toNum(o.total);\r\n row.orders += 1;\r\n salesByDate.set(key, row);\r\n }\r\n for (const o of returnOrders) {\r\n const key = toIsoDate(new Date(o.createdAt));\r\n const row = returnsByDate.get(key) ?? { value: 0, count: 0 };\r\n row.value += toNum(o.total);\r\n row.count += 1;\r\n returnsByDate.set(key, row);\r\n }\r\n\r\n const salesOverTime: SalesTrendPoint[] = [];\r\n const returnsTrend: ReturnsTrendPoint[] = [];\r\n for (let i = days - 1; i >= 0; i--) {\r\n const d = new Date(end.getTime() - i * 24 * 60 * 60 * 1000);\r\n const key = toIsoDate(d);\r\n const sales = salesByDate.get(key) ?? { value: 0, orders: 0 };\r\n const returns = returnsByDate.get(key) ?? { value: 0, count: 0 };\r\n salesOverTime.push({ date: key, value: Number(sales.value.toFixed(2)), orders: sales.orders });\r\n returnsTrend.push({ date: key, value: Number(returns.value.toFixed(2)), count: returns.count });\r\n }\r\n\r\n const productNameMap = new Map<number, string>();\r\n for (const p of products) productNameMap.set(Number(p.id), (p.name || `Product #${p.id}`).trim());\r\n const productAgg = new Map<number, { name: string; units: number; sales: number }>();\r\n for (const item of orderItems) {\r\n const productId = Number(item.productId);\r\n const productName = productNameMap.get(productId) || `Product #${productId}`;\r\n const row = productAgg.get(productId) ?? { name: productName, units: 0, sales: 0 };\r\n row.units += toNum(item.quantity);\r\n row.sales += toNum(item.total);\r\n productAgg.set(productId, row);\r\n }\r\n const topProducts = Array.from(productAgg.values())\r\n .sort((a, b) => b.sales - a.sales)\r\n .slice(0, 5)\r\n .map((p) => ({ ...p, sales: Number(p.sales.toFixed(2)) }));\r\n\r\n const allSaleOrderContactIds = Array.from(new Set(salesOrders.map((o) => Number(o.contactId)).filter((n) => Number.isInteger(n) && n > 0)));\r\n const allTimeCounts = allSaleOrderContactIds.length\r\n ? await orderRepo\r\n .createQueryBuilder('o')\r\n .select('o.contactId', 'contactId')\r\n .addSelect('COUNT(*)', 'total')\r\n .where('o.deleted = :deleted', { deleted: false })\r\n .andWhere('o.orderKind = :orderKind', { orderKind: 'sale' })\r\n .andWhere('o.contactId IN (:...contactIds)', { contactIds: allSaleOrderContactIds })\r\n .groupBy('o.contactId')\r\n .getRawMany<{ contactId: string; total: string }>()\r\n : [];\r\n const countMap = new Map<number, number>();\r\n for (const c of allTimeCounts) countMap.set(Number(c.contactId), Number(c.total));\r\n const purchasingCustomers = allSaleOrderContactIds.length;\r\n const returningCustomers = allSaleOrderContactIds.filter((id) => (countMap.get(id) ?? 0) > 1).length;\r\n const newCustomers = Math.max(0, purchasingCustomers - returningCustomers);\r\n const returningCustomerRate = purchasingCustomers > 0 ? (returningCustomers / purchasingCustomers) * 100 : 0;\r\n\r\n const totalPayments = payments.length;\r\n const completedPayments = payments.filter((p) => p.status === 'completed').length;\r\n const failedPayments = payments.filter((p) => p.status === 'failed').length;\r\n const paymentSuccessRate = totalPayments > 0 ? (completedPayments / totalPayments) * 100 : 0;\r\n const paymentMethodMap = new Map<string, { method: string; count: number; amount: number }>();\r\n for (const p of payments) {\r\n const method = (p.method || 'unknown').toLowerCase();\r\n const row = paymentMethodMap.get(method) ?? { method, count: 0, amount: 0 };\r\n row.count += 1;\r\n row.amount += toNum(p.amount);\r\n paymentMethodMap.set(method, row);\r\n }\r\n const paymentMethods = Array.from(paymentMethodMap.values())\r\n .sort((a, b) => b.count - a.count)\r\n .map((p) => ({ ...p, amount: Number(p.amount.toFixed(2)) }));\r\n\r\n const totalInventory = products.reduce((sum, p) => sum + toNum(p.quantity), 0);\r\n const outOfStockCount = products.filter((p) => toNum(p.quantity) <= 0).length;\r\n const lowStockCount = products.filter((p) => toNum(p.quantity) > 0 && toNum(p.quantity) <= 5).length;\r\n const inventoryRisk = {\r\n outOfStockCount,\r\n lowStockCount,\r\n totalInventory,\r\n };\r\n\r\n return json({\r\n rangeDays: days,\r\n kpis: {\r\n netSales: Number(netSales.toFixed(2)),\r\n grossSales: Number(grossSales.toFixed(2)),\r\n ordersPlaced: ordersCount,\r\n averageOrderValue: Number(aov.toFixed(2)),\r\n returningCustomerRate: Number(returningCustomerRate.toFixed(2)),\r\n returnRate: Number(returnRate.toFixed(2)),\r\n returnValue: Number(returnsValue.toFixed(2)),\r\n discounts: Number(discounts.toFixed(2)),\r\n taxes: Number(taxes.toFixed(2)),\r\n paymentSuccessRate: Number(paymentSuccessRate.toFixed(2)),\r\n },\r\n salesOverTime,\r\n topProducts,\r\n customerMix: {\r\n newCustomers,\r\n returningCustomers,\r\n repeatPurchaseRate: Number(returningCustomerRate.toFixed(2)),\r\n },\r\n returnsTrend,\r\n paymentPerformance: {\r\n successCount: completedPayments,\r\n failedCount: failedPayments,\r\n successRate: Number(paymentSuccessRate.toFixed(2)),\r\n methods: paymentMethods,\r\n },\r\n conversionProxy: {\r\n sessions: 0,\r\n checkoutStarted: 0,\r\n ordersPlaced: ordersCount,\r\n },\r\n salesBreakdown: {\r\n sales: { count: ordersCount, value: Number(grossSales.toFixed(2)) },\r\n returns: { count: returnOrders.length, value: Number(returnsValue.toFixed(2)) },\r\n replacements: { count: replacementOrders.length, value: Number(replacementsValue.toFixed(2)) },\r\n },\r\n geoPerformance: [],\r\n inventoryRisk,\r\n });\r\n } catch {\r\n return json({ error: 'Failed to fetch ecommerce analytics' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface AnalyticsHandlerConfig extends CmsHandlersBase {\r\n getAnalyticsData?: (days: number) => Promise<unknown>;\r\n getPropertyId?: () => ({ currentViewId?: string; [k: string]: unknown });\r\n getPermissions?: () => ({ serviceAccountEmail?: string; currentViewId?: string; [k: string]: unknown });\r\n}\r\n\r\nexport function createAnalyticsHandlers(config: AnalyticsHandlerConfig) {\r\n const { json, getAnalyticsData, getPropertyId, getPermissions } = config;\r\n return {\r\n async GET(req: Request): Promise<Response> {\r\n if (!getAnalyticsData) return json({ error: 'Analytics not configured' }, { status: 404 });\r\n try {\r\n const url = new URL(req.url);\r\n const days = parseInt(url.searchParams.get('days') || '30', 10);\r\n const data = await getAnalyticsData(days);\r\n return json(data);\r\n } catch (err: unknown) {\r\n const msg = err instanceof Error ? err.message : '';\r\n if (msg.includes('authentication credential')) return json({ error: 'Google Analytics authentication failed.' }, { status: 401 });\r\n if (msg.includes('sufficient permissions')) return json({ error: 'Service account does not have access.' }, { status: 403 });\r\n return json({ error: 'Failed to fetch analytics data' }, { status: 500 });\r\n }\r\n },\r\n propertyId: async (): Promise<Response> => {\r\n const payload = getPropertyId ? getPropertyId() : { currentViewId: process.env.GOOGLE_ANALYTICS_VIEW_ID };\r\n return json({ message: 'Property ID Information', ...payload });\r\n },\r\n permissions: async (): Promise<Response> => {\r\n const payload = getPermissions ? getPermissions() : {\r\n serviceAccountEmail: process.env.GOOGLE_ANALYTICS_CLIENT_EMAIL,\r\n currentViewId: process.env.GOOGLE_ANALYTICS_VIEW_ID,\r\n };\r\n return json({ message: 'Permission Troubleshooting Guide', ...payload });\r\n },\r\n };\r\n}\r\n\r\nimport type { StorageService } from '../plugins/storage';\r\nimport { sanitizeMediaFolderPath } from '../lib/media-folder-path';\r\nimport { relativePathFromMediaParentId } from '../lib/media-parent-path';\r\nimport { extractZipMediaIntoParentTree } from '../lib/media-zip-extract';\r\n\r\nexport type { StorageService };\r\n\r\nexport interface UploadHandlerConfig extends CmsHandlersBase {\r\n /** Storage plugin instance or getter (e.g. () => getCms().then(c => c.getPlugin('storage'))). If not set, uses local fallback. */\r\n storage?: StorageService | (() => StorageService | undefined) | (() => Promise<StorageService | undefined>);\r\n /** Fallback when storage not set: dir relative to cwd (e.g. \"public/uploads\") */\r\n localUploadDir?: string;\r\n allowedTypes?: string[];\r\n maxSizeBytes?: number;\r\n /** Resolve folder chain for `parentId` (merged from createCmsApiHandler when omitted). */\r\n dataSource?: DataSource;\r\n entityMap?: EntityMap;\r\n}\r\n\r\nexport function createUploadHandler(config: UploadHandlerConfig) {\r\n const {\r\n json,\r\n requireAuth,\r\n requireEntityPermission,\r\n storage,\r\n localUploadDir = 'public/uploads',\r\n allowedTypes,\r\n maxSizeBytes = 10 * 1024 * 1024,\r\n dataSource,\r\n entityMap,\r\n } = config;\r\n const allowed = allowedTypes ?? [\r\n 'image/jpeg',\r\n 'image/png',\r\n 'image/gif',\r\n 'image/webp',\r\n 'application/pdf',\r\n 'text/plain',\r\n 'application/zip',\r\n 'application/x-zip-compressed',\r\n ];\r\n return async function POST(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'upload', 'create');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const formData = await req.formData();\r\n const file = formData.get('file') as File | null;\r\n if (!file) return json({ error: 'No file uploaded' }, { status: 400 });\r\n if (!allowed.includes(file.type)) return json({ error: 'File type not allowed' }, { status: 400 });\r\n const defaultMax = 10 * 1024 * 1024;\r\n const maxZipBytes = 80 * 1024 * 1024;\r\n const baseMax = maxSizeBytes ?? defaultMax;\r\n const effectiveMax =\r\n file.type === 'application/zip' || file.type === 'application/x-zip-compressed'\r\n ? Math.max(baseMax, maxZipBytes)\r\n : baseMax;\r\n if (file.size > effectiveMax) return json({ error: 'File size exceeds limit' }, { status: 400 });\r\n const parentRaw = formData.get('parentId');\r\n let parentId: number | null = null;\r\n if (parentRaw != null && String(parentRaw).trim() !== '') {\r\n const n = Number(parentRaw);\r\n if (!Number.isFinite(n)) return json({ error: 'Invalid parentId' }, { status: 400 });\r\n parentId = n;\r\n }\r\n let folder = '';\r\n if (parentId != null) {\r\n if (!dataSource || !entityMap?.media) {\r\n return json({ error: 'Upload handler needs dataSource and entityMap for folder uploads' }, { status: 400 });\r\n }\r\n const repo = dataSource.getRepository(entityMap.media);\r\n const p = await repo.findOne({ where: { id: parentId } });\r\n if (!p || (p as { kind: string }).kind !== 'folder') {\r\n return json({ error: 'parent must be a folder' }, { status: 400 });\r\n }\r\n folder = await relativePathFromMediaParentId(dataSource, entityMap, parentId);\r\n } else {\r\n const folderRawLegacy = formData.get('folder') ?? formData.get('folderPath');\r\n if (folderRawLegacy && typeof folderRawLegacy === 'string' && folderRawLegacy.trim()) {\r\n folder = sanitizeMediaFolderPath(folderRawLegacy);\r\n }\r\n }\r\n const buffer = Buffer.from(await file.arrayBuffer());\r\n const fileName = `${Date.now()}-${file.name}`;\r\n const contentType = file.type || 'application/octet-stream';\r\n const relativeUnderUploads = folder ? `${folder}/${fileName}` : fileName;\r\n const raw = typeof storage === 'function' ? storage() : storage;\r\n const storageService = raw instanceof Promise ? await raw : raw;\r\n if (storageService) {\r\n const fileUrl = await storageService.upload(buffer, `uploads/${relativeUnderUploads}`, contentType);\r\n return json({ filePath: fileUrl, parentId });\r\n }\r\n const fs = await import('fs/promises');\r\n const path = await import('path');\r\n const dir = path.join(process.cwd(), localUploadDir);\r\n const filePath = path.join(dir, relativeUnderUploads);\r\n await fs.mkdir(path.dirname(filePath), { recursive: true });\r\n await fs.writeFile(filePath, buffer);\r\n const urlRel = `${localUploadDir.replace(/^\\/+/, '').replace(/\\\\/g, '/')}/${relativeUnderUploads.replace(/\\\\/g, '/')}`;\r\n return json({ filePath: `/${urlRel}`, parentId });\r\n } catch (err) {\r\n return json({ error: 'File upload failed' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\n/** POST /api/media/extract/:id — expand a zip media row into folders/files under the zip’s parent folder. */\r\nexport function createMediaZipExtractHandler(config: UploadHandlerConfig) {\r\n const { json, requireAuth, requireEntityPermission, storage, localUploadDir = 'public/uploads', dataSource, entityMap } =\r\n config;\r\n return async function POST(_req: Request, zipMediaId: string): Promise<Response> {\r\n const authErr = await requireAuth(_req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(_req, 'media', 'create');\r\n if (pe) return pe;\r\n }\r\n if (!dataSource || !entityMap?.media) {\r\n return json({ error: 'Media extract requires dataSource and entityMap' }, { status: 500 });\r\n }\r\n const id = Number(zipMediaId);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const repo = dataSource.getRepository(entityMap.media);\r\n const row = await repo.findOne({ where: { id } });\r\n if (!row) return json({ error: 'Not found' }, { status: 404 });\r\n try {\r\n const raw = typeof storage === 'function' ? storage() : storage;\r\n const storageService = raw instanceof Promise ? await raw : raw;\r\n const result = await extractZipMediaIntoParentTree({\r\n dataSource,\r\n entityMap,\r\n zipMediaRow: row,\r\n storage: storageService,\r\n localUploadDir,\r\n });\r\n return json({ ok: true, ...result });\r\n } catch (e) {\r\n const msg = e instanceof Error ? e.message : 'Extract failed';\r\n return json({ error: msg }, { status: 400 });\r\n }\r\n };\r\n}\r\n\r\nexport interface BlogBySlugConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n}\r\n\r\nexport function createBlogBySlugHandler(config: BlogBySlugConfig) {\r\n const { dataSource, entityMap, json } = config;\r\n return async function GET(_req: Request, slug: string): Promise<Response> {\r\n try {\r\n const blogRepo = dataSource.getRepository(entityMap.blogs);\r\n const blog = await blogRepo.findOne({\r\n where: { slug, published: true },\r\n relations: ['author', 'category', 'tags', 'seo'],\r\n });\r\n if (!blog) return json({ error: 'Blog not found' }, { status: 404 });\r\n return json(blog);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface FormBySlugConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n}\r\n\r\nexport function createFormBySlugHandler(config: FormBySlugConfig) {\r\n const { dataSource, entityMap, json } = config;\r\n return async function GET(_req: Request, slug: string): Promise<Response> {\r\n try {\r\n const formRepo = dataSource.getRepository(entityMap.forms);\r\n const form = await formRepo.findOne({\r\n where: { slug, published: true, deleted: false },\r\n relations: ['fields'],\r\n order: { fields: { order: 'ASC' } },\r\n });\r\n if (!form) return json({ error: 'Form not found' }, { status: 404 });\r\n const out = form as { fields?: unknown[] };\r\n if (Array.isArray(out.fields)) out.fields = out.fields.filter((f) => !(f as { deleted?: boolean }).deleted);\r\n return json(form);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface FormSaveHandlersConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n}\r\n\r\n/** Normalize a field from payload for DB: only include columns that exist on form_fields. */\r\nfunction normalizeFieldRow(f: Record<string, unknown>, formId: number): Record<string, unknown> {\r\n const order = typeof f.order === 'number' ? f.order : Number(f.order) || 0;\r\n const groupId = typeof f.groupId === 'number' ? f.groupId : Number(f.groupId) || 1;\r\n const columnWidth = typeof f.columnWidth === 'number' ? f.columnWidth : Number(f.columnWidth) || 12;\r\n return {\r\n formId,\r\n label: f.label != null ? String(f.label) : '',\r\n type: f.type != null ? String(f.type) : 'text',\r\n placeholder: f.placeholder != null ? String(f.placeholder) : null,\r\n options: f.options != null ? (typeof f.options === 'string' ? f.options : JSON.stringify(f.options)) : null,\r\n required: Boolean(f.required),\r\n validation: f.validation != null ? (typeof f.validation === 'string' ? f.validation : JSON.stringify(f.validation)) : null,\r\n order,\r\n groupId,\r\n columnWidth,\r\n };\r\n}\r\n\r\nexport function createFormSaveHandlers(config: FormSaveHandlersConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n const formRepo = () => dataSource.getRepository(entityMap.forms);\r\n const fieldRepo = () => dataSource.getRepository(entityMap.form_fields);\r\n\r\n return {\r\n async GET(req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'forms', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const formId = Number(id);\r\n if (!Number.isInteger(formId) || formId <= 0) return json({ error: 'Invalid form id' }, { status: 400 });\r\n const form = await formRepo().findOne({\r\n where: { id: formId },\r\n relations: ['fields'],\r\n order: { fields: { order: 'ASC' } },\r\n });\r\n if (!form) return json({ message: 'Not found' }, { status: 404 });\r\n const out = form as { fields?: { deleted?: boolean }[] };\r\n if (Array.isArray(out.fields)) out.fields = out.fields.filter((f) => !f.deleted);\r\n return json(form);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async POST(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'forms', 'create');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const body = (await req.json()) as Record<string, unknown> | null;\r\n if (!body || typeof body !== 'object') return json({ error: 'Invalid request payload' }, { status: 400 });\r\n const fields = Array.isArray(body.fields) ? body.fields : [];\r\n const { fields: _f, ...formRow } = body;\r\n const form = await formRepo().save(formRepo().create(formRow as object));\r\n for (let i = 0; i < fields.length; i++) {\r\n const row = normalizeFieldRow(fields[i] as Record<string, unknown>, form.id);\r\n (row as Record<string, unknown>).order = i + 1;\r\n await fieldRepo().save(fieldRepo().create(row as object));\r\n }\r\n const saved = await formRepo().findOne({ where: { id: form.id }, relations: ['fields'], order: { fields: { order: 'ASC' } } });\r\n return json(saved ?? form, { status: 201 });\r\n } catch (e) {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async PUT(req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'forms', 'update');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const formId = Number(id);\r\n if (!Number.isInteger(formId) || formId <= 0) return json({ error: 'Invalid form id' }, { status: 400 });\r\n const body = (await req.json()) as Record<string, unknown> | null;\r\n if (!body || typeof body !== 'object') return json({ error: 'Invalid request payload' }, { status: 400 });\r\n const existing = await formRepo().findOne({ where: { id: formId } });\r\n if (!existing) return json({ message: 'Not found' }, { status: 404 });\r\n const fields = Array.isArray(body.fields) ? body.fields : [];\r\n const formRow: Record<string, unknown> = {};\r\n for (const key of ['name', 'description', 'campaign', 'slug', 'published']) {\r\n if (body[key] !== undefined) formRow[key] = body[key];\r\n }\r\n if (Object.keys(formRow).length > 0) await formRepo().update(formId, formRow as object);\r\n await fieldRepo().delete({ formId });\r\n for (let i = 0; i < fields.length; i++) {\r\n const row = normalizeFieldRow(fields[i] as Record<string, unknown>, formId);\r\n (row as Record<string, unknown>).order = i + 1;\r\n await fieldRepo().save(fieldRepo().create(row as object));\r\n }\r\n const saved = await formRepo().findOne({ where: { id: formId }, relations: ['fields'], order: { fields: { order: 'ASC' } } });\r\n return saved ? json(saved) : json({ message: 'Not found' }, { status: 404 });\r\n } catch (e) {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport interface FormSubmissionHandlerConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n /** When set, form submission notification email is queued (CRM recipient). */\r\n getCms?: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n getCompanyDetails?: () => Promise<CompanyDetails>;\r\n getRecipientForChannel?: (channel: 'crm' | 'sales' | 'fulfilment') => Promise<string | null>;\r\n}\r\n\r\nasync function isErpIntegrationEnabled(dataSource: DataSource, entityMap: EntityMap): Promise<boolean> {\r\n const repo = dataSource.getRepository(entityMap.configs);\r\n const rows = await repo.find({ where: { settings: 'erp', deleted: false } as object });\r\n for (const row of rows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'enabled') return r.value !== 'false';\r\n }\r\n return true;\r\n}\r\n\r\n/** Form IDs that use `form.submitted` (opportunity). `null` = config key absent (treat as no IDs → all submissions use lead). */\r\nasync function getErpOpportunityFormIds(dataSource: DataSource, entityMap: EntityMap): Promise<number[] | null> {\r\n const repo = dataSource.getRepository(entityMap.configs);\r\n const row = await repo.findOne({\r\n where: { settings: 'erp', key: 'opportunityFormIds', deleted: false } as object,\r\n });\r\n if (!row) return null;\r\n const raw = ((row as { value: string }).value ?? '').trim();\r\n if (!raw) return [];\r\n try {\r\n const parsed = JSON.parse(raw) as unknown;\r\n if (!Array.isArray(parsed)) return [];\r\n const ids = parsed\r\n .map((x) => (typeof x === 'number' ? x : Number(x)))\r\n .filter((n): n is number => Number.isInteger(n) && n > 0);\r\n return [...new Set(ids)];\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\nexport interface FormSubmissionGetByIdConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n}\r\n\r\nexport function createFormSubmissionGetByIdHandler(config: FormSubmissionGetByIdConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n return async function GET(req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'form_submissions', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const submissionId = Number(id);\r\n if (!Number.isInteger(submissionId) || submissionId <= 0) return json({ error: 'Invalid id' }, { status: 400 });\r\n const repo = dataSource.getRepository(entityMap.form_submissions);\r\n const submission = await repo.findOne({\r\n where: { id: submissionId },\r\n relations: ['form', 'contact'],\r\n });\r\n if (!submission) return json({ message: 'Not found' }, { status: 404 });\r\n const form = submission as { form?: { id: number; fields?: unknown[] } };\r\n if (form.form?.id) {\r\n const formRepo = dataSource.getRepository(entityMap.forms);\r\n const formWithFields = await formRepo.findOne({\r\n where: { id: form.form.id },\r\n relations: ['fields'],\r\n order: { fields: { order: 'ASC' as const } },\r\n });\r\n if (formWithFields) (submission as { form?: unknown }).form = formWithFields;\r\n }\r\n return json(submission);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface FormSubmissionListConfig extends FormSubmissionGetByIdConfig {}\r\n\r\nexport function createFormSubmissionListHandler(config: FormSubmissionListConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n return async function GET(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'form_submissions', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const repo = dataSource.getRepository(entityMap.form_submissions);\r\n const { searchParams } = new URL(req.url);\r\n const page = Number(searchParams.get('page')) || 1;\r\n const limit = Math.min(100, Number(searchParams.get('limit')) || 10);\r\n const skip = (page - 1) * limit;\r\n const sortField = searchParams.get('sortField') || 'createdAt';\r\n const sortOrder = searchParams.get('sortOrder') === 'desc' ? 'DESC' : 'ASC';\r\n const [data, total] = await repo.findAndCount({\r\n skip,\r\n take: limit,\r\n order: { [sortField]: sortOrder },\r\n relations: ['form', 'contact'],\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nfunction formatSubmissionFieldValue(raw: unknown): string {\r\n if (raw == null || raw === '') return '—';\r\n if (typeof raw === 'object') return JSON.stringify(raw);\r\n return String(raw);\r\n}\r\n\r\nfunction pickContactFromSubmission(\r\n fields: { id: number; type: string; label: string }[],\r\n data: Record<string, unknown>\r\n): { name: string; email: string; phone: string | null } | null {\r\n let email: string | null = null;\r\n let name: string | null = null;\r\n let phone: string | null = null;\r\n for (const f of fields) {\r\n const val = data[String(f.id)];\r\n if (val == null || val === '') continue;\r\n const str = String(val).trim();\r\n if (f.type === 'email' || (f.label && f.label.toLowerCase().includes('email'))) {\r\n if (str && !email) email = str;\r\n } else if (f.type === 'phone' || (f.label && f.label.toLowerCase().includes('phone'))) {\r\n if (str && !phone) phone = str;\r\n } else if (f.label && f.label.toLowerCase().includes('name') && (f.type === 'text' || !f.type)) {\r\n if (str && !name) name = str;\r\n }\r\n }\r\n if (!email) return null;\r\n return { name: name || email, email, phone: phone || null };\r\n}\r\n\r\nexport function createFormSubmissionHandler(config: FormSubmissionHandlerConfig) {\r\n const { dataSource, entityMap, json, getCms } = config;\r\n return async function POST(req: Request): Promise<Response> {\r\n try {\r\n const body = (await req.json()) as Record<string, unknown> | null;\r\n if (!body || typeof body !== 'object') {\r\n return json({ error: 'Invalid request payload' }, { status: 400 });\r\n }\r\n const captchaErr = await assertCaptchaOk(getCms, body, req, json);\r\n if (captchaErr) return captchaErr;\r\n const formId = typeof body.formId === 'number' ? body.formId : Number(body.formId);\r\n if (!Number.isInteger(formId) || formId <= 0) {\r\n return json({ error: 'formId is required and must be a positive integer' }, { status: 400 });\r\n }\r\n const data = body.data;\r\n if (!data || typeof data !== 'object' || Array.isArray(data)) {\r\n return json({ error: 'data is required and must be an object' }, { status: 400 });\r\n }\r\n const formRepo = dataSource.getRepository(entityMap.forms);\r\n const form = await formRepo.findOne({\r\n where: { id: formId, published: true, deleted: false },\r\n relations: ['fields'],\r\n });\r\n if (!form) {\r\n return json({ error: 'Form not found' }, { status: 404 });\r\n }\r\n const fields = (form as { fields?: { id: number; type: string; label: string; deleted?: boolean }[] }).fields ?? [];\r\n const activeFields = fields.filter((f) => !f.deleted);\r\n\r\n let contactId: number | null =\r\n body.contactId != null && body.contactId !== ''\r\n ? (typeof body.contactId === 'number' ? body.contactId : Number(body.contactId))\r\n : null;\r\n\r\n if (!contactId) {\r\n const contactData = pickContactFromSubmission(activeFields, data as Record<string, unknown>);\r\n if (contactData) {\r\n const contactRepo = dataSource.getRepository(entityMap.contacts);\r\n let contact = await contactRepo.findOne({ where: { email: contactData.email } });\r\n if (!contact) {\r\n const createdAt = new Date();\r\n contact = await contactRepo.save(\r\n contactRepo.create({\r\n name: contactData.name,\r\n email: contactData.email,\r\n phone: contactData.phone,\r\n createdAt,\r\n updatedAt: createdAt,\r\n })\r\n );\r\n }\r\n contactId = contact.id;\r\n }\r\n }\r\n\r\n const ipAddress = (req.headers.get('x-forwarded-for') ?? req.headers.get('x-real-ip') ?? null) as string | null;\r\n const userAgent = req.headers.get('user-agent') ?? null;\r\n const submissionRepo = dataSource.getRepository(entityMap.form_submissions);\r\n const created = await submissionRepo.save(\r\n submissionRepo.create({\r\n formId,\r\n contactId: Number.isInteger(contactId) ? contactId : null,\r\n data: data as Record<string, unknown>,\r\n ipAddress: ipAddress?.slice(0, 255) ?? null,\r\n userAgent: userAgent?.slice(0, 500) ?? null,\r\n })\r\n );\r\n\r\n const formWithName = form as { name?: string };\r\n const formName = formWithName.name ?? 'Form';\r\n let contactName = 'Unknown';\r\n let contactEmail = '';\r\n if (Number.isInteger(contactId)) {\r\n const contactRepo = dataSource.getRepository(entityMap.contacts);\r\n const contact = await contactRepo.findOne({ where: { id: contactId }, select: ['name', 'email'] });\r\n if (contact) {\r\n contactName = (contact as { name: string }).name ?? contactName;\r\n contactEmail = (contact as { email: string }).email ?? contactEmail;\r\n }\r\n } else {\r\n const contactData = pickContactFromSubmission(activeFields, data as Record<string, unknown>);\r\n if (contactData) {\r\n contactName = contactData.name;\r\n contactEmail = contactData.email;\r\n }\r\n }\r\n\r\n if (config.getCms) {\r\n try {\r\n const cms = await config.getCms();\r\n if (config.getCompanyDetails && config.getRecipientForChannel) {\r\n const to = await config.getRecipientForChannel('crm');\r\n if (to) {\r\n const companyDetails = await config.getCompanyDetails();\r\n const formFieldRows = activeFields.map((f) => ({\r\n label: (f.label && String(f.label).trim()) || `Field ${f.id}`,\r\n value: formatSubmissionFieldValue(data[String(f.id)]),\r\n }));\r\n await queueEmail(cms, {\r\n to,\r\n templateName: 'formSubmission',\r\n ctx: {\r\n formName,\r\n contactName,\r\n contactEmail,\r\n formData: data,\r\n formFieldRows,\r\n companyDetails: companyDetails ?? {},\r\n },\r\n });\r\n }\r\n }\r\n if (await isErpIntegrationEnabled(dataSource, entityMap)) {\r\n const erp = cms.getPlugin('erp') as { submission: ERPSubmissionService } | undefined;\r\n if (erp) {\r\n const contact = erp.submission.extractContactData(data as Record<string, unknown>, activeFields);\r\n if (contact?.email?.trim()) {\r\n const opportunityFormIds = await getErpOpportunityFormIds(dataSource, entityMap);\r\n const asOpportunity =\r\n opportunityFormIds != null &&\r\n opportunityFormIds.length > 0 &&\r\n opportunityFormIds.includes(formId);\r\n await queueErp(\r\n cms,\r\n asOpportunity ? { kind: 'formOpportunity', contact } : { kind: 'lead', contact }\r\n );\r\n }\r\n }\r\n }\r\n } catch {\r\n // do not fail the submission if notification / ERP queue fails\r\n }\r\n }\r\n\r\n return json(created, { status: 201 });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface UsersApiConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n baseUrl: string;\r\n /** When set with email queue/plugin, invite emails are sent on user create and regenerate-invite. */\r\n getCms?: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n getCompanyDetails?: () => Promise<CompanyDetails>;\r\n /** When set, soft-delete sets `deletedBy` on the user row. */\r\n getSessionUser?: () => Promise<SessionUser | null>;\r\n}\r\n\r\nexport function createUsersApiHandlers(config: UsersApiConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission, baseUrl, getCms, getCompanyDetails, getSessionUser } = config;\r\n\r\n async function trySendInviteEmail(toEmail: string, inviteLink: string, inviteeName: string): Promise<void> {\r\n if (!getCms) return;\r\n try {\r\n const cms = await getCms();\r\n const companyDetails = getCompanyDetails ? await getCompanyDetails() : {};\r\n await queueEmail(cms, {\r\n to: toEmail,\r\n templateName: 'invite',\r\n ctx: {\r\n inviteLink,\r\n email: toEmail,\r\n inviteeName: inviteeName.trim(),\r\n companyDetails: companyDetails ?? {},\r\n },\r\n });\r\n } catch {\r\n // do not fail user APIs if email fails\r\n }\r\n }\r\n const userRepo = () => dataSource.getRepository(entityMap.users);\r\n return {\r\n async list(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'users', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const url = new URL(req.url);\r\n const page = Math.max(1, parseInt(url.searchParams.get('page') || '1', 10));\r\n const limit = Math.min(100, parseInt(url.searchParams.get('limit') || '10', 10));\r\n const skip = (page - 1) * limit;\r\n const sortField = url.searchParams.get('sortField') || 'createdAt';\r\n const sortOrder = url.searchParams.get('sortOrder') === 'desc' ? 'DESC' : 'ASC';\r\n const search = url.searchParams.get('search');\r\n const where = search\r\n ? [\r\n { name: ILike(`%${search}%`), deleted: false },\r\n { email: ILike(`%${search}%`), deleted: false },\r\n ]\r\n : { deleted: false };\r\n const [data, total] = await userRepo().findAndCount({\r\n skip,\r\n take: limit,\r\n order: { [sortField]: sortOrder },\r\n where,\r\n relations: ['group'],\r\n select: ['id', 'name', 'email', 'blocked', 'createdAt', 'updatedAt', 'groupId'],\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async create(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'users', 'create');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const body = await req.json() as Record<string, unknown>;\r\n if (!body?.name || !body?.email) return json({ error: 'Name and email are required' }, { status: 400 });\r\n const existing = await userRepo().findOne({ where: { email: body.email as string } });\r\n if (existing) return json({ error: 'User with this email already exists' }, { status: 400 });\r\n const groupRepo = dataSource.getRepository(entityMap.user_groups);\r\n const customerG = await groupRepo.findOne({ where: { name: 'Customer', deleted: false } });\r\n const gid = (body.groupId as number) ?? null;\r\n const isCustomer = !!(customerG && gid === customerG.id);\r\n const adminAccess = isCustomer ? false : body.adminAccess === false ? false : true;\r\n const blocked =\r\n body.blocked === true ||\r\n body.blocked === 'true' ||\r\n body.blocked === 1 ||\r\n body.blocked === '1';\r\n const newUser = await userRepo().save(\r\n userRepo().create({\r\n name: body.name,\r\n email: body.email,\r\n password: null,\r\n blocked,\r\n groupId: gid,\r\n adminAccess,\r\n })\r\n );\r\n if (entityMap.contacts) {\r\n await linkUnclaimedContactToUser(dataSource, entityMap.contacts, newUser.id, newUser.email as string);\r\n }\r\n const emailToken = Buffer.from(newUser.email).toString('base64');\r\n const inviteLink = `${baseUrl}/admin/invite?token=${emailToken}`;\r\n await trySendInviteEmail(\r\n newUser.email as string,\r\n inviteLink,\r\n (newUser.name as string) ?? ''\r\n );\r\n return json(\r\n {\r\n message: blocked\r\n ? 'User created successfully (blocked until password is set)'\r\n : 'User created successfully',\r\n user: newUser,\r\n inviteLink,\r\n },\r\n { status: 201 }\r\n );\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async getById(_req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(new Request(_req.url));\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(_req, 'users', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const user = await userRepo().findOne({\r\n where: { id: parseInt(id, 10), deleted: false },\r\n relations: ['group'],\r\n select: ['id', 'name', 'email', 'blocked', 'createdAt', 'updatedAt', 'groupId'],\r\n });\r\n if (!user) return json({ error: 'User not found' }, { status: 404 });\r\n return json(user);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async update(req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'users', 'update');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const uid = parseInt(id, 10);\r\n const existing = await userRepo().findOne({ where: { id: uid, deleted: false } });\r\n if (!existing) return json({ error: 'Not found' }, { status: 404 });\r\n const body = await req.json() as Record<string, unknown>;\r\n const { password: _p, ...safe } = body;\r\n await userRepo().update(uid, safe as object);\r\n const updated = await userRepo().findOne({\r\n where: { id: uid, deleted: false },\r\n relations: ['group'],\r\n select: ['id', 'name', 'email', 'blocked', 'createdAt', 'updatedAt', 'groupId'],\r\n });\r\n return updated ? json(updated) : json({ error: 'Not found' }, { status: 404 });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async delete(_req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(new Request(_req.url));\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(_req, 'users', 'delete');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const uid = parseInt(id, 10);\r\n const existing = await userRepo().findOne({ where: { id: uid, deleted: false } });\r\n if (!existing) return json({ error: 'User not found' }, { status: 404 });\r\n let deletedBy: number | null = null;\r\n if (getSessionUser) {\r\n try {\r\n const u = await getSessionUser();\r\n if (u?.id) {\r\n const n = Number(u.id);\r\n if (Number.isFinite(n)) deletedBy = n;\r\n }\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n const payload: Record<string, unknown> = { deleted: true, deletedAt: new Date() };\r\n if (deletedBy != null) payload.deletedBy = deletedBy;\r\n await userRepo().update(uid, payload as object);\r\n return json({ message: 'User deleted successfully' });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async regenerateInvite(_req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(new Request(_req.url));\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(_req, 'users', 'update');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const user = await userRepo().findOne({\r\n where: { id: parseInt(id, 10), deleted: false },\r\n select: ['email', 'name'],\r\n });\r\n if (!user) return json({ error: 'User not found' }, { status: 404 });\r\n const emailToken = Buffer.from(user.email).toString('base64');\r\n const inviteLink = `${baseUrl}/admin/invite?token=${emailToken}`;\r\n await trySendInviteEmail(user.email as string, inviteLink, (user.name as string) ?? '');\r\n return json({ message: 'New invite link generated successfully', inviteLink });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport interface UserAvatarConfig extends CmsHandlersBase {\r\n getSession: () => Promise<{ user?: { email?: string | null } } | null>;\r\n /** Save avatar (buffer, fileName) => publicUrl. Default: local public/uploads/avatars */\r\n saveAvatar?: (buffer: Buffer, fileName: string) => Promise<string>;\r\n}\r\n\r\nexport function createUserAvatarHandler(config: UserAvatarConfig) {\r\n const { json, getSession, saveAvatar } = config;\r\n return async function POST(req: Request): Promise<Response> {\r\n const session = await getSession();\r\n if (!session?.user?.email) return json({ error: 'Unauthorized' }, { status: 401 });\r\n try {\r\n const formData = await req.formData();\r\n const file = formData.get('avatar') as File | null;\r\n if (!file) return json({ error: 'No file uploaded' }, { status: 400 });\r\n if (!file.type.startsWith('image/')) return json({ error: 'File must be an image' }, { status: 400 });\r\n if (file.size > 5 * 1024 * 1024) return json({ error: 'File size must be less than 5MB' }, { status: 400 });\r\n const buffer = Buffer.from(await file.arrayBuffer());\r\n const ext = file.name.split('.').pop() || 'jpg';\r\n const fileName = `avatar_${session.user.email}_${Date.now()}.${ext}`;\r\n const avatarUrl = saveAvatar\r\n ? await saveAvatar(buffer, fileName)\r\n : await (async () => {\r\n const fs = await import('fs/promises');\r\n const path = await import('path');\r\n const dir = path.join(process.cwd(), 'public', 'uploads', 'avatars');\r\n await fs.mkdir(dir, { recursive: true });\r\n await fs.writeFile(path.join(dir, fileName), buffer);\r\n return `/uploads/avatars/${fileName}`;\r\n })();\r\n return json({ message: 'Avatar uploaded successfully', avatarUrl });\r\n } catch {\r\n return json({ error: 'Internal server error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface UserProfileConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n getSession: () => Promise<{ user?: { email?: string | null; name?: string | null } } | null>;\r\n}\r\n\r\nexport function createUserProfileHandler(config: UserProfileConfig) {\r\n const { dataSource, entityMap, json, getSession } = config;\r\n return async function PUT(req: Request): Promise<Response> {\r\n const session = await getSession();\r\n if (!session?.user?.email) return json({ error: 'Unauthorized' }, { status: 401 });\r\n try {\r\n const body = await req.json() as { name?: string };\r\n if (!body?.name) return json({ error: 'Name is required' }, { status: 400 });\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n await userRepo.update({ email: session.user.email }, { name: body.name, updatedAt: new Date() });\r\n const updated = await userRepo.findOne({ where: { email: session.user.email }, select: ['id', 'name', 'email'] });\r\n if (!updated) return json({ error: 'Not found' }, { status: 404 });\r\n return json({ message: 'Profile updated successfully', user: { id: updated.id, name: updated.name, email: updated.email } });\r\n } catch {\r\n return json({ error: 'Internal server error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface SettingsApiConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n encryptionKey?: string;\r\n /** Groups in this list are readable without auth (GET returns all keys for the group). */\r\n publicGetGroups?: string[];\r\n}\r\n\r\nfunction simpleEncrypt(text: string, key: string): string {\r\n const buf = Buffer.from(text, 'utf8');\r\n const keyBuf = Buffer.from(key.padEnd(32, '0').slice(0, 32), 'utf8');\r\n const out = Buffer.alloc(buf.length);\r\n for (let i = 0; i < buf.length; i++) out[i] = buf[i] ^ keyBuf[i % keyBuf.length];\r\n return out.toString('base64');\r\n}\r\n\r\nfunction simpleDecrypt(encoded: string, key: string): string {\r\n const buf = Buffer.from(encoded, 'base64');\r\n const keyBuf = Buffer.from(key.padEnd(32, '0').slice(0, 32), 'utf8');\r\n const out = Buffer.alloc(buf.length);\r\n for (let i = 0; i < buf.length; i++) out[i] = buf[i] ^ keyBuf[i % keyBuf.length];\r\n return out.toString('utf8');\r\n}\r\n\r\n/**\r\n * Structural types so apps with their own `typeorm` install (e.g. npm link) typecheck without duplicate-package errors.\r\n */\r\nexport type GetPublicSettingsGroupDataSource = {\r\n getRepository(entity: unknown): {\r\n find(options: object): Promise<unknown[]>;\r\n };\r\n};\r\n\r\nexport interface GetPublicSettingsGroupConfig {\r\n dataSource: GetPublicSettingsGroupDataSource;\r\n entityMap: Record<string, unknown>;\r\n encryptionKey?: string;\r\n}\r\n\r\n/** Same rows as unauthenticated GET /api/settings/:group when the group is in publicGetGroups. */\r\nexport async function getPublicSettingsGroup(\r\n config: GetPublicSettingsGroupConfig,\r\n group: string\r\n): Promise<Record<string, string>> {\r\n const { dataSource, entityMap, encryptionKey } = config;\r\n const repo = dataSource.getRepository(entityMap.configs);\r\n const rows = await repo.find({ where: { settings: group, deleted: false } });\r\n const result: Record<string, string> = {};\r\n for (const row of rows) {\r\n const r = row as { key: string; value: string; encrypted?: boolean };\r\n let val = r.value;\r\n if (r.encrypted && encryptionKey) {\r\n try {\r\n val = simpleDecrypt(val, encryptionKey);\r\n } catch {\r\n /* keep raw if decrypt fails */\r\n }\r\n }\r\n result[r.key] = val;\r\n }\r\n return result;\r\n}\r\n\r\nexport function createSettingsApiHandlers(config: SettingsApiConfig) {\r\n const { dataSource, entityMap, json, requireAuth, encryptionKey, publicGetGroups } = config;\r\n const configRepo = () => dataSource.getRepository(entityMap.configs);\r\n\r\n return {\r\n async GET(req: Request, group: string): Promise<Response> {\r\n const isPublicGroup = publicGetGroups?.includes(group);\r\n const authErr = isPublicGroup ? null : await requireAuth(req);\r\n const isAuthed = !authErr;\r\n\r\n try {\r\n if (isPublicGroup) {\r\n const result = await getPublicSettingsGroup(\r\n { dataSource, entityMap, encryptionKey },\r\n group\r\n );\r\n return json(result);\r\n }\r\n\r\n const where: Record<string, unknown> = { settings: group, deleted: false };\r\n if (!isAuthed && !isPublicGroup) where.type = 'public';\r\n\r\n const rows = await configRepo().find({ where });\r\n const result: Record<string, unknown> = {};\r\n for (const row of rows) {\r\n const r = row as { key: string; value: string; encrypted?: boolean; type?: string };\r\n let val = r.value;\r\n if (r.encrypted && encryptionKey) {\r\n try { val = simpleDecrypt(val, encryptionKey); } catch { /* return raw if decrypt fails */ }\r\n }\r\n result[r.key] = val;\r\n }\r\n return json(result);\r\n } catch {\r\n return json({ error: 'Failed to fetch settings' }, { status: 500 });\r\n }\r\n },\r\n\r\n async PUT(req: Request, group: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n\r\n try {\r\n const body = await req.json() as Record<string, { value: string; type?: 'public' | 'private'; encrypted?: boolean }>;\r\n if (!body || typeof body !== 'object') return json({ error: 'Invalid payload' }, { status: 400 });\r\n\r\n const repo = configRepo();\r\n for (const [key, entry] of Object.entries(body)) {\r\n const val = typeof entry === 'string' ? entry : entry.value;\r\n const type = (typeof entry === 'object' && entry.type) || 'private';\r\n const encrypted = !!(typeof entry === 'object' && entry.encrypted);\r\n\r\n let storedValue = val;\r\n if (encrypted && encryptionKey) {\r\n storedValue = simpleEncrypt(val, encryptionKey);\r\n }\r\n\r\n const existing = await repo.findOne({ where: { settings: group, key } });\r\n if (existing) {\r\n await repo.update(existing.id, { value: storedValue, type, encrypted, updatedAt: new Date() } as object);\r\n } else {\r\n await repo.save(repo.create({ settings: group, key, value: storedValue, type, encrypted } as object));\r\n }\r\n }\r\n return json({ message: 'Settings saved' });\r\n } catch {\r\n return json({ error: 'Failed to save settings' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport interface ChatApiConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n getCms: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n}\r\n\r\nconst KB_CHUNK_LIMIT = 10;\r\nconst KB_CONTEXT_MAX_CHARS = 4000;\r\nconst RAG_LOG = '[rag-context]';\r\n\r\nfunction getQueryTerms(message: string): string[] {\r\n return message\r\n .replace(/[^\\w\\s]/g, ' ')\r\n .split(/\\s+/)\r\n .filter((w) => w.length > 2)\r\n .slice(0, 6);\r\n}\r\n\r\nfunction normalizeChatModeSetting(raw: string | undefined): 'whatsapp' | 'external' | 'llm' {\r\n if (raw === 'external' || raw === 'llm') return raw;\r\n return 'whatsapp';\r\n}\r\n\r\nasync function loadLlmSettingsMap(dataSource: DataSource, entityMap: EntityMap): Promise<Record<string, string>> {\r\n if (!entityMap.configs) return {};\r\n const repo = dataSource.getRepository(entityMap.configs);\r\n const rows = await repo.find({ where: { settings: 'llm', deleted: false } as object });\r\n const out: Record<string, string> = {};\r\n for (const row of rows as { key: string; value: string }[]) {\r\n out[row.key] = row.value;\r\n }\r\n return out;\r\n}\r\n\r\n/** Safe subset of `llm` settings for the storefront chat widget (`GET /api/chat/config`). */\r\nexport interface ChatPublicConfig {\r\n enabled: boolean;\r\n chatMode: 'whatsapp' | 'external' | 'llm';\r\n /** When `chatMode === 'llm'`, slug of the attached agent (from `attachedAgentSlug` setting). */\r\n agentSlug: string;\r\n botName: string;\r\n icon: string;\r\n iconImageUrl: string;\r\n iconBackgroundColor: string;\r\n headerColor: string;\r\n whatsappPhone: string;\r\n}\r\n\r\nexport function createChatHandlers(config: ChatApiConfig) {\r\n const { dataSource, entityMap, json, getCms } = config;\r\n const contactRepo = () => dataSource.getRepository(entityMap.contacts);\r\n const convRepo = () => dataSource.getRepository(entityMap.chat_conversations);\r\n const msgRepo = () => dataSource.getRepository(entityMap.chat_messages);\r\n const chunkRepo = () => dataSource.getRepository(entityMap.knowledge_base_chunks);\r\n\r\n return {\r\n async publicConfig(_req: Request): Promise<Response> {\r\n try {\r\n const map = await loadLlmSettingsMap(dataSource, entityMap);\r\n const mode = normalizeChatModeSetting(map.chatMode);\r\n const body: ChatPublicConfig = {\r\n enabled: map.enabled !== 'false',\r\n chatMode: mode,\r\n agentSlug: mode === 'llm' ? (map.attachedAgentSlug ?? '').trim() : '',\r\n botName: map.botName ?? '',\r\n icon: map.icon ?? '',\r\n iconImageUrl: map.iconImageUrl ?? '',\r\n iconBackgroundColor: map.iconBackgroundColor ?? '#6366f1',\r\n headerColor: map.headerColor ?? '#6366f1',\r\n whatsappPhone: map.whatsappPhone ?? '',\r\n };\r\n return json(body);\r\n } catch {\r\n return json({ error: 'Failed to load chat config' }, { status: 500 });\r\n }\r\n },\r\n async identify(req: Request): Promise<Response> {\r\n try {\r\n const body = (await req.json()) as { name?: string; email?: string; phone?: string };\r\n const name = body?.name?.trim();\r\n const email = body?.email?.trim();\r\n if (!name || !email) return json({ error: 'name and email required' }, { status: 400 });\r\n const repo = contactRepo();\r\n const phone = body.phone?.trim() || null;\r\n const existing = await repo.findOne({ where: { email } as import('typeorm').ObjectLiteral });\r\n let contact: import('typeorm').ObjectLiteral;\r\n if (!existing) {\r\n const createdAt = new Date();\r\n contact = (await repo.save(\r\n repo.create({ name, email, phone, createdAt, updatedAt: createdAt } as object)\r\n )) as import('typeorm').ObjectLiteral;\r\n } else {\r\n const row = existing as { id: number; deleted: boolean };\r\n if (row.deleted) {\r\n await repo.update(row.id, {\r\n deleted: false,\r\n deletedAt: null,\r\n deletedBy: null,\r\n name,\r\n phone,\r\n } as object);\r\n const refreshed = await repo.findOne({ where: { id: row.id } });\r\n if (!refreshed) return json({ error: 'Failed to identify', detail: 'contact missing after reactivate' }, { status: 500 });\r\n contact = refreshed as import('typeorm').ObjectLiteral;\r\n } else {\r\n contact = existing as import('typeorm').ObjectLiteral;\r\n }\r\n }\r\n const convRepoInst = convRepo();\r\n const contactId = (contact as { id: number }).id;\r\n const conv = await convRepoInst.save(convRepoInst.create({ contactId } as object));\r\n return json({\r\n contactId,\r\n conversationId: (conv as { id: number }).id,\r\n });\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to identify';\r\n return json({ error: 'Failed to identify', detail: message }, { status: 500 });\r\n }\r\n },\r\n async getMessages(req: Request, conversationId: string): Promise<Response> {\r\n try {\r\n const conv = await convRepo().findOne({\r\n where: { id: parseInt(conversationId, 10) },\r\n relations: ['messages'],\r\n });\r\n if (!conv) return json({ error: 'Conversation not found' }, { status: 404 });\r\n const messages = ((conv as { messages?: Array<{ role: string; content: string; createdAt: string }> }).messages ?? [])\r\n .sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())\r\n .map((m) => ({ role: m.role, content: m.content }));\r\n return json({ messages });\r\n } catch {\r\n return json({ error: 'Failed to fetch messages' }, { status: 500 });\r\n }\r\n },\r\n async postMessage(req: Request): Promise<Response> {\r\n try {\r\n const body = (await req.json()) as { conversationId?: number; message?: string; agentSlug?: string };\r\n const conversationId = body?.conversationId;\r\n const message = body?.message?.trim();\r\n if (!conversationId || !message) return json({ error: 'conversationId and message required' }, { status: 400 });\r\n const conv = await convRepo().findOne({\r\n where: { id: conversationId },\r\n relations: ['messages'],\r\n });\r\n if (!conv) return json({ error: 'Conversation not found' }, { status: 404 });\r\n const cms = await getCms();\r\n const llm = cms.getPlugin('llm') as {\r\n chat: (messages: LlmMessage[], opts?: object) => Promise<{ content: string }>;\r\n chatAgent?: (opts: LlmAgentOptions) => Promise<{ content: string }>;\r\n embed?: (text: string) => Promise<number[]>;\r\n } | undefined;\r\n if (!llm?.chat) return json({ error: 'LLM not configured' }, { status: 503 });\r\n\r\n const llmSettings = await loadLlmSettingsMap(dataSource, entityMap);\r\n const supportMode = normalizeChatModeSetting(llmSettings.chatMode);\r\n let effectiveSlug = (body?.agentSlug ?? '').trim();\r\n if (!effectiveSlug && supportMode === 'llm' && entityMap.llm_agents) {\r\n effectiveSlug = (llmSettings.attachedAgentSlug ?? '').trim();\r\n }\r\n\r\n let agentRow: LlmAgent | null = null;\r\n if (effectiveSlug) {\r\n if (!entityMap.llm_agents) {\r\n return json({ error: 'LLM agents are not configured on this deployment' }, { status: 400 });\r\n }\r\n const agentRepo = dataSource.getRepository(\r\n entityMap.llm_agents as EntityTarget<LlmAgent>\r\n );\r\n agentRow = await agentRepo.findOne({\r\n where: { slug: effectiveSlug, deleted: false, enabled: true },\r\n });\r\n if (!agentRow && (body?.agentSlug ?? '').trim()) {\r\n return json({ error: 'Agent not found or disabled', agentSlug: effectiveSlug }, { status: 404 });\r\n }\r\n }\r\n console.info(RAG_LOG, 'step 1 | resolve agent', {\r\n agentSlug: effectiveSlug || '(none)',\r\n agentFound: !!agentRow,\r\n agentId: agentRow?.id ?? null,\r\n });\r\n\r\n const parsedValidation = agentRow\r\n ? parseLlmAgentValidationRules(agentRow.validationRules)\r\n : { structured: {} as ParsedLlmAgentValidation['structured'], guardrailsForPrompt: null as string | null };\r\n if (agentRow) {\r\n const v = validateUserMessageAgainstStructuredRules(message, parsedValidation.structured);\r\n if (!v.ok) return json({ error: v.error, reason: 'validation_failed' }, { status: 400 });\r\n }\r\n\r\n let kbDocumentScope: number[] | undefined;\r\n const Junction = entityMap.llm_agent_knowledge_documents as EntityTarget<import('typeorm').ObjectLiteral> | undefined;\r\n if (agentRow && Junction) {\r\n const linkRepo = dataSource.getRepository(Junction);\r\n const links = await linkRepo.find({ where: { agentId: agentRow.id } as object });\r\n const ids = [...new Set((links as Array<{ documentId: number }>).map((l) => l.documentId))];\r\n if (ids.length > 0) kbDocumentScope = ids;\r\n }\r\n console.info(RAG_LOG, 'step 2 | knowledge scope', {\r\n scopedDocumentIds: kbDocumentScope ?? '(all documents)',\r\n documentCount: kbDocumentScope?.length ?? 'all',\r\n });\r\n\r\n const msgRepoInst = msgRepo();\r\n await msgRepoInst.save(msgRepoInst.create({ conversationId, role: 'user', content: message } as object));\r\n let contextParts: string[] = [];\r\n console.info(RAG_LOG, 'step 3 | embed user query', {\r\n messageChars: message.length,\r\n embedAvailable: !!llm.embed,\r\n });\r\n const queryEmbedding = llm.embed ? await llm.embed(message) : null;\r\n console.info(RAG_LOG, 'step 4 | query embedding result', {\r\n dimensions: queryEmbedding?.length ?? 0,\r\n hasEmbedding: !!(queryEmbedding && queryEmbedding.length > 0),\r\n });\r\n if (queryEmbedding && queryEmbedding.length > 0) {\r\n const vectorStr = '[' + queryEmbedding.join(',') + ']';\r\n try {\r\n const rows = (kbDocumentScope?.length\r\n ? await dataSource.query(\r\n `SELECT id, content FROM knowledge_base_chunks WHERE embedding IS NOT NULL AND \"documentId\" = ANY($3::int[]) ORDER BY embedding <=> $1::vector LIMIT $2`,\r\n [vectorStr, KB_CHUNK_LIMIT, kbDocumentScope]\r\n )\r\n : await dataSource.query(\r\n `SELECT id, content FROM knowledge_base_chunks WHERE embedding IS NOT NULL ORDER BY embedding <=> $1::vector LIMIT $2`,\r\n [vectorStr, KB_CHUNK_LIMIT]\r\n )) as Array<{ id: number; content: string }>;\r\n console.info(RAG_LOG, 'step 5 | vector search results', {\r\n rowsReturned: rows.length,\r\n chunkIds: rows.map((r) => r.id),\r\n });\r\n let totalLen = 0;\r\n for (const r of rows) {\r\n const text = (r.content ?? '').trim();\r\n if (!text || totalLen + text.length > KB_CONTEXT_MAX_CHARS) continue;\r\n contextParts.push(text);\r\n totalLen += text.length;\r\n }\r\n console.info(RAG_LOG, 'step 5a | vector context selected', {\r\n chunksUsed: contextParts.length,\r\n totalChars: totalLen,\r\n });\r\n } catch (vecErr) {\r\n console.warn(RAG_LOG, 'step 5 | vector search failed; falling back to keyword', {\r\n err: vecErr instanceof Error ? vecErr.message : String(vecErr),\r\n });\r\n }\r\n }\r\n if (contextParts.length === 0) {\r\n const terms = getQueryTerms(message);\r\n console.info(RAG_LOG, 'step 6 | keyword fallback', {\r\n reason: !(queryEmbedding && queryEmbedding.length > 0) ? 'no embedding' : 'vector search returned nothing',\r\n searchTerms: terms,\r\n });\r\n if (terms.length > 0) {\r\n const conditions = kbDocumentScope?.length\r\n ? terms.map((t) => ({ content: ILike(`%${t}%`), documentId: In(kbDocumentScope) }))\r\n : terms.map((t) => ({ content: ILike(`%${t}%`) }));\r\n const chunks = await chunkRepo().find({\r\n where: conditions,\r\n take: KB_CHUNK_LIMIT,\r\n order: { id: 'ASC' },\r\n });\r\n const seen = new Set<string>();\r\n let totalLen = 0;\r\n for (const c of chunks as Array<{ content: string }>) {\r\n const text = c.content.trim();\r\n if (seen.has(text) || totalLen + text.length > KB_CONTEXT_MAX_CHARS) continue;\r\n seen.add(text);\r\n contextParts.push(text);\r\n totalLen += text.length;\r\n }\r\n console.info(RAG_LOG, 'step 6a | keyword results', {\r\n chunksFound: chunks.length,\r\n chunksUsed: contextParts.length,\r\n totalChars: totalLen,\r\n });\r\n }\r\n }\r\n const historyRaw = ((conv as { messages?: Array<{ role: string; content: string; createdAt?: string }> }).messages ?? [])\r\n .sort((a, b) => new Date(a.createdAt ?? 0).getTime() - new Date(b.createdAt ?? 0).getTime())\r\n .map((m) => ({ role: m.role as LlmMessage['role'], content: m.content }));\r\n const history = historyBeforeCurrentUser(historyRaw, message);\r\n\r\n let content: string;\r\n const ragContext = contextParts.length > 0 ? contextParts.join('\\n\\n') : undefined;\r\n console.info(RAG_LOG, 'step 7 | final context', {\r\n method: contextParts.length > 0 ? 'rag' : 'none',\r\n contextChunks: contextParts.length,\r\n contextChars: ragContext?.length ?? 0,\r\n contextPreview: ragContext ? ragContext.slice(0, 200) + (ragContext.length > 200 ? '…' : '') : '(no context)',\r\n });\r\n\r\n if (agentRow && llm.chatAgent) {\r\n const fromAgent = llmAgentToChatAgentOptions(agentRow);\r\n const systemPrompt = mergeGuardrailsIntoSystemPrompt(\r\n fromAgent.systemPrompt,\r\n parsedValidation.guardrailsForPrompt\r\n );\r\n const res = await llm.chatAgent({\r\n ...fromAgent,\r\n systemPrompt: systemPrompt || undefined,\r\n context: ragContext,\r\n history,\r\n userPrompt: message,\r\n });\r\n content = res.content;\r\n } else {\r\n const ragSystem = contextParts.length > 0\r\n ? `Use the following context about the company and its products to answer. If the answer is not in the context, say so.\\n\\nContext:\\n${contextParts.join('\\n\\n')}`\r\n : '';\r\n const defaultSystem = 'You are a helpful assistant for the company. If you do not have specific information, say so.';\r\n let systemContent: string;\r\n if (agentRow) {\r\n const base = agentRow.systemInstruction?.trim() || '';\r\n systemContent = mergeGuardrailsIntoSystemPrompt(\r\n [base, ragSystem].filter(Boolean).join('\\n\\n') || defaultSystem,\r\n parsedValidation.guardrailsForPrompt\r\n );\r\n } else {\r\n systemContent = ragSystem || defaultSystem;\r\n }\r\n const messages: LlmMessage[] = [\r\n { role: 'system', content: systemContent },\r\n ...history,\r\n { role: 'user', content: message },\r\n ];\r\n const chatOpts = agentRow\r\n ? {\r\n model: agentRow.model ?? undefined,\r\n temperature: agentRow.temperature ?? undefined,\r\n max_tokens: agentRow.maxTokens ?? undefined,\r\n }\r\n : {};\r\n const res = await llm.chat(messages, chatOpts);\r\n content = res.content;\r\n }\r\n await msgRepoInst.save(msgRepoInst.create({ conversationId, role: 'assistant', content } as object));\r\n return json({ content });\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : '';\r\n return json({ error: msg || 'Failed to send message' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n","import type { CaptchaService } from './captcha-service';\r\n\r\ntype JsonResponse = (body: unknown, init?: { status?: number; headers?: HeadersInit }) => Response;\r\n\r\nexport async function assertCaptchaOk(\r\n getCms: (() => Promise<{ getPlugin: (name: string) => unknown }>) | undefined,\r\n body: Record<string, unknown>,\r\n req: Request,\r\n json: JsonResponse\r\n): Promise<Response | null> {\r\n if (!getCms) return null;\r\n let cms: { getPlugin: (name: string) => unknown };\r\n try {\r\n cms = await getCms();\r\n } catch {\r\n return null;\r\n }\r\n const svc = cms.getPlugin('captcha') as CaptchaService | undefined;\r\n if (!svc || typeof (svc as CaptchaService).verify !== 'function') return null;\r\n const result = await svc.verify(body, req);\r\n if (result.ok) return null;\r\n return json({ error: result.message }, { status: result.status });\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\nimport type { LlmAgentOptions } from '../plugins/llm/llm-service';\r\n\r\n@Entity('llm_agents')\r\nexport class LlmAgent {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n /** Stable key for API / widgets (e.g. `support`, `sales`). */\r\n @Column('varchar')\r\n slug: string;\r\n\r\n /** Passed as `systemPrompt` to `LlmService.chatAgent`. */\r\n @Column('text', { name: 'system_instruction', default: '' })\r\n systemInstruction: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n model: string | null;\r\n\r\n @Column('double precision', { name: 'temperature', nullable: true })\r\n temperature: number | null;\r\n\r\n @Column('int', { name: 'max_tokens', nullable: true })\r\n maxTokens: number | null;\r\n\r\n /**\r\n * Rules string: plain prose → appended to system prompt as output guardrails; JSON → see `parseLlmAgentValidationRules` in cms-handlers\r\n * (structural checks + optional `guardrails` / `outputRules` / `outputInstructions` for the model).\r\n */\r\n @Column('text', { name: 'validation_rules', nullable: true })\r\n validationRules: string | null;\r\n\r\n @Column('boolean', { default: true })\r\n enabled: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n\r\n/** Partial {@link LlmAgentOptions} for merging with `userPrompt` / `history` / `context`. */\r\nexport function llmAgentToChatAgentOptions(\r\n agent: LlmAgent\r\n): Pick<LlmAgentOptions, 'systemPrompt' | 'model' | 'temperature' | 'max_tokens'> {\r\n return {\r\n systemPrompt: agent.systemInstruction?.trim() || undefined,\r\n model: agent.model?.trim() || undefined,\r\n temperature: agent.temperature ?? undefined,\r\n max_tokens: agent.maxTokens ?? undefined,\r\n };\r\n}\r\n","/** Normalize a logical media folder path: no leading/trailing slashes, no \"..\" segments, max length. */\r\nexport function sanitizeMediaFolderPath(input: unknown): string {\r\n if (input == null) return '';\r\n if (typeof input !== 'string') return '';\r\n const segments = input\r\n .replace(/\\\\/g, '/')\r\n .split('/')\r\n .map((s) => s.trim())\r\n .filter(Boolean)\r\n .filter((s) => s !== '..' && s !== '.');\r\n const joined = segments.join('/');\r\n return joined.length > 512 ? joined.slice(0, 512) : joined;\r\n}\r\n\r\n/** Single path segment for storage (folder name or legacy path segment). */\r\nexport function sanitizeStorageSegment(name: string): string {\r\n const s = name.replace(/[/\\\\]/g, '-').trim().slice(0, 255);\r\n return s || 'item';\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport type { ObjectLiteral } from 'typeorm';\r\nimport type { EntityTarget } from 'typeorm';\r\nimport { sanitizeStorageSegment } from './media-folder-path';\r\n\r\ntype EntityMap = Record<string, EntityTarget<ObjectLiteral>>;\r\n\r\n/** Build `a/b/c` path under `uploads/` from the chain of folder rows up to root. */\r\nexport async function relativePathFromMediaParentId(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n parentId: number | null\r\n): Promise<string> {\r\n if (parentId == null) return '';\r\n const repo = dataSource.getRepository(entityMap.media);\r\n const segments: string[] = [];\r\n let id: number | null = parentId;\r\n for (let d = 0; d < 64 && id != null; d++) {\r\n const row = await repo.findOne({ where: { id } as ObjectLiteral });\r\n if (!row) break;\r\n const m = row as { kind?: string; filename: string; parentId: number | null };\r\n if (m.kind !== 'folder') break;\r\n segments.unshift(sanitizeStorageSegment(m.filename));\r\n id = m.parentId ?? null;\r\n }\r\n return segments.join('/');\r\n}\r\n","import { IsNull } from 'typeorm';\r\nimport type { DataSource } from 'typeorm';\r\nimport type { ObjectLiteral } from 'typeorm';\r\nimport type { EntityTarget } from 'typeorm';\r\nimport type { StorageService } from '../plugins/storage';\r\nimport { relativePathFromMediaParentId } from './media-parent-path';\r\nimport { sanitizeStorageSegment } from './media-folder-path';\r\n\r\ntype EntityMap = Record<string, EntityTarget<ObjectLiteral>>;\r\n\r\nexport const ZIP_MIME_TYPES = new Set(['application/zip', 'application/x-zip-compressed']);\r\n\r\nconst MAX_ENTRIES = 2000;\r\nconst MAX_TOTAL_UNCOMPRESSED = 80 * 1024 * 1024;\r\n\r\nexport function isZipMedia(mime: string | null | undefined, filename: string): boolean {\r\n if (mime && ZIP_MIME_TYPES.has(mime)) return true;\r\n return filename.toLowerCase().endsWith('.zip');\r\n}\r\n\r\nexport async function readBufferFromPublicUrl(url: string): Promise<Buffer> {\r\n if (url.startsWith('http://') || url.startsWith('https://')) {\r\n const r = await fetch(url);\r\n if (!r.ok) throw new Error('Failed to download file');\r\n return Buffer.from(await r.arrayBuffer());\r\n }\r\n if (url.startsWith('/')) {\r\n const { readFile } = await import('fs/promises');\r\n const { join } = await import('path');\r\n const rel = url.replace(/^\\/+/, '');\r\n return readFile(join(process.cwd(), 'public', rel));\r\n }\r\n throw new Error('Unsupported media URL');\r\n}\r\n\r\nfunction sanitizeZipPath(entryName: string): string[] | null {\r\n const norm = entryName.replace(/\\\\/g, '/').split('/').filter(Boolean);\r\n for (const seg of norm) {\r\n if (seg === '..' || seg === '.') return null;\r\n }\r\n return norm;\r\n}\r\n\r\nfunction shouldSkipEntry(parts: string[]): boolean {\r\n if (parts[0] === '__MACOSX') return true;\r\n const last = parts[parts.length - 1];\r\n if (last === '.DS_Store') return true;\r\n return false;\r\n}\r\n\r\nfunction guessMimeType(fileName: string): string {\r\n const lower = fileName.toLowerCase();\r\n if (lower.endsWith('.png')) return 'image/png';\r\n if (lower.endsWith('.jpg') || lower.endsWith('.jpeg')) return 'image/jpeg';\r\n if (lower.endsWith('.gif')) return 'image/gif';\r\n if (lower.endsWith('.webp')) return 'image/webp';\r\n if (lower.endsWith('.svg')) return 'image/svg+xml';\r\n if (lower.endsWith('.pdf')) return 'application/pdf';\r\n if (lower.endsWith('.txt')) return 'text/plain';\r\n if (lower.endsWith('.json')) return 'application/json';\r\n if (lower.endsWith('.zip')) return 'application/zip';\r\n return 'application/octet-stream';\r\n}\r\n\r\nasync function findOrCreateFolder(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n parentId: number | null,\r\n name: string\r\n): Promise<number> {\r\n const safe = sanitizeStorageSegment(name);\r\n const repo = dataSource.getRepository(entityMap.media);\r\n const where: ObjectLiteral =\r\n parentId == null\r\n ? { kind: 'folder', filename: safe, parentId: IsNull() }\r\n : { kind: 'folder', filename: safe, parentId };\r\n const existing = await repo.findOne({ where });\r\n if (existing) return (existing as { id: number }).id;\r\n const row = await repo.save(\r\n repo.create({\r\n kind: 'folder',\r\n parentId,\r\n filename: safe,\r\n url: null,\r\n mimeType: 'inode/directory',\r\n size: 0,\r\n alt: null,\r\n isPublic: false,\r\n deleted: false,\r\n } as object)\r\n );\r\n return (row as { id: number }).id;\r\n}\r\n\r\nasync function ensureFolderChain(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n rootParentId: number | null,\r\n pathSegments: string[]\r\n): Promise<number | null> {\r\n let pid: number | null = rootParentId;\r\n for (const seg of pathSegments) {\r\n if (!seg) continue;\r\n pid = await findOrCreateFolder(dataSource, entityMap, pid, seg);\r\n }\r\n return pid;\r\n}\r\n\r\nexport async function extractZipMediaIntoParentTree(opts: {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n zipMediaRow: ObjectLiteral;\r\n storage: StorageService | undefined;\r\n localUploadDir: string;\r\n}): Promise<{ files: number; folderEntries: number }> {\r\n const { dataSource, entityMap, zipMediaRow } = opts;\r\n const row = zipMediaRow as {\r\n id: number;\r\n kind: string;\r\n parentId: number | null;\r\n url: string | null;\r\n mimeType: string | null;\r\n filename: string;\r\n };\r\n if (row.kind !== 'file' || !row.url) throw new Error('Not a file');\r\n if (!isZipMedia(row.mimeType, row.filename)) throw new Error('Not a zip archive');\r\n\r\n const buffer = await readBufferFromPublicUrl(row.url);\r\n const { default: AdmZip } = await import('adm-zip');\r\n const zip = new AdmZip(buffer);\r\n const entries = zip.getEntries();\r\n if (entries.length > MAX_ENTRIES) throw new Error(`Too many zip entries (max ${MAX_ENTRIES})`);\r\n\r\n const rootParentId = row.parentId;\r\n\r\n type Item = { parts: string[]; isDir: boolean; data: Buffer | null };\r\n const items: Item[] = [];\r\n let totalUncompressed = 0;\r\n\r\n for (const e of entries) {\r\n const raw = e.entryName;\r\n const parts = sanitizeZipPath(raw);\r\n if (!parts || shouldSkipEntry(parts)) continue;\r\n const isDir = e.isDirectory || /\\/$/.test(raw);\r\n let data: Buffer | null = null;\r\n if (!isDir) {\r\n data = e.getData();\r\n totalUncompressed += data.length;\r\n if (totalUncompressed > MAX_TOTAL_UNCOMPRESSED) {\r\n throw new Error(`Uncompressed content exceeds limit (${MAX_TOTAL_UNCOMPRESSED} bytes)`);\r\n }\r\n }\r\n items.push({ parts, isDir, data });\r\n }\r\n\r\n items.sort((a, b) => {\r\n const da = a.parts.length;\r\n const db = b.parts.length;\r\n if (da !== db) return da - db;\r\n return a.parts.join('/').localeCompare(b.parts.join('/'));\r\n });\r\n\r\n let files = 0;\r\n let folderEntries = 0;\r\n const repo = dataSource.getRepository(entityMap.media);\r\n\r\n for (const it of items) {\r\n if (it.isDir) {\r\n await ensureFolderChain(dataSource, entityMap, rootParentId, it.parts);\r\n folderEntries++;\r\n continue;\r\n }\r\n const fileName = it.parts[it.parts.length - 1]!;\r\n const dirParts = it.parts.slice(0, -1);\r\n const parentFolderId = await ensureFolderChain(dataSource, entityMap, rootParentId, dirParts);\r\n const buf = it.data!;\r\n const relBase = await relativePathFromMediaParentId(dataSource, entityMap, parentFolderId);\r\n const relativeUnderUploads = relBase ? `${relBase}/${fileName}` : fileName;\r\n const contentType = guessMimeType(fileName);\r\n\r\n let publicUrl: string;\r\n if (opts.storage) {\r\n publicUrl = await opts.storage.upload(buf, `uploads/${relativeUnderUploads}`, contentType);\r\n } else {\r\n const fs = await import('fs/promises');\r\n const pathMod = await import('path');\r\n const dir = pathMod.join(process.cwd(), opts.localUploadDir);\r\n const filePath = pathMod.join(dir, relativeUnderUploads);\r\n await fs.mkdir(pathMod.dirname(filePath), { recursive: true });\r\n await fs.writeFile(filePath, buf);\r\n publicUrl = `/${opts.localUploadDir.replace(/^\\/+/, '').replace(/\\\\/g, '/')}/${relativeUnderUploads.replace(/\\\\/g, '/')}`;\r\n }\r\n\r\n await repo.save(\r\n repo.create({\r\n kind: 'file',\r\n parentId: parentFolderId,\r\n filename: fileName,\r\n url: publicUrl,\r\n mimeType: contentType,\r\n size: buf.length,\r\n alt: null,\r\n isPublic: false,\r\n deleted: false,\r\n } as object)\r\n );\r\n files++;\r\n }\r\n\r\n return { files, folderEntries };\r\n}\r\n","/**\n * Admin API: attach knowledge base documents to an LLM agent, ingest text into chunks + embeddings.\n * Routes: GET/POST /api/llm_agents/:slug/knowledge, DELETE /api/llm_agents/:slug/knowledge/:documentId\n *\n * Pipeline logs (grep `[llm-agent-knowledge] pipeline`):\n * - 01_request — incoming POST, content-type preview\n * - 02_agent_loaded — agent id for slug\n * - 03_body_parsed — JSON vs multipart, sizes / documentId\n * - 04_* — file decode or PDF extract (multipart)\n * - 05_branch — link_existing_document | new_upload_ingest\n * - 06_* — KB row + junction (link create / exists)\n * - 06b_chunks_existing_count — link path: existing chunk rows\n * - 06_knowledge_document_saved — new ingest: document row id\n * - 07_chunk_split — split stats\n * - 07b_chunks_persisted — chunk rows saved\n * - 07_query_chunks_missing_embedding — link path: rows with NULL embedding\n * - 08_* — resolve LLM plugin, embed availability or skip\n * - 09_embedding_workers_start / 10_embedding_workers_finished — concurrent embed+DB update\n * - 11_response — final outcome summary\n * - 99_pipeline_error — uncaught exception\n */\nimport type { DataSource, EntityTarget, ObjectLiteral } from 'typeorm';\nimport { In } from 'typeorm';\nimport type { EntityMap } from './crud';\nimport type { RequireEntityPermissionFn } from './cms-handlers';\nimport type { LlmAgent } from '../entities/llm-agent.entity';\n\nconst INGEST_CHUNK_CHARS = 900;\n/** Avoid serverless / DB timeouts on huge uploads; ~400 × 900 ≈ 360k chars. */\nconst MAX_CHUNKS_PER_UPLOAD = 400;\nconst EMBED_CONCURRENCY = 5;\n/** Limit PDF buffer size before parsing (memory / CPU). */\nconst MAX_PDF_BYTES = 25 * 1024 * 1024;\n\nconst TEXT_FILE_TYPES = new Set(['text/plain', 'text/markdown', 'application/json']);\n\nconst KB_LOG = '[llm-agent-knowledge]';\n\n/** Ordered pipeline logs: upload → KB document → chunks → junction → embeddings. */\nfunction logKbPipeline(step: string, meta?: Record<string, unknown>): void {\n console.info(`${KB_LOG} pipeline`, { step, ...meta });\n}\n\nfunction llmEmbedDebug(): boolean {\n const v = process.env.LLM_EMBED_DEBUG?.toLowerCase();\n return v === '1' || v === 'true' || v === 'yes';\n}\n\nfunction isPdfUpload(mime: string, fileName: string): boolean {\n if (mime === 'application/pdf') return true;\n const n = fileName.toLowerCase();\n return n.endsWith('.pdf');\n}\n\nasync function extractTextFromPdf(buffer: Buffer): Promise<string> {\n const pdfParse = (await import('pdf-parse')) as unknown as (\n data: Buffer\n ) => Promise<{ text?: string }>;\n const data = await pdfParse(buffer);\n return (data?.text ?? '').trim();\n}\n\n/** Chunks that still need vectors (e.g. after a failed embed pass or CRUD-created documents). */\nasync function loadChunksMissingEmbeddings(\n dataSource: DataSource,\n documentId: number,\n slug: string\n): Promise<Array<{ id: number; content: string }>> {\n const rows = (await dataSource.query(\n `SELECT id, content FROM knowledge_base_chunks WHERE \"documentId\" = $1 AND embedding IS NULL ORDER BY \"chunkIndex\" ASC`,\n [documentId]\n )) as Array<{ id: number; content: string }>;\n const list = rows ?? [];\n logKbPipeline('07_query_chunks_missing_embedding', {\n slug,\n documentId,\n missingEmbeddingCount: list.length,\n });\n return list;\n}\n\nasync function writeEmbeddingsConcurrent(\n dataSource: DataSource,\n embed: (t: string) => Promise<number[]>,\n chunks: Array<{ id: number; content: string }>,\n concurrency: number,\n slug: string\n): Promise<{ written: number; failed: number }> {\n let next = 0;\n let written = 0;\n let failed = 0;\n let skippedEmpty = 0;\n\n logKbPipeline('09_embedding_workers_start', {\n slug,\n chunkCount: chunks.length,\n concurrency: Math.max(1, Math.min(concurrency, chunks.length)),\n });\n\n async function worker() {\n for (;;) {\n const i = next++;\n if (i >= chunks.length) return;\n const c = chunks[i]!;\n try {\n const emb = await embed(c.content);\n if (emb?.length) {\n const vectorStr = '[' + emb.join(',') + ']';\n await dataSource.query(\n `UPDATE knowledge_base_chunks SET embedding = $1::vector WHERE id = $2`,\n [vectorStr, c.id]\n );\n written++;\n } else {\n skippedEmpty++;\n if (llmEmbedDebug()) {\n console.warn(`${KB_LOG} embed() returned empty vector`, { chunkId: c.id });\n }\n }\n } catch (err) {\n failed++;\n console.error(`${KB_LOG} embedding DB update failed`, {\n chunkId: c.id,\n err: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n const n = Math.max(1, Math.min(concurrency, chunks.length));\n await Promise.all(Array.from({ length: n }, () => worker()));\n const summary: Record<string, unknown> = {\n chunkCount: chunks.length,\n written,\n failed,\n skippedEmpty,\n };\n if (skippedEmpty > 0 && written === 0) {\n summary.hint =\n 'embed() returned empty vectors — see [LLM embed] / [LLM embed HF] logs (OpenAI gateway vs @huggingface/inference + legacy HTTP).';\n }\n logKbPipeline('10_embedding_workers_finished', { slug, ...summary });\n if (failed > 0 || (skippedEmpty > 0 && written === 0)) {\n console.error(`${KB_LOG} embedding pass finished with issues`, summary);\n }\n return { written, failed };\n}\n\nexport interface LlmAgentKnowledgeApiConfig {\n dataSource: DataSource;\n entityMap: EntityMap;\n getCms: () => Promise<{ getPlugin: (name: string) => unknown }>;\n json: (body: unknown, init?: { status?: number }) => Response;\n requireAuth: (req: Request) => Promise<Response | null>;\n requireEntityPermission?: RequireEntityPermissionFn;\n}\n\nfunction splitIntoChunks(text: string, maxLen: number): string[] {\n const t = text.trim();\n if (!t) return [];\n const chunks: string[] = [];\n for (let i = 0; i < t.length; i += maxLen) {\n chunks.push(t.slice(i, i + maxLen));\n }\n return chunks;\n}\n\nasync function findAgentBySlug(\n dataSource: DataSource,\n llmAgents: EntityTarget<ObjectLiteral>,\n slug: string\n): Promise<LlmAgent | null> {\n const repo = dataSource.getRepository(llmAgents as EntityTarget<LlmAgent>);\n return repo.findOne({\n where: { slug, deleted: false } as object,\n });\n}\n\nexport function createLlmAgentKnowledgeHandlers(config: LlmAgentKnowledgeApiConfig) {\n const { dataSource, entityMap, getCms, json, requireAuth, requireEntityPermission } = config;\n\n const kbDoc = entityMap.knowledge_base_documents;\n const kbChunk = entityMap.knowledge_base_chunks;\n const llmAgents = entityMap.llm_agents;\n const junction = entityMap.llm_agent_knowledge_documents;\n\n if (!kbDoc || !kbChunk || !llmAgents || !junction) {\n return null;\n }\n\n async function gate(req: Request, action: 'read' | 'update'): Promise<Response | null> {\n const a = await requireAuth(req);\n if (a) return a;\n if (requireEntityPermission) {\n const pe = await requireEntityPermission(req, 'llm_agents', action);\n if (pe) return pe;\n }\n return null;\n }\n\n async function runEmbeddingPass(\n slug: string,\n savedChunks: Array<{ id: number; content: string }>\n ): Promise<{ embeddingsWritten: number; embeddingsFailed: number; embedError?: string }> {\n let embeddingsWritten = 0;\n let embeddingsFailed = 0;\n try {\n logKbPipeline('08_resolve_llm_plugin', { slug, chunkCount: savedChunks.length });\n const cms = await getCms();\n const llm = cms.getPlugin('llm') as { embed?: (t: string) => Promise<number[]> } | undefined;\n if (llm?.embed && savedChunks.length > 0) {\n logKbPipeline('08b_embed_fn_available', {\n slug,\n chunkCount: savedChunks.length,\n firstChunkId: savedChunks[0]?.id,\n lastChunkId: savedChunks[savedChunks.length - 1]?.id,\n });\n const embedBound = (text: string) => llm.embed!(text);\n const { written, failed } = await writeEmbeddingsConcurrent(\n dataSource,\n embedBound,\n savedChunks,\n EMBED_CONCURRENCY,\n slug\n );\n embeddingsWritten = written;\n embeddingsFailed = failed;\n } else {\n logKbPipeline('08c_embed_skipped', {\n slug,\n hasLlmPlugin: !!llm,\n hasEmbed: typeof llm?.embed === 'function',\n chunkCount: savedChunks.length,\n reason: savedChunks.length === 0 ? 'no_chunks' : !llm ? 'no_llm_plugin' : 'no_embed_method',\n });\n console.error(`${KB_LOG} embeddings skipped`, {\n slug,\n hasLlmPlugin: !!llm,\n hasEmbed: typeof llm?.embed === 'function',\n chunkCount: savedChunks.length,\n hint:\n !llm || typeof llm.embed !== 'function'\n ? 'LLM plugin missing or no embed(); check LLM_GATEWAY_URL + LLM_API_KEY so llm plugin initializes.'\n : undefined,\n });\n }\n } catch (embErr) {\n const detail = embErr instanceof Error ? embErr.message : String(embErr);\n logKbPipeline('08d_embed_pass_exception', { slug, detail });\n console.error(`${KB_LOG} embedding step threw before/during batch`, { slug, detail, embErr });\n return {\n embeddingsWritten: 0,\n embeddingsFailed: savedChunks.length,\n embedError: detail,\n };\n }\n return { embeddingsWritten, embeddingsFailed };\n }\n\n return {\n async list(req: Request, slug: string): Promise<Response> {\n const denied = await gate(req, 'read');\n if (denied) return denied;\n try {\n const agent = await findAgentBySlug(dataSource, llmAgents, slug);\n if (!agent) return json({ error: 'Agent not found' }, { status: 404 });\n const linkRepo = dataSource.getRepository(junction);\n const links = await linkRepo.find({ where: { agentId: agent.id } as object });\n const docIds = [...new Set((links as Array<{ documentId: number }>).map((l) => l.documentId))];\n if (docIds.length === 0) return json({ documents: [] });\n const docRepo = dataSource.getRepository(kbDoc);\n const docs = await docRepo.find({ where: { id: In(docIds) } as object });\n const byId = new Map((docs as Array<{ id: number; name: string }>).map((d) => [d.id, d]));\n const documents = docIds\n .map((id) => {\n const d = byId.get(id);\n return d ? { id: d.id, name: d.name } : null;\n })\n .filter(Boolean);\n return json({ documents });\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to list knowledge';\n return json({ error: msg }, { status: 500 });\n }\n },\n\n async post(req: Request, slug: string): Promise<Response> {\n const denied = await gate(req, 'update');\n if (denied) return denied;\n try {\n const ct0 = req.headers.get('content-type') || '';\n logKbPipeline('01_request', { slug, contentType: ct0.slice(0, 80) });\n\n const agent = await findAgentBySlug(dataSource, llmAgents, slug);\n if (!agent) return json({ error: 'Agent not found' }, { status: 404 });\n logKbPipeline('02_agent_loaded', { slug, agentId: agent.id });\n\n let name = '';\n let text = '';\n let sourceUrl: string | null = null;\n let existingDocumentId: number | null = null;\n\n const ct = req.headers.get('content-type') || '';\n if (ct.includes('application/json')) {\n const body = (await req.json()) as {\n name?: string;\n text?: string;\n sourceUrl?: string | null;\n documentId?: number;\n };\n existingDocumentId =\n typeof body?.documentId === 'number' && Number.isFinite(body.documentId) ? body.documentId : null;\n name = (body?.name ?? '').trim();\n text = (body?.text ?? '').trim();\n sourceUrl =\n typeof body?.sourceUrl === 'string' && body.sourceUrl.trim() ? body.sourceUrl.trim() : null;\n logKbPipeline('03_body_parsed', {\n slug,\n mode: 'json',\n existingDocumentId,\n nameLen: name.length,\n textChars: text.length,\n hasSourceUrl: !!sourceUrl,\n });\n } else if (ct.includes('multipart/form-data')) {\n const form = await req.formData();\n name = (form.get('name') as string | null)?.trim() ?? '';\n text = (form.get('text') as string | null)?.trim() ?? '';\n const file = form.get('file');\n if (file && typeof file !== 'string' && 'arrayBuffer' in file) {\n const f = file as File;\n const mime = (f.type || '').split(';')[0]!.trim().toLowerCase();\n const buf = Buffer.from(await f.arrayBuffer());\n logKbPipeline('03_body_parsed', {\n slug,\n mode: 'multipart',\n fileName: f.name || '(no name)',\n mime,\n fileBytes: buf.length,\n });\n if (TEXT_FILE_TYPES.has(mime)) {\n const decoded = buf.toString('utf8');\n if (!text) text = decoded;\n logKbPipeline('04_file_decoded_text', { slug, mime, textChars: text.length });\n } else if (isPdfUpload(mime, f.name || '')) {\n if (buf.length > MAX_PDF_BYTES) {\n return json(\n { error: `PDF too large (max ${Math.floor(MAX_PDF_BYTES / (1024 * 1024))}MB)` },\n { status: 413 }\n );\n }\n try {\n logKbPipeline('04_pdf_extract_start', { slug, fileBytes: buf.length });\n const extracted = await extractTextFromPdf(buf);\n if (!text) text = extracted;\n logKbPipeline('04_pdf_extract_done', { slug, textChars: text.length });\n } catch {\n return json(\n { error: 'Could not read PDF text (file may be encrypted, corrupt, or image-only)' },\n { status: 422 }\n );\n }\n } else {\n return json(\n {\n error:\n 'Unsupported file type; use text/plain, text/markdown, application/json, or application/pdf',\n },\n { status: 415 }\n );\n }\n if (!name && f.name) name = f.name.replace(/\\.[^/.]+$/, '') || f.name;\n } else {\n logKbPipeline('03_body_parsed', { slug, mode: 'multipart', hasFile: false, textChars: text.length });\n }\n } else {\n return json({ error: 'Use application/json or multipart/form-data' }, { status: 400 });\n }\n\n const linkRepo = dataSource.getRepository(junction);\n\n if (existingDocumentId != null) {\n logKbPipeline('05_branch', { slug, branch: 'link_existing_document', documentId: existingDocumentId });\n const docRepo = dataSource.getRepository(kbDoc);\n const existing = await docRepo.findOne({ where: { id: existingDocumentId } as object });\n if (!existing) return json({ error: 'documentId not found' }, { status: 404 });\n const dup = await linkRepo.findOne({\n where: { agentId: agent.id, documentId: existingDocumentId } as object,\n });\n if (!dup) {\n await linkRepo.save(linkRepo.create({ agentId: agent.id, documentId: existingDocumentId } as object));\n logKbPipeline('06_junction_link_created', {\n slug,\n agentId: agent.id,\n documentId: existingDocumentId,\n });\n } else {\n logKbPipeline('06_junction_link_exists', {\n slug,\n agentId: agent.id,\n documentId: existingDocumentId,\n });\n }\n\n const chunkRepo = dataSource.getRepository(kbChunk);\n const docRow = existing as { id: number; content: string };\n const chunkCount = await chunkRepo.count({ where: { documentId: existingDocumentId } as object });\n logKbPipeline('06b_chunks_existing_count', {\n slug,\n documentId: existingDocumentId,\n chunkCount,\n });\n\n let chunksToEmbed: Array<{ id: number; content: string }> = [];\n let chunksCreated = 0;\n\n if (chunkCount === 0) {\n const text = (docRow.content ?? '').trim();\n if (!text) {\n logKbPipeline('07_ingest_aborted_empty_document', { slug, documentId: existingDocumentId });\n return json({\n documentId: existingDocumentId,\n linked: true,\n created: false,\n chunkCount: 0,\n embeddingsWritten: 0,\n embeddingsFailed: 0,\n warning: 'Document has no text content; add content then attach again to build chunks and embeddings.',\n });\n }\n const parts = splitIntoChunks(text, INGEST_CHUNK_CHARS);\n if (parts.length > MAX_CHUNKS_PER_UPLOAD) {\n return json(\n {\n error: `Document is too large for one ingest (${parts.length} chunks; max ${MAX_CHUNKS_PER_UPLOAD}). Split into smaller files.`,\n },\n { status: 413 }\n );\n }\n logKbPipeline('07_chunk_split', {\n slug,\n documentId: existingDocumentId,\n partCount: parts.length,\n maxChunkChars: INGEST_CHUNK_CHARS,\n totalChars: text.length,\n });\n const now = new Date();\n const chunkRows = parts.map((content, i) =>\n chunkRepo.create({\n documentId: existingDocumentId,\n content,\n chunkIndex: i,\n createdAt: now,\n } as object)\n );\n const savedList = await chunkRepo.save(chunkRows);\n chunksCreated = savedList.length;\n chunksToEmbed = (savedList as Array<{ id: number }>).map((row, i) => ({\n id: row.id,\n content: parts[i]!,\n }));\n logKbPipeline('07b_chunks_persisted', {\n slug,\n documentId: existingDocumentId,\n rowsInserted: chunksCreated,\n });\n } else {\n chunksToEmbed = await loadChunksMissingEmbeddings(dataSource, existingDocumentId, slug);\n if (chunksToEmbed.length === 0) {\n logKbPipeline('08_skip_embed_all_chunks_have_vectors', {\n slug,\n documentId: existingDocumentId,\n existingChunkCount: chunkCount,\n });\n }\n }\n\n const embedResult =\n chunksToEmbed.length > 0\n ? await runEmbeddingPass(slug, chunksToEmbed)\n : { embeddingsWritten: 0, embeddingsFailed: 0 };\n if (embedResult.embedError) {\n logKbPipeline('11_response', {\n slug,\n branch: 'link',\n documentId: existingDocumentId,\n ok: false,\n embeddingError: true,\n });\n return json(\n {\n documentId: existingDocumentId,\n linked: true,\n created: false,\n chunkCount: chunkCount + chunksCreated,\n chunksCreated,\n embeddingAttempted: true,\n embeddingsWritten: 0,\n embeddingsFailed: chunksToEmbed.length,\n warning: 'Document linked; embedding step failed. Fix LLM/embed config and attach again (or unlink and re-attach) to retry NULL embeddings.',\n detail: embedResult.embedError,\n },\n { status: 201 }\n );\n }\n\n logKbPipeline('11_response', {\n slug,\n branch: 'link',\n documentId: existingDocumentId,\n ok: true,\n chunkCount: chunkCount + chunksCreated,\n chunksCreated,\n chunksQueuedForEmbedding: chunksToEmbed.length,\n embeddingsWritten: embedResult.embeddingsWritten,\n embeddingsFailed: embedResult.embeddingsFailed,\n });\n return json({\n documentId: existingDocumentId,\n linked: true,\n created: false,\n chunkCount: chunkCount + chunksCreated,\n chunksCreated: chunksCreated || undefined,\n chunksQueuedForEmbedding: chunksToEmbed.length,\n embeddingAttempted: chunksToEmbed.length > 0,\n embeddingsWritten: embedResult.embeddingsWritten,\n embeddingsFailed: embedResult.embeddingsFailed,\n });\n }\n\n logKbPipeline('05_branch', { slug, branch: 'new_upload_ingest' });\n\n if (!text) return json({ error: 'text or file with text content is required' }, { status: 400 });\n if (!name) name = 'Untitled';\n\n const parts = splitIntoChunks(text, INGEST_CHUNK_CHARS);\n if (parts.length === 0) {\n return json({ error: 'text or file with text content is required' }, { status: 400 });\n }\n if (parts.length > MAX_CHUNKS_PER_UPLOAD) {\n return json(\n {\n error: `Document is too large for one upload (${parts.length} chunks; max ${MAX_CHUNKS_PER_UPLOAD}). Split into smaller files.`,\n },\n { status: 413 }\n );\n }\n logKbPipeline('07_chunk_split', {\n slug,\n partCount: parts.length,\n maxChunkChars: INGEST_CHUNK_CHARS,\n totalChars: text.length,\n documentName: name,\n });\n\n const docRepo = dataSource.getRepository(kbDoc);\n const chunkRepo = dataSource.getRepository(kbChunk);\n const now = new Date();\n const doc = await docRepo.save(\n docRepo.create({ name, content: text, sourceUrl, createdAt: now, updatedAt: now } as object)\n );\n const docId = (doc as { id: number }).id;\n logKbPipeline('06_knowledge_document_saved', {\n slug,\n documentId: docId,\n name,\n contentChars: text.length,\n hasSourceUrl: !!sourceUrl,\n });\n\n const chunkRows = parts.map((content, i) =>\n chunkRepo.create({ documentId: docId, content, chunkIndex: i, createdAt: now } as object)\n );\n const savedList = await chunkRepo.save(chunkRows);\n const savedChunks: Array<{ id: number; content: string }> = (savedList as Array<{ id: number }>).map(\n (row, i) => ({\n id: row.id,\n content: parts[i]!,\n })\n );\n logKbPipeline('07b_chunks_persisted', {\n slug,\n documentId: docId,\n rowsInserted: savedChunks.length,\n firstChunkId: savedChunks[0]?.id,\n lastChunkId: savedChunks[savedChunks.length - 1]?.id,\n });\n\n const dup = await linkRepo.findOne({ where: { agentId: agent.id, documentId: docId } as object });\n if (!dup) {\n await linkRepo.save(linkRepo.create({ agentId: agent.id, documentId: docId } as object));\n logKbPipeline('06c_junction_link_created', { slug, agentId: agent.id, documentId: docId });\n } else {\n logKbPipeline('06c_junction_link_exists', { slug, agentId: agent.id, documentId: docId });\n }\n\n const embedResult = await runEmbeddingPass(slug, savedChunks);\n if (embedResult.embedError) {\n logKbPipeline('11_response', {\n slug,\n branch: 'ingest',\n documentId: docId,\n ok: false,\n embeddingError: true,\n });\n return json(\n {\n documentId: docId,\n chunkCount: savedChunks.length,\n embeddingAttempted: true,\n created: true,\n linked: true,\n embeddingsWritten: 0,\n embeddingsFailed: savedChunks.length,\n warning: 'Document saved and linked; embedding step failed.',\n detail: embedResult.embedError,\n },\n { status: 201 }\n );\n }\n\n logKbPipeline('11_response', {\n slug,\n branch: 'ingest',\n documentId: docId,\n ok: true,\n chunkCount: savedChunks.length,\n embeddingsWritten: embedResult.embeddingsWritten,\n embeddingsFailed: embedResult.embeddingsFailed,\n });\n return json({\n documentId: docId,\n chunkCount: savedChunks.length,\n embeddingAttempted: savedChunks.length > 0,\n created: true,\n linked: true,\n embeddingsWritten: embedResult.embeddingsWritten,\n embeddingsFailed: embedResult.embeddingsFailed,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to ingest knowledge';\n const name = err instanceof Error ? err.name : '';\n logKbPipeline('99_pipeline_error', { slug, errorName: name, message: msg });\n return json({ error: msg, errorName: name || undefined }, { status: 500 });\n }\n },\n\n async unlink(req: Request, slug: string, documentIdStr: string): Promise<Response> {\n const denied = await gate(req, 'update');\n if (denied) return denied;\n const documentId = parseInt(documentIdStr, 10);\n if (!Number.isFinite(documentId)) return json({ error: 'Invalid document id' }, { status: 400 });\n try {\n const agent = await findAgentBySlug(dataSource, llmAgents, slug);\n if (!agent) return json({ error: 'Agent not found' }, { status: 404 });\n logKbPipeline('unlink_junction', { slug, agentId: agent.id, documentId });\n const linkRepo = dataSource.getRepository(junction);\n await linkRepo.delete({ agentId: agent.id, documentId } as object);\n return json({ ok: true });\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to unlink';\n return json({ error: msg }, { status: 500 });\n }\n },\n };\n}\n","export type SmsMessageTemplateDefault = {\r\n templateKey: string;\r\n name: string;\r\n body: string;\r\n externalTemplateRef?: string;\r\n providerMeta?: { otpVarKey?: string };\r\n};\r\n\r\nexport const SMS_MESSAGE_TEMPLATE_DEFAULTS: SmsMessageTemplateDefault[] = [\r\n {\r\n templateKey: 'auth.otp_login',\r\n name: 'Sign-in OTP (SMS)',\r\n body: 'Your sign-in code is {{code}}. Valid 10 minutes.',\r\n providerMeta: { otpVarKey: 'var1' },\r\n },\r\n {\r\n templateKey: 'auth.otp_verify_phone',\r\n name: 'Verify phone OTP (SMS)',\r\n body: 'Your verification code is {{code}}. Valid 10 minutes.',\r\n providerMeta: { otpVarKey: 'var1' },\r\n },\r\n];\r\n\r\nexport function getSmsTemplateDefault(templateKey: string): SmsMessageTemplateDefault | undefined {\r\n return SMS_MESSAGE_TEMPLATE_DEFAULTS.find((d) => d.templateKey === templateKey);\r\n}\r\n\r\nexport type ResolvedSmsTemplate = {\r\n body: string;\r\n externalTemplateRef: string | undefined;\r\n otpVarKey: string;\r\n};\r\n\r\nexport async function resolveSmsTemplateForSend(\r\n templateKey: string,\r\n getRow: (channel: string, key: string) => Promise<{\r\n body: string;\r\n externalTemplateRef: string | null;\r\n providerMeta: Record<string, unknown> | null;\r\n enabled: boolean;\r\n } | null>\r\n): Promise<ResolvedSmsTemplate | null> {\r\n const def = getSmsTemplateDefault(templateKey);\r\n if (!def) return null;\r\n\r\n const row = await getRow('sms', templateKey);\r\n let body = def.body;\r\n let ref = def.externalTemplateRef;\r\n let otpVarKey = def.providerMeta?.otpVarKey ?? 'var1';\r\n\r\n if (row && row.enabled !== false) {\r\n if (row.body.trim()) body = row.body;\r\n if (row.externalTemplateRef?.trim()) ref = row.externalTemplateRef.trim();\r\n const pm = row.providerMeta;\r\n const k = pm && typeof pm.otpVarKey === 'string' ? pm.otpVarKey.trim() : '';\r\n if (k) otpVarKey = k;\r\n }\r\n\r\n return {\r\n body,\r\n externalTemplateRef: ref?.trim() || undefined,\r\n otpVarKey: otpVarKey || 'var1',\r\n };\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport type { EntityMap } from './crud';\r\nimport { SMS_MESSAGE_TEMPLATE_DEFAULTS, getSmsTemplateDefault } from '../message-templates/sms-defaults';\r\nimport type { RequireEntityPermissionFn } from './cms-handlers';\r\n\r\nexport interface MessageTemplateAdminHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n requireAuth: (req: Request) => Promise<Response | null>;\r\n requireEntityPermission?: RequireEntityPermissionFn;\r\n}\r\n\r\nexport function createSmsMessageTemplateHandlers(config: MessageTemplateAdminHandlersConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n\r\n const repo = () => dataSource.getRepository(entityMap.message_templates);\r\n\r\n async function requireSettingsRead(req: Request): Promise<Response | null> {\r\n const a = await requireAuth(req);\r\n if (a) return a;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'settings', 'read');\r\n if (pe) return pe;\r\n }\r\n return null;\r\n }\r\n\r\n async function requireSettingsUpdate(req: Request): Promise<Response | null> {\r\n const a = await requireAuth(req);\r\n if (a) return a;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'settings', 'update');\r\n if (pe) return pe;\r\n }\r\n return null;\r\n }\r\n\r\n return {\r\n async GET(req: Request): Promise<Response> {\r\n const err = await requireSettingsRead(req);\r\n if (err) return err;\r\n try {\r\n const rows = await repo().find({ where: { channel: 'sms', deleted: false } as object });\r\n const byKey = new Map(rows.map((r) => [r.templateKey, r]));\r\n const items = SMS_MESSAGE_TEMPLATE_DEFAULTS.map((def) => {\r\n const row = byKey.get(def.templateKey);\r\n return {\r\n templateKey: def.templateKey,\r\n name: def.name,\r\n defaultBody: def.body,\r\n body: row?.body?.trim() ? row.body : def.body,\r\n externalTemplateRef: row?.externalTemplateRef?.trim() ?? '',\r\n otpVarKey:\r\n row?.providerMeta && typeof row.providerMeta.otpVarKey === 'string'\r\n ? String(row.providerMeta.otpVarKey)\r\n : def.providerMeta?.otpVarKey ?? 'var1',\r\n enabled: row ? row.enabled : false,\r\n dbId: row?.id ?? null,\r\n };\r\n });\r\n return json({ items });\r\n } catch {\r\n return json({ error: 'Failed to load templates' }, { status: 500 });\r\n }\r\n },\r\n\r\n async PUT(req: Request): Promise<Response> {\r\n const err = await requireSettingsUpdate(req);\r\n if (err) return err;\r\n try {\r\n const raw = (await req.json().catch(() => null)) as {\r\n items?: Array<{\r\n templateKey?: string;\r\n body?: string;\r\n externalTemplateRef?: string;\r\n otpVarKey?: string;\r\n enabled?: boolean;\r\n }>;\r\n } | null;\r\n if (!raw?.items || !Array.isArray(raw.items)) {\r\n return json({ error: 'Invalid payload' }, { status: 400 });\r\n }\r\n\r\n for (const item of raw.items) {\r\n const templateKey = typeof item.templateKey === 'string' ? item.templateKey.trim() : '';\r\n if (!getSmsTemplateDefault(templateKey)) continue;\r\n\r\n const body = typeof item.body === 'string' ? item.body : '';\r\n const externalTemplateRef =\r\n typeof item.externalTemplateRef === 'string' ? item.externalTemplateRef.trim() : '';\r\n const otpVarKey =\r\n typeof item.otpVarKey === 'string' && item.otpVarKey.trim()\r\n ? item.otpVarKey.trim()\r\n : 'var1';\r\n const enabled = item.enabled !== false;\r\n\r\n const existing = await repo().findOne({\r\n where: { channel: 'sms', templateKey, deleted: false } as object,\r\n });\r\n const def = getSmsTemplateDefault(templateKey)!;\r\n const providerMeta = { otpVarKey };\r\n\r\n if (existing) {\r\n await repo().update(existing.id, {\r\n name: def.name,\r\n body,\r\n externalTemplateRef: externalTemplateRef || null,\r\n providerMeta,\r\n enabled,\r\n updatedAt: new Date(),\r\n } as object);\r\n } else {\r\n await repo().save(\r\n repo().create({\r\n channel: 'sms',\r\n templateKey,\r\n name: def.name,\r\n subject: null,\r\n body,\r\n externalTemplateRef: externalTemplateRef || null,\r\n providerMeta,\r\n enabled,\r\n deleted: false,\r\n } as object)\r\n );\r\n }\r\n }\r\n return json({ ok: true });\r\n } catch {\r\n return json({ error: 'Failed to save templates' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n","/** API resource keys excluded from the permission matrix (internal / not admin-CRUD). */\r\nexport const PERMISSION_ENTITY_INTERNAL_EXCLUDE = new Set([\r\n 'users',\r\n 'password_reset_tokens',\r\n 'user_groups',\r\n 'permissions',\r\n 'comments',\r\n 'form_fields',\r\n 'configs',\r\n 'knowledge_base_chunks',\r\n 'carts',\r\n 'cart_items',\r\n 'wishlists',\r\n 'wishlist_items',\r\n 'message_templates',\r\n]);\r\n\r\n/** Non-CRUD admin surfaces mapped to entity keys for RBAC. */\r\nexport const PERMISSION_LOGICAL_ENTITIES = [\r\n 'users',\r\n 'forms',\r\n 'form_submissions',\r\n 'dashboard',\r\n 'upload',\r\n 'settings',\r\n 'analytics',\r\n 'chat',\r\n] as const;\r\n\r\n/** Canonical name for new installs / migrations */\r\nexport const ADMIN_GROUP_NAME = 'Administrator';\r\n\r\n/** System administrator group (roles UI + users / user_groups / permissions bypass). */\r\nexport function isSuperAdminGroupName(name: string | null | undefined): boolean {\r\n return name === ADMIN_GROUP_NAME;\r\n}\r\n\r\nexport type EntityCrudAction = 'create' | 'read' | 'update' | 'delete';\r\n\r\nexport type EntityPermissionFlags = { c: boolean; r: boolean; u: boolean; d: boolean };\r\n\r\nexport function getPermissionableEntityKeys(entityMap: Record<string, unknown>): string[] {\r\n const fromMap = Object.keys(entityMap).filter((k) => !PERMISSION_ENTITY_INTERNAL_EXCLUDE.has(k));\r\n const logical = PERMISSION_LOGICAL_ENTITIES.filter((k) => !fromMap.includes(k));\r\n return [...fromMap.sort(), ...logical].filter((k, i, a) => a.indexOf(k) === i);\r\n}\r\n\r\nexport function permissionRowsToRecord(\r\n rows: Array<{ entity: string; canCreate: boolean; canRead: boolean; canUpdate: boolean; canDelete: boolean }> | undefined\r\n): Record<string, EntityPermissionFlags> {\r\n const out: Record<string, EntityPermissionFlags> = {};\r\n if (!rows?.length) return out;\r\n for (const p of rows) {\r\n out[p.entity] = {\r\n c: !!p.canCreate,\r\n r: !!p.canRead,\r\n u: !!p.canUpdate,\r\n d: !!p.canDelete,\r\n };\r\n }\r\n return out;\r\n}\r\n\r\nexport function hasEntityPermission(\r\n record: Record<string, EntityPermissionFlags> | undefined,\r\n entity: string,\r\n action: EntityCrudAction\r\n): boolean {\r\n const p = record?.[entity];\r\n if (!p) return false;\r\n if (action === 'create') return p.c;\r\n if (action === 'read') return p.r;\r\n if (action === 'update') return p.u;\r\n return p.d;\r\n}\r\n","import type { EntityCrudAction, EntityPermissionFlags } from './permission-entities';\r\nimport { hasEntityPermission } from './permission-entities';\r\n\r\n/** isRBACAdmin bypasses entity checks only for these (users / roles plumbing). */\r\nexport const RBAC_ADMIN_ONLY_ENTITIES = new Set(['users', 'user_groups', 'permissions']);\r\n\r\nexport interface SessionUser {\r\n id?: string;\r\n email?: string | null;\r\n name?: string | null;\r\n groupId?: number;\r\n /** @deprecated use entityPerms / isRBACAdmin */\r\n permissions?: string[];\r\n /** Administrator group: full access only for users, user_groups, permissions */\r\n isRBACAdmin?: boolean;\r\n entityPerms?: Record<string, EntityPermissionFlags>;\r\n /** When false and not isRBACAdmin, admin API/UI is denied. */\r\n adminAccess?: boolean;\r\n}\r\n\r\nexport function sessionHasEntityAccess(\r\n user: SessionUser | null | undefined,\r\n entity: string,\r\n action: EntityCrudAction\r\n): boolean {\r\n if (!user?.email) return false;\r\n if (user.isRBACAdmin && RBAC_ADMIN_ONLY_ENTITIES.has(entity)) return true;\r\n return hasEntityPermission(user.entityPerms, entity, action);\r\n}\r\n\r\nexport function canManageRoles(user: SessionUser | null | undefined): boolean {\r\n return !!(user?.email && user.isRBACAdmin);\r\n}\r\n\r\nexport type GetSession = () => Promise<{ user?: SessionUser } | null>;\r\n\r\nexport const OPEN_ENDPOINTS: Array<Record<string, string[]>> = [\r\n { '/api/contacts': ['POST'] },\r\n { '/api/form-submissions': ['POST'] },\r\n { '/api/blogs': ['GET'] },\r\n];\r\n\r\nexport const PERMISSION_REQUIRED_ENDPOINTS: Record<string, string[]> = {};\r\n\r\nexport function isOpenEndpoint(pathname: string): boolean {\r\n return OPEN_ENDPOINTS.some((endpoint) => pathname.startsWith(Object.keys(endpoint)[0]));\r\n}\r\n\r\nexport function getRequiredPermission(pathname: string): string[] | null {\r\n return null;\r\n}\r\n\r\nexport function isPublicMethod(pathname: string, method: string): boolean {\r\n for (const endpoint of OPEN_ENDPOINTS) {\r\n const key = Object.keys(endpoint)[0];\r\n if (pathname.startsWith(key) && endpoint[key].includes(method)) return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport interface AuthHelpers {\r\n requireAuth(req: Request): Promise<Response | null>;\r\n requirePermission(req: Request, permission: string): Promise<Response | null>;\r\n requireEntityPermission(req: Request, entity: string, action: EntityCrudAction): Promise<Response | null>;\r\n requireAdminAccess(req: Request): Promise<Response | null>;\r\n getAuthenticatedUser(): Promise<SessionUser | null>;\r\n}\r\n\r\nexport function createAuthHelpers(getSession: GetSession, NextResponse: { json: (body: unknown, init?: { status?: number }) => Response }): AuthHelpers {\r\n return {\r\n async requireAuth() {\r\n const session = await getSession();\r\n if (!session?.user?.email) {\r\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });\r\n }\r\n return null;\r\n },\r\n async requirePermission() {\r\n const session = await getSession();\r\n if (!session?.user?.email) {\r\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });\r\n }\r\n return null;\r\n },\r\n async requireEntityPermission(_req: Request, entity: string, action: EntityCrudAction) {\r\n const session = await getSession();\r\n if (!session?.user?.email) {\r\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });\r\n }\r\n const u = session.user as SessionUser;\r\n if (sessionHasEntityAccess(u, entity, action)) return null;\r\n return NextResponse.json({ error: 'Forbidden', entity, action }, { status: 403 });\r\n },\r\n async requireAdminAccess() {\r\n const session = await getSession();\r\n if (!session?.user?.email) {\r\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });\r\n }\r\n const u = session.user as SessionUser;\r\n if (u.isRBACAdmin) return null;\r\n if (u.adminAccess === false) return NextResponse.json({ error: 'Forbidden', reason: 'admin_access' }, { status: 403 });\r\n return null;\r\n },\r\n async getAuthenticatedUser() {\r\n const session = await getSession();\r\n return (session?.user as SessionUser) ?? null;\r\n },\r\n };\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport type { EntityMap } from './crud';\r\nimport { getPermissionableEntityKeys, isSuperAdminGroupName } from '../auth/permission-entities';\r\nimport type { SessionUser } from '../auth/helpers';\r\nimport { canManageRoles } from '../auth/helpers';\r\n\r\nexport type GetSessionUser = () => Promise<SessionUser | null>;\r\n\r\nexport interface AdminRolesHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n getSessionUser: GetSessionUser;\r\n}\r\n\r\nexport function createAdminRolesHandlers(config: AdminRolesHandlersConfig) {\r\n const { dataSource, entityMap, json, getSessionUser } = config;\r\n const baseEntities = getPermissionableEntityKeys(entityMap as Record<string, unknown>);\r\n const allowEntities = new Set([...baseEntities, 'users']);\r\n const groupRepo = () => dataSource.getRepository(entityMap.user_groups);\r\n const permRepo = () => dataSource.getRepository(entityMap.permissions);\r\n const userRepo = () => dataSource.getRepository(entityMap.users);\r\n\r\n async function gate(): Promise<Response | null> {\r\n const u = await getSessionUser();\r\n if (!u?.email) return json({ error: 'Unauthorized' }, { status: 401 });\r\n if (!canManageRoles(u)) return json({ error: 'Forbidden' }, { status: 403 });\r\n return null;\r\n }\r\n\r\n return {\r\n async list(): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n const groups = await groupRepo().find({\r\n where: { deleted: false },\r\n order: { id: 'ASC' },\r\n relations: ['permissions'],\r\n });\r\n const entities = [...allowEntities].sort();\r\n return json({\r\n entities,\r\n groups: groups.map((g) => ({\r\n id: g.id,\r\n name: g.name,\r\n permissions: (g.permissions ?? [])\r\n .filter((p) => !p.deleted)\r\n .map((p) => ({\r\n entity: p.entity,\r\n canCreate: p.canCreate,\r\n canRead: p.canRead,\r\n canUpdate: p.canUpdate,\r\n canDelete: p.canDelete,\r\n })),\r\n })),\r\n });\r\n },\r\n\r\n async createGroup(req: Request): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n try {\r\n const body = (await req.json()) as { name?: string };\r\n const name = body?.name?.trim();\r\n if (!name) return json({ error: 'Name is required' }, { status: 400 });\r\n const repo = groupRepo();\r\n const existing = await repo.findOne({ where: { name } });\r\n if (existing) return json({ error: 'Group name already exists' }, { status: 400 });\r\n const g = await repo.save(repo.create({ name }));\r\n return json({ id: g.id, name: g.name, permissions: [] }, { status: 201 });\r\n } catch {\r\n return json({ error: 'Server error' }, { status: 500 });\r\n }\r\n },\r\n\r\n async patchGroup(req: Request, idStr: string): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n const id = parseInt(idStr, 10);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n try {\r\n const body = (await req.json()) as { name?: string };\r\n const name = body?.name?.trim();\r\n if (!name) return json({ error: 'Name is required' }, { status: 400 });\r\n const repo = groupRepo();\r\n const g = await repo.findOne({ where: { id, deleted: false } });\r\n if (!g) return json({ error: 'Not found' }, { status: 404 });\r\n if (isSuperAdminGroupName(g.name) && !isSuperAdminGroupName(name)) {\r\n return json({ error: 'Cannot rename the administrator group' }, { status: 400 });\r\n }\r\n const dup = await repo.findOne({ where: { name } });\r\n if (dup && dup.id !== id) return json({ error: 'Name already in use' }, { status: 400 });\r\n g.name = name;\r\n await repo.save(g);\r\n return json({ id: g.id, name: g.name });\r\n } catch {\r\n return json({ error: 'Server error' }, { status: 500 });\r\n }\r\n },\r\n\r\n async deleteGroup(idStr: string): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n const id = parseInt(idStr, 10);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const repo = groupRepo();\r\n const g = await repo.findOne({ where: { id, deleted: false } });\r\n if (!g) return json({ error: 'Not found' }, { status: 404 });\r\n if (isSuperAdminGroupName(g.name)) return json({ error: 'Cannot delete the administrator group' }, { status: 400 });\r\n const userCount = await userRepo().count({ where: { groupId: id } });\r\n if (userCount > 0) return json({ error: 'Reassign users before deleting this group' }, { status: 409 });\r\n await permRepo().delete({ groupId: id });\r\n await repo.update(id, { deleted: true, deletedAt: new Date() } as object);\r\n return json({ ok: true });\r\n },\r\n\r\n async putPermissions(req: Request, idStr: string): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n const groupId = parseInt(idStr, 10);\r\n if (!Number.isFinite(groupId)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const groupRepository = groupRepo();\r\n const g = await groupRepository.findOne({ where: { id: groupId, deleted: false } });\r\n if (!g) return json({ error: 'Group not found' }, { status: 404 });\r\n try {\r\n const body = (await req.json()) as {\r\n permissions?: Array<{\r\n entity: string;\r\n canCreate?: boolean;\r\n canRead?: boolean;\r\n canUpdate?: boolean;\r\n canDelete?: boolean;\r\n }>;\r\n };\r\n const rows = body?.permissions;\r\n if (!Array.isArray(rows)) return json({ error: 'permissions array required' }, { status: 400 });\r\n for (const r of rows) {\r\n if (!r?.entity || !allowEntities.has(r.entity)) {\r\n return json({ error: `Invalid entity: ${r?.entity ?? ''}` }, { status: 400 });\r\n }\r\n }\r\n await dataSource.transaction(async (em) => {\r\n await em.getRepository(entityMap.permissions).delete({ groupId });\r\n for (const r of rows) {\r\n await em.getRepository(entityMap.permissions).save(\r\n em.getRepository(entityMap.permissions).create({\r\n groupId,\r\n entity: r.entity,\r\n canCreate: !!r.canCreate,\r\n canRead: !!r.canRead,\r\n canUpdate: !!r.canUpdate,\r\n canDelete: !!r.canDelete,\r\n })\r\n );\r\n }\r\n });\r\n const updated = await groupRepository.findOne({\r\n where: { id: groupId },\r\n relations: ['permissions'],\r\n });\r\n return json({\r\n id: groupId,\r\n permissions: (updated?.permissions ?? []).map((p) => ({\r\n entity: p.entity,\r\n canCreate: p.canCreate,\r\n canRead: p.canRead,\r\n canUpdate: p.canUpdate,\r\n canDelete: p.canDelete,\r\n })),\r\n });\r\n } catch {\r\n return json({ error: 'Server error' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { UserGroup } from './user-group.entity';\r\n\r\n@Entity('users')\r\nexport class User {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n email: string;\r\n\r\n /** E.164 when set; unique among non-null values (partial index in DB). */\r\n @Column('varchar', { nullable: true })\r\n phone: string | null;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n phoneVerifiedAt: Date | null;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n emailVerifiedAt: Date | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n password: string | null;\r\n\r\n @Column('boolean', { default: false })\r\n blocked: boolean;\r\n\r\n @Column('boolean', { default: false })\r\n adminAccess: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n groupId: number | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => UserGroup, (g) => g.users, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'groupId' })\r\n group: UserGroup | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport { Permission } from './permission.entity';\r\nimport { User } from './user.entity';\r\n\r\n@Entity('user_groups')\r\nexport class UserGroup {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { unique: true })\r\n name: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @OneToMany(() => Permission, (p) => p.group)\r\n permissions: Permission[];\r\n\r\n @OneToMany(() => User, (u) => u.group)\r\n users: User[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { UserGroup } from './user-group.entity';\r\n\r\n@Entity('permissions')\r\nexport class Permission {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n groupId: number;\r\n\r\n @Column('varchar')\r\n entity: string;\r\n\r\n @Column('boolean', { default: false })\r\n canCreate: boolean;\r\n\r\n @Column('boolean', { default: false })\r\n canRead: boolean;\r\n\r\n @Column('boolean', { default: false })\r\n canUpdate: boolean;\r\n\r\n @Column('boolean', { default: false })\r\n canDelete: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => UserGroup, (g) => g.permissions, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'groupId' })\r\n group: UserGroup;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, Index } from 'typeorm';\r\n\r\n@Entity('otp_challenges')\r\n@Index(['purpose', 'identifier'])\r\nexport class OtpChallenge {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n purpose: string;\r\n\r\n @Column('varchar')\r\n channel: string;\r\n\r\n @Column('varchar')\r\n identifier: string;\r\n\r\n @Column('varchar')\r\n codeHash: string;\r\n\r\n @Column({ type: 'timestamp' })\r\n expiresAt: Date;\r\n\r\n @Column('int', { default: 0 })\r\n attempts: number;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n consumedAt: Date | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\n\r\n@Entity('password_reset_tokens')\r\nexport class PasswordResetToken {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n email: string;\r\n\r\n @Column('varchar', { unique: true })\r\n token: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n expiresAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n}\r\n","import {\r\n Entity,\r\n PrimaryGeneratedColumn,\r\n Column,\r\n ManyToOne,\r\n OneToMany,\r\n ManyToMany,\r\n JoinTable,\r\n JoinColumn,\r\n} from 'typeorm';\r\nimport { User } from './user.entity';\r\nimport { Category } from './category.entity';\r\nimport { Seo } from './seo.entity';\r\nimport { Comment } from './comment.entity';\r\nimport { Tag } from './tag.entity';\r\n\r\n@Entity('blogs')\r\nexport class Blog {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n title: string;\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n coverImage: string | null;\r\n\r\n @Column('int')\r\n authorId: number;\r\n\r\n @Column('int', { nullable: true })\r\n categoryId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @Column('boolean', { default: false })\r\n published: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @ManyToOne(() => User, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'authorId' })\r\n author: User;\r\n\r\n @ManyToOne(() => Category, (c) => c.blogs, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'categoryId' })\r\n category: Category | null;\r\n\r\n @ManyToOne(() => Seo, (s) => s.blogs, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @OneToMany(() => Comment, (c) => c.blog)\r\n comments: Comment[];\r\n\r\n @ManyToMany(() => Tag, (t) => t.blogs)\r\n @JoinTable({\r\n name: 'blog_tags',\r\n joinColumn: { name: 'blogId', referencedColumnName: 'id' },\r\n inverseJoinColumn: { name: 'tagId', referencedColumnName: 'id' },\r\n })\r\n tags: Tag[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport type { Blog } from './blog.entity';\r\n\r\n@Entity('categories')\r\nexport class Category {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { unique: true })\r\n name: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @OneToMany('Blog', 'category')\r\n blogs: Blog[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport { Blog } from './blog.entity';\r\n\r\n@Entity('seos')\r\nexport class Seo {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n title: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n keywords: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n ogTitle: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n ogDescription: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n ogImage: string | null;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @OneToMany(() => Blog, (blog) => blog.seo)\r\n blogs: Blog[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { User } from './user.entity';\r\nimport { Blog } from './blog.entity';\r\n\r\n@Entity('comments')\r\nexport class Comment {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column('int')\r\n blogId: number;\r\n\r\n @Column('int')\r\n authorId: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => User, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'authorId' })\r\n author: User;\r\n\r\n @ManyToOne(() => Blog, (b) => b.comments, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'blogId' })\r\n blog: Blog;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from 'typeorm';\r\nimport { Blog } from './blog.entity';\r\n\r\n@Entity('tags')\r\nexport class Tag {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { unique: true })\r\n name: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToMany(() => Blog, (blog) => blog.tags)\r\n blogs: Blog[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { User } from './user.entity';\r\nimport { FormSubmission } from './form-submission.entity';\r\nimport { Address } from './address.entity';\r\nimport { Order } from './order.entity';\r\nimport { Payment } from './payment.entity';\r\nimport { ChatConversation } from './chat-conversation.entity';\r\n\r\n@Entity('contacts')\r\nexport class Contact {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n email: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n phone: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n type: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n company: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n taxId: string | null;\r\n\r\n @Column('text', { nullable: true })\r\n notes: string | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n userId: number | null;\r\n\r\n @ManyToOne(() => User, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'userId' })\r\n user: User | null;\r\n\r\n @OneToMany(() => FormSubmission, (fs) => fs.contact)\r\n form_submissions: FormSubmission[];\r\n\r\n @OneToMany(() => Address, (a) => a.contact)\r\n addresses: Address[];\r\n\r\n @OneToMany(() => Order, (o) => o.contact)\r\n orders: Order[];\r\n\r\n @OneToMany(() => Payment, (p) => p.contact)\r\n payments: Payment[];\r\n\r\n @OneToMany(() => ChatConversation, (c) => c.contact)\r\n chatConversations: ChatConversation[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Form } from './form.entity';\r\nimport { Contact } from './contact.entity';\r\n\r\n@Entity('form_submissions')\r\nexport class FormSubmission {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n formId: number;\r\n\r\n @Column('int', { nullable: true })\r\n contactId: number | null;\r\n\r\n @Column('jsonb')\r\n data: Record<string, unknown>;\r\n\r\n @Column('varchar', { nullable: true })\r\n ipAddress: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n userAgent: string | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Form, (f) => f.submissions, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'formId' })\r\n form: Form;\r\n\r\n @ManyToOne(() => Contact, (c) => c.form_submissions, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport { FormField } from './form-field.entity';\r\nimport { FormSubmission } from './form-submission.entity';\r\n\r\n@Entity('forms')\r\nexport class Form {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n campaign: string | null;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('boolean', { default: false })\r\n published: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @OneToMany(() => FormField, (f) => f.form)\r\n fields: FormField[];\r\n\r\n @OneToMany(() => FormSubmission, (s) => s.form)\r\n submissions: FormSubmission[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Form } from './form.entity';\r\n\r\n@Entity('form_fields')\r\nexport class FormField {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n formId: number;\r\n\r\n @Column('varchar')\r\n label: string;\r\n\r\n @Column('varchar')\r\n type: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n placeholder: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n options: string | null;\r\n\r\n @Column('boolean', { default: false })\r\n required: boolean;\r\n\r\n @Column('varchar', { nullable: true })\r\n validation: string | null;\r\n\r\n @Column('int')\r\n order: number;\r\n\r\n @Column('int', { default: 1 })\r\n groupId: number;\r\n\r\n @Column('int', { default: 12 })\r\n columnWidth: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => Form, (f) => f.fields, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'formId' })\r\n form: Form;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\n\r\n@Entity('addresses')\r\nexport class Address {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n contactId: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n tag: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n line1: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n line2: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n city: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n state: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n postalCode: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n country: string | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Contact, (c) => c.addresses, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\nimport { Address } from './address.entity';\r\nimport type { OrderItem } from './order-item.entity';\r\nimport type { Payment } from './payment.entity';\r\n\r\nexport type OrderKind = 'sale' | 'return' | 'replacement';\r\n\r\n@Entity('orders')\r\nexport class Order {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { unique: true })\r\n orderNumber: string;\r\n\r\n @Column('varchar', { default: 'sale' })\r\n orderKind: OrderKind;\r\n\r\n @Column('int', { nullable: true })\r\n parentOrderId: number | null;\r\n\r\n @Column('int')\r\n contactId: number;\r\n\r\n @Column('int', { nullable: true })\r\n billingAddressId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n shippingAddressId: number | null;\r\n\r\n @Column('varchar', { default: 'pending' })\r\n status: 'pending' | 'confirmed' | 'processing' | 'completed' | 'cancelled';\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n subtotal: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n tax: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n discount: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n total: number;\r\n\r\n @Column('varchar', { default: 'INR' })\r\n currency: string;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => Order, (o) => o.children, { nullable: true, onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'parentOrderId' })\r\n parentOrder: Order | null;\r\n\r\n @OneToMany(() => Order, (o) => o.parentOrder)\r\n children: Order[];\r\n\r\n @ManyToOne(() => Contact, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact;\r\n\r\n @ManyToOne(() => Address, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'billingAddressId' })\r\n billingAddress: Address | null;\r\n\r\n @ManyToOne(() => Address, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'shippingAddressId' })\r\n shippingAddress: Address | null;\r\n\r\n @OneToMany('OrderItem', 'order')\r\n items: OrderItem[];\r\n\r\n @OneToMany('Payment', 'order')\r\n payments: Payment[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Order } from './order.entity';\r\nimport { Contact } from './contact.entity';\r\n\r\n@Entity('payments')\r\nexport class Payment {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n orderId: number;\r\n\r\n @Column('int', { nullable: true })\r\n contactId: number | null;\r\n\r\n @Column('decimal', { precision: 12, scale: 2 })\r\n amount: number;\r\n\r\n @Column('varchar', { default: 'INR' })\r\n currency: string;\r\n\r\n @Column('varchar', { default: 'pending' })\r\n status: 'pending' | 'processing' | 'completed' | 'failed' | 'refunded';\r\n\r\n @Column('varchar', { nullable: true })\r\n method: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n externalReference: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n paidAt: Date | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => Order, (o) => o.payments, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'orderId' })\r\n order: Order;\r\n\r\n @ManyToOne(() => Contact, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\nimport { ChatMessage } from './chat-message.entity';\r\n\r\n@Entity('chat_conversations')\r\nexport class ChatConversation {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n contactId: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Contact, (c) => c.chatConversations, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact;\r\n\r\n @OneToMany(() => ChatMessage, (m) => m.conversation)\r\n messages: ChatMessage[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { ChatConversation } from './chat-conversation.entity';\r\n\r\n@Entity('chat_messages')\r\nexport class ChatMessage {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n conversationId: number;\r\n\r\n @Column('varchar')\r\n role: 'user' | 'assistant' | 'system';\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @ManyToOne(() => ChatConversation, (c) => c.messages, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'conversationId' })\r\n conversation: ChatConversation;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, Unique } from 'typeorm';\r\n\r\n@Entity('configs')\r\n@Unique(['settings', 'key'])\r\nexport class Config {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n settings: string;\r\n\r\n @Column('varchar')\r\n key: string;\r\n\r\n @Column('varchar')\r\n value: string;\r\n\r\n @Column('varchar', { default: 'private' })\r\n type: 'public' | 'private';\r\n\r\n @Column('boolean', { default: false })\r\n encrypted: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\n\r\n@Entity('message_templates')\r\nexport class MessageTemplate {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n channel: string;\r\n\r\n @Column('varchar', { name: 'template_key' })\r\n templateKey: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n name: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n subject: string | null;\r\n\r\n @Column('text', { default: '' })\r\n body: string;\r\n\r\n @Column('varchar', { name: 'external_template_ref', nullable: true })\r\n externalTemplateRef: string | null;\r\n\r\n @Column({ type: 'jsonb', nullable: true })\r\n providerMeta: Record<string, unknown> | null;\r\n\r\n @Column('boolean', { default: true })\r\n enabled: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\n\r\n@Entity('media')\r\nexport class Media {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column({ type: 'varchar', length: 16, default: 'file' })\r\n kind: 'file' | 'folder';\r\n\r\n @Column({ type: 'int', nullable: true })\r\n parentId: number | null;\r\n\r\n @ManyToOne(() => Media, (m) => m.children, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'parentId' })\r\n parent: Media | null;\r\n\r\n @OneToMany(() => Media, (m) => m.parent)\r\n children: Media[];\r\n\r\n @Column('varchar')\r\n filename: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n url: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n mimeType: string | null;\r\n\r\n @Column('int', { default: 0 })\r\n size: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n alt: string | null;\r\n\r\n @Column('boolean', { default: false })\r\n isPublic: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Seo } from './seo.entity';\r\n\r\n@Entity('pages')\r\nexport class Page {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n title: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column({ type: 'jsonb', default: {} })\r\n content: object;\r\n\r\n @Column('boolean', { default: false })\r\n published: boolean;\r\n\r\n @Column('varchar', { default: 'default' })\r\n theme: string;\r\n\r\n @Column('int', { nullable: true })\r\n parentId: number | null;\r\n\r\n @ManyToOne(() => Page, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'parentId' })\r\n parent: Page | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @ManyToOne(() => Seo, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport type { Product } from './product.entity';\r\nimport type { Collection } from './collection.entity';\r\n\r\n@Entity('product_categories')\r\nexport class ProductCategory {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('int', { nullable: true })\r\n parentId: number | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n image: string | null;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('int', { default: 0 })\r\n sortOrder: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => ProductCategory, (c) => c.children, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'parentId' })\r\n parent: ProductCategory | null;\r\n\r\n @OneToMany(() => ProductCategory, (c) => c.parent)\r\n children: ProductCategory[];\r\n\r\n @OneToMany('Product', 'category')\r\n products: Product[];\r\n\r\n @OneToMany('Collection', 'category')\r\n collections: Collection[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { ProductCategory } from './product-category.entity';\r\nimport { Brand } from './brand.entity';\r\nimport { Seo } from './seo.entity';\r\nimport type { Product } from './product.entity';\r\n\r\n@Entity('collections')\r\nexport class Collection {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int', { nullable: true })\r\n categoryId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n brandId: number | null;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n hsn: string | null;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n image: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n variants: Array<Record<string, unknown>> | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('int', { default: 0 })\r\n sortOrder: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @ManyToOne(() => Seo, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @ManyToOne(() => ProductCategory, (c) => c.collections, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'categoryId' })\r\n category: ProductCategory | null;\r\n\r\n @ManyToOne(() => Brand, (b) => b.collections, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'brandId' })\r\n brand: Brand | null;\r\n\r\n @OneToMany('Product', 'collection')\r\n products: Product[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Seo } from './seo.entity';\r\nimport type { Product } from './product.entity';\r\nimport type { Collection } from './collection.entity';\r\n\r\n@Entity('brands')\r\nexport class Brand {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n logo: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('int', { default: 0 })\r\n sortOrder: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @ManyToOne(() => Seo, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @OneToMany('Product', 'brand')\r\n products: Product[];\r\n\r\n @OneToMany('Collection', 'brand')\r\n collections: Collection[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Collection } from './collection.entity';\r\nimport { Brand } from './brand.entity';\r\nimport { ProductCategory } from './product-category.entity';\r\nimport { Seo } from './seo.entity';\r\nimport type { ProductAttribute } from './product-attribute.entity';\r\nimport type { ProductTax } from './product-tax.entity';\r\n\r\n@Entity('products')\r\nexport class Product {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int', { nullable: true })\r\n collectionId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n brandId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n categoryId: number | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n sku: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n hsn: string | null;\r\n\r\n /** Unit of measure, e.g. pcs, kg, hrs */\r\n @Column('varchar', { nullable: true })\r\n uom: string | null;\r\n\r\n @Column('varchar', { default: 'product' })\r\n type: 'product' | 'service';\r\n\r\n @Column('varchar', { unique: true, nullable: true })\r\n slug: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n name: string | null;\r\n\r\n @Column('decimal', { precision: 12, scale: 2 })\r\n price: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, nullable: true })\r\n compareAtPrice: number | null;\r\n\r\n @Column('int', { default: 0 })\r\n quantity: number;\r\n\r\n @Column('varchar', { default: 'draft' })\r\n status: 'draft' | 'available' | 'reserved' | 'sold';\r\n\r\n @Column('boolean', { default: false })\r\n featured: boolean;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @ManyToOne(() => Seo, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @ManyToOne(() => Collection, (c) => c.products, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'collectionId' })\r\n collection: Collection | null;\r\n\r\n @ManyToOne(() => Brand, (b) => b.products, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'brandId' })\r\n brand: Brand | null;\r\n\r\n @ManyToOne(() => ProductCategory, (c) => c.products, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'categoryId' })\r\n category: ProductCategory | null;\r\n\r\n @OneToMany('ProductAttribute', 'product')\r\n attributes: ProductAttribute[];\r\n\r\n @OneToMany('ProductTax', 'product')\r\n taxes: ProductTax[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\n\r\n@Entity('attributes')\r\nexport class Attribute {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('varchar', { default: 'text' })\r\n type: 'text' | 'number' | 'select' | 'boolean';\r\n\r\n @Column('jsonb', { nullable: true })\r\n options: string[] | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('int', { default: 0 })\r\n sortOrder: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Product } from './product.entity';\r\nimport { Attribute } from './attribute.entity';\r\n\r\n@Entity('product_attributes')\r\nexport class ProductAttribute {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('int')\r\n attributeId: number;\r\n\r\n @Column('varchar')\r\n value: string;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Product, (p) => p.attributes, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n\r\n @ManyToOne(() => Attribute, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'attributeId' })\r\n attribute: Attribute;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\n\r\n@Entity('taxes')\r\nexport class Tax {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('decimal', { precision: 5, scale: 2 })\r\n rate: number;\r\n\r\n @Column('boolean', { default: false })\r\n isDefault: boolean;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Product } from './product.entity';\r\nimport { Tax } from './tax.entity';\r\n\r\n@Entity('product_taxes')\r\nexport class ProductTax {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('int')\r\n taxId: number;\r\n\r\n @Column('decimal', { precision: 5, scale: 2, nullable: true })\r\n rate: number | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Product, (p) => p.taxes, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n\r\n @ManyToOne(() => Tax, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'taxId' })\r\n tax: Tax;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Order } from './order.entity';\r\nimport { Product } from './product.entity';\r\n\r\n@Entity('order_items')\r\nexport class OrderItem {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n orderId: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('int', { default: 1 })\r\n quantity: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2 })\r\n unitPrice: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n tax: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2 })\r\n total: number;\r\n\r\n /** Snapshot at order time */\r\n @Column('varchar', { nullable: true })\r\n hsn: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n uom: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n productType: string | null;\r\n\r\n @Column('decimal', { precision: 5, scale: 2, nullable: true })\r\n taxRate: number | null;\r\n\r\n /** Tax slug snapshot (from taxes.slug) */\r\n @Column('varchar', { nullable: true })\r\n taxCode: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Order, (o) => o.items, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'orderId' })\r\n order: Order;\r\n\r\n @ManyToOne(() => Product, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport { KnowledgeBaseChunk } from './knowledge-base-chunk.entity';\r\n\r\n@Entity('knowledge_base_documents')\r\nexport class KnowledgeBaseDocument {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n sourceUrl: string | null;\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @OneToMany(() => KnowledgeBaseChunk, (c) => c.document)\r\n chunks: KnowledgeBaseChunk[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { KnowledgeBaseDocument } from './knowledge-base-document.entity';\r\n\r\n@Entity('knowledge_base_chunks')\r\nexport class KnowledgeBaseChunk {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n documentId: number;\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column('int', { default: 0 })\r\n chunkIndex: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @ManyToOne(() => KnowledgeBaseDocument, (d) => d.chunks, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'documentId' })\r\n document: KnowledgeBaseDocument;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\nimport type { CartItem } from './cart-item.entity';\r\n\r\n@Entity('carts')\r\nexport class Cart {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n guestToken: string | null;\r\n\r\n @Column('int', { nullable: true })\r\n contactId: number | null;\r\n\r\n @Column('varchar', { default: 'INR' })\r\n currency: string;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n expiresAt: Date | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Contact, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact | null;\r\n\r\n @OneToMany('CartItem', 'cart')\r\n items: CartItem[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Cart } from './cart.entity';\r\nimport { Product } from './product.entity';\r\n\r\n@Entity('cart_items')\r\nexport class CartItem {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n cartId: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('int', { default: 1 })\r\n quantity: number;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Cart, (c) => c.items, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'cartId' })\r\n cart: Cart;\r\n\r\n @ManyToOne(() => Product, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\nimport type { WishlistItem } from './wishlist-item.entity';\r\n\r\n@Entity('wishlists')\r\nexport class Wishlist {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n guestId: string | null;\r\n\r\n @Column('int', { nullable: true })\r\n contactId: number | null;\r\n\r\n @Column('varchar', { default: 'default' })\r\n name: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Contact, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact | null;\r\n\r\n @OneToMany('WishlistItem', 'wishlist')\r\n items: WishlistItem[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Wishlist } from './wishlist.entity';\r\nimport { Product } from './product.entity';\r\n\r\n@Entity('wishlist_items')\r\nexport class WishlistItem {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n wishlistId: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Wishlist, (w) => w.items, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'wishlistId' })\r\n wishlist: Wishlist;\r\n\r\n @ManyToOne(() => Product, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn, Index, Unique } from 'typeorm';\r\nimport { LlmAgent } from './llm-agent.entity';\r\nimport { KnowledgeBaseDocument } from './knowledge-base-document.entity';\r\n\r\n@Entity('llm_agent_knowledge_documents')\r\n@Unique('UQ_llm_agent_knowledge_agent_document', ['agentId', 'documentId'])\r\n@Index('IDX_llm_agent_knowledge_agent', ['agentId'])\r\nexport class LlmAgentKnowledgeDocument {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n agentId: number;\r\n\r\n @Column('int')\r\n documentId: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @ManyToOne(() => LlmAgent, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'agentId' })\r\n agent: LlmAgent;\r\n\r\n @ManyToOne(() => KnowledgeBaseDocument, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'documentId' })\r\n document: KnowledgeBaseDocument;\r\n}\r\n","import type { EntityTarget } from 'typeorm';\nimport { User } from './user.entity';\nimport { OtpChallenge } from './otp-challenge.entity';\nimport { PasswordResetToken } from './password-reset-token.entity';\nimport { UserGroup } from './user-group.entity';\nimport { Permission } from './permission.entity';\nimport { Blog } from './blog.entity';\nimport { Tag } from './tag.entity';\nimport { Category } from './category.entity';\nimport { Comment } from './comment.entity';\nimport { Contact } from './contact.entity';\nimport { Address } from './address.entity';\nimport { Form } from './form.entity';\nimport { FormField } from './form-field.entity';\nimport { FormSubmission } from './form-submission.entity';\nimport { Seo } from './seo.entity';\nimport { Config } from './config.entity';\nimport { MessageTemplate } from './message-template.entity';\nimport { Media } from './media.entity';\nimport { Page } from './page.entity';\nimport { ProductCategory } from './product-category.entity';\nimport { Collection } from './collection.entity';\nimport { Product } from './product.entity';\nimport { Attribute } from './attribute.entity';\nimport { ProductAttribute } from './product-attribute.entity';\nimport { Tax } from './tax.entity';\nimport { ProductTax } from './product-tax.entity';\nimport { Order } from './order.entity';\nimport { OrderItem } from './order-item.entity';\nimport { Payment } from './payment.entity';\nimport { Brand } from './brand.entity';\nimport { KnowledgeBaseDocument } from './knowledge-base-document.entity';\nimport { KnowledgeBaseChunk } from './knowledge-base-chunk.entity';\nimport { ChatConversation } from './chat-conversation.entity';\nimport { ChatMessage } from './chat-message.entity';\nimport { Cart } from './cart.entity';\nimport { CartItem } from './cart-item.entity';\nimport { Wishlist } from './wishlist.entity';\nimport { WishlistItem } from './wishlist-item.entity';\nimport { LlmAgent, llmAgentToChatAgentOptions } from './llm-agent.entity';\nimport { LlmAgentKnowledgeDocument } from './llm-agent-knowledge-document.entity';\n\nexport {\n User,\n OtpChallenge,\n PasswordResetToken,\n UserGroup,\n Permission,\n Blog,\n Tag,\n Category,\n Comment,\n Contact,\n Address,\n Form,\n FormField,\n FormSubmission,\n Seo,\n Config,\n MessageTemplate,\n Media,\n Page,\n ProductCategory,\n Collection,\n Product,\n Attribute,\n ProductAttribute,\n Tax,\n ProductTax,\n Order,\n OrderItem,\n Payment,\n Brand,\n KnowledgeBaseDocument,\n KnowledgeBaseChunk,\n ChatConversation,\n ChatMessage,\n Cart,\n CartItem,\n Wishlist,\n WishlistItem,\n LlmAgent,\n llmAgentToChatAgentOptions,\n};\n\n/** Map API resource segment (e.g. \"blogs\", \"form_submissions\") to entity. Used by CRUD handler. */\nexport const CMS_ENTITY_MAP: Record<string, EntityTarget<import('typeorm').ObjectLiteral>> = {\n users: User,\n otp_challenges: OtpChallenge,\n password_reset_tokens: PasswordResetToken,\n user_groups: UserGroup,\n permissions: Permission,\n blogs: Blog,\n tags: Tag,\n categories: Category,\n comments: Comment,\n contacts: Contact,\n addresses: Address,\n forms: Form,\n form_fields: FormField,\n form_submissions: FormSubmission,\n seos: Seo,\n configs: Config,\n message_templates: MessageTemplate,\n media: Media,\n pages: Page,\n product_categories: ProductCategory,\n collections: Collection,\n products: Product,\n attributes: Attribute,\n product_attributes: ProductAttribute,\n taxes: Tax,\n product_taxes: ProductTax,\n orders: Order,\n order_items: OrderItem,\n payments: Payment,\n brands: Brand,\n knowledge_base_documents: KnowledgeBaseDocument,\n knowledge_base_chunks: KnowledgeBaseChunk,\n chat_conversations: ChatConversation,\n chat_messages: ChatMessage,\n carts: Cart,\n cart_items: CartItem,\n wishlists: Wishlist,\n wishlist_items: WishlistItem,\n llm_agents: LlmAgent,\n llm_agent_knowledge_documents: LlmAgentKnowledgeDocument,\n};\n","/**\r\n * Single CMS API handler: dashboard, analytics, upload, media zip extract, blog/form by slug, users API, user auth, CRUD. Mount once (e.g. app/api/[[...path]]/route.ts).\r\n */\r\nimport type { DataSource } from 'typeorm';\r\nimport { createCrudHandler, createCrudByIdHandler } from './crud';\r\nimport type { CrudHandlerOptions, EntityMap } from './crud';\r\nimport { createUserAuthApiRouter } from './auth-handlers';\r\nimport type { UserAuthApiConfig } from './auth-handlers';\r\nimport {\r\n createDashboardStatsHandler,\r\n createAnalyticsHandlers,\r\n createEcommerceAnalyticsHandler,\r\n createUploadHandler,\r\n createMediaZipExtractHandler,\r\n createBlogBySlugHandler,\r\n createFormBySlugHandler,\r\n createFormSaveHandlers,\r\n createFormSubmissionHandler,\r\n createFormSubmissionGetByIdHandler,\r\n createFormSubmissionListHandler,\r\n createUsersApiHandlers,\r\n createUserAvatarHandler,\r\n createUserProfileHandler,\r\n createSettingsApiHandlers,\r\n createChatHandlers,\r\n} from './cms-handlers';\r\nimport { createLlmAgentKnowledgeHandlers } from './llm-agent-knowledge-handlers';\r\nimport type { LlmAgentKnowledgeApiConfig } from './llm-agent-knowledge-handlers';\r\nimport { createSmsMessageTemplateHandlers } from './message-template-admin-handlers';\r\nimport type {\r\n DashboardStatsConfig,\r\n AnalyticsHandlerConfig,\r\n EcommerceAnalyticsConfig,\r\n UploadHandlerConfig,\r\n BlogBySlugConfig,\r\n FormBySlugConfig,\r\n FormSaveHandlersConfig,\r\n FormSubmissionHandlerConfig,\r\n FormSubmissionGetByIdConfig,\r\n UsersApiConfig,\r\n UserAvatarConfig,\r\n UserProfileConfig,\r\n SettingsApiConfig,\r\n ChatApiConfig,\r\n} from './cms-handlers';\r\nimport type { EntityCrudAction } from '../auth/permission-entities';\r\nimport type { SessionUser } from '../auth/helpers';\r\nimport type { CompanyDetails } from '../plugins/email/templates/types';\r\nimport { createAdminRolesHandlers } from './admin-roles-handlers';\r\nimport { CMS_ENTITY_MAP } from '../entities';\r\nimport { LlmAgent } from '../entities/llm-agent.entity';\r\n\r\n/** CMS instance with getPlugin; when provided, analytics and userAuth.sendEmail can be resolved from plugins when not passed. */\r\nexport type CmsGetter = () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n\r\nconst KNOWLEDGE_SUFFIX = 'knowledge';\r\nconst CMS_API_LOG = '[cms-api]';\r\n\r\n/**\r\n * Some apps pass a subset of {@link CMS_ENTITY_MAP}. LLM plugins + knowledge CRUD need these keys;\r\n * merge missing ones from the core map so `/api/llm_agents` and knowledge routes do not return \"Invalid resource\".\r\n */\r\nfunction withLlmKnowledgeEntityFallbacks(base: EntityMap): EntityMap {\r\n const keys = [\r\n 'llm_agents',\r\n 'llm_agent_knowledge_documents',\r\n 'knowledge_base_documents',\r\n 'knowledge_base_chunks',\r\n ] as const;\r\n const patch: Partial<EntityMap> = {};\r\n for (const key of keys) {\r\n if (!(key in base) || base[key as keyof EntityMap] == null) {\r\n const fallback = CMS_ENTITY_MAP[key as keyof typeof CMS_ENTITY_MAP] as EntityMap[string] | undefined;\r\n if (fallback) (patch as Record<string, EntityMap[string]>)[key] = fallback;\r\n }\r\n }\r\n const merged = Object.keys(patch).length > 0 ? ({ ...base, ...patch } as EntityMap) : base;\r\n // Direct class fallback so POST/GET /api/llm_agents never loses the entity (e.g. odd bundling of CMS_ENTITY_MAP).\r\n if (!merged.llm_agents) {\r\n const agent = (CMS_ENTITY_MAP.llm_agents ?? LlmAgent) as EntityMap['llm_agents'];\r\n return { ...merged, llm_agents: agent };\r\n }\r\n return merged;\r\n}\r\n\r\n/**\r\n * Resolves LLM agent knowledge routes for {@link createCmsApiHandler}.\r\n * - Canonical: `llm_agents`, `:slug`, `knowledge` (optional 4th segment for DELETE).\r\n * - Some clients / path parsers merge slug + `knowledge` into one segment (`jm-assistantknowledge`); accept that shape too.\r\n */\r\nfunction matchLlmAgentKnowledgeRoute(path: string[]): { slug: string; documentId: string | undefined } | null {\r\n const p = path[0] === 'api' ? path.slice(1) : path;\r\n if (p[0] !== 'llm_agents' || p.length < 2) return null;\r\n const seg1 = p[1];\r\n if (!seg1) return null;\r\n\r\n if (p[2] === KNOWLEDGE_SUFFIX) {\r\n return {\r\n slug: seg1,\r\n documentId: p.length >= 4 ? p[3] : undefined,\r\n };\r\n }\r\n\r\n if (seg1.endsWith(KNOWLEDGE_SUFFIX) && seg1.length > KNOWLEDGE_SUFFIX.length) {\r\n const slug = seg1.slice(0, -KNOWLEDGE_SUFFIX.length);\r\n if (!slug) return null;\r\n if (p.length === 2) return { slug, documentId: undefined };\r\n if (p.length === 3) return { slug, documentId: p[2] };\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport interface CmsApiHandlerConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n requireAuth: (req: Request) => Promise<Response | null>;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n pathToModel?: (segment: string) => string;\r\n crudResources?: string[];\r\n /** When set, analytics and userAuth.sendEmail can be derived from getPlugin('analytics') and getPlugin('email') when not provided. */\r\n getCms?: CmsGetter;\r\n /** Optional: used when deriving userAuth.sendEmail to pass company details into email templates (e.g. from settings). */\r\n getCompanyDetails?: () => Promise<CompanyDetails>;\r\n /** Optional: used for form submission and other channel-based email recipients (from settings group \"email\"). */\r\n getRecipientForChannel?: (channel: 'crm' | 'sales' | 'fulfilment') => Promise<string | null>;\r\n userAuth?: UserAuthApiConfig;\r\n /** GET /api/dashboard/stats */\r\n dashboard?: DashboardStatsConfig;\r\n /** GET /api/dashboard/ecommerce */\r\n ecommerceAnalytics?: EcommerceAnalyticsConfig;\r\n /** GET /api/analytics. If omitted and getCms is set, uses getCms().getPlugin('analytics'). */\r\n analytics?: AnalyticsHandlerConfig;\r\n /** POST /api/upload (S3 or local) */\r\n upload?: UploadHandlerConfig;\r\n /** GET /api/blogs/slug/:slug (public) */\r\n blogBySlug?: BlogBySlugConfig;\r\n /** GET /api/forms/slug/:slug (public) */\r\n formBySlug?: FormBySlugConfig;\r\n /** POST/PUT /api/forms (save form + fields; when set, overrides CRUD for forms) */\r\n formSave?: FormSaveHandlersConfig;\r\n /** POST /api/form-submissions (public, no auth) */\r\n formSubmission?: FormSubmissionHandlerConfig;\r\n /** GET /api/form-submissions/:id (auth) with form + contact relations */\r\n formSubmissionGetById?: FormSubmissionGetByIdConfig;\r\n /** GET/POST /api/users, GET/PUT/DELETE /api/users/:id, POST /api/users/:id/regenerate-invite */\r\n usersApi?: UsersApiConfig;\r\n /** POST /api/users/avatar */\r\n userAvatar?: UserAvatarConfig;\r\n /** PUT /api/users/profile */\r\n userProfile?: UserProfileConfig;\r\n /** GET/PUT /api/settings/:group */\r\n settings?: SettingsApiConfig;\r\n /** GET /api/chat/config (public); POST /api/chat/identify; GET /api/chat/conversations/:id/messages; POST /api/chat/messages */\r\n chat?: ChatApiConfig;\r\n /**\r\n * GET/POST /api/llm_agents/:slug/knowledge; DELETE …/knowledge/:documentId — agent KB ingest + links.\r\n * When omitted but `chat` is set, the same dataSource / entityMap / getCms / json / requireAuth are reused automatically.\r\n */\r\n llmAgentKnowledge?: LlmAgentKnowledgeApiConfig;\r\n /**\r\n * Entity-level RBAC (session `entityPerms` / Administrator). When omitted, admin routes that need it respond with 403\r\n * (`entity_rbac_required`) so CRUD cannot run as auth-only. Pass `createAuthHelpers(...).requireEntityPermission` from the app.\r\n */\r\n requireEntityPermission?: (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;\r\n /** Required for GET/POST/PATCH/DELETE /api/admin/roles */\r\n getSessionUser?: () => Promise<SessionUser | null>;\r\n}\r\n\r\nconst DEFAULT_EXCLUDE = new Set([\r\n 'users',\r\n 'password_reset_tokens',\r\n 'user_groups',\r\n 'permissions',\r\n 'comments',\r\n 'form_fields',\r\n 'configs',\r\n 'carts',\r\n 'cart_items',\r\n 'wishlists',\r\n 'wishlist_items',\r\n 'message_templates',\r\n 'llm_agent_knowledge_documents',\r\n]);\r\n\r\nexport function createCmsApiHandler(config: CmsApiHandlerConfig) {\r\n const {\r\n dataSource,\r\n entityMap: rawEntityMap,\r\n pathToModel = (s) => s,\r\n crudResources: crudResourcesOverride,\r\n getCms,\r\n userAuth: userAuthConfig,\r\n dashboard,\r\n ecommerceAnalytics,\r\n analytics: analyticsConfig,\r\n upload,\r\n blogBySlug,\r\n formBySlug,\r\n formSave: formSaveConfig,\r\n formSubmission: formSubmissionConfig,\r\n formSubmissionGetById: formSubmissionGetByIdConfig,\r\n usersApi,\r\n userAvatar,\r\n userProfile,\r\n settings: settingsConfig,\r\n chat: chatConfig,\r\n llmAgentKnowledge: llmAgentKnowledgeConfig,\r\n requireEntityPermission: userRequireEntityPermission,\r\n getSessionUser,\r\n } = config;\r\n\r\n const entityMap = withLlmKnowledgeEntityFallbacks(rawEntityMap);\r\n const baseCrudResources =\r\n crudResourcesOverride ?? Object.keys(entityMap).filter((k) => !DEFAULT_EXCLUDE.has(k));\r\n /** Plugins + dedicated routes use `llm_agents` even when the host app passes a narrow `crudResources` allowlist. */\r\n const crudResources =\r\n entityMap.llm_agents && !baseCrudResources.includes('llm_agents')\r\n ? [...baseCrudResources, 'llm_agents']\r\n : baseCrudResources;\r\n\r\n const requireEntityPermissionEffective =\r\n userRequireEntityPermission ??\r\n (async (_req: Request, entity: string, action: EntityCrudAction): Promise<Response | null> =>\r\n config.json({ error: 'Forbidden', reason: 'entity_rbac_required', entity, action }, { status: 403 }));\r\n\r\n const analytics: AnalyticsHandlerConfig | undefined =\r\n analyticsConfig ??\r\n (getCms\r\n ? {\r\n json: config.json,\r\n requireAuth: async () => null,\r\n getAnalyticsData: async (days) => {\r\n const cms = await getCms();\r\n const a = cms.getPlugin('analytics') as { getAnalyticsData?: (days: number) => Promise<unknown> } | undefined;\r\n if (!a?.getAnalyticsData) throw new Error('Analytics not configured');\r\n return a.getAnalyticsData(days);\r\n },\r\n getPropertyId: () => ({ currentViewId: process.env.GOOGLE_ANALYTICS_VIEW_ID }),\r\n getPermissions: () => ({\r\n serviceAccountEmail: process.env.GOOGLE_ANALYTICS_CLIENT_EMAIL,\r\n currentViewId: process.env.GOOGLE_ANALYTICS_VIEW_ID,\r\n }),\r\n }\r\n : undefined);\r\n\r\n const userAuth: UserAuthApiConfig | undefined =\r\n userAuthConfig && getCms && userAuthConfig.sendEmail === undefined\r\n ? {\r\n ...userAuthConfig,\r\n sendEmail: async (opts) => {\r\n const cms = await getCms();\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void> } | undefined;\r\n const companyDetails = config.getCompanyDetails ? await config.getCompanyDetails() : {};\r\n const resetLink =\r\n (typeof opts.resetLink === 'string' && opts.resetLink.trim()) ||\r\n (typeof opts.text === 'string' && opts.text.trim()) ||\r\n (typeof opts.html === 'string' ? (opts.html.match(/href\\s*=\\s*[\"']([^\"']+)[\"']/)?.[1] ?? '') : '');\r\n const ctx = { resetLink, companyDetails };\r\n if (queue) {\r\n const { queueEmail } = await import('../plugins/email/email-queue');\r\n await queueEmail(cms as { getPlugin: (name: string) => unknown }, { to: opts.to, templateName: 'passwordReset', ctx });\r\n return;\r\n }\r\n const email = cms.getPlugin('email') as { send: (data: { subject: string; html: string; text?: string; to?: string }) => Promise<boolean>; renderTemplate: (name: string, ctx: unknown) => { subject: string; html: string; text?: string } } | undefined;\r\n if (!email?.send) return;\r\n const rendered = email.renderTemplate('passwordReset', ctx);\r\n await email.send({ subject: rendered.subject, html: rendered.html, text: rendered.text, to: opts.to });\r\n },\r\n }\r\n : userAuthConfig;\r\n\r\n const crudOpts: CrudHandlerOptions = {\r\n requireAuth: config.requireAuth,\r\n json: config.json,\r\n requireEntityPermission: requireEntityPermissionEffective,\r\n getCms,\r\n ...(getSessionUser\r\n ? {\r\n getDeletedByUserId: async () => {\r\n const u = await getSessionUser();\r\n if (!u?.id) return null;\r\n const n = Number(u.id);\r\n return Number.isFinite(n) ? n : null;\r\n },\r\n }\r\n : {}),\r\n };\r\n const crud = createCrudHandler(dataSource, entityMap, crudOpts);\r\n const crudById = createCrudByIdHandler(dataSource, entityMap, crudOpts);\r\n\r\n const mergePerm = <T extends object>(c: T | undefined): T | undefined =>\r\n !c ? undefined : ({ ...c, requireEntityPermission: requireEntityPermissionEffective } as T);\r\n\r\n const adminRoles =\r\n getSessionUser &&\r\n createAdminRolesHandlers({\r\n dataSource,\r\n entityMap,\r\n json: config.json,\r\n getSessionUser,\r\n });\r\n const userAuthRouter = userAuth ? createUserAuthApiRouter(userAuth) : null;\r\n\r\n const dashboardGet = dashboard ? createDashboardStatsHandler(mergePerm(dashboard) ?? dashboard) : null;\r\n const ecommerceAnalyticsResolved: EcommerceAnalyticsConfig =\r\n mergePerm(\r\n ecommerceAnalytics ?? {\r\n dataSource,\r\n entityMap,\r\n json: config.json,\r\n requireAuth: config.requireAuth,\r\n }\r\n )!;\r\n const ecommerceAnalyticsGet = createEcommerceAnalyticsHandler(ecommerceAnalyticsResolved);\r\n const analyticsHandlers = analytics ? createAnalyticsHandlers(analytics) : null;\r\n const uploadMerged = upload\r\n ? {\r\n ...(mergePerm(upload) ?? upload),\r\n dataSource: upload.dataSource ?? dataSource,\r\n entityMap: upload.entityMap ?? entityMap,\r\n }\r\n : null;\r\n const uploadPost = uploadMerged ? createUploadHandler(uploadMerged) : null;\r\n const zipExtractPost = uploadMerged ? createMediaZipExtractHandler(uploadMerged) : null;\r\n const blogBySlugGet = blogBySlug ? createBlogBySlugHandler(blogBySlug) : null;\r\n const formBySlugGet = formBySlug ? createFormBySlugHandler(formBySlug) : null;\r\n const formSaveHandlers = formSaveConfig ? createFormSaveHandlers(mergePerm(formSaveConfig) ?? formSaveConfig) : null;\r\n const formSubmissionPost = formSubmissionConfig ? createFormSubmissionHandler(formSubmissionConfig) : null;\r\n const formSubmissionGetById = formSubmissionGetByIdConfig\r\n ? createFormSubmissionGetByIdHandler(mergePerm(formSubmissionGetByIdConfig) ?? formSubmissionGetByIdConfig)\r\n : null;\r\n const formSubmissionList = formSubmissionGetByIdConfig\r\n ? createFormSubmissionListHandler(mergePerm(formSubmissionGetByIdConfig) ?? formSubmissionGetByIdConfig)\r\n : null;\r\n const usersApiMerged =\r\n usersApi && getCms\r\n ? {\r\n ...usersApi,\r\n getCms: usersApi.getCms ?? getCms,\r\n getCompanyDetails: usersApi.getCompanyDetails ?? config.getCompanyDetails,\r\n ...(getSessionUser ? { getSessionUser: usersApi.getSessionUser ?? getSessionUser } : {}),\r\n }\r\n : usersApi\r\n ? {\r\n ...usersApi,\r\n ...(getSessionUser ? { getSessionUser: usersApi.getSessionUser ?? getSessionUser } : {}),\r\n }\r\n : usersApi;\r\n const usersHandlers = usersApiMerged ? createUsersApiHandlers(mergePerm(usersApiMerged) ?? usersApiMerged) : null;\r\n const avatarPost = userAvatar ? createUserAvatarHandler(userAvatar) : null;\r\n const profilePut = userProfile ? createUserProfileHandler(userProfile) : null;\r\n const settingsHandlers = settingsConfig ? createSettingsApiHandlers(settingsConfig) : null;\r\n const smsMessageTemplateHandlers = createSmsMessageTemplateHandlers({\r\n dataSource,\r\n entityMap,\r\n json: config.json,\r\n requireAuth: config.requireAuth,\r\n requireEntityPermission: requireEntityPermissionEffective,\r\n });\r\n const chatHandlers = chatConfig ? createChatHandlers(chatConfig) : null;\r\n\r\n const llmAgentKnowledgeMerged: LlmAgentKnowledgeApiConfig | undefined =\r\n llmAgentKnowledgeConfig ??\r\n (chatConfig\r\n ? {\r\n dataSource: chatConfig.dataSource,\r\n entityMap: withLlmKnowledgeEntityFallbacks(chatConfig.entityMap ?? rawEntityMap),\r\n getCms: chatConfig.getCms,\r\n json: chatConfig.json,\r\n requireAuth: chatConfig.requireAuth,\r\n }\r\n : undefined);\r\n\r\n const llmAgentKnowledgeHandlers = llmAgentKnowledgeMerged\r\n ? createLlmAgentKnowledgeHandlers({\r\n ...llmAgentKnowledgeMerged,\r\n requireEntityPermission: requireEntityPermissionEffective,\r\n })\r\n : null;\r\n\r\n function resolveResource(segment: string): string {\r\n const model = pathToModel(segment);\r\n return crudResources.includes(model) ? model : segment;\r\n }\r\n\r\n return {\r\n async handle(method: string, pathInput: string[], req: Request): Promise<Response> {\r\n const m = typeof method === 'string' ? method.toUpperCase() : 'GET';\r\n const path = pathInput.length > 0 && pathInput[0] === 'api' ? pathInput.slice(1) : pathInput;\r\n async function analyticsGate(): Promise<Response | null> {\r\n const a = await config.requireAuth(req);\r\n if (a) return a;\r\n return requireEntityPermissionEffective(req, 'analytics', 'read');\r\n }\r\n\r\n // Admin roles: [\"admin\", \"roles\"], [\"admin\", \"roles\", id], [\"admin\", \"roles\", id, \"permissions\"]\r\n if (path[0] === 'admin' && path[1] === 'roles') {\r\n if (!adminRoles) return config.json({ error: 'Not found' }, { status: 404 });\r\n if (path.length === 2 && m === 'GET') return adminRoles.list();\r\n if (path.length === 2 && m === 'POST') return adminRoles.createGroup(req);\r\n if (path.length === 3 && m === 'PATCH') return adminRoles.patchGroup(req, path[2]!);\r\n if (path.length === 3 && m === 'DELETE') return adminRoles.deleteGroup(path[2]!);\r\n if (path.length === 4 && path[3] === 'permissions' && m === 'PUT') return adminRoles.putPermissions(req, path[2]!);\r\n return config.json({ error: 'Not found' }, { status: 404 });\r\n }\r\n\r\n // Dashboard: [\"dashboard\", \"stats\"]\r\n if (path[0] === 'dashboard' && path[1] === 'stats' && path.length === 2 && m === 'GET' && dashboardGet) {\r\n return dashboardGet(req);\r\n }\r\n if (path[0] === 'dashboard' && path[1] === 'ecommerce' && path.length === 2 && m === 'GET' && ecommerceAnalyticsGet) {\r\n const g = await analyticsGate();\r\n if (g) return g;\r\n return ecommerceAnalyticsGet(req);\r\n }\r\n // Analytics: [\"analytics\"], [\"analytics\", \"property-id\"], [\"analytics\", \"permissions\"]\r\n if (path[0] === 'analytics' && analyticsHandlers) {\r\n if (path.length === 1 && m === 'GET') {\r\n const g = await analyticsGate();\r\n if (g) return g;\r\n return analyticsHandlers.GET(req);\r\n }\r\n if (path.length === 2 && path[1] === 'property-id' && m === 'GET') {\r\n const g = await analyticsGate();\r\n if (g) return g;\r\n return analyticsHandlers.propertyId();\r\n }\r\n if (path.length === 2 && path[1] === 'permissions' && m === 'GET') {\r\n const g = await analyticsGate();\r\n if (g) return g;\r\n return analyticsHandlers.permissions();\r\n }\r\n }\r\n // Upload: [\"upload\"]\r\n if (path[0] === 'upload' && path.length === 1 && m === 'POST' && uploadPost) return uploadPost(req);\r\n // Media zip extract: [\"media\", \"extract\", id] POST\r\n if (path[0] === 'media' && path[1] === 'extract' && path.length === 3 && m === 'POST' && zipExtractPost) {\r\n return zipExtractPost(req, path[2]!);\r\n }\r\n // Blog by slug: [\"blogs\", \"slug\", slug] (public)\r\n if (path[0] === 'blogs' && path[1] === 'slug' && path.length === 3 && m === 'GET' && blogBySlugGet) {\r\n return blogBySlugGet(req, path[2]);\r\n }\r\n // Form by slug: [\"forms\", \"slug\", slug] (public)\r\n if (path[0] === 'forms' && path[1] === 'slug' && path.length === 3 && m === 'GET' && formBySlugGet) {\r\n return formBySlugGet(req, path[2]);\r\n }\r\n // Form submission: [\"form-submissions\"] GET (auth, list with relations) or POST (public); [\"form-submissions\", id] GET (auth, with relations)\r\n if (path[0] === 'form-submissions') {\r\n if (path.length === 1) {\r\n if (m === 'GET' && formSubmissionList) return formSubmissionList(req);\r\n if (m === 'POST' && formSubmissionPost) return formSubmissionPost(req);\r\n }\r\n if (path.length === 2 && m === 'GET' && formSubmissionGetById) return formSubmissionGetById(req, path[1]);\r\n }\r\n // Form save: [\"forms\"] POST; [\"forms\", id] GET (with fields) or PUT/PATCH (saves form + fields)\r\n if (path[0] === 'forms' && formSaveHandlers) {\r\n if (path.length === 1 && m === 'POST') return formSaveHandlers.POST(req);\r\n if (path.length === 2) {\r\n if (m === 'GET') return formSaveHandlers.GET(req, path[1]);\r\n if (m === 'PUT' || m === 'PATCH') return formSaveHandlers.PUT(req, path[1]);\r\n }\r\n }\r\n // Users API\r\n if (path[0] === 'users' && usersHandlers) {\r\n if (path.length === 1) {\r\n if (m === 'GET') return usersHandlers.list(req);\r\n if (m === 'POST') return usersHandlers.create(req);\r\n }\r\n if (path.length === 2) {\r\n if (path[1] === 'avatar' && m === 'POST' && avatarPost) return avatarPost(req);\r\n if (path[1] === 'profile' && m === 'PUT' && profilePut) return profilePut(req);\r\n // users/:id\r\n const id = path[1];\r\n if (m === 'GET') return usersHandlers.getById(req, id);\r\n if (m === 'PUT' || m === 'PATCH') return usersHandlers.update(req, id);\r\n if (m === 'DELETE') return usersHandlers.delete(req, id);\r\n }\r\n if (path.length === 3 && path[2] === 'regenerate-invite' && m === 'POST') {\r\n return usersHandlers.regenerateInvite(req, path[1]);\r\n }\r\n }\r\n // User auth: [\"users\", \"forgot-password\"] etc.\r\n if (path[0] === 'users' && path.length === 2 && userAuthRouter && m === 'POST') {\r\n return userAuthRouter.POST(req, path[1]);\r\n }\r\n // Settings: [\"settings\", group]\r\n if (path[0] === 'settings' && path.length === 2 && settingsHandlers) {\r\n const group = path[1]!;\r\n const isPublic = settingsConfig?.publicGetGroups?.includes(group);\r\n if (m === 'GET') {\r\n if (!isPublic) {\r\n const a = await config.requireAuth(req);\r\n if (a) return a;\r\n const pe = await requireEntityPermissionEffective(req, 'settings', 'read');\r\n if (pe) return pe;\r\n }\r\n return settingsHandlers.GET(req, group);\r\n }\r\n if (m === 'PUT') {\r\n const pe = await requireEntityPermissionEffective(req, 'settings', 'update');\r\n if (pe) return pe;\r\n return settingsHandlers.PUT(req, group);\r\n }\r\n }\r\n // SMS message templates (plugins page only): [\"message-templates\", \"sms\"]\r\n if (path[0] === 'message-templates' && path[1] === 'sms' && path.length === 2) {\r\n if (m === 'GET') return smsMessageTemplateHandlers.GET(req);\r\n if (m === 'PUT') return smsMessageTemplateHandlers.PUT(req);\r\n }\r\n // LLM agents CRUD: [\"llm_agents\"] GET/POST, [\"llm_agents\", id] GET/PUT/PATCH/DELETE\r\n // Handled before generic CRUD so it works even when crudResources is customised by the consuming app.\r\n if (path[0] === 'llm_agents') {\r\n if (!entityMap.llm_agents) {\r\n console.error(CMS_API_LOG, 'llm_agents route: entity missing after merge', {\r\n method: m,\r\n pathJoined: path.join('/'),\r\n entityMapKeyCount: Object.keys(entityMap).length,\r\n });\r\n return config.json(\r\n { error: 'LlmAgent entity is not registered', hint: 'Ensure migrations ran and entities include LlmAgent.' },\r\n { status: 503 }\r\n );\r\n }\r\n if (path.length === 1) {\r\n if (m === 'GET') return crud.GET(req, 'llm_agents');\r\n if (m === 'POST') return crud.POST(req, 'llm_agents');\r\n }\r\n if (path.length === 2 && !path[1]?.includes('knowledge')) {\r\n const id = path[1]!;\r\n if (m === 'GET') return crudById.GET(req, 'llm_agents', id);\r\n if (m === 'PUT' || m === 'PATCH') return crudById.PUT(req, 'llm_agents', id);\r\n if (m === 'DELETE') return crudById.DELETE(req, 'llm_agents', id);\r\n }\r\n }\r\n // LLM agent knowledge: canonical + merged-segment variants (see matchLlmAgentKnowledgeRoute)\r\n {\r\n const kbMatch = matchLlmAgentKnowledgeRoute(path);\r\n if (kbMatch) {\r\n if (!llmAgentKnowledgeHandlers) {\r\n return config.json(\r\n {\r\n error: 'LLM agent knowledge is not available',\r\n hint:\r\n 'With chat enabled, routes usually work automatically. Otherwise pass llmAgentKnowledge. If this persists, ensure entityMap includes knowledge_base_documents, knowledge_base_chunks, llm_agent_knowledge_documents, and run migrations.',\r\n },\r\n { status: 503 }\r\n );\r\n }\r\n const { slug, documentId } = kbMatch;\r\n if (m === 'DELETE' && documentId != null && documentId !== '') {\r\n return llmAgentKnowledgeHandlers.unlink(req, slug, documentId);\r\n }\r\n if (m === 'GET' && (documentId == null || documentId === '')) {\r\n return llmAgentKnowledgeHandlers.list(req, slug);\r\n }\r\n if (m === 'POST' && (documentId == null || documentId === '')) {\r\n return llmAgentKnowledgeHandlers.post(req, slug);\r\n }\r\n }\r\n }\r\n // Chat: [\"chat\", \"identify\"] POST; [\"chat\", \"conversations\", id, \"messages\"] GET; [\"chat\", \"messages\"] POST\r\n if (path[0] === 'chat' && chatHandlers) {\r\n if (path.length === 2 && path[1] === 'config' && m === 'GET') return chatHandlers.publicConfig(req);\r\n if (path.length === 2 && path[1] === 'identify' && m === 'POST') return chatHandlers.identify(req);\r\n if (path.length === 4 && path[1] === 'conversations' && path[3] === 'messages' && m === 'GET') return chatHandlers.getMessages(req, path[2]);\r\n if (path.length === 2 && path[1] === 'messages' && m === 'POST') return chatHandlers.postMessage(req);\r\n }\r\n\r\n // Invoice PDF: [\"orders\", id, \"invoice\"] (admin auth + orders:read)\r\n if (path[0] === 'orders' && path.length === 3 && path[2] === 'invoice' && m === 'GET' && getCms) {\r\n const a = await config.requireAuth(req);\r\n if (a) return a;\r\n const pe = await requireEntityPermissionEffective(req, 'orders', 'read');\r\n if (pe) return pe;\r\n const cms = await getCms();\r\n const { streamOrderInvoicePdf } = await import('../plugins/erp/erp-order-invoice');\r\n const oid = Number(path[1]);\r\n if (!Number.isFinite(oid)) return config.json({ error: 'Invalid id' }, { status: 400 });\r\n return streamOrderInvoicePdf(cms, dataSource, entityMap, oid, {});\r\n }\r\n // ERP repost: [\"orders\", id, \"repost-erp\"] (admin auth + orders:update)\r\n if (path[0] === 'orders' && path.length === 3 && path[2] === 'repost-erp' && getCms) {\r\n const a = await config.requireAuth(req);\r\n if (a) return a;\r\n const pe = await requireEntityPermissionEffective(req, 'orders', m === 'GET' ? 'read' : 'update');\r\n if (pe) return pe;\r\n const oid = Number(path[1]);\r\n if (!Number.isFinite(oid)) return config.json({ error: 'Invalid id' }, { status: 400 });\r\n const cms = await getCms();\r\n const { isErpIntegrationEnabled } = await import('../plugins/erp/erp-config-enabled');\r\n const enabled = await isErpIntegrationEnabled(cms, dataSource, entityMap);\r\n if (m === 'GET') {\r\n return config.json({ enabled });\r\n }\r\n if (m === 'POST') {\r\n if (!enabled) return config.json({ error: 'ERP integration is disabled' }, { status: 409 });\r\n const { queueErpPaidOrderForOrderId } = await import('../plugins/erp/paid-order-erp');\r\n await queueErpPaidOrderForOrderId(cms, dataSource, entityMap, oid);\r\n return config.json({ ok: true });\r\n }\r\n return config.json({ error: 'Method not allowed' }, { status: 405 });\r\n }\r\n\r\n // CRUD: [\"blogs\"] or [\"blogs\", \"123\"]\r\n if (path.length === 0) return config.json({ error: 'Not found' }, { status: 404 });\r\n const resource = resolveResource(path[0]);\r\n if (!crudResources.includes(resource)) {\r\n console.warn(CMS_API_LOG, 'generic CRUD gate: Invalid resource (not in crudResources)', {\r\n method: m,\r\n pathJoined: path.join('/'),\r\n pathSegments: path,\r\n resource,\r\n hasLlmAgentsEntity: Boolean(entityMap.llm_agents),\r\n crudResourcesHasResource: crudResources.includes(resource),\r\n crudResourcesLength: crudResources.length,\r\n });\r\n return config.json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n\r\n // Bulk operations: [\"products\", \"metadata\"], [\"products\", \"bulk\"], [\"products\", \"export\"]\r\n if (path.length === 2) {\r\n if (path[1] === 'metadata' && m === 'GET') {\r\n return crud.GET_METADATA(req, resource);\r\n }\r\n if (path[1] === 'bulk' && m === 'POST') {\r\n return crud.BULK_POST(req, resource);\r\n }\r\n if (path[1] === 'export' && m === 'GET') {\r\n return crud.GET_EXPORT(req, resource);\r\n }\r\n }\r\n\r\n if (path.length === 1) {\r\n if (m === 'GET') return crud.GET(req, resource);\r\n if (m === 'POST') return crud.POST(req, resource);\r\n return config.json({ error: 'Method not allowed' }, { status: 405 });\r\n }\r\n if (path.length === 2) {\r\n const id = path[1];\r\n if (m === 'GET') return crudById.GET(req, resource, id);\r\n if (m === 'PUT' || m === 'PATCH') return crudById.PUT(req, resource, id);\r\n if (m === 'DELETE') return crudById.DELETE(req, resource, id);\r\n return config.json({ error: 'Method not allowed' }, { status: 405 });\r\n }\r\n return config.json({ error: 'Not found' }, { status: 404 });\r\n },\r\n };\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport type { EntityTarget, ObjectLiteral } from 'typeorm';\r\nimport { In, IsNull } from 'typeorm';\r\nimport type { SessionUser } from '../auth/helpers';\r\nimport type { EntityMap } from './crud';\r\nimport { linkUnclaimedContactToUser } from '../lib/link-contact-to-user';\r\nimport { isValidSignupEmail } from '../lib/is-valid-signup-email';\r\nimport { queueEmail } from '../plugins/email/email-queue';\r\nimport { queueErpCreateContactIfEnabled } from '../plugins/erp/erp-contact-sync';\r\nimport { buildCanonicalOrderNumber, temporaryOrderNumberPlaceholder } from '../lib/order-number';\r\nimport { tryRefreshOrderFromErpForStorefront } from '../plugins/erp/erp-order-sync';\r\nimport { streamOrderInvoicePdf } from '../plugins/erp/erp-order-invoice';\r\nimport type { CompanyDetails } from '../plugins/email/templates/types';\r\nimport { assertCaptchaOk } from '../plugins/captcha/assert';\r\nimport { queueSms } from '../plugins/sms/sms-queue';\r\nimport {\r\n createOtpChallenge,\r\n verifyAndConsumeOtpChallenge,\r\n generateNumericOtp,\r\n normalizePhoneE164,\r\n type OtpPurpose,\r\n} from '../lib/otp-challenge';\r\nconst GUEST_COOKIE = 'guest_id';\r\nconst ONE_YEAR = 60 * 60 * 24 * 365;\r\n\r\nexport interface StorefrontOtpFlags {\r\n login?: boolean;\r\n verifyEmail?: boolean;\r\n verifyPhone?: boolean;\r\n}\r\n\r\nfunction parseCookies(header: string | null): Record<string, string> {\r\n const out: Record<string, string> = {};\r\n if (!header) return out;\r\n for (const part of header.split(';')) {\r\n const i = part.indexOf('=');\r\n if (i === -1) continue;\r\n const k = part.slice(0, i).trim();\r\n const v = part.slice(i + 1).trim();\r\n out[k] = decodeURIComponent(v);\r\n }\r\n return out;\r\n}\r\n\r\nfunction guestCookieHeader(name: string, token: string): string {\r\n return `${name}=${encodeURIComponent(token)}; Path=/; HttpOnly; SameSite=Lax; Max-Age=${ONE_YEAR}`;\r\n}\r\n\r\nexport interface StorefrontApiConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number; headers?: HeadersInit }) => Response;\r\n getSessionUser: () => Promise<SessionUser | null>;\r\n guestCookieName?: string;\r\n /** Required for POST storefront/register */\r\n hashPassword?: (plain: string) => Promise<string>;\r\n /** When set, new registrations are blocked until email is verified and a signup email is sent. */\r\n getCms?: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n getCompanyDetails?: () => Promise<CompanyDetails>;\r\n /** Origin for verify links (e.g. process.env.NEXTAUTH_URL). Required with getCms for verification URLs. */\r\n publicSiteUrl?: string;\r\n /** When a flag is true, the corresponding OTP storefront route is enabled. */\r\n otpFlags?: StorefrontOtpFlags;\r\n /** Defaults to OTP_PEPPER or NEXTAUTH_SECRET. */\r\n otpPepper?: string;\r\n defaultPhoneCountryCode?: string;\r\n /** When false, login OTP send accepts email only (no phone). Default true. */\r\n otpAllowPhoneLogin?: boolean;\r\n}\r\n\r\nconst SIGNUP_VERIFY_EXPIRY_HOURS = 72;\r\n\r\nexport function createStorefrontApiHandler(config: StorefrontApiConfig) {\r\n const { dataSource, entityMap, json, getSessionUser, getCms, getCompanyDetails, publicSiteUrl } = config;\r\n const cookieName = config.guestCookieName ?? GUEST_COOKIE;\r\n const otpFlags = config.otpFlags;\r\n const otpPepper = config.otpPepper;\r\n const defaultPhoneCc = config.defaultPhoneCountryCode;\r\n const otpAllowPhoneLogin = config.otpAllowPhoneLogin !== false;\r\n\r\n function otpOff(key: keyof StorefrontOtpFlags) {\r\n return !otpFlags || otpFlags[key] !== true;\r\n }\r\n\r\n const cartRepo = () => dataSource.getRepository(entityMap.carts);\r\n const cartItemRepo = () => dataSource.getRepository(entityMap.cart_items);\r\n const productRepo = () => dataSource.getRepository(entityMap.products);\r\n const contactRepo = () => dataSource.getRepository(entityMap.contacts);\r\n const addressRepo = () => dataSource.getRepository(entityMap.addresses);\r\n const orderRepo = () => dataSource.getRepository(entityMap.orders);\r\n const orderItemRepo = () => dataSource.getRepository(entityMap.order_items);\r\n const wishlistRepo = () => dataSource.getRepository(entityMap.wishlists);\r\n const wishlistItemRepo = () => dataSource.getRepository(entityMap.wishlist_items);\r\n const userRepo = () => dataSource.getRepository(entityMap.users);\r\n const tokenRepo = () => dataSource.getRepository(entityMap.password_reset_tokens);\r\n const collectionRepo = () => dataSource.getRepository(entityMap.collections);\r\n const groupRepo = () => dataSource.getRepository(entityMap.user_groups);\r\n const configRepo = () => dataSource.getRepository(entityMap.configs);\r\n\r\n const CART_CHECKOUT_RELATIONS = ['items', 'items.product', 'items.product.taxes', 'items.product.taxes.tax'] as const;\r\n\r\n function roundMoney(n: number): number {\r\n return Math.round(n * 100) / 100;\r\n }\r\n\r\n type CheckoutDraftLine = {\r\n productId: number;\r\n quantity: number;\r\n unitPrice: number;\r\n tax: number;\r\n total: number;\r\n hsn: string | null;\r\n uom: string | null;\r\n productType: string | null;\r\n taxRate: number | null;\r\n taxCode: string | null;\r\n };\r\n\r\n async function getStoreDefaultTaxRate(): Promise<number | null> {\r\n const rows = await configRepo().find({ where: { settings: 'store', deleted: false } as ObjectLiteral });\r\n for (const row of rows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'defaultTaxRate') {\r\n const n = parseFloat(String(r.value ?? '').trim());\r\n return Number.isFinite(n) && n >= 0 ? n : null;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n function computeTaxForProductLine(\r\n p: ObjectLiteral,\r\n lineSubtotal: number,\r\n defaultRate: number | null\r\n ): { tax: number; taxRate: number | null; taxCode: string | null } {\r\n const pts = (p.taxes as ObjectLiteral[] | undefined) ?? [];\r\n const activePts = pts.filter((pt) => {\r\n const t = pt.tax as ObjectLiteral | undefined;\r\n return t != null && t.active !== false;\r\n });\r\n if (activePts.length) {\r\n let sumRate = 0;\r\n const slugs: string[] = [];\r\n for (const pt of activePts) {\r\n const t = pt.tax as ObjectLiteral;\r\n const r = Number(pt.rate != null && pt.rate !== '' ? pt.rate : (t.rate ?? 0));\r\n if (Number.isFinite(r)) sumRate += r;\r\n const slug = String(t.slug ?? '').trim();\r\n if (slug) slugs.push(slug);\r\n }\r\n const tax = roundMoney((lineSubtotal * sumRate) / 100);\r\n return {\r\n tax,\r\n taxRate: sumRate > 0 ? roundMoney(sumRate) : null,\r\n taxCode: slugs.length ? [...new Set(slugs)].sort().join(',') : null,\r\n };\r\n }\r\n if (defaultRate != null && defaultRate > 0) {\r\n return {\r\n tax: roundMoney((lineSubtotal * defaultRate) / 100),\r\n taxRate: roundMoney(defaultRate),\r\n taxCode: null,\r\n };\r\n }\r\n return { tax: 0, taxRate: null, taxCode: null };\r\n }\r\n\r\n function parseInlineAddress(raw: unknown): Record<string, string> | null {\r\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\r\n const o = raw as Record<string, unknown>;\r\n const line1 = String(o.line1 ?? '').trim();\r\n if (!line1) return null;\r\n return {\r\n line1,\r\n line2: o.line2 != null ? String(o.line2) : '',\r\n city: o.city != null ? String(o.city) : '',\r\n state: o.state != null ? String(o.state) : '',\r\n postalCode: o.postalCode != null ? String(o.postalCode) : '',\r\n country: o.country != null ? String(o.country) : '',\r\n };\r\n }\r\n\r\n function intFromBody(v: unknown): number | undefined {\r\n if (typeof v === 'number' && Number.isInteger(v)) return v;\r\n if (typeof v === 'string' && /^\\d+$/.test(v)) return parseInt(v, 10);\r\n return undefined;\r\n }\r\n\r\n async function resolveCheckoutAddress(\r\n contactId: number,\r\n idVal: unknown,\r\n inlineVal: unknown\r\n ): Promise<{ id: number | null; error?: string }> {\r\n const aid = intFromBody(idVal);\r\n if (aid != null) {\r\n const existing = await addressRepo().findOne({\r\n where: { id: aid, contactId } as ObjectLiteral,\r\n });\r\n if (!existing) return { id: null, error: 'Address not found' };\r\n return { id: aid };\r\n }\r\n const addr = parseInlineAddress(inlineVal);\r\n if (addr) {\r\n const saved = await addressRepo().save(\r\n addressRepo().create({\r\n contactId,\r\n line1: addr.line1,\r\n line2: addr.line2?.trim() ? addr.line2 : null,\r\n city: addr.city?.trim() ? addr.city : null,\r\n state: addr.state?.trim() ? addr.state : null,\r\n postalCode: addr.postalCode?.trim() ? addr.postalCode : null,\r\n country: addr.country?.trim() ? addr.country : null,\r\n } as ObjectLiteral)\r\n );\r\n return { id: (saved as { id: number }).id };\r\n }\r\n return { id: null };\r\n }\r\n\r\n async function prepareCheckoutFromCart(\r\n b: Record<string, unknown>,\r\n cart: ObjectLiteral,\r\n contactId: number\r\n ): Promise<\r\n | {\r\n ok: true;\r\n lines: CheckoutDraftLine[];\r\n subtotal: number;\r\n orderTax: number;\r\n orderTotal: number;\r\n billingAddressId: number;\r\n shippingAddressId: number | null;\r\n }\r\n | { ok: false; status: number; message: string }\r\n > {\r\n const defaultRate = await getStoreDefaultTaxRate();\r\n const lines: CheckoutDraftLine[] = [];\r\n let subtotal = 0;\r\n let orderTax = 0;\r\n let needsShipping = false;\r\n\r\n for (const it of (cart.items as ObjectLiteral[]) || []) {\r\n const p = it.product as ObjectLiteral | undefined;\r\n if (!p || p.deleted || p.status !== 'available') continue;\r\n const unit = Number(p.price);\r\n const qty = (it.quantity as number) || 1;\r\n const lineSubtotal = unit * qty;\r\n const pType = p.type === 'service' ? 'service' : 'product';\r\n if (pType === 'product') needsShipping = true;\r\n\r\n const { tax, taxRate, taxCode } = computeTaxForProductLine(p, lineSubtotal, defaultRate);\r\n const lineTotal = roundMoney(lineSubtotal + tax);\r\n subtotal = roundMoney(subtotal + lineSubtotal);\r\n orderTax = roundMoney(orderTax + tax);\r\n\r\n lines.push({\r\n productId: p.id as number,\r\n quantity: qty,\r\n unitPrice: unit,\r\n tax,\r\n total: lineTotal,\r\n hsn: (p.hsn as string | null) ?? null,\r\n uom: (p.uom as string | null) ?? null,\r\n productType: pType,\r\n taxRate,\r\n taxCode,\r\n });\r\n }\r\n\r\n if (!lines.length) return { ok: false, status: 400, message: 'No available items in cart' };\r\n\r\n const bill = await resolveCheckoutAddress(contactId, b.billingAddressId, b.billingAddress);\r\n if (bill.error) return { ok: false, status: 400, message: bill.error };\r\n if (bill.id == null) return { ok: false, status: 400, message: 'Billing address required' };\r\n\r\n const ship = await resolveCheckoutAddress(contactId, b.shippingAddressId, b.shippingAddress);\r\n if (ship.error) return { ok: false, status: 400, message: ship.error };\r\n\r\n let shippingAddressId: number | null = ship.id;\r\n if (needsShipping && shippingAddressId == null) shippingAddressId = bill.id;\r\n if (needsShipping && shippingAddressId == null) {\r\n return { ok: false, status: 400, message: 'Shipping address required' };\r\n }\r\n\r\n const orderTotal = roundMoney(subtotal + orderTax);\r\n\r\n return {\r\n ok: true,\r\n lines,\r\n subtotal,\r\n orderTax,\r\n orderTotal,\r\n billingAddressId: bill.id,\r\n shippingAddressId,\r\n };\r\n }\r\n\r\n async function syncContactToErp(contact: ObjectLiteral): Promise<void> {\r\n if (!getCms) return;\r\n try {\r\n const cms = await getCms();\r\n await queueErpCreateContactIfEnabled(cms, dataSource, entityMap, {\r\n name: String((contact as { name: string }).name ?? ''),\r\n email: String((contact as { email: string }).email ?? '').trim(),\r\n phone: (contact as { phone: string | null }).phone,\r\n type: (contact as { type: string | null }).type,\r\n company: (contact as { company: string | null }).company,\r\n notes: (contact as { notes: string | null }).notes,\r\n });\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n\r\n async function ensureContactForUser(userId: number): Promise<{ id: number } | null> {\r\n let c = await contactRepo().findOne({ where: { userId, deleted: false } as ObjectLiteral });\r\n if (c) return c as { id: number };\r\n const u = await userRepo().findOne({ where: { id: userId } });\r\n if (!u) return null;\r\n const unclaimed = await contactRepo().findOne({\r\n where: { email: u.email, userId: IsNull(), deleted: false } as ObjectLiteral,\r\n });\r\n if (unclaimed) {\r\n await contactRepo().update((unclaimed as { id: number }).id, { userId });\r\n return { id: (unclaimed as { id: number }).id };\r\n }\r\n const created = await contactRepo().save(\r\n contactRepo().create({\r\n name: u.name,\r\n email: u.email,\r\n phone: null,\r\n userId,\r\n deleted: false,\r\n } as ObjectLiteral)\r\n );\r\n await syncContactToErp(created as ObjectLiteral);\r\n return { id: (created as { id: number }).id };\r\n }\r\n\r\n async function getOrCreateCart(req: Request): Promise<{ cart: ObjectLiteral; setCookie: string | null; err: Response | null }> {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (Number.isFinite(uid)) {\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return { cart: {} as ObjectLiteral, setCookie: null, err: json({ error: 'User not found' }, { status: 400 }) };\r\n let cart = await cartRepo().findOne({\r\n where: { contactId: contact.id } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!cart) {\r\n cart = await cartRepo().save(\r\n cartRepo().create({ contactId: contact.id, guestToken: null, currency: 'INR' } as ObjectLiteral)\r\n );\r\n cart = await cartRepo().findOne({\r\n where: { id: (cart as { id: number }).id },\r\n relations: ['items', 'items.product'],\r\n });\r\n }\r\n return { cart: cart!, setCookie: null, err: null };\r\n }\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n let token = cookies[cookieName] || '';\r\n if (!token) {\r\n token = crypto.randomUUID();\r\n let cart = await cartRepo().findOne({\r\n where: { guestToken: token } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!cart) {\r\n cart = await cartRepo().save(\r\n cartRepo().create({ guestToken: token, contactId: null, currency: 'INR' } as ObjectLiteral)\r\n );\r\n cart = await cartRepo().findOne({\r\n where: { id: (cart as { id: number }).id },\r\n relations: ['items', 'items.product'],\r\n });\r\n }\r\n return { cart: cart!, setCookie: guestCookieHeader(cookieName, token), err: null };\r\n }\r\n let cart = await cartRepo().findOne({\r\n where: { guestToken: token } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!cart) {\r\n cart = await cartRepo().save(\r\n cartRepo().create({ guestToken: token, contactId: null, currency: 'INR' } as ObjectLiteral)\r\n );\r\n cart = await cartRepo().findOne({\r\n where: { id: (cart as { id: number }).id },\r\n relations: ['items', 'items.product'],\r\n });\r\n }\r\n return { cart: cart!, setCookie: null, err: null };\r\n }\r\n\r\n function primaryProductImageUrl(metadata: unknown): string | null {\r\n const meta = metadata as { images?: Array<{ url?: string; isDefault?: boolean }> } | null;\r\n const images = meta?.images;\r\n if (!Array.isArray(images) || !images.length) return null;\r\n const sorted = images.filter((i) => i?.url) as Array<{ url: string; isDefault?: boolean }>;\r\n if (!sorted.length) return null;\r\n const di = sorted.findIndex((i) => i.isDefault);\r\n if (di > 0) {\r\n const [d] = sorted.splice(di, 1);\r\n sorted.unshift(d!);\r\n }\r\n return sorted[0]!.url;\r\n }\r\n\r\n function serializeCart(cart: ObjectLiteral) {\r\n const items = (cart.items as ObjectLiteral[]) || [];\r\n return {\r\n id: cart.id,\r\n currency: cart.currency,\r\n items: items.map((it) => {\r\n const p = it.product as ObjectLiteral | undefined;\r\n return {\r\n id: it.id,\r\n productId: it.productId,\r\n quantity: it.quantity,\r\n metadata: it.metadata,\r\n product: p\r\n ? {\r\n id: p.id,\r\n name: p.name,\r\n slug: p.slug,\r\n price: p.price,\r\n sku: p.sku,\r\n type: p.type === 'service' ? 'service' : 'product',\r\n image: primaryProductImageUrl(p.metadata),\r\n }\r\n : null,\r\n };\r\n }),\r\n };\r\n }\r\n\r\n function serializeSeo(seo: unknown): ObjectLiteral | undefined {\r\n if (!seo || typeof seo !== 'object') return undefined;\r\n const s = seo as ObjectLiteral;\r\n return {\r\n title: s.title ?? null,\r\n description: s.description ?? null,\r\n keywords: s.keywords ?? null,\r\n ogTitle: s.ogTitle ?? null,\r\n ogDescription: s.ogDescription ?? null,\r\n ogImage: s.ogImage ?? null,\r\n slug: s.slug ?? null,\r\n };\r\n }\r\n\r\n function serializeProduct(p: ObjectLiteral) {\r\n const seo = serializeSeo(p.seo);\r\n return {\r\n id: p.id,\r\n name: p.name,\r\n slug: p.slug,\r\n sku: p.sku,\r\n hsn: p.hsn,\r\n uom: p.uom ?? null,\r\n type: p.type === 'service' ? 'service' : 'product',\r\n price: p.price,\r\n compareAtPrice: p.compareAtPrice,\r\n status: p.status,\r\n collectionId: p.collectionId,\r\n metadata: p.metadata,\r\n ...(seo ? { seo } : {}),\r\n };\r\n }\r\n\r\n return {\r\n async handle(method: string, path: string[], req: Request): Promise<Response> {\r\n try {\r\n // --- products GET list ---\r\n if (path[0] === 'products' && path.length === 1 && method === 'GET') {\r\n const url = new URL(req.url || '', 'http://localhost');\r\n const collectionSlug = url.searchParams.get('collection')?.trim();\r\n const collectionId = url.searchParams.get('collectionId');\r\n const limit = Math.min(100, Math.max(1, parseInt(url.searchParams.get('limit') || '20', 10)));\r\n const offset = Math.max(0, parseInt(url.searchParams.get('offset') || '0', 10));\r\n const where: ObjectLiteral = { status: 'available', deleted: false };\r\n let collectionFilter: { name: string | null; slug: string | null } | null = null;\r\n if (collectionSlug) {\r\n let col: ObjectLiteral | null = null;\r\n if (/^\\d+$/.test(collectionSlug)) {\r\n col = (await collectionRepo().findOne({\r\n where: {\r\n id: parseInt(collectionSlug, 10),\r\n active: true,\r\n deleted: false,\r\n } as ObjectLiteral,\r\n })) as ObjectLiteral | null;\r\n } else {\r\n col = (await collectionRepo()\r\n .createQueryBuilder('c')\r\n .where('LOWER(c.slug) = LOWER(:slug)', { slug: collectionSlug })\r\n .andWhere('c.active = :a', { a: true })\r\n .andWhere('c.deleted = :d', { d: false })\r\n .getOne()) as ObjectLiteral | null;\r\n }\r\n if (!col) {\r\n return json({ products: [], total: 0, collection: null });\r\n }\r\n where.collectionId = col.id;\r\n collectionFilter = { name: col.name as string | null, slug: col.slug as string | null };\r\n } else if (collectionId) {\r\n const cid = parseInt(collectionId, 10);\r\n if (Number.isFinite(cid)) where.collectionId = cid;\r\n }\r\n const [items, total] = await productRepo().findAndCount({\r\n where,\r\n order: { id: 'ASC' },\r\n take: limit,\r\n skip: offset,\r\n });\r\n return json({\r\n products: items.map(serializeProduct),\r\n total,\r\n ...(collectionFilter && { collection: collectionFilter }),\r\n });\r\n }\r\n\r\n // --- products GET by id or slug ---\r\n if (path[0] === 'products' && path.length === 2 && method === 'GET') {\r\n const idOrSlug = path[1]!;\r\n const byId = /^\\d+$/.test(idOrSlug);\r\n const product = await productRepo().findOne({\r\n where: byId\r\n ? { id: parseInt(idOrSlug, 10), status: 'available', deleted: false }\r\n : { slug: idOrSlug, status: 'available', deleted: false },\r\n relations: ['attributes', 'attributes.attribute', 'seo'],\r\n } as ObjectLiteral);\r\n if (!product) return json({ error: 'Not found' }, { status: 404 });\r\n const p = product as ObjectLiteral;\r\n const attrRows = (p.attributes as ObjectLiteral[] | undefined) ?? [];\r\n const attributeTags = attrRows.map((pa) => ({\r\n name: ((pa.attribute as ObjectLiteral)?.name as string) ?? '',\r\n value: String(pa.value ?? ''),\r\n })).filter((t) => t.name || t.value);\r\n return json({ ...serializeProduct(p), attributes: attributeTags });\r\n }\r\n\r\n // --- collections GET list ---\r\n if (path[0] === 'collections' && path.length === 1 && method === 'GET') {\r\n const items = await collectionRepo().find({\r\n where: { active: true, deleted: false } as ObjectLiteral,\r\n order: { sortOrder: 'ASC', id: 'ASC' },\r\n });\r\n const ids = items.map((c) => (c as ObjectLiteral).id as number);\r\n const countByCollection: Record<number, number> = {};\r\n if (ids.length > 0) {\r\n const rows = await productRepo()\r\n .createQueryBuilder('p')\r\n .select('p.collectionId', 'collectionId')\r\n .addSelect('COUNT(p.id)', 'cnt')\r\n .where('p.collectionId IN (:...ids)', { ids })\r\n .andWhere('p.status = :status', { status: 'available' })\r\n .andWhere('p.deleted = :del', { del: false })\r\n .groupBy('p.collectionId')\r\n .getRawMany();\r\n for (const r of rows) {\r\n const cid = (r as ObjectLiteral).collectionId;\r\n if (cid != null) countByCollection[Number(cid)] = parseInt(String((r as ObjectLiteral).cnt), 10);\r\n }\r\n }\r\n return json({\r\n collections: items.map((c) => {\r\n const col = c as ObjectLiteral;\r\n const id = col.id as number;\r\n return {\r\n id,\r\n name: col.name,\r\n slug: col.slug,\r\n description: col.description,\r\n image: col.image,\r\n productCount: countByCollection[id] ?? 0,\r\n };\r\n }),\r\n });\r\n }\r\n\r\n // --- collections GET by id or slug ---\r\n if (path[0] === 'collections' && path.length === 2 && method === 'GET') {\r\n const idOrSlug = path[1]!;\r\n const byId = /^\\d+$/.test(idOrSlug);\r\n const collection = await collectionRepo().findOne({\r\n where: byId\r\n ? { id: parseInt(idOrSlug, 10), active: true, deleted: false }\r\n : { slug: idOrSlug, active: true, deleted: false },\r\n relations: ['seo'],\r\n } as ObjectLiteral);\r\n if (!collection) return json({ error: 'Not found' }, { status: 404 });\r\n const col = collection as ObjectLiteral;\r\n const products = await productRepo().find({\r\n where: { collectionId: col.id, status: 'available', deleted: false } as ObjectLiteral,\r\n order: { id: 'ASC' },\r\n });\r\n const colSeo = serializeSeo(col.seo);\r\n return json({\r\n id: col.id,\r\n name: col.name,\r\n slug: col.slug,\r\n description: col.description,\r\n image: col.image,\r\n ...(colSeo ? { seo: colSeo } : {}),\r\n products: products.map((p) => serializeProduct(p as ObjectLiteral)),\r\n });\r\n }\r\n\r\n // --- profile GET (auth) ---\r\n if (path[0] === 'profile' && path.length === 1 && method === 'GET') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const user = await userRepo().findOne({ where: { id: uid }, select: ['id', 'name', 'email'] });\r\n if (!user) return json({ error: 'Not found' }, { status: 404 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n return json({\r\n user: { id: (user as ObjectLiteral).id, name: (user as ObjectLiteral).name, email: (user as ObjectLiteral).email },\r\n contact: contact\r\n ? {\r\n id: (contact as ObjectLiteral).id,\r\n name: (contact as ObjectLiteral).name,\r\n email: (contact as ObjectLiteral).email,\r\n phone: (contact as ObjectLiteral).phone,\r\n }\r\n : null,\r\n });\r\n }\r\n\r\n // --- profile PUT (auth) ---\r\n if (path[0] === 'profile' && path.length === 1 && method === 'PUT') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const b = (await req.json().catch(() => ({}))) as { name?: string; phone?: string };\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (contact) {\r\n const updates: ObjectLiteral = {};\r\n if (typeof b.name === 'string' && b.name.trim()) updates.name = b.name.trim();\r\n if (b.phone !== undefined) updates.phone = b.phone === null || b.phone === '' ? null : String(b.phone);\r\n if (Object.keys(updates).length) await contactRepo().update((contact as { id: number }).id, updates);\r\n }\r\n const user = await userRepo().findOne({ where: { id: uid }, select: ['id', 'name', 'email'] });\r\n if (user && typeof b.name === 'string' && b.name.trim()) {\r\n await userRepo().update(uid, { name: b.name.trim() });\r\n }\r\n const updatedContact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (updatedContact) await syncContactToErp(updatedContact as ObjectLiteral);\r\n const updatedUser = await userRepo().findOne({ where: { id: uid }, select: ['id', 'name', 'email'] });\r\n return json({\r\n user: updatedUser ? { id: (updatedUser as ObjectLiteral).id, name: (updatedUser as ObjectLiteral).name, email: (updatedUser as ObjectLiteral).email } : null,\r\n contact: updatedContact\r\n ? {\r\n id: (updatedContact as ObjectLiteral).id,\r\n name: (updatedContact as ObjectLiteral).name,\r\n email: (updatedContact as ObjectLiteral).email,\r\n phone: (updatedContact as ObjectLiteral).phone,\r\n }\r\n : null,\r\n });\r\n }\r\n\r\n // --- addresses (auth: contact's addresses) ---\r\n async function getContactForAddresses(): Promise<{ contactId: number } | Response> {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (!contact) return json({ error: 'Contact not found' }, { status: 404 });\r\n return { contactId: (contact as { id: number }).id };\r\n }\r\n function serializeAddress(a: ObjectLiteral) {\r\n return {\r\n id: a.id,\r\n contactId: a.contactId,\r\n tag: a.tag,\r\n line1: a.line1,\r\n line2: a.line2,\r\n city: a.city,\r\n state: a.state,\r\n postalCode: a.postalCode,\r\n country: a.country,\r\n };\r\n }\r\n if (path[0] === 'addresses' && path.length === 1 && method === 'GET') {\r\n const contactOrErr = await getContactForAddresses();\r\n if (contactOrErr instanceof Response) return contactOrErr;\r\n const list = await addressRepo().find({\r\n where: { contactId: contactOrErr.contactId },\r\n order: { id: 'ASC' },\r\n });\r\n return json({ addresses: list.map((a) => serializeAddress(a as ObjectLiteral)) });\r\n }\r\n if (path[0] === 'addresses' && path.length === 1 && method === 'POST') {\r\n const contactOrErr = await getContactForAddresses();\r\n if (contactOrErr instanceof Response) return contactOrErr;\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const created = await addressRepo().save(\r\n addressRepo().create({\r\n contactId: contactOrErr.contactId,\r\n tag: typeof b.tag === 'string' ? b.tag.trim() || null : null,\r\n line1: typeof b.line1 === 'string' ? b.line1.trim() || null : null,\r\n line2: typeof b.line2 === 'string' ? b.line2.trim() || null : null,\r\n city: typeof b.city === 'string' ? b.city.trim() || null : null,\r\n state: typeof b.state === 'string' ? b.state.trim() || null : null,\r\n postalCode: typeof b.postalCode === 'string' ? b.postalCode.trim() || null : null,\r\n country: typeof b.country === 'string' ? b.country.trim() || null : null,\r\n } as ObjectLiteral)\r\n );\r\n return json(serializeAddress(created as ObjectLiteral));\r\n }\r\n if (path[0] === 'addresses' && path.length === 2 && (method === 'PATCH' || method === 'PUT')) {\r\n const contactOrErr = await getContactForAddresses();\r\n if (contactOrErr instanceof Response) return contactOrErr;\r\n const id = parseInt(path[1]!, 10);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const existing = await addressRepo().findOne({ where: { id, contactId: contactOrErr.contactId } as ObjectLiteral });\r\n if (!existing) return json({ error: 'Not found' }, { status: 404 });\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const updates: ObjectLiteral = {};\r\n if (b.tag !== undefined) updates.tag = typeof b.tag === 'string' ? b.tag.trim() || null : null;\r\n if (b.line1 !== undefined) updates.line1 = typeof b.line1 === 'string' ? b.line1.trim() || null : null;\r\n if (b.line2 !== undefined) updates.line2 = typeof b.line2 === 'string' ? b.line2.trim() || null : null;\r\n if (b.city !== undefined) updates.city = typeof b.city === 'string' ? b.city.trim() || null : null;\r\n if (b.state !== undefined) updates.state = typeof b.state === 'string' ? b.state.trim() || null : null;\r\n if (b.postalCode !== undefined) updates.postalCode = typeof b.postalCode === 'string' ? b.postalCode.trim() || null : null;\r\n if (b.country !== undefined) updates.country = typeof b.country === 'string' ? b.country.trim() || null : null;\r\n if (Object.keys(updates).length) await addressRepo().update(id, updates);\r\n const updated = await addressRepo().findOne({ where: { id } as ObjectLiteral });\r\n return json(serializeAddress(updated as ObjectLiteral));\r\n }\r\n if (path[0] === 'addresses' && path.length === 2 && method === 'DELETE') {\r\n const contactOrErr = await getContactForAddresses();\r\n if (contactOrErr instanceof Response) return contactOrErr;\r\n const id = parseInt(path[1]!, 10);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const existing = await addressRepo().findOne({ where: { id, contactId: contactOrErr.contactId } as ObjectLiteral });\r\n if (!existing) return json({ error: 'Not found' }, { status: 404 });\r\n await addressRepo().delete(id);\r\n return json({ deleted: true });\r\n }\r\n\r\n // --- verify-email POST (public) ---\r\n if (path[0] === 'verify-email' && path.length === 1 && method === 'POST') {\r\n const b = (await req.json().catch(() => ({}))) as { token?: string };\r\n const token = typeof b.token === 'string' ? b.token.trim() : '';\r\n if (!token) return json({ error: 'token is required' }, { status: 400 });\r\n const record = await tokenRepo().findOne({ where: { token } as ObjectLiteral });\r\n if (!record || (record as { expiresAt: Date }).expiresAt < new Date()) {\r\n return json({ error: 'Invalid or expired link. Please sign up again or contact support.' }, { status: 400 });\r\n }\r\n const email = (record as { email: string }).email;\r\n const user = await userRepo().findOne({ where: { email }, select: ['id', 'blocked'] });\r\n if (!user) return json({ error: 'User not found' }, { status: 400 });\r\n await userRepo().update((user as { id: number }).id, {\r\n blocked: false,\r\n emailVerifiedAt: new Date(),\r\n updatedAt: new Date(),\r\n } as ObjectLiteral);\r\n await tokenRepo().delete({ email } as ObjectLiteral);\r\n return json({ success: true, message: 'Email verified. You can sign in.' });\r\n }\r\n\r\n // --- auth/otp/send POST ---\r\n if (path[0] === 'auth' && path[1] === 'otp' && path[2] === 'send' && path.length === 3 && method === 'POST') {\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const purposeRaw = typeof b.purpose === 'string' ? b.purpose.trim() : '';\r\n const purpose = (purposeRaw === 'login' || purposeRaw === 'verify_email' || purposeRaw === 'verify_phone'\r\n ? purposeRaw\r\n : '') as OtpPurpose | '';\r\n if (!purpose) return json({ error: 'purpose must be login, verify_email, or verify_phone' }, { status: 400 });\r\n if (purpose === 'login' && otpOff('login')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n if (purpose === 'verify_email' && otpOff('verifyEmail')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n if (purpose === 'verify_phone' && otpOff('verifyPhone')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n\r\n const capOtp = await assertCaptchaOk(getCms, b, req, json);\r\n if (capOtp) return capOtp;\r\n\r\n const emailIn = typeof b.email === 'string' ? b.email.trim().toLowerCase() : '';\r\n const phoneIn = typeof b.phone === 'string' ? b.phone.trim() : '';\r\n let identifier: string;\r\n let channel: 'email' | 'sms';\r\n\r\n if (purpose === 'login') {\r\n if (emailIn) {\r\n identifier = emailIn;\r\n channel = 'email';\r\n } else if (phoneIn) {\r\n if (!otpAllowPhoneLogin) {\r\n return json({ error: 'Phone sign-in is not enabled' }, { status: 403 });\r\n }\r\n const p = normalizePhoneE164(phoneIn, defaultPhoneCc);\r\n if (!p) return json({ error: 'Invalid phone' }, { status: 400 });\r\n identifier = p;\r\n channel = 'sms';\r\n } else {\r\n return json({ error: 'email or phone required' }, { status: 400 });\r\n }\r\n const user =\r\n channel === 'email'\r\n ? await userRepo().findOne({ where: { email: identifier } as ObjectLiteral })\r\n : await userRepo().findOne({ where: { phone: identifier } as ObjectLiteral });\r\n if (!user || (user as { deleted?: boolean }).deleted || (user as { blocked?: boolean }).blocked) {\r\n return json({ ok: true });\r\n }\r\n } else if (purpose === 'verify_email') {\r\n if (!emailIn || !isValidSignupEmail(emailIn)) return json({ error: 'Valid email required' }, { status: 400 });\r\n identifier = emailIn;\r\n channel = 'email';\r\n const user = await userRepo().findOne({ where: { email: identifier } as ObjectLiteral });\r\n if (!user || (user as { deleted?: boolean }).deleted) return json({ ok: true });\r\n } else {\r\n const su = await getSessionUser();\r\n const uid = su?.id ? parseInt(String(su.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const p = normalizePhoneE164(phoneIn, defaultPhoneCc);\r\n if (!p) return json({ error: 'Valid phone required' }, { status: 400 });\r\n identifier = p;\r\n channel = 'sms';\r\n const taken = await userRepo().findOne({\r\n where: { phone: identifier } as ObjectLiteral,\r\n select: ['id'],\r\n });\r\n if (taken && (taken as { id: number }).id !== uid) {\r\n return json({ error: 'Phone already in use' }, { status: 400 });\r\n }\r\n }\r\n\r\n const code = generateNumericOtp(6);\r\n const created = await createOtpChallenge(dataSource, entityMap, {\r\n purpose,\r\n channel,\r\n identifier,\r\n code,\r\n pepper: otpPepper,\r\n });\r\n if (!created.ok) return json({ error: created.error }, { status: created.status });\r\n\r\n if (!getCms) return json({ error: 'OTP delivery not configured' }, { status: 503 });\r\n\r\n try {\r\n const cms = await getCms();\r\n if (channel === 'email') {\r\n if (!cms.getPlugin('email')) return json({ error: 'Email not configured' }, { status: 503 });\r\n const companyDetails = getCompanyDetails ? await getCompanyDetails() : {};\r\n await queueEmail(cms, {\r\n to: identifier,\r\n templateName: 'otp',\r\n ctx: { code, companyDetails: companyDetails ?? {} },\r\n });\r\n } else {\r\n if (!cms.getPlugin('sms')) return json({ error: 'SMS not configured' }, { status: 503 });\r\n const templateKey = purpose === 'verify_phone' ? 'auth.otp_verify_phone' : 'auth.otp_login';\r\n await queueSms(cms, { to: identifier, templateKey, variables: { code } });\r\n }\r\n } catch {\r\n return json({ error: 'Failed to send code' }, { status: 500 });\r\n }\r\n return json({ ok: true });\r\n }\r\n\r\n // --- auth/otp/verify-email POST ---\r\n if (path[0] === 'auth' && path[1] === 'otp' && path[2] === 'verify-email' && path.length === 3 && method === 'POST') {\r\n if (otpOff('verifyEmail')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n const b = (await req.json().catch(() => ({}))) as { email?: string; code?: string };\r\n const email = typeof b.email === 'string' ? b.email.trim().toLowerCase() : '';\r\n const code = typeof b.code === 'string' ? b.code.trim() : '';\r\n if (!email || !code) return json({ error: 'email and code required' }, { status: 400 });\r\n const v = await verifyAndConsumeOtpChallenge(dataSource, entityMap, {\r\n purpose: 'verify_email',\r\n identifier: email,\r\n code,\r\n pepper: otpPepper,\r\n });\r\n if (!v.ok) return json({ error: v.error }, { status: v.status });\r\n const user = await userRepo().findOne({ where: { email } as ObjectLiteral });\r\n if (!user) return json({ error: 'User not found' }, { status: 400 });\r\n await userRepo().update((user as { id: number }).id, {\r\n blocked: false,\r\n emailVerifiedAt: new Date(),\r\n updatedAt: new Date(),\r\n } as ObjectLiteral);\r\n await tokenRepo().delete({ email } as ObjectLiteral);\r\n return json({ success: true, message: 'Email verified. You can sign in.' });\r\n }\r\n\r\n // --- auth/otp/verify-phone POST ---\r\n if (path[0] === 'auth' && path[1] === 'otp' && path[2] === 'verify-phone' && path.length === 3 && method === 'POST') {\r\n if (otpOff('verifyPhone')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n const su = await getSessionUser();\r\n const uid = su?.id ? parseInt(String(su.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const b = (await req.json().catch(() => ({}))) as { phone?: string; code?: string };\r\n const phoneRaw = typeof b.phone === 'string' ? b.phone.trim() : '';\r\n const code = typeof b.code === 'string' ? b.code.trim() : '';\r\n const phone = normalizePhoneE164(phoneRaw, defaultPhoneCc);\r\n if (!phone || !code) return json({ error: 'phone and code required' }, { status: 400 });\r\n const v = await verifyAndConsumeOtpChallenge(dataSource, entityMap, {\r\n purpose: 'verify_phone',\r\n identifier: phone,\r\n code,\r\n pepper: otpPepper,\r\n });\r\n if (!v.ok) return json({ error: v.error }, { status: v.status });\r\n const taken = await userRepo().findOne({ where: { phone } as ObjectLiteral, select: ['id'] });\r\n if (taken && (taken as { id: number }).id !== uid) {\r\n return json({ error: 'Phone already in use' }, { status: 400 });\r\n }\r\n await userRepo().update(uid, { phone, phoneVerifiedAt: new Date(), updatedAt: new Date() } as ObjectLiteral);\r\n const contact = await ensureContactForUser(uid);\r\n if (contact) {\r\n await contactRepo().update(contact.id, { phone } as ObjectLiteral);\r\n }\r\n return json({ success: true });\r\n }\r\n\r\n // --- register POST ---\r\n if (path[0] === 'register' && path.length === 1 && method === 'POST') {\r\n if (!config.hashPassword) return json({ error: 'Registration not configured' }, { status: 501 });\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capReg = await assertCaptchaOk(getCms, b, req, json);\r\n if (capReg) return capReg;\r\n const name = typeof b.name === 'string' ? b.name.trim() : '';\r\n const email = typeof b.email === 'string' ? b.email.trim().toLowerCase() : '';\r\n const password = typeof b.password === 'string' ? b.password : '';\r\n if (!name || !email || !password) return json({ error: 'name, email and password are required' }, { status: 400 });\r\n if (!isValidSignupEmail(email)) return json({ error: 'Invalid email address' }, { status: 400 });\r\n const existing = await userRepo().findOne({ where: { email } });\r\n if (existing) return json({ error: 'User with this email already exists' }, { status: 400 });\r\n const customerG = await groupRepo().findOne({ where: { name: 'Customer', deleted: false } as ObjectLiteral });\r\n const groupId = customerG ? (customerG as { id: number }).id : null;\r\n const hashed = await config.hashPassword(password);\r\n const requireEmailVerification = Boolean(getCms);\r\n const newUser = await userRepo().save(\r\n userRepo().create({\r\n name,\r\n email,\r\n password: hashed,\r\n blocked: requireEmailVerification,\r\n groupId,\r\n adminAccess: false,\r\n } as ObjectLiteral)\r\n );\r\n const userId = (newUser as { id: number }).id;\r\n await linkUnclaimedContactToUser(dataSource, entityMap.contacts, userId, email);\r\n\r\n let emailVerificationSent = false;\r\n if (requireEmailVerification && getCms) {\r\n try {\r\n const crypto = await import('crypto');\r\n const rawToken = crypto.randomBytes(32).toString('hex');\r\n const expiresAt = new Date(Date.now() + SIGNUP_VERIFY_EXPIRY_HOURS * 60 * 60 * 1000);\r\n await tokenRepo().save(\r\n tokenRepo().create({ email, token: rawToken, expiresAt } as ObjectLiteral)\r\n );\r\n const cms = await getCms();\r\n const companyDetails = getCompanyDetails ? await getCompanyDetails() : {};\r\n const base = (publicSiteUrl || '').replace(/\\/$/, '').trim() || 'http://localhost:3000';\r\n const verifyEmailUrl = `${base}/verify-email?token=${encodeURIComponent(rawToken)}`;\r\n await queueEmail(cms, {\r\n to: email,\r\n templateName: 'signup',\r\n ctx: { name, verifyEmailUrl, companyDetails: companyDetails ?? {} },\r\n });\r\n emailVerificationSent = true;\r\n } catch {\r\n await userRepo().update(userId, { blocked: false, updatedAt: new Date() } as ObjectLiteral);\r\n }\r\n }\r\n\r\n return json({\r\n success: true,\r\n userId,\r\n emailVerificationSent,\r\n });\r\n }\r\n\r\n // --- cart GET ---\r\n if (path[0] === 'cart' && path.length === 1 && method === 'GET') {\r\n const { cart, setCookie, err } = await getOrCreateCart(req);\r\n if (err) return err;\r\n const body = serializeCart(cart);\r\n if (setCookie) return json(body, { headers: { 'Set-Cookie': setCookie } });\r\n return json(body);\r\n }\r\n\r\n // --- cart/items POST ---\r\n if (path[0] === 'cart' && path[1] === 'items' && path.length === 2 && method === 'POST') {\r\n const body = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capCart = await assertCaptchaOk(getCms, body, req, json);\r\n if (capCart) return capCart;\r\n const productId = Number(body.productId);\r\n const quantity = Math.max(1, Number(body.quantity) || 1);\r\n if (!Number.isFinite(productId)) return json({ error: 'productId required' }, { status: 400 });\r\n const product = await productRepo().findOne({ where: { id: productId, deleted: false } as ObjectLiteral });\r\n if (!product) return json({ error: 'Product not found' }, { status: 404 });\r\n const { cart, setCookie, err } = await getOrCreateCart(req);\r\n if (err) return err;\r\n const cartId = (cart as { id: number }).id;\r\n const existing = await cartItemRepo().findOne({ where: { cartId, productId } as ObjectLiteral });\r\n if (existing) {\r\n await cartItemRepo().update((existing as { id: number }).id, {\r\n quantity: (existing as { quantity: number }).quantity + quantity,\r\n });\r\n } else {\r\n await cartItemRepo().save(\r\n cartItemRepo().create({ cartId, productId, quantity } as ObjectLiteral)\r\n );\r\n }\r\n await cartRepo().update(cartId, { updatedAt: new Date() });\r\n const fresh = await cartRepo().findOne({\r\n where: { id: cartId },\r\n relations: ['items', 'items.product'],\r\n });\r\n const out = serializeCart(fresh!);\r\n if (setCookie) return json(out, { headers: { 'Set-Cookie': setCookie } });\r\n return json(out);\r\n }\r\n\r\n // --- cart/items/:id PATCH DELETE ---\r\n if (path[0] === 'cart' && path[1] === 'items' && path.length === 3) {\r\n const itemId = parseInt(path[2]!, 10);\r\n if (!Number.isFinite(itemId)) return json({ error: 'Invalid item id' }, { status: 400 });\r\n const { cart, setCookie, err } = await getOrCreateCart(req);\r\n if (err) return err;\r\n const cartId = (cart as { id: number }).id;\r\n const item = await cartItemRepo().findOne({ where: { id: itemId, cartId } as ObjectLiteral });\r\n if (!item) return json({ error: 'Not found' }, { status: 404 });\r\n if (method === 'DELETE') {\r\n await cartItemRepo().delete(itemId);\r\n await cartRepo().update(cartId, { updatedAt: new Date() });\r\n const fresh = await cartRepo().findOne({\r\n where: { id: cartId },\r\n relations: ['items', 'items.product'],\r\n });\r\n const out = serializeCart(fresh!);\r\n if (setCookie) return json(out, { headers: { 'Set-Cookie': setCookie } });\r\n return json(out);\r\n }\r\n if (method === 'PATCH') {\r\n const b = (await req.json().catch(() => ({}))) as { quantity?: number };\r\n const q = Math.max(0, Number(b.quantity) || 0);\r\n if (q === 0) await cartItemRepo().delete(itemId);\r\n else await cartItemRepo().update(itemId, { quantity: q });\r\n await cartRepo().update(cartId, { updatedAt: new Date() });\r\n const fresh = await cartRepo().findOne({\r\n where: { id: cartId },\r\n relations: ['items', 'items.product'],\r\n });\r\n const out = serializeCart(fresh!);\r\n if (setCookie) return json(out, { headers: { 'Set-Cookie': setCookie } });\r\n return json(out);\r\n }\r\n }\r\n\r\n // --- cart/merge POST (auth) ---\r\n if (path[0] === 'cart' && path[1] === 'merge' && method === 'POST') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return json({ error: 'Contact not found' }, { status: 400 });\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n const guestToken = cookies[cookieName];\r\n if (!guestToken) return json({ merged: false, message: 'No guest cart' });\r\n const guestCart = await cartRepo().findOne({\r\n where: { guestToken } as ObjectLiteral,\r\n relations: ['items'],\r\n });\r\n if (!guestCart || !((guestCart as { items?: unknown[] }).items || []).length) {\r\n let uc = await cartRepo().findOne({\r\n where: { contactId: contact.id } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!uc) uc = { items: [] } as ObjectLiteral;\r\n return json(\r\n { merged: false, cart: serializeCart(uc) },\r\n { headers: { 'Set-Cookie': `${cookieName}=; Path=/; Max-Age=0` } }\r\n );\r\n }\r\n let userCart = await cartRepo().findOne({ where: { contactId: contact.id } as ObjectLiteral });\r\n if (!userCart) {\r\n userCart = await cartRepo().save(\r\n cartRepo().create({ contactId: contact.id, guestToken: null, currency: (guestCart as { currency: string }).currency } as ObjectLiteral)\r\n );\r\n }\r\n const uidCart = (userCart as { id: number }).id;\r\n const gItems = ((guestCart as { items: ObjectLiteral[] }).items) || [];\r\n for (const gi of gItems) {\r\n const existing = await cartItemRepo().findOne({\r\n where: { cartId: uidCart, productId: (gi as { productId: number }).productId } as ObjectLiteral,\r\n });\r\n if (existing) {\r\n await cartItemRepo().update((existing as { id: number }).id, {\r\n quantity: (existing as { quantity: number }).quantity + (gi as { quantity: number }).quantity,\r\n });\r\n } else {\r\n await cartItemRepo().save(\r\n cartItemRepo().create({\r\n cartId: uidCart,\r\n productId: (gi as { productId: number }).productId,\r\n quantity: (gi as { quantity: number }).quantity,\r\n metadata: (gi as { metadata: unknown }).metadata,\r\n } as ObjectLiteral)\r\n );\r\n }\r\n }\r\n await cartRepo().delete((guestCart as { id: number }).id);\r\n await cartRepo().update(uidCart, { updatedAt: new Date() });\r\n const fresh = await cartRepo().findOne({\r\n where: { id: uidCart },\r\n relations: ['items', 'items.product'],\r\n });\r\n // Merge guest wishlist into contact wishlist (same guestId cookie)\r\n const guestWishlist = await wishlistRepo().findOne({\r\n where: { guestId: guestToken } as ObjectLiteral,\r\n relations: ['items'],\r\n });\r\n if (guestWishlist && ((guestWishlist as { items?: unknown[] }).items || []).length > 0) {\r\n const userWishlist = await getDefaultWishlist(contact.id);\r\n const gItems = ((guestWishlist as { items: ObjectLiteral[] }).items) || [];\r\n for (const gi of gItems) {\r\n const pid = (gi as { productId: number }).productId;\r\n const ex = await wishlistItemRepo().findOne({ where: { wishlistId: userWishlist.id, productId: pid } as ObjectLiteral });\r\n if (!ex) await wishlistItemRepo().save(wishlistItemRepo().create({ wishlistId: userWishlist.id, productId: pid } as ObjectLiteral));\r\n }\r\n await wishlistRepo().delete((guestWishlist as { id: number }).id);\r\n }\r\n return json({ merged: true, cart: serializeCart(fresh!) }, { headers: { 'Set-Cookie': `${cookieName}=; Path=/; Max-Age=0` } });\r\n }\r\n\r\n // --- wishlist (guest or auth: same guestId cookie as cart) ---\r\n async function getDefaultWishlist(contactId: number) {\r\n let w = await wishlistRepo().findOne({ where: { contactId, name: 'default' } as ObjectLiteral });\r\n if (!w) {\r\n w = await wishlistRepo().save(wishlistRepo().create({ contactId, guestId: null, name: 'default' } as ObjectLiteral));\r\n }\r\n return w as { id: number };\r\n }\r\n\r\n async function getOrCreateWishlist(req: Request): Promise<{ wishlist: ObjectLiteral; setCookie: string | null; err: Response | null }> {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (Number.isFinite(uid)) {\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return { wishlist: {} as ObjectLiteral, setCookie: null, err: json({ error: 'User not found' }, { status: 400 }) };\r\n const w = await getDefaultWishlist(contact.id);\r\n const wishlist = await wishlistRepo().findOne({ where: { id: w.id } as ObjectLiteral });\r\n return { wishlist: wishlist!, setCookie: null, err: null };\r\n }\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n let token = cookies[cookieName] || '';\r\n if (!token) {\r\n token = crypto.randomUUID();\r\n let w = await wishlistRepo().findOne({ where: { guestId: token } as ObjectLiteral });\r\n if (!w) {\r\n w = await wishlistRepo().save(wishlistRepo().create({ guestId: token, contactId: null, name: 'default' } as ObjectLiteral));\r\n }\r\n return { wishlist: w!, setCookie: guestCookieHeader(cookieName, token), err: null };\r\n }\r\n let w = await wishlistRepo().findOne({ where: { guestId: token } as ObjectLiteral });\r\n if (!w) {\r\n w = await wishlistRepo().save(wishlistRepo().create({ guestId: token, contactId: null, name: 'default' } as ObjectLiteral));\r\n }\r\n return { wishlist: w!, setCookie: null, err: null };\r\n }\r\n\r\n if (path[0] === 'wishlist' && path.length === 1 && method === 'GET') {\r\n const { wishlist, setCookie, err } = await getOrCreateWishlist(req);\r\n if (err) return err;\r\n const items = await wishlistItemRepo().find({\r\n where: { wishlistId: (wishlist as { id: number }).id } as ObjectLiteral,\r\n relations: ['product'],\r\n });\r\n const body = {\r\n wishlistId: (wishlist as { id: number }).id,\r\n items: items.map((it) => {\r\n const p = (it as ObjectLiteral).product as ObjectLiteral | undefined;\r\n return {\r\n id: (it as ObjectLiteral).id,\r\n productId: (it as ObjectLiteral).productId,\r\n product: p\r\n ? {\r\n id: p.id,\r\n name: p.name,\r\n slug: p.slug,\r\n price: p.price,\r\n sku: p.sku,\r\n image: primaryProductImageUrl(p.metadata),\r\n }\r\n : null,\r\n };\r\n }),\r\n };\r\n if (setCookie) return json(body, { headers: { 'Set-Cookie': setCookie } });\r\n return json(body);\r\n }\r\n\r\n if (path[0] === 'wishlist' && path[1] === 'items' && path.length === 2 && method === 'POST') {\r\n const { wishlist, setCookie, err } = await getOrCreateWishlist(req);\r\n if (err) return err;\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capWl = await assertCaptchaOk(getCms, b, req, json);\r\n if (capWl) return capWl;\r\n const productId = Number(b.productId);\r\n if (!Number.isFinite(productId)) return json({ error: 'productId required' }, { status: 400 });\r\n const wid = (wishlist as { id: number }).id;\r\n const ex = await wishlistItemRepo().findOne({ where: { wishlistId: wid, productId } as ObjectLiteral });\r\n if (!ex) await wishlistItemRepo().save(wishlistItemRepo().create({ wishlistId: wid, productId } as ObjectLiteral));\r\n if (setCookie) return json({ ok: true }, { headers: { 'Set-Cookie': setCookie } });\r\n return json({ ok: true });\r\n }\r\n\r\n if (path[0] === 'wishlist' && path[1] === 'items' && path.length === 3 && method === 'DELETE') {\r\n const { wishlist, setCookie, err } = await getOrCreateWishlist(req);\r\n if (err) return err;\r\n const productId = parseInt(path[2]!, 10);\r\n await wishlistItemRepo().delete({ wishlistId: (wishlist as { id: number }).id, productId } as ObjectLiteral);\r\n if (setCookie) return json({ ok: true }, { headers: { 'Set-Cookie': setCookie } });\r\n return json({ ok: true });\r\n }\r\n\r\n // --- checkout/order POST (create order only, for Razorpay; do not clear cart) ---\r\n if (path[0] === 'checkout' && path[1] === 'order' && path.length === 2 && method === 'POST') {\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capOrd = await assertCaptchaOk(getCms, b, req, json);\r\n if (capOrd) return capOrd;\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n let contactId: number;\r\n let cart: ObjectLiteral | null;\r\n if (Number.isFinite(uid)) {\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return json({ error: 'Contact required' }, { status: 400 });\r\n contactId = contact.id;\r\n cart = await cartRepo().findOne({\r\n where: { contactId } as ObjectLiteral,\r\n relations: [...CART_CHECKOUT_RELATIONS],\r\n });\r\n } else {\r\n const email = String(b.email ?? '').trim();\r\n const name = String(b.name ?? '').trim();\r\n if (!email || !name) return json({ error: 'name and email required for guest checkout' }, { status: 400 });\r\n let contact = await contactRepo().findOne({ where: { email, deleted: false } as ObjectLiteral });\r\n if (contact && (contact as { userId: number | null }).userId != null) {\r\n return json({ error: 'Please sign in to complete checkout' }, { status: 400 });\r\n }\r\n if (!contact) {\r\n contact = await contactRepo().save(\r\n contactRepo().create({\r\n name,\r\n email,\r\n phone: b.phone != null && b.phone !== '' ? String(b.phone) : null,\r\n userId: null,\r\n deleted: false,\r\n } as ObjectLiteral)\r\n );\r\n } else if (name)\r\n await contactRepo().update((contact as { id: number }).id, {\r\n name,\r\n phone: b.phone != null && b.phone !== '' ? String(b.phone) : (contact as { phone: string | null }).phone,\r\n });\r\n contactId = (contact as { id: number }).id;\r\n const guestForErp = await contactRepo().findOne({ where: { id: contactId } as ObjectLiteral });\r\n if (guestForErp) await syncContactToErp(guestForErp);\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n const guestToken = cookies[cookieName];\r\n if (!guestToken) return json({ error: 'Cart not found' }, { status: 400 });\r\n cart = await cartRepo().findOne({\r\n where: { guestToken } as ObjectLiteral,\r\n relations: [...CART_CHECKOUT_RELATIONS],\r\n });\r\n }\r\n if (!cart || !((cart.items as ObjectLiteral[]) || []).length) {\r\n return json({ error: 'Cart is empty' }, { status: 400 });\r\n }\r\n const prepOrd = await prepareCheckoutFromCart(b, cart, contactId);\r\n if (!prepOrd.ok) return json({ error: prepOrd.message }, { status: prepOrd.status });\r\n const cartId = (cart as { id: number }).id;\r\n const ord = await orderRepo().save(\r\n orderRepo().create({\r\n orderNumber: temporaryOrderNumberPlaceholder(),\r\n orderKind: 'sale',\r\n parentOrderId: null,\r\n contactId,\r\n billingAddressId: prepOrd.billingAddressId,\r\n shippingAddressId: prepOrd.shippingAddressId,\r\n status: 'pending',\r\n subtotal: prepOrd.subtotal,\r\n tax: prepOrd.orderTax,\r\n discount: 0,\r\n total: prepOrd.orderTotal,\r\n currency: (cart.currency as string) || 'INR',\r\n metadata: { cartId },\r\n } as ObjectLiteral)\r\n );\r\n const oid = (ord as { id: number }).id;\r\n await orderRepo().update(oid, {\r\n orderNumber: buildCanonicalOrderNumber('sale', oid, (ord as { createdAt?: Date }).createdAt ?? new Date()),\r\n } as ObjectLiteral);\r\n for (const line of prepOrd.lines) {\r\n await orderItemRepo().save(\r\n orderItemRepo().create({\r\n orderId: oid,\r\n productId: line.productId,\r\n quantity: line.quantity,\r\n unitPrice: line.unitPrice,\r\n tax: line.tax,\r\n total: line.total,\r\n hsn: line.hsn,\r\n uom: line.uom,\r\n productType: line.productType,\r\n taxRate: line.taxRate,\r\n taxCode: line.taxCode,\r\n } as ObjectLiteral)\r\n );\r\n }\r\n return json({\r\n orderId: oid,\r\n orderNumber: (ord as { orderNumber: string }).orderNumber,\r\n subtotal: prepOrd.subtotal,\r\n tax: prepOrd.orderTax,\r\n total: prepOrd.orderTotal,\r\n currency: (cart.currency as string) || 'INR',\r\n });\r\n }\r\n\r\n // --- checkout POST ---\r\n if (path[0] === 'checkout' && path.length === 1 && method === 'POST') {\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capChk = await assertCaptchaOk(getCms, b, req, json);\r\n if (capChk) return capChk;\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n let contactId: number;\r\n let cart: ObjectLiteral | null;\r\n if (Number.isFinite(uid)) {\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return json({ error: 'Contact required' }, { status: 400 });\r\n contactId = contact.id;\r\n cart = await cartRepo().findOne({\r\n where: { contactId } as ObjectLiteral,\r\n relations: [...CART_CHECKOUT_RELATIONS],\r\n });\r\n } else {\r\n const email = String(b.email ?? '').trim();\r\n const name = String(b.name ?? '').trim();\r\n if (!email || !name) return json({ error: 'name and email required for guest checkout' }, { status: 400 });\r\n let contact = await contactRepo().findOne({ where: { email, deleted: false } as ObjectLiteral });\r\n if (contact && (contact as { userId: number | null }).userId != null) {\r\n return json({ error: 'Please sign in to complete checkout' }, { status: 400 });\r\n }\r\n if (!contact) {\r\n contact = await contactRepo().save(\r\n contactRepo().create({\r\n name,\r\n email,\r\n phone: b.phone != null && b.phone !== '' ? String(b.phone) : null,\r\n userId: null,\r\n deleted: false,\r\n } as ObjectLiteral)\r\n );\r\n } else if (name)\r\n await contactRepo().update((contact as { id: number }).id, {\r\n name,\r\n phone: b.phone != null && b.phone !== '' ? String(b.phone) : (contact as { phone: string | null }).phone,\r\n });\r\n contactId = (contact as { id: number }).id;\r\n const guestForErp2 = await contactRepo().findOne({ where: { id: contactId } as ObjectLiteral });\r\n if (guestForErp2) await syncContactToErp(guestForErp2);\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n const guestToken = cookies[cookieName];\r\n if (!guestToken) return json({ error: 'Cart not found' }, { status: 400 });\r\n cart = await cartRepo().findOne({\r\n where: { guestToken } as ObjectLiteral,\r\n relations: [...CART_CHECKOUT_RELATIONS],\r\n });\r\n }\r\n if (!cart || !((cart.items as ObjectLiteral[]) || []).length) {\r\n return json({ error: 'Cart is empty' }, { status: 400 });\r\n }\r\n const prepChk = await prepareCheckoutFromCart(b, cart, contactId);\r\n if (!prepChk.ok) return json({ error: prepChk.message }, { status: prepChk.status });\r\n const ord = await orderRepo().save(\r\n orderRepo().create({\r\n orderNumber: temporaryOrderNumberPlaceholder(),\r\n orderKind: 'sale',\r\n parentOrderId: null,\r\n contactId,\r\n billingAddressId: prepChk.billingAddressId,\r\n shippingAddressId: prepChk.shippingAddressId,\r\n status: 'pending',\r\n subtotal: prepChk.subtotal,\r\n tax: prepChk.orderTax,\r\n discount: 0,\r\n total: prepChk.orderTotal,\r\n currency: (cart.currency as string) || 'INR',\r\n } as ObjectLiteral)\r\n );\r\n const oid = (ord as { id: number }).id;\r\n await orderRepo().update(oid, {\r\n orderNumber: buildCanonicalOrderNumber('sale', oid, (ord as { createdAt?: Date }).createdAt ?? new Date()),\r\n } as ObjectLiteral);\r\n for (const line of prepChk.lines) {\r\n await orderItemRepo().save(\r\n orderItemRepo().create({\r\n orderId: oid,\r\n productId: line.productId,\r\n quantity: line.quantity,\r\n unitPrice: line.unitPrice,\r\n tax: line.tax,\r\n total: line.total,\r\n hsn: line.hsn,\r\n uom: line.uom,\r\n productType: line.productType,\r\n taxRate: line.taxRate,\r\n taxCode: line.taxCode,\r\n } as ObjectLiteral)\r\n );\r\n }\r\n await cartItemRepo().delete({ cartId: (cart as { id: number }).id } as ObjectLiteral);\r\n await cartRepo().delete((cart as { id: number }).id);\r\n return json({\r\n orderId: oid,\r\n orderNumber: (ord as { orderNumber: string }).orderNumber,\r\n subtotal: prepChk.subtotal,\r\n tax: prepChk.orderTax,\r\n total: prepChk.orderTotal,\r\n });\r\n }\r\n\r\n // --- orders GET ---\r\n if (path[0] === 'orders' && path.length === 1 && method === 'GET') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (!contact) return json({ orders: [] });\r\n const orders = await orderRepo().find({\r\n where: { contactId: (contact as { id: number }).id, deleted: false, orderKind: 'sale' } as ObjectLiteral,\r\n order: { createdAt: 'DESC' },\r\n take: 50,\r\n });\r\n const orderIds = orders.map((o) => (o as ObjectLiteral).id as number);\r\n const previewByOrder: Record<number, string[]> = {};\r\n if (orderIds.length) {\r\n const oItems = await orderItemRepo().find({\r\n where: { orderId: In(orderIds) },\r\n relations: ['product'],\r\n order: { id: 'ASC' },\r\n });\r\n for (const oi of oItems) {\r\n const oid = (oi as ObjectLiteral).orderId as number;\r\n if (!previewByOrder[oid]) previewByOrder[oid] = [];\r\n if (previewByOrder[oid].length >= 4) continue;\r\n const url = primaryProductImageUrl(((oi as ObjectLiteral).product as ObjectLiteral)?.metadata);\r\n if (url && !previewByOrder[oid].includes(url)) previewByOrder[oid].push(url);\r\n }\r\n }\r\n return json({\r\n orders: orders.map((o) => {\r\n const ol = o as ObjectLiteral;\r\n return {\r\n id: ol.id,\r\n orderNumber: ol.orderNumber,\r\n status: ol.status,\r\n total: ol.total,\r\n currency: ol.currency,\r\n createdAt: ol.createdAt,\r\n previewImages: previewByOrder[ol.id as number] ?? [],\r\n };\r\n }),\r\n });\r\n }\r\n\r\n if (path[0] === 'orders' && path.length === 3 && path[2] === 'invoice' && method === 'GET') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n if (!getCms) return json({ error: 'Not found' }, { status: 404 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (!contact) return json({ error: 'Not found' }, { status: 404 });\r\n const orderId = parseInt(path[1]!, 10);\r\n if (!Number.isFinite(orderId)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const cms = await getCms();\r\n return streamOrderInvoicePdf(cms, dataSource, entityMap, orderId, {\r\n ownerContactId: (contact as { id: number }).id,\r\n });\r\n }\r\n\r\n if (path[0] === 'orders' && path.length === 2 && method === 'GET') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (!contact) return json({ error: 'Not found' }, { status: 404 });\r\n const orderId = parseInt(path[1]!, 10);\r\n let order = await orderRepo().findOne({\r\n where: { id: orderId, contactId: (contact as { id: number }).id, deleted: false } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!order) return json({ error: 'Not found' }, { status: 404 });\r\n if (getCms) {\r\n const cms = await getCms();\r\n await tryRefreshOrderFromErpForStorefront(cms, dataSource, entityMap, order as ObjectLiteral);\r\n order = await orderRepo().findOne({\r\n where: { id: orderId, contactId: (contact as { id: number }).id, deleted: false } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n }\r\n if (!order) return json({ error: 'Not found' }, { status: 404 });\r\n const o = order as ObjectLiteral;\r\n const lines = ((o.items as ObjectLiteral[]) || []).map((line) => {\r\n const p = line.product as ObjectLiteral | undefined;\r\n return {\r\n id: line.id,\r\n productId: line.productId,\r\n quantity: line.quantity,\r\n unitPrice: line.unitPrice,\r\n tax: line.tax,\r\n total: line.total,\r\n product: p\r\n ? {\r\n name: p.name,\r\n slug: p.slug,\r\n sku: p.sku,\r\n image: primaryProductImageUrl(p.metadata),\r\n }\r\n : null,\r\n };\r\n });\r\n const kind = (o.orderKind as string) || 'sale';\r\n let relatedOrders: ObjectLiteral[] = [];\r\n if (kind === 'sale') {\r\n relatedOrders = await orderRepo().find({\r\n where: { parentOrderId: orderId, deleted: false } as ObjectLiteral,\r\n order: { id: 'ASC' },\r\n });\r\n }\r\n const meta = o.metadata as Record<string, unknown> | null | undefined;\r\n const fulfillmentPreview =\r\n meta && typeof meta.fulfillment === 'object' && meta.fulfillment && 'status' in (meta.fulfillment as object)\r\n ? String((meta.fulfillment as { status?: string }).status ?? '')\r\n : '';\r\n return json({\r\n order: {\r\n id: o.id,\r\n orderNumber: o.orderNumber,\r\n orderKind: kind,\r\n parentOrderId: o.parentOrderId ?? null,\r\n status: o.status,\r\n subtotal: o.subtotal,\r\n tax: o.tax,\r\n discount: o.discount,\r\n total: o.total,\r\n currency: o.currency,\r\n createdAt: o.createdAt,\r\n metadata: o.metadata ?? null,\r\n items: lines,\r\n },\r\n relatedOrders: relatedOrders.map((r) => ({\r\n id: r.id,\r\n orderNumber: r.orderNumber,\r\n orderKind: r.orderKind ?? 'return',\r\n status: r.status,\r\n createdAt: r.createdAt,\r\n fulfillmentStatus:\r\n r.metadata &&\r\n typeof r.metadata === 'object' &&\r\n (r.metadata as { fulfillment?: { status?: string } }).fulfillment?.status,\r\n })),\r\n fulfillmentPreview: fulfillmentPreview || undefined,\r\n });\r\n }\r\n\r\n return json({ error: 'Not found' }, { status: 404 });\r\n } catch {\r\n return json({ error: 'Server error' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n","/** Max lengths per RFC 5321 / 5322 (practical subset). */\r\nconst MAX_EMAIL = 254;\r\nconst MAX_LOCAL = 64;\r\n\r\n/**\r\n * Rejects obviously invalid signup addresses (format, length, missing TLD).\r\n * Used by storefront register so junk strings cannot create accounts.\r\n */\r\nexport function isValidSignupEmail(email: string): boolean {\r\n if (!email || email.length > MAX_EMAIL) return false;\r\n const at = email.indexOf('@');\r\n if (at <= 0 || at !== email.lastIndexOf('@')) return false;\r\n const local = email.slice(0, at);\r\n const domain = email.slice(at + 1);\r\n if (!local || local.length > MAX_LOCAL || !domain || domain.length > 253) return false;\r\n if (local.startsWith('.') || local.endsWith('.') || local.includes('..')) return false;\r\n if (domain.startsWith('.') || domain.endsWith('.') || domain.includes('..')) return false;\r\n if (!/^[a-z0-9._%+-]+$/i.test(local)) return false;\r\n if (!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/i.test(domain)) return false;\r\n const tld = domain.split('.').pop()!;\r\n return tld.length >= 2;\r\n}\r\n","export type OrderKind = 'sale' | 'return' | 'replacement';\r\n\r\nconst KIND_PREFIX: Record<OrderKind, string> = {\r\n sale: 'OSL',\r\n return: 'ORT',\r\n replacement: 'ORP',\r\n};\r\n\r\n/** YYMM in UTC (two-digit year + month). */\r\nexport function orderNumberYymmUtc(at: Date): string {\r\n const yy = String(at.getUTCFullYear()).slice(-2);\r\n const mm = String(at.getUTCMonth() + 1).padStart(2, '0');\r\n return yy + mm;\r\n}\r\n\r\n/** Stable 8-char mask from numeric id (not reversible as plain decimal). */\r\nexport function maskOrderIdSegment(id: number): string {\r\n let x = (id >>> 0) ^ 0xa5a5a5a5;\r\n x = Math.imul(x, 2654435761) >>> 0;\r\n return x.toString(36).toUpperCase().padStart(8, '0').slice(-8);\r\n}\r\n\r\nexport function buildCanonicalOrderNumber(kind: OrderKind, id: number, at: Date): string {\r\n return KIND_PREFIX[kind] + orderNumberYymmUtc(at) + maskOrderIdSegment(id);\r\n}\r\n\r\nexport function temporaryOrderNumberPlaceholder(): string {\r\n return `TMP${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`.toUpperCase();\r\n}\r\n","export interface OrderFulfillmentEvent {\r\n at?: string;\r\n label?: string;\r\n detail?: string;\r\n}\r\n\r\nexport interface OrderFulfillmentMetadata {\r\n status?: string;\r\n trackingId?: string;\r\n events?: OrderFulfillmentEvent[];\r\n}\r\n\r\nexport interface OrderInvoiceMetadata {\r\n invoiceNumber?: string;\r\n /** ERP invoice UUID for PDF fetch (no JWT). */\r\n invoiceId?: string;\r\n /** App path for invoice PDF (storefront or site-relative). */\r\n link?: string;\r\n}\r\n\r\nexport interface OrderStorefrontMetadataShape {\r\n fulfillment?: OrderFulfillmentMetadata;\r\n invoice?: OrderInvoiceMetadata;\r\n cartId?: number;\r\n platformRef?: string;\r\n [key: string]: unknown;\r\n}\r\n\r\nexport function mergeOrderMetadataPatch(\r\n existing: Record<string, unknown> | null | undefined,\r\n patch: { fulfillment?: OrderFulfillmentMetadata | null; invoice?: OrderInvoiceMetadata | null }\r\n): Record<string, unknown> {\r\n const base =\r\n existing && typeof existing === 'object' && !Array.isArray(existing) ? { ...existing } : {};\r\n if (patch.fulfillment !== undefined) {\r\n if (patch.fulfillment === null) delete base.fulfillment;\r\n else base.fulfillment = patch.fulfillment;\r\n }\r\n if (patch.invoice !== undefined) {\r\n if (patch.invoice === null) delete base.invoice;\r\n else base.invoice = patch.invoice;\r\n }\r\n return base;\r\n}\r\n","import type { Order } from '../../entities/order.entity';\r\n\r\n/** Map ERP sale-order status labels into CMS `Order.status`. Unknown → undefined (caller keeps existing). */\r\nexport function mapErpSaleStatusToOrderStatus(erpLabel: string | undefined): Order['status'] | undefined {\r\n if (!erpLabel || typeof erpLabel !== 'string') return undefined;\r\n const k = erpLabel.trim().toLowerCase().replace(/\\s+/g, '_');\r\n const map: Record<string, Order['status']> = {\r\n draft: 'pending',\r\n pending: 'pending',\r\n open: 'pending',\r\n new: 'pending',\r\n unconfirmed: 'pending',\r\n confirmed: 'confirmed',\r\n processing: 'processing',\r\n packed: 'processing',\r\n shipped: 'processing',\r\n in_transit: 'processing',\r\n out_for_delivery: 'processing',\r\n delivered: 'completed',\r\n completed: 'completed',\r\n closed: 'completed',\r\n fulfilled: 'completed',\r\n cancelled: 'cancelled',\r\n canceled: 'cancelled',\r\n void: 'cancelled',\r\n };\r\n return map[k];\r\n}\r\n","import type { ObjectLiteral, Repository } from 'typeorm';\r\nimport { buildCanonicalOrderNumber, temporaryOrderNumberPlaceholder, type OrderKind } from '../../lib/order-number';\r\nimport { mergeOrderMetadataPatch, type OrderFulfillmentMetadata, type OrderInvoiceMetadata } from '../../lib/order-storefront-metadata';\r\nimport { mapErpSaleStatusToOrderStatus } from './erp-order-status-map';\r\nimport {\r\n extractChildOrderRefsFromSalePayload,\r\n mapErpPayloadToFulfillment,\r\n mapErpPayloadToInvoiceNumber,\r\n unwrapErpReadData,\r\n} from './erp-response-map';\r\nimport type { ERPSubmissionService } from './erp-submission';\r\nimport { isErpIntegrationEnabled, type CmsAppLike, type ErpConfigDataSource } from './erp-config-enabled';\r\n\r\nfunction pickInvoiceId(data: Record<string, unknown>): string | undefined {\r\n const nested =\r\n data.invoice && typeof data.invoice === 'object' && !Array.isArray(data.invoice)\r\n ? (data.invoice as Record<string, unknown>)\r\n : null;\r\n const src = nested || data;\r\n for (const k of ['invoiceId', 'invoice_id', 'id']) {\r\n const v = src[k];\r\n if (typeof v === 'string' && v.trim()) return v.trim();\r\n }\r\n return undefined;\r\n}\r\n\r\nasync function ensureChildOrdersFromRefs(\r\n orderRepo: Repository<ObjectLiteral>,\r\n parent: ObjectLiteral,\r\n refs: ReturnType<typeof extractChildOrderRefsFromSalePayload>,\r\n contactId: number,\r\n currency: string\r\n): Promise<void> {\r\n for (const { ref, orderKind } of refs) {\r\n const existing = await orderRepo\r\n .createQueryBuilder('o')\r\n .where('o.parentOrderId = :pid', { pid: parent.id as number })\r\n .andWhere('o.deleted = :d', { d: false })\r\n .andWhere(\"o.metadata->>'platformRef' = :ref\", { ref })\r\n .getOne();\r\n if (existing) continue;\r\n const tmp = temporaryOrderNumberPlaceholder();\r\n const row = await orderRepo.save(\r\n orderRepo.create({\r\n orderNumber: tmp,\r\n orderKind,\r\n parentOrderId: parent.id as number,\r\n contactId,\r\n billingAddressId: null,\r\n shippingAddressId: null,\r\n status: 'pending',\r\n subtotal: 0,\r\n tax: 0,\r\n discount: 0,\r\n total: 0,\r\n currency,\r\n metadata: { platformRef: ref },\r\n deleted: false,\r\n } as ObjectLiteral)\r\n );\r\n const r = row as { id: number; createdAt: Date };\r\n await orderRepo.update(r.id, {\r\n orderNumber: buildCanonicalOrderNumber(orderKind as OrderKind, r.id, r.createdAt ?? new Date()),\r\n } as ObjectLiteral);\r\n }\r\n}\r\n\r\nfunction deepMergeFulfillment(\r\n a: OrderFulfillmentMetadata | undefined,\r\n b: OrderFulfillmentMetadata | undefined\r\n): OrderFulfillmentMetadata | undefined {\r\n if (!a) return b;\r\n if (!b) return a;\r\n return {\r\n ...a,\r\n ...b,\r\n events: b.events?.length ? b.events : a.events,\r\n };\r\n}\r\n\r\n/**\r\n * Calls ERP §7d reads for the given order row, updates `status` + `metadata` (fulfillment / invoice),\r\n * and upserts child return/replacement rows when the sale payload lists them.\r\n */\r\nexport async function refreshOrderFromErp(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>,\r\n submission: ERPSubmissionService,\r\n order: ObjectLiteral\r\n): Promise<void> {\r\n const orderRepo = dataSource.getRepository(entityMap.orders) as Repository<ObjectLiteral>;\r\n\r\n const kind = (order.orderKind as string) || 'sale';\r\n const meta =\r\n order.metadata && typeof order.metadata === 'object' && !Array.isArray(order.metadata)\r\n ? { ...(order.metadata as Record<string, unknown>) }\r\n : {};\r\n\r\n if (kind === 'sale') {\r\n const refId = String(order.orderNumber || '');\r\n let fulfillment: OrderFulfillmentMetadata | undefined;\r\n let invoiceNumber: string | undefined;\r\n let invoiceId: string | undefined;\r\n let newStatus: string | undefined;\r\n\r\n const r1 = await submission.postErpReadAction('get-order-status', { platformOrderId: refId });\r\n const d1 = r1.ok ? unwrapErpReadData(r1.json) : null;\r\n if (d1) {\r\n const mapped = mapErpSaleStatusToOrderStatus(\r\n typeof d1.status === 'string'\r\n ? d1.status\r\n : typeof d1.orderStatus === 'string'\r\n ? d1.orderStatus\r\n : typeof d1.state === 'string'\r\n ? d1.state\r\n : undefined\r\n );\r\n if (mapped) newStatus = mapped;\r\n fulfillment = mapErpPayloadToFulfillment(d1);\r\n const refs = extractChildOrderRefsFromSalePayload(d1);\r\n if (refs.length) {\r\n await ensureChildOrdersFromRefs(\r\n orderRepo,\r\n order,\r\n refs,\r\n order.contactId as number,\r\n String(order.currency || 'INR')\r\n );\r\n }\r\n }\r\n\r\n const r2 = await submission.postErpReadAction('get-fulfillment-status', { platformOrderId: refId });\r\n const d2 = r2.ok ? unwrapErpReadData(r2.json) : null;\r\n if (d2) {\r\n fulfillment = deepMergeFulfillment(fulfillment, mapErpPayloadToFulfillment(d2));\r\n }\r\n\r\n const r3 = await submission.postErpReadAction('get-invoice', { platformOrderId: refId });\r\n const d3 = r3.ok ? unwrapErpReadData(r3.json) : null;\r\n if (d3) {\r\n invoiceNumber = mapErpPayloadToInvoiceNumber(d3);\r\n invoiceId = pickInvoiceId(d3);\r\n }\r\n\r\n const oid = order.id as number;\r\n const prevInv =\r\n meta.invoice && typeof meta.invoice === 'object' && !Array.isArray(meta.invoice)\r\n ? { ...(meta.invoice as Record<string, unknown>) }\r\n : {};\r\n const nextInvoice: OrderInvoiceMetadata = {\r\n ...prevInv,\r\n link: `/api/storefront/orders/${oid}/invoice`,\r\n ...(invoiceNumber ? { invoiceNumber } : {}),\r\n ...(invoiceId ? { invoiceId } : {}),\r\n };\r\n\r\n const patch: {\r\n fulfillment?: OrderFulfillmentMetadata | null;\r\n invoice?: OrderInvoiceMetadata | null;\r\n } = { invoice: nextInvoice };\r\n if (fulfillment !== undefined) patch.fulfillment = fulfillment;\r\n\r\n const nextMeta = mergeOrderMetadataPatch(meta, patch);\r\n\r\n await orderRepo.update(oid, {\r\n ...(newStatus ? { status: newStatus } : {}),\r\n metadata: nextMeta,\r\n updatedAt: new Date(),\r\n } as ObjectLiteral);\r\n return;\r\n }\r\n\r\n if (kind === 'return' || kind === 'replacement') {\r\n const platformReturnId = String(order.orderNumber || '');\r\n const r = await submission.postErpReadAction('get-return-status', { platformReturnId });\r\n const d = r.ok ? unwrapErpReadData(r.json) : null;\r\n if (!d) return;\r\n const mapped = mapErpSaleStatusToOrderStatus(\r\n typeof d.status === 'string' ? d.status : typeof d.returnStatus === 'string' ? d.returnStatus : undefined\r\n );\r\n const fulfillment = mapErpPayloadToFulfillment(d);\r\n const patch: { fulfillment?: OrderFulfillmentMetadata | null } = {};\r\n if (fulfillment !== undefined) patch.fulfillment = fulfillment;\r\n const nextMeta = Object.keys(patch).length ? mergeOrderMetadataPatch(meta, patch) : meta;\r\n await orderRepo.update(order.id as number, {\r\n ...(mapped ? { status: mapped } : {}),\r\n metadata: nextMeta,\r\n updatedAt: new Date(),\r\n } as ObjectLiteral);\r\n }\r\n}\r\n\r\nexport async function tryRefreshOrderFromErpForStorefront(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>,\r\n order: ObjectLiteral\r\n): Promise<void> {\r\n try {\r\n const on = await isErpIntegrationEnabled(cms, dataSource, entityMap);\r\n if (!on) return;\r\n const erp = cms.getPlugin('erp') as { submission: ERPSubmissionService } | undefined;\r\n if (!erp?.submission) return;\r\n await refreshOrderFromErp(cms, dataSource, entityMap, erp.submission, order);\r\n } catch {\r\n /* non-fatal */\r\n }\r\n}\r\n","const SMS_QUEUE_NAME = 'sms';\r\n\r\nexport interface CmsAppLike {\r\n getPlugin(name: string): unknown;\r\n}\r\n\r\nexport interface SmsJobPayload {\r\n to: string;\r\n /** Legacy / Twilio / sendhttp plain text. */\r\n body?: string;\r\n templateKey?: string;\r\n variables?: Record<string, string>;\r\n otpCode?: string;\r\n}\r\n\r\nexport function registerSmsQueueProcessor(cms: CmsAppLike): void {\r\n const queue = cms.getPlugin('queue') as\r\n | { add: (name: string, data: object) => Promise<void>; registerProcessor: (name: string, fn: (data: object) => Promise<void>) => void }\r\n | undefined;\r\n const sms = cms.getPlugin('sms') as\r\n | {\r\n send: (opts: {\r\n to: string;\r\n body?: string;\r\n templateKey?: string;\r\n variables?: Record<string, string>;\r\n otpCode?: string;\r\n }) => Promise<boolean>;\r\n }\r\n | undefined;\r\n if (!queue || !sms || typeof sms.send !== 'function') return;\r\n queue.registerProcessor(SMS_QUEUE_NAME, async (data: object) => {\r\n const payload = data as SmsJobPayload;\r\n if (!payload.to) return;\r\n if (payload.templateKey?.trim()) {\r\n await sms.send({\r\n to: payload.to,\r\n templateKey: payload.templateKey.trim(),\r\n variables: payload.variables,\r\n otpCode: payload.otpCode,\r\n });\r\n return;\r\n }\r\n if (!payload.body?.trim()) return;\r\n await sms.send({\r\n to: payload.to,\r\n body: payload.body,\r\n otpCode: payload.otpCode,\r\n variables: payload.variables,\r\n });\r\n });\r\n}\r\n\r\nexport async function queueSms(cms: CmsAppLike, payload: SmsJobPayload): Promise<void> {\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void> } | undefined;\r\n const sms = cms.getPlugin('sms') as\r\n | {\r\n send: (opts: {\r\n to: string;\r\n body?: string;\r\n templateKey?: string;\r\n variables?: Record<string, string>;\r\n otpCode?: string;\r\n }) => Promise<boolean>;\r\n }\r\n | undefined;\r\n if (queue) {\r\n await queue.add(SMS_QUEUE_NAME, payload);\r\n return;\r\n }\r\n if (sms && typeof sms.send === 'function') {\r\n if (payload.templateKey?.trim()) {\r\n await sms.send({\r\n to: payload.to,\r\n templateKey: payload.templateKey.trim(),\r\n variables: payload.variables,\r\n otpCode: payload.otpCode,\r\n });\r\n return;\r\n }\r\n if (payload.body?.trim()) {\r\n await sms.send({\r\n to: payload.to,\r\n body: payload.body,\r\n otpCode: payload.otpCode,\r\n variables: payload.variables,\r\n });\r\n }\r\n }\r\n}\r\n","import { createHmac, randomInt, timingSafeEqual } from 'crypto';\r\nimport type { DataSource } from 'typeorm';\r\nimport type { EntityTarget, ObjectLiteral } from 'typeorm';\r\nimport { IsNull, MoreThan } from 'typeorm';\r\n\r\nexport type OtpPurpose = 'login' | 'verify_email' | 'verify_phone';\r\nexport type OtpChannel = 'email' | 'sms';\r\n\r\nconst OTP_TTL_MS = 10 * 60 * 1000;\r\nconst MAX_SENDS_PER_HOUR = 5;\r\nconst MAX_VERIFY_ATTEMPTS = 8;\r\n\r\nfunction getPepper(explicit?: string): string {\r\n return (explicit || process.env.OTP_PEPPER || process.env.NEXTAUTH_SECRET || 'dev-otp-pepper').trim();\r\n}\r\n\r\nexport function hashOtpCode(code: string, purpose: string, identifier: string, pepper?: string): string {\r\n return createHmac('sha256', getPepper(pepper)).update(`${purpose}|${identifier}|${code}`).digest('hex');\r\n}\r\n\r\nexport function verifyOtpCodeHash(code: string, storedHash: string, purpose: string, identifier: string, pepper?: string): boolean {\r\n const h = hashOtpCode(code, purpose, identifier, pepper);\r\n try {\r\n return timingSafeEqual(Buffer.from(h, 'utf8'), Buffer.from(storedHash, 'utf8'));\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport function generateNumericOtp(length = 6): string {\r\n const max = 10 ** length;\r\n return randomInt(0, max).toString().padStart(length, '0');\r\n}\r\n\r\n/** Normalize to E.164-like +digits */\r\nexport function normalizePhoneE164(raw: string, defaultCountryCode?: string): string | null {\r\n const t = raw.trim();\r\n const digitsOnly = t.replace(/\\D/g, '');\r\n if (digitsOnly.length < 10) return null;\r\n if (t.startsWith('+')) return `+${digitsOnly}`;\r\n const cc = (defaultCountryCode || process.env.DEFAULT_PHONE_COUNTRY_CODE || '91').replace(/\\D/g, '');\r\n if (digitsOnly.length > 10) return `+${digitsOnly}`;\r\n return `+${cc}${digitsOnly}`;\r\n}\r\n\r\ntype EntityMap = Record<string, EntityTarget<ObjectLiteral>>;\r\n\r\nexport async function countRecentOtpSends(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n purpose: OtpPurpose,\r\n identifier: string,\r\n since: Date\r\n): Promise<number> {\r\n const repo = dataSource.getRepository(entityMap.otp_challenges);\r\n return repo.count({\r\n where: { purpose, identifier, createdAt: MoreThan(since) } as ObjectLiteral,\r\n });\r\n}\r\n\r\nexport async function createOtpChallenge(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n input: { purpose: OtpPurpose; channel: OtpChannel; identifier: string; code: string; pepper?: string }\r\n): Promise<{ ok: true } | { ok: false; error: string; status: number }> {\r\n const { purpose, channel, identifier, code, pepper } = input;\r\n const since = new Date(Date.now() - 60 * 60 * 1000);\r\n const recent = await countRecentOtpSends(dataSource, entityMap, purpose, identifier, since);\r\n if (recent >= MAX_SENDS_PER_HOUR) {\r\n return { ok: false, error: 'Too many codes sent. Try again later.', status: 429 };\r\n }\r\n\r\n const repo = dataSource.getRepository(entityMap.otp_challenges);\r\n await repo.delete({\r\n purpose,\r\n identifier,\r\n consumedAt: IsNull(),\r\n } as ObjectLiteral);\r\n\r\n const expiresAt = new Date(Date.now() + OTP_TTL_MS);\r\n const codeHash = hashOtpCode(code, purpose, identifier, pepper);\r\n await repo.save(\r\n repo.create({\r\n purpose,\r\n channel,\r\n identifier,\r\n codeHash,\r\n expiresAt,\r\n attempts: 0,\r\n consumedAt: null,\r\n } as ObjectLiteral)\r\n );\r\n return { ok: true };\r\n}\r\n\r\nexport async function verifyAndConsumeOtpChallenge(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n input: { purpose: OtpPurpose; identifier: string; code: string; pepper?: string }\r\n): Promise<{ ok: true } | { ok: false; error: string; status: number }> {\r\n const { purpose, identifier, code, pepper } = input;\r\n const repo = dataSource.getRepository(entityMap.otp_challenges);\r\n const row = await repo.findOne({\r\n where: { purpose, identifier, consumedAt: IsNull() } as ObjectLiteral,\r\n order: { id: 'DESC' },\r\n });\r\n if (!row) {\r\n return { ok: false, error: 'Invalid or expired code', status: 400 };\r\n }\r\n const r = row as ObjectLiteral;\r\n if (new Date(r.expiresAt as Date) < new Date()) {\r\n await repo.delete((row as { id: number }).id);\r\n return { ok: false, error: 'Invalid or expired code', status: 400 };\r\n }\r\n const attempts = (r.attempts as number) || 0;\r\n if (attempts >= MAX_VERIFY_ATTEMPTS) {\r\n await repo.delete((row as { id: number }).id);\r\n return { ok: false, error: 'Too many attempts', status: 400 };\r\n }\r\n\r\n const valid = verifyOtpCodeHash(code, r.codeHash as string, purpose, identifier, pepper);\r\n if (!valid) {\r\n await repo.update((row as { id: number }).id, { attempts: attempts + 1 } as ObjectLiteral);\r\n return { ok: false, error: 'Invalid or expired code', status: 400 };\r\n }\r\n\r\n await repo.update((row as { id: number }).id, { consumedAt: new Date(), attempts: attempts + 1 } as ObjectLiteral);\r\n return { ok: true };\r\n}\r\n"],"mappings":"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","names":["repo","sortField","total","data","typeFilter","updatePayload","updated","result","crypto","ILike","IsNull","IsNull","isErpIntegrationEnabled","ILike","result","In","docRepo","dup","chunkRepo","text","parts","now","chunkRows","savedList","embedResult","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","PrimaryGeneratedColumn","Column","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","ManyToMany","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","PrimaryGeneratedColumn","Column","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","OneToMany","PrimaryGeneratedColumn","Column","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","ManyToMany","Entity","Entity","PrimaryGeneratedColumn","Column","OneToMany","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Index","Unique","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Unique","Index","queueEmail","streamOrderInvoicePdf","isErpIntegrationEnabled","queueErpPaidOrderForOrderId","In","IsNull","pickInvoiceId","IsNull","MoreThan","roundMoney","IsNull","cart","serializeAddress","crypto","gItems","req","w","In"]}
1
+ {"version":3,"sources":["../src/plugins/erp/erp-log.ts","../src/plugins/erp/erp-queue.ts","../src/plugins/erp/erp-config-enabled.ts","../src/plugins/email/email-queue.ts","../src/plugins/erp/erp-response-map.ts","../src/plugins/erp/erp-order-invoice.ts","../src/plugins/erp/paid-order-erp.ts","../src/api/crud.ts","../src/plugins/erp/erp-contact-sync.ts","../src/plugins/erp/erp-product-sync.ts","../src/lib/address-geo-validation.ts","../src/lib/link-contact-to-user.ts","../src/api/auth-handlers.ts","../src/api/cms-handlers.ts","../src/plugins/captcha/assert.ts","../src/entities/llm-agent.entity.ts","../src/lib/media-folder-path.ts","../src/lib/media-parent-path.ts","../src/lib/media-zip-extract.ts","../src/api/llm-agent-knowledge-handlers.ts","../src/message-templates/sms-defaults.ts","../src/api/message-template-admin-handlers.ts","../src/auth/permission-entities.ts","../src/auth/helpers.ts","../src/api/admin-roles-handlers.ts","../src/entities/user.entity.ts","../src/entities/user-group.entity.ts","../src/entities/permission.entity.ts","../src/entities/otp-challenge.entity.ts","../src/entities/password-reset-token.entity.ts","../src/entities/blog.entity.ts","../src/entities/category.entity.ts","../src/entities/seo.entity.ts","../src/entities/comment.entity.ts","../src/entities/tag.entity.ts","../src/entities/contact.entity.ts","../src/entities/form-submission.entity.ts","../src/entities/form.entity.ts","../src/entities/form-field.entity.ts","../src/entities/address.entity.ts","../src/entities/order.entity.ts","../src/entities/payment.entity.ts","../src/entities/chat-conversation.entity.ts","../src/entities/chat-message.entity.ts","../src/entities/config.entity.ts","../src/entities/message-template.entity.ts","../src/entities/media.entity.ts","../src/entities/page.entity.ts","../src/entities/product-category.entity.ts","../src/entities/collection.entity.ts","../src/entities/brand.entity.ts","../src/entities/product.entity.ts","../src/entities/attribute.entity.ts","../src/entities/product-attribute.entity.ts","../src/entities/tax.entity.ts","../src/entities/product-tax.entity.ts","../src/entities/order-item.entity.ts","../src/entities/knowledge-base-document.entity.ts","../src/entities/knowledge-base-chunk.entity.ts","../src/entities/cart.entity.ts","../src/entities/cart-item.entity.ts","../src/entities/wishlist.entity.ts","../src/entities/wishlist-item.entity.ts","../src/entities/llm-agent-knowledge-document.entity.ts","../src/entities/index.ts","../src/api/cms-api-handler.ts","../src/api/storefront-handlers.ts","../src/lib/is-valid-signup-email.ts","../src/lib/order-number.ts","../src/lib/order-storefront-metadata.ts","../src/plugins/erp/erp-order-status-map.ts","../src/plugins/erp/erp-order-sync.ts","../src/plugins/sms/sms-queue.ts","../src/lib/otp-challenge.ts"],"sourcesContent":["/** Server-side ERP integration traces (no secrets). */\r\nexport const ERP_LOG = '[webcore:erp]';\r\n\r\nexport function logErp(event: string, detail?: Record<string, unknown>): void {\r\n if (detail && Object.keys(detail).length) console.info(ERP_LOG, event, detail);\r\n else console.info(ERP_LOG, event);\r\n}\r\n\r\nexport function warnErp(event: string, detail: Record<string, unknown>): void {\r\n console.warn(ERP_LOG, event, detail);\r\n}\r\n\r\nexport function errorErp(event: string, detail: Record<string, unknown>): void {\r\n console.error(ERP_LOG, event, detail);\r\n}\r\n\r\n/** Origin + pathname only; drops query (e.g. token=). */\r\nexport function erpSafeWebhookUrl(url: string): string {\r\n try {\r\n const u = new URL(url);\r\n return `${u.origin}${u.pathname}`;\r\n } catch {\r\n return '(invalid webhook URL)';\r\n }\r\n}\r\n","import { errorErp, logErp, warnErp } from './erp-log';\r\nimport type { ERPSubmissionService } from './erp-submission';\r\nimport type { ContactFormData, ErpCreateContactPayload } from './erp-submission';\r\n\r\nexport interface CmsAppLike {\r\n getPlugin(name: string): unknown;\r\n}\r\n\r\nconst ERP_QUEUE_NAME = 'erp';\r\n\r\nexport type ErpJobPayload =\r\n | { kind: 'lead'; contact: ContactFormData }\r\n | { kind: 'formOpportunity'; contact: ContactFormData }\r\n | { kind: 'createContact'; contact: ErpCreateContactPayload }\r\n | { kind: 'order'; order: Record<string, unknown> }\r\n | { kind: 'productUpsert'; product: Record<string, unknown> };\r\n\r\nfunction queuePayloadSummary(payload: ErpJobPayload): Record<string, unknown> {\r\n if (payload.kind === 'order') {\r\n const o = payload.order;\r\n return {\r\n kind: payload.kind,\r\n platformOrderId: o.platformOrderId ?? o.platformOrderNumber,\r\n itemCount: Array.isArray(o.items) ? o.items.length : 0,\r\n };\r\n }\r\n return { kind: payload.kind };\r\n}\r\n\r\nexport async function queueErp(cms: CmsAppLike, payload: ErpJobPayload): Promise<void> {\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void> } | undefined;\r\n if (!queue) {\r\n warnErp('queue:add_skipped', { reason: 'queue_plugin_missing', ...queuePayloadSummary(payload) });\r\n return;\r\n }\r\n logErp('queue:add', { job: ERP_QUEUE_NAME, ...queuePayloadSummary(payload) });\r\n await queue.add(ERP_QUEUE_NAME, payload as object);\r\n}\r\n\r\nexport function registerErpQueueProcessor(cms: CmsAppLike): void {\r\n const queue = cms.getPlugin('queue') as\r\n | { registerProcessor: (name: string, fn: (data: object) => Promise<void>) => void }\r\n | undefined;\r\n if (!queue) return;\r\n queue.registerProcessor(ERP_QUEUE_NAME, async (data: object) => {\r\n const erp = cms.getPlugin('erp') as { submission: ERPSubmissionService } | undefined;\r\n if (!erp) {\r\n warnErp('queue:processor_skip', { reason: 'erp_plugin_missing' });\r\n return;\r\n }\r\n const payload = data as ErpJobPayload;\r\n logErp('queue:job_start', queuePayloadSummary(payload));\r\n try {\r\n if (payload.kind === 'lead') {\r\n await erp.submission.submitContact(payload.contact);\r\n } else if (payload.kind === 'formOpportunity') {\r\n await erp.submission.submitFormOpportunity(payload.contact);\r\n } else if (payload.kind === 'createContact') {\r\n await erp.submission.submitCreateContact(payload.contact);\r\n } else if (payload.kind === 'order') {\r\n await erp.submission.submitOrder(payload.order);\r\n } else if (payload.kind === 'productUpsert') {\r\n await erp.submission.submitProductUpsert(payload.product);\r\n }\r\n logErp('queue:job_done', queuePayloadSummary(payload));\r\n } catch (e) {\r\n errorErp('queue:job_failed', {\r\n ...queuePayloadSummary(payload),\r\n message: e instanceof Error ? e.message : String(e),\r\n });\r\n throw e;\r\n }\r\n });\r\n}\r\n","import type { ObjectLiteral } from 'typeorm';\r\n\r\nexport type CmsAppLike = { getPlugin(name: string): unknown };\r\n\r\nexport type ErpConfigDataSource = {\r\n getRepository(entity: unknown): {\r\n find(options?: object): Promise<unknown[]>;\r\n };\r\n};\r\n\r\n/** True when ERP plugin is loaded and config `erp.enabled` is not `'false'`. */\r\nexport async function isErpIntegrationEnabled(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>\r\n): Promise<boolean> {\r\n if (!cms.getPlugin('erp')) return false;\r\n const configRepo = dataSource.getRepository(entityMap.configs);\r\n const cfgRows = await configRepo.find({ where: { settings: 'erp', deleted: false } as ObjectLiteral });\r\n for (const row of cfgRows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'enabled' && r.value === 'false') return false;\r\n }\r\n return true;\r\n}\r\n","import type { CompanyDetails, EmailTemplateName, OrderPlacedLineItem } from './templates/types';\r\n\r\nexport interface CmsAppLike {\r\n getPlugin(name: string): unknown;\r\n}\r\n\r\n/** Context for template rendering: at least companyDetails; template-specific fields (formName, etc.) are allowed. */\r\nexport interface EmailJobPayload {\r\n to: string;\r\n templateName?: EmailTemplateName;\r\n ctx?: Record<string, unknown> & { companyDetails: CompanyDetails };\r\n subject?: string;\r\n html?: string;\r\n text?: string;\r\n}\r\n\r\nconst EMAIL_QUEUE_NAME = 'email';\r\n\r\nexport function registerEmailQueueProcessor(cms: CmsAppLike): void {\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void>; registerProcessor: (name: string, fn: (data: object) => Promise<void>) => void } | undefined;\r\n const email = cms.getPlugin('email') as { send: (opts: { to: string; subject: string; html: string; text?: string }) => Promise<boolean>; renderTemplate: (name: string, ctx: unknown) => { subject: string; html: string; text?: string } } | undefined;\r\n if (!queue || !email) return;\r\n queue.registerProcessor(EMAIL_QUEUE_NAME, async (data: object) => {\r\n const payload = data as EmailJobPayload;\r\n const { to, templateName, ctx, subject, html, text } = payload;\r\n if (!to) return;\r\n if (templateName && ctx) {\r\n const rendered = email.renderTemplate(templateName, ctx);\r\n await email.send({ to, subject: rendered.subject, html: rendered.html, text: rendered.text });\r\n } else if (subject != null && html != null) {\r\n await email.send({ to, subject, html, text });\r\n }\r\n });\r\n}\r\n\r\nexport async function queueEmail(cms: CmsAppLike, payload: EmailJobPayload): Promise<void> {\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void> } | undefined;\r\n if (queue) {\r\n await queue.add(EMAIL_QUEUE_NAME, payload);\r\n return;\r\n }\r\n const email = cms.getPlugin('email') as { send: (opts: { to: string; subject: string; html: string; text?: string }) => Promise<boolean>; renderTemplate: (name: string, ctx: unknown) => { subject: string; html: string; text?: string } } | undefined;\r\n if (email && payload.templateName && payload.ctx) {\r\n const rendered = email.renderTemplate(payload.templateName, payload.ctx);\r\n await email.send({ to: payload.to, subject: rendered.subject, html: rendered.html, text: rendered.text });\r\n } else if (email && payload.subject != null && payload.html != null) {\r\n await email.send({ to: payload.to, subject: payload.subject, html: payload.html, text: payload.text });\r\n }\r\n}\r\n\r\nexport interface OrderPlacedEmailPayload {\r\n orderNumber: string;\r\n total?: string | number;\r\n subtotal?: string | number;\r\n tax?: string | number;\r\n currency?: string;\r\n customerName?: string;\r\n /** Customer receipt; omitted if empty */\r\n customerEmail?: string | null;\r\n /** Parsed list from email plugin “Sales team” settings */\r\n salesTeamEmails: string[];\r\n companyDetails: CompanyDetails;\r\n lineItems: OrderPlacedLineItem[];\r\n billingAddress?: Record<string, string>;\r\n shippingAddress?: Record<string, string>;\r\n}\r\n\r\n/** Queues one `orderPlaced` email per recipient (customer + each unique sales address; skips sales if same as customer). */\r\nexport async function queueOrderPlacedEmails(cms: CmsAppLike, payload: OrderPlacedEmailPayload): Promise<void> {\r\n const {\r\n orderNumber,\r\n total,\r\n subtotal,\r\n tax,\r\n currency,\r\n customerName,\r\n customerEmail,\r\n salesTeamEmails,\r\n companyDetails,\r\n lineItems,\r\n billingAddress,\r\n shippingAddress,\r\n } = payload;\r\n const base = {\r\n orderNumber,\r\n total: total != null ? String(total) : undefined,\r\n subtotal: subtotal != null ? String(subtotal) : undefined,\r\n tax: tax != null ? String(tax) : undefined,\r\n currency,\r\n customerName,\r\n companyDetails: companyDetails ?? {},\r\n lineItems: lineItems ?? [],\r\n billingAddress,\r\n shippingAddress,\r\n };\r\n const customerLower = customerEmail?.trim().toLowerCase() ?? '';\r\n const jobs: Promise<void>[] = [];\r\n if (customerEmail?.trim()) {\r\n jobs.push(\r\n queueEmail(cms, {\r\n to: customerEmail.trim(),\r\n templateName: 'orderPlaced',\r\n ctx: { ...base, audience: 'customer' as const },\r\n })\r\n );\r\n }\r\n const seen = new Set<string>();\r\n for (const raw of salesTeamEmails) {\r\n const to = raw.trim();\r\n if (!to) continue;\r\n const key = to.toLowerCase();\r\n if (seen.has(key)) continue;\r\n seen.add(key);\r\n if (customerLower && key === customerLower) continue;\r\n jobs.push(\r\n queueEmail(cms, {\r\n to,\r\n templateName: 'orderPlaced',\r\n ctx: {\r\n ...base,\r\n audience: 'sales' as const,\r\n internalCustomerEmail: customerEmail?.trim() || undefined,\r\n },\r\n })\r\n );\r\n }\r\n await Promise.all(jobs);\r\n}\r\n","import type { OrderFulfillmentEvent, OrderFulfillmentMetadata } from '../../lib/order-storefront-metadata';\r\n\r\nfunction pickString(o: Record<string, unknown>, keys: string[]): string | undefined {\r\n for (const k of keys) {\r\n const v = o[k];\r\n if (typeof v === 'string' && v.trim()) return v.trim();\r\n }\r\n return undefined;\r\n}\r\n\r\nexport function unwrapErpReadData(json: unknown): Record<string, unknown> | null {\r\n if (!json || typeof json !== 'object') return null;\r\n const o = json as Record<string, unknown>;\r\n const d = o.data;\r\n if (d && typeof d === 'object' && !Array.isArray(d)) return d as Record<string, unknown>;\r\n return o;\r\n}\r\n\r\nfunction firstObject(\r\n data: Record<string, unknown>,\r\n keys: string[]\r\n): Record<string, unknown> | null {\r\n for (const k of keys) {\r\n const v = data[k];\r\n if (v && typeof v === 'object' && !Array.isArray(v)) return v as Record<string, unknown>;\r\n }\r\n return null;\r\n}\r\n\r\nfunction extractEvents(src: Record<string, unknown>): OrderFulfillmentEvent[] | undefined {\r\n const timeline = src.timeline ?? src.events ?? src.history ?? src.trackingEvents;\r\n if (!Array.isArray(timeline) || !timeline.length) return undefined;\r\n const events: OrderFulfillmentEvent[] = [];\r\n for (const row of timeline) {\r\n if (!row || typeof row !== 'object') continue;\r\n const r = row as Record<string, unknown>;\r\n const at =\r\n pickString(r, ['at', 'timestamp', 'date', 'occurredAt']) ??\r\n (r.at instanceof Date ? (r.at as Date).toISOString() : undefined);\r\n const label = pickString(r, ['label', 'status', 'title', 'message', 'description']);\r\n const detail = pickString(r, ['detail', 'notes', 'description']);\r\n if (at || label || detail) events.push({ at, label, detail });\r\n }\r\n return events.length ? events : undefined;\r\n}\r\n\r\nexport function mapErpPayloadToFulfillment(data: Record<string, unknown>): OrderFulfillmentMetadata | undefined {\r\n const nested = firstObject(data, ['fulfillment', 'packaging', 'shipment', 'shipping', 'delivery']);\r\n const src = nested || data;\r\n const status = pickString(src, ['status', 'fulfillmentStatus', 'state', 'label', 'packagingStatus']);\r\n const trackingId = pickString(src, ['trackingId', 'tracking_id', 'trackingNumber', 'awb', 'trackingUrl']);\r\n const events = extractEvents(src);\r\n if (!status && !trackingId && !(events && events.length)) return undefined;\r\n return { status, trackingId, events };\r\n}\r\n\r\nexport function mapErpPayloadToInvoiceNumber(data: Record<string, unknown>): string | undefined {\r\n const nested = firstObject(data, ['invoice', 'latestInvoice', 'postedInvoice']);\r\n const src = nested || data;\r\n return pickString(src, ['invoiceNumber', 'invoice_number', 'number', 'name', 'id']);\r\n}\r\n\r\nexport type ErpChildOrderRef = { ref: string; orderKind: 'return' | 'replacement' };\r\n\r\nexport function extractChildOrderRefsFromSalePayload(data: Record<string, unknown>): ErpChildOrderRef[] {\r\n const lists = [data.returns, data.returnOrders, data.relatedReturns, data.childOrders, data.children];\r\n const seen = new Set<string>();\r\n const out: ErpChildOrderRef[] = [];\r\n for (const list of lists) {\r\n if (!Array.isArray(list)) continue;\r\n for (const item of list) {\r\n if (!item || typeof item !== 'object') continue;\r\n const o = item as Record<string, unknown>;\r\n const ref =\r\n pickString(o, ['platformReturnId', 'platform_return_id', 'refId', 'ref_id']) ??\r\n (typeof o.id === 'string' ? o.id : undefined);\r\n if (!ref || seen.has(ref)) continue;\r\n seen.add(ref);\r\n const t = (pickString(o, ['kind', 'type', 'orderKind']) || '').toLowerCase();\r\n const orderKind: 'return' | 'replacement' = /replac/.test(t) ? 'replacement' : 'return';\r\n out.push({ ref, orderKind });\r\n }\r\n }\r\n return out;\r\n}\r\n","import type { ObjectLiteral, Repository } from 'typeorm';\r\nimport { unwrapErpReadData } from './erp-response-map';\r\nimport type { ERPSubmissionService } from './erp-submission';\r\nimport { isErpIntegrationEnabled, type CmsAppLike, type ErpConfigDataSource } from './erp-config-enabled';\r\n\r\nfunction pickInvoiceId(data: Record<string, unknown>): string | undefined {\r\n const nested =\r\n data.invoice && typeof data.invoice === 'object' && !Array.isArray(data.invoice)\r\n ? (data.invoice as Record<string, unknown>)\r\n : null;\r\n const src = nested || data;\r\n for (const k of ['invoiceId', 'invoice_id', 'id']) {\r\n const v = src[k];\r\n if (typeof v === 'string' && v.trim()) return v.trim();\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Streams invoice PDF for a **sale** order. Resolves `invoiceId` from order metadata or `get-invoice`.\r\n */\r\nexport async function streamOrderInvoicePdf(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>,\r\n orderId: number,\r\n options: { ownerContactId?: number }\r\n): Promise<Response> {\r\n const jsonErr = (msg: string, status: number) =>\r\n new Response(JSON.stringify({ error: msg }), {\r\n status,\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n\r\n const on = await isErpIntegrationEnabled(cms, dataSource, entityMap);\r\n if (!on) return jsonErr('Invoice not available', 503);\r\n\r\n const erp = cms.getPlugin('erp') as { submission: ERPSubmissionService } | undefined;\r\n if (!erp?.submission) return jsonErr('Invoice not available', 503);\r\n\r\n const orderRepo = dataSource.getRepository(entityMap.orders) as Repository<ObjectLiteral>;\r\n const order = await orderRepo.findOne({ where: { id: orderId, deleted: false } as ObjectLiteral });\r\n if (!order) return jsonErr('Not found', 404);\r\n\r\n const kind = (order.orderKind as string) || 'sale';\r\n if (kind !== 'sale') return jsonErr('Invoice only for sale orders', 400);\r\n\r\n if (options.ownerContactId != null && order.contactId !== options.ownerContactId) {\r\n return jsonErr('Not found', 404);\r\n }\r\n\r\n const meta =\r\n order.metadata && typeof order.metadata === 'object' && !Array.isArray(order.metadata)\r\n ? (order.metadata as Record<string, unknown>)\r\n : {};\r\n const inv = meta.invoice && typeof meta.invoice === 'object' && !Array.isArray(meta.invoice)\r\n ? (meta.invoice as Record<string, unknown>)\r\n : {};\r\n let invoiceId = typeof inv.invoiceId === 'string' ? inv.invoiceId.trim() : '';\r\n\r\n if (!invoiceId) {\r\n const refId = String(order.orderNumber || '');\r\n const r = await erp.submission.postErpReadAction('get-invoice', { platformOrderId: refId });\r\n const d = r.ok ? unwrapErpReadData(r.json) : null;\r\n invoiceId = d ? pickInvoiceId(d) || '' : '';\r\n }\r\n\r\n if (!invoiceId) return jsonErr('Invoice not ready', 404);\r\n\r\n const pdf = await erp.submission.fetchInvoicePdf(invoiceId);\r\n if (!pdf.ok || !pdf.buffer) return jsonErr(pdf.error || 'PDF fetch failed', 502);\r\n\r\n const filename = `invoice-${orderId}.pdf`;\r\n return new Response(pdf.buffer, {\r\n status: 200,\r\n headers: {\r\n 'Content-Type': pdf.contentType || 'application/pdf',\r\n 'Content-Disposition': `attachment; filename=\"${filename}\"`,\r\n },\r\n });\r\n}\r\n","import type { ObjectLiteral } from 'typeorm';\r\nimport { errorErp, logErp } from './erp-log';\r\nimport { queueErp, type CmsAppLike } from './erp-queue';\r\n\r\n/**\r\n * Duck-typed DataSource so host apps (e.g. Next) can pass their own TypeORM instance\r\n * without duplicate-package type errors vs core’s node_modules/typeorm.\r\n */\r\nexport type ErpPaidOrderDataSource = {\r\n getRepository(entity: unknown): {\r\n find(options?: object): Promise<unknown[]>;\r\n findOne(options?: object): Promise<unknown | null>;\r\n };\r\n};\r\n\r\n/**\r\n * Entity map with `configs` and `orders` entries (e.g. ENTITY_MAP).\r\n * Typed as `Record<string, unknown>` so apps that cast their map to `Record<string, EntityTarget<…>>` still pass.\r\n */\r\nexport type ErpPaidOrderEntityMap = Record<string, unknown>;\r\n\r\nfunction roundMoney(major: number): number {\r\n return Math.round(major * 100) / 100;\r\n}\r\n\r\nfunction addressToWebhookDto(a: ObjectLiteral | null | undefined): Record<string, unknown> {\r\n if (!a) return {};\r\n return {\r\n line1: a.line1 ?? '',\r\n line2: a.line2 ?? '',\r\n city: a.city ?? '',\r\n state: a.state ?? '',\r\n postalCode: a.postalCode ?? '',\r\n country: a.country ?? '',\r\n };\r\n}\r\n\r\nfunction orderStatusLabel(status: string | undefined): string {\r\n const s = (status || '').toLowerCase();\r\n if (s === 'confirmed') return 'Confirmed';\r\n if (s === 'pending') return 'Pending';\r\n if (!status) return 'Pending';\r\n return status.charAt(0).toUpperCase() + status.slice(1);\r\n}\r\n\r\nfunction paymentRowToWebhookDto(p: ObjectLiteral, amountMajorOverride?: number): Record<string, unknown> {\r\n const currency = String(p.currency || 'INR');\r\n const amountMajor =\r\n amountMajorOverride != null && Number.isFinite(amountMajorOverride)\r\n ? amountMajorOverride\r\n : Number(p.amount);\r\n const meta = { ...((p.metadata as Record<string, unknown>) || {}) };\r\n delete meta.amount;\r\n delete meta.currency;\r\n return {\r\n id: String(p.externalReference || `payment_${p.id}`),\r\n amount: roundMoney(amountMajor),\r\n currency_code: currency,\r\n captured_at: p.paidAt\r\n ? new Date(p.paidAt as Date | string).toISOString()\r\n : new Date().toISOString(),\r\n provider_id: String(p.method || 'unknown'),\r\n data: { status: 'captured', ...meta },\r\n };\r\n}\r\n\r\n/**\r\n * Enqueues ERP `order.created` only when the order has at least one **completed** payment.\r\n * Include `payments` in the payload.\r\n */\r\nexport async function queueErpPaidOrderForOrderId(\r\n cms: CmsAppLike,\r\n dataSource: ErpPaidOrderDataSource,\r\n entityMap: ErpPaidOrderEntityMap,\r\n orderId: number\r\n): Promise<void> {\r\n try {\r\n const configRepo = dataSource.getRepository(entityMap.configs);\r\n const cfgRows = await configRepo.find({ where: { settings: 'erp', deleted: false } as ObjectLiteral });\r\n for (const row of cfgRows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'enabled' && r.value === 'false') {\r\n logErp('paid-order:skip', { orderId, reason: 'erp_config_disabled' });\r\n return;\r\n }\r\n }\r\n if (!cms.getPlugin('erp')) {\r\n logErp('paid-order:skip', { orderId, reason: 'erp_plugin_missing' });\r\n return;\r\n }\r\n\r\n const orderRepo = dataSource.getRepository(entityMap.orders);\r\n const ord = await orderRepo.findOne({\r\n where: { id: orderId } as ObjectLiteral,\r\n relations: ['items', 'items.product', 'contact', 'billingAddress', 'shippingAddress', 'payments'],\r\n });\r\n if (!ord) {\r\n logErp('paid-order:skip', { orderId, reason: 'order_not_found' });\r\n return;\r\n }\r\n const o = ord as ObjectLiteral;\r\n const okKind = o.orderKind === undefined || o.orderKind === null || o.orderKind === 'sale';\r\n if (!okKind) {\r\n logErp('paid-order:skip', { orderId, reason: 'order_kind_not_sale', orderKind: o.orderKind });\r\n return;\r\n }\r\n const rawPayments = (o.payments as ObjectLiteral[]) ?? [];\r\n const completedPayments = rawPayments.filter((pay) => pay.status === 'completed' && pay.deleted !== true);\r\n if (!completedPayments.length) {\r\n logErp('paid-order:skip', { orderId, reason: 'no_completed_payments' });\r\n return;\r\n }\r\n\r\n const rawItems = (o.items as ObjectLiteral[]) ?? [];\r\n const lines = rawItems\r\n .filter((it) => it.product)\r\n .map((it) => {\r\n const p = it.product as ObjectLiteral;\r\n const sku = (p.sku as string) || `SKU-${p.id}`;\r\n const itemType =\r\n typeof it.productType === 'string' && it.productType.trim()\r\n ? String(it.productType).trim()\r\n : p.type === 'service'\r\n ? 'service'\r\n : 'product';\r\n return {\r\n sku,\r\n quantity: Number(it.quantity) || 1,\r\n unitPrice: Number(it.unitPrice),\r\n title: (p.name as string) || sku,\r\n discount: 0,\r\n tax: Number(it.tax) || 0,\r\n uom: (typeof it.uom === 'string' && it.uom.trim() ? it.uom : p.uom) || undefined,\r\n tax_code:\r\n typeof it.taxCode === 'string' && it.taxCode.trim() ? String(it.taxCode).trim() : undefined,\r\n hsn_number:\r\n (typeof it.hsn === 'string' && it.hsn.trim() ? it.hsn : p.hsn) || undefined,\r\n type: itemType,\r\n };\r\n });\r\n if (!lines.length) {\r\n logErp('paid-order:skip', { orderId, reason: 'no_line_items_with_product' });\r\n return;\r\n }\r\n\r\n const contact = o.contact as ObjectLiteral | undefined;\r\n const orderTotalMajor = Number(o.total);\r\n const paymentDtos =\r\n completedPayments.length === 1 && Number.isFinite(orderTotalMajor)\r\n ? [paymentRowToWebhookDto(completedPayments[0]!, orderTotalMajor)]\r\n : completedPayments.map((pay) => paymentRowToWebhookDto(pay));\r\n const baseMeta =\r\n o.metadata && typeof o.metadata === 'object' && !Array.isArray(o.metadata)\r\n ? { ...(o.metadata as Record<string, unknown>) }\r\n : {};\r\n\r\n const orderDto: Record<string, unknown> = {\r\n platformType: 'website',\r\n platformOrderId: String(o.orderNumber),\r\n platformOrderNumber: String(o.orderNumber),\r\n order_date: o.createdAt ? new Date(o.createdAt as Date | string).toISOString() : undefined,\r\n status: orderStatusLabel(o.status as string | undefined),\r\n customer: {\r\n name: (contact?.name as string) || '',\r\n email: (contact?.email as string) || '',\r\n phone: (contact?.phone as string) || '',\r\n },\r\n shippingAddress: addressToWebhookDto(o.shippingAddress as ObjectLiteral),\r\n billingAddress: addressToWebhookDto(o.billingAddress as ObjectLiteral),\r\n items: lines,\r\n payments: paymentDtos,\r\n metadata: { ...baseMeta, source: 'storefront' },\r\n };\r\n\r\n logErp('paid-order:payload_built', {\r\n orderId,\r\n platformOrderId: orderDto.platformOrderId,\r\n status: orderDto.status,\r\n itemCount: lines.length,\r\n skus: lines.map((l) => l.sku),\r\n paymentCount: paymentDtos.length,\r\n paymentIds: paymentDtos.map((p) => p.id),\r\n total: orderTotalMajor,\r\n });\r\n\r\n await queueErp(cms, { kind: 'order', order: orderDto });\r\n } catch (e) {\r\n errorErp('paid-order:enqueue_failed', {\r\n orderId,\r\n message: e instanceof Error ? e.message : String(e),\r\n });\r\n }\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport { Between, Brackets, ILike, LessThanOrEqual, MoreThan, MoreThanOrEqual, Not } from 'typeorm';\r\nimport type { EntityMetadata, Repository } from 'typeorm';\r\nimport type { EntityCrudAction } from '../auth/permission-entities';\r\nimport { queueErpCreateContactIfEnabled } from '../plugins/erp/erp-contact-sync';\r\nimport { queueErpProductUpsertIfEnabled } from '../plugins/erp/erp-product-sync';\r\nimport { validateAndNormalizeAddressRow } from '../lib/address-geo-validation';\r\n\r\nexport type EntityMap = Record<string, import('typeorm').EntityTarget<import('typeorm').ObjectLiteral>>;\r\n\r\nexport interface CrudHandlerOptions {\r\n requireAuth: (req: Request) => Promise<Response | null>;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n requireEntityPermission?: (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;\r\n /** When set, contact create/update enqueues ERP `create-contact` (non-fatal). */\r\n getCms?: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n /** When set, soft-delete sets `deletedBy` from the current admin user. */\r\n getDeletedByUserId?: (req: Request) => Promise<number | null>;\r\n}\r\n\r\nconst CRUD_LOG = '[cms-crud]';\r\n\r\nfunction logCrudClientError(op: string, detail: Record<string, unknown>): void {\r\n console.warn(CRUD_LOG, op, detail);\r\n}\r\n\r\nfunction logCrudServerError(op: string, detail: Record<string, unknown>): void {\r\n console.error(CRUD_LOG, op, detail);\r\n}\r\n\r\n/** Recursive sum of `size` for all `file` descendants under each folder id (Postgres). */\r\nasync function aggregateMediaFolderFileSizes(dataSource: DataSource, folderIds: number[]): Promise<Map<number, number>> {\r\n const map = new Map<number, number>();\r\n if (folderIds.length === 0) return map;\r\n try {\r\n const rows = (await dataSource.query(\r\n `\r\n WITH RECURSIVE walk AS (\r\n SELECT m.\"parentId\" AS root_id, m.id, m.kind, m.size\r\n FROM media m\r\n WHERE m.\"parentId\" = ANY($1) AND m.deleted = false\r\n UNION ALL\r\n SELECT w.root_id, m.id, m.kind, m.size\r\n FROM walk w\r\n INNER JOIN media m ON m.\"parentId\" = w.id AND m.deleted = false\r\n )\r\n SELECT root_id AS \"rootId\", COALESCE(SUM(size) FILTER (WHERE kind = 'file'), 0)::bigint AS \"totalSize\"\r\n FROM walk\r\n GROUP BY root_id\r\n `,\r\n [folderIds]\r\n )) as { rootId: number; totalSize: string | number }[];\r\n for (const r of rows) {\r\n map.set(Number(r.rootId), Number(r.totalSize));\r\n }\r\n for (const id of folderIds) {\r\n if (!map.has(id)) map.set(id, 0);\r\n }\r\n } catch (err) {\r\n logCrudServerError('media folder size aggregate failed', {\r\n message: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n return map;\r\n}\r\n\r\nconst DATE_COLUMN_TYPES = new Set([\r\n 'date', 'datetime', 'datetime2', 'timestamp', 'timestamptz', 'timetz', 'smalldatetime', 'timestamp with time zone', 'timestamp without time zone',\r\n]);\r\n\r\nconst TIMESTAMP_PROP_NAMES = new Set(['createdAt', 'updatedAt', 'deletedAt']);\r\n\r\nfunction isInvalidDateValue(v: unknown): boolean {\r\n if (v === '' || v == null) return true;\r\n if (typeof v === 'string') return isNaN(Date.parse(v)) || /NaN|Invalid/i.test(v);\r\n if (v instanceof Date) return isNaN(v.getTime());\r\n return false;\r\n}\r\n\r\n/** Strip empty/invalid values for boolean, number, and date columns so DB defaults apply. */\r\nfunction sanitizeBodyForEntity(repo: Repository<import('typeorm').ObjectLiteral>, body: Record<string, unknown>): void {\r\n const meta = repo.metadata;\r\n for (const col of meta.columns) {\r\n if (!(col.propertyName in body)) continue;\r\n const v = body[col.propertyName];\r\n const t = typeof col.type === 'string' ? col.type : (col.type as Function)?.name ?? '';\r\n const isBoolean = t === 'boolean' || t === 'bool' || col.type === Boolean;\r\n const isNumber = ['int', 'integer', 'int2', 'int4', 'int8', 'smallint', 'bigint', 'number', 'Number'].includes(t) || col.type === Number;\r\n const isDate = DATE_COLUMN_TYPES.has(t) || col.type === Date || TIMESTAMP_PROP_NAMES.has(col.propertyName);\r\n if (v === '' && (isBoolean || isNumber)) {\r\n delete body[col.propertyName];\r\n } else if (isDate && isInvalidDateValue(v)) {\r\n delete body[col.propertyName];\r\n }\r\n }\r\n}\r\n\r\n/** Keep only scalar columns (excludes relations like tags) so repo.update() does not throw. */\r\nfunction pickColumnUpdates(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n body: Record<string, unknown>\r\n): Record<string, unknown> {\r\n const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));\r\n const out: Record<string, unknown> = {};\r\n for (const k of Object.keys(body)) {\r\n if (cols.has(k)) out[k] = body[k];\r\n }\r\n return out;\r\n}\r\n\r\n/** OR search on columns that exist on the entity (avoids Tag/Category etc. without `title`). */\r\nfunction buildSearchWhereClause(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n search: string\r\n): Record<string, unknown>[] | Record<string, unknown> {\r\n const cols = new Set(repo.metadata.columns.map((c) => c.propertyName));\r\n const term = ILike(`%${search}%`);\r\n const ors: Record<string, unknown>[] = [];\r\n for (const field of ['name', 'title', 'slug', 'email', 'filename'] as const) {\r\n if (cols.has(field)) ors.push({ [field]: term });\r\n }\r\n if (ors.length === 0) return {};\r\n return ors.length === 1 ? ors[0]! : ors;\r\n}\r\n\r\nfunction entityHasSoftDelete(repo: Repository<import('typeorm').ObjectLiteral>): boolean {\r\n return repo.metadata.columns.some((c) => c.propertyName === 'deleted');\r\n}\r\n\r\nconst LIST_QUERY_RESERVED = new Set(['page', 'limit', 'sortField', 'sortOrder', 'search']);\r\n\r\nfunction dayStartUtc(isoDay: string): Date {\r\n return new Date(isoDay + 'T00:00:00.000Z');\r\n}\r\n\r\nfunction dayEndUtc(isoDay: string): Date {\r\n return new Date(isoDay + 'T23:59:59.999Z');\r\n}\r\n\r\nfunction columnTypeLabel(col: { type: unknown }): string {\r\n const t = col.type;\r\n if (typeof t === 'string') return t.toLowerCase();\r\n if (typeof t === 'function') return (t as { name?: string }).name?.toLowerCase?.() ?? '';\r\n if (t && typeof t === 'object' && 'name' in t && typeof (t as { name: unknown }).name === 'string') {\r\n return String((t as { name: string }).name).toLowerCase();\r\n }\r\n return '';\r\n}\r\n\r\ntype ListColumnMeta = import('typeorm').EntityMetadata['columns'][number];\r\n\r\nfunction isListDateColumn(col: ListColumnMeta): boolean {\r\n const tl = columnTypeLabel(col);\r\n return DATE_COLUMN_TYPES.has(tl) || col.type === Date || TIMESTAMP_PROP_NAMES.has(col.propertyName);\r\n}\r\n\r\nfunction isListNumericColumn(col: ListColumnMeta): boolean {\r\n const tl = columnTypeLabel(col);\r\n if (col.type === Number) return true;\r\n const patterns = [\r\n 'int',\r\n 'integer',\r\n 'int2',\r\n 'int4',\r\n 'int8',\r\n 'smallint',\r\n 'bigint',\r\n 'float',\r\n 'double',\r\n 'decimal',\r\n 'numeric',\r\n 'real',\r\n 'tinyint',\r\n 'mediumint',\r\n ];\r\n if (patterns.some((x) => tl.includes(x))) return true;\r\n if (tl.includes('unsigned') && (tl.includes('int') || tl.includes('bigint') || tl.includes('small'))) return true;\r\n // Driver/metadata quirks: FK columns are almost always integers\r\n if (!tl && /Id$/i.test(col.propertyName) && !TIMESTAMP_PROP_NAMES.has(col.propertyName)) return true;\r\n return false;\r\n}\r\n\r\nfunction isListBooleanColumn(col: ListColumnMeta): boolean {\r\n const tl = columnTypeLabel(col);\r\n return tl === 'boolean' || tl === 'bool' || col.type === Boolean;\r\n}\r\n\r\nfunction isListStringColumn(col: ListColumnMeta): boolean {\r\n const tl = columnTypeLabel(col);\r\n if (isListDateColumn(col) || isListNumericColumn(col) || isListBooleanColumn(col)) return false;\r\n if (\r\n ['varchar', 'character varying', 'text', 'citext', 'uuid', 'char', 'character', 'enum'].some((x) =>\r\n tl.includes(x)\r\n )\r\n ) {\r\n return true;\r\n }\r\n if (col.type === String) return true;\r\n return false;\r\n}\r\n\r\n/** Merge `patch` into list `where` (OR-array or single object) the same way as int/bool filters. */\r\nfunction mergeListWhereAnd(\r\n where: Record<string, unknown>[] | Record<string, unknown>,\r\n patch: Record<string, unknown>\r\n): Record<string, unknown>[] | Record<string, unknown> {\r\n if (Object.keys(patch).length === 0) return where;\r\n if (Array.isArray(where)) {\r\n if (where.length === 0) return [patch];\r\n return where.map((w) => ({ ...w, ...patch }));\r\n }\r\n if (where && typeof where === 'object' && Object.keys(where).length > 0) {\r\n return { ...where, ...patch };\r\n }\r\n return patch;\r\n}\r\n\r\n/**\r\n * Scalar list filters from query params: `{col}From`/`{col}To` (dates), `{col}Min`/`{col}Max` (numbers),\r\n * and `{col}` (ILIKE) for string columns. Skips reserved keys and int FK params handled elsewhere.\r\n */\r\nfunction buildListFilterAndFromSearchParams(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n searchParams: URLSearchParams\r\n): Record<string, unknown> {\r\n const and: Record<string, unknown> = {};\r\n const columnNames = new Set(repo.metadata.columns.map((c) => c.propertyName));\r\n\r\n for (const col of repo.metadata.columns) {\r\n const name = col.propertyName;\r\n if (!columnNames.has(name)) continue;\r\n if (name === 'deleted' || name === 'deletedAt' || name === 'deletedBy') continue;\r\n if (!isListDateColumn(col)) continue;\r\n const from = searchParams.get(`${name}From`)?.trim();\r\n const to = searchParams.get(`${name}To`)?.trim();\r\n if (!from && !to) continue;\r\n if (from && to) {\r\n and[name] = Between(dayStartUtc(from), dayEndUtc(to));\r\n } else if (from) {\r\n and[name] = MoreThanOrEqual(dayStartUtc(from));\r\n } else if (to) {\r\n and[name] = LessThanOrEqual(dayEndUtc(to));\r\n }\r\n }\r\n\r\n for (const col of repo.metadata.columns) {\r\n const name = col.propertyName;\r\n if (!columnNames.has(name)) continue;\r\n if (name === 'deleted' || name === 'deletedAt' || name === 'deletedBy') continue;\r\n if (!isListNumericColumn(col)) continue;\r\n if (Object.prototype.hasOwnProperty.call(and, name)) continue;\r\n const minRaw = searchParams.get(`${name}Min`)?.trim();\r\n const maxRaw = searchParams.get(`${name}Max`)?.trim();\r\n if (!minRaw && !maxRaw) continue;\r\n const parseNum = (s: string): number | null => {\r\n const n = Number(s);\r\n return Number.isFinite(n) ? n : null;\r\n };\r\n const nMin = minRaw ? parseNum(minRaw) : null;\r\n const nMax = maxRaw ? parseNum(maxRaw) : null;\r\n if (nMin != null && nMax != null) {\r\n and[name] = Between(nMin, nMax);\r\n } else if (nMin != null) {\r\n and[name] = MoreThanOrEqual(nMin);\r\n } else if (nMax != null) {\r\n and[name] = LessThanOrEqual(nMax);\r\n }\r\n }\r\n\r\n for (const col of repo.metadata.columns) {\r\n const name = col.propertyName;\r\n if (!columnNames.has(name)) continue;\r\n if (LIST_QUERY_RESERVED.has(name)) continue;\r\n if (name === 'deleted' || name === 'deletedAt' || name === 'deletedBy') continue;\r\n if (!isListStringColumn(col)) continue;\r\n if (Object.prototype.hasOwnProperty.call(and, name)) continue;\r\n const raw = searchParams.get(name)?.trim();\r\n if (!raw) continue;\r\n and[name] = ILike(`%${raw}%`);\r\n }\r\n return and;\r\n}\r\n\r\n/**\r\n * Exact query filters: `?locationId=129`, `?contactId=46`, `?featured=true`.\r\n * Applied after range/ILIKE filters so equality always wins and rows match the request payload.\r\n */\r\nfunction buildExactListParamWhere(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n searchParams: URLSearchParams\r\n): Record<string, unknown> {\r\n const extraWhere: Record<string, unknown> = {};\r\n const columnNames = new Set(repo.metadata.columns.map((c) => c.propertyName));\r\n\r\n for (const col of repo.metadata.columns) {\r\n const name = col.propertyName;\r\n if (!columnNames.has(name)) continue;\r\n if (name === 'deleted' || name === 'deletedAt' || name === 'deletedBy') continue;\r\n if (!isListNumericColumn(col)) continue;\r\n const v = searchParams.get(name)?.trim();\r\n if (v == null || v === '') continue;\r\n const n = Number(v);\r\n if (!Number.isFinite(n)) continue;\r\n extraWhere[name] = n;\r\n }\r\n for (const col of repo.metadata.columns) {\r\n if (String(col.type) !== 'boolean') continue;\r\n const name = col.propertyName;\r\n if (!columnNames.has(name)) continue;\r\n const raw = searchParams.get(name)?.trim();\r\n if (raw === 'true' || raw === 'false') {\r\n extraWhere[name] = raw === 'true';\r\n }\r\n }\r\n return extraWhere;\r\n}\r\n\r\nfunction mergeDeletedFalseWhere(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n where: Record<string, unknown>[] | Record<string, unknown>\r\n): Record<string, unknown>[] | Record<string, unknown> {\r\n if (!entityHasSoftDelete(repo)) return where;\r\n const d = { deleted: false };\r\n if (Array.isArray(where)) {\r\n if (where.length === 0) return [d];\r\n return where.map((w) => ({ ...w, ...d }));\r\n }\r\n return Object.keys(where).length > 0 ? { ...where, ...d } : d;\r\n}\r\n\r\n/** Prefer common list sort keys that exist on the entity (custom tables may omit `createdAt`). */\r\nfunction pickDefaultListSortField(\r\n columnNames: Set<string>,\r\n columns: readonly { propertyName: string }[]\r\n): string {\r\n for (const candidate of ['createdAt', 'updatedAt', 'id', 'name', 'sortOrder', 'title'] as const) {\r\n if (columnNames.has(candidate)) return candidate;\r\n }\r\n return columns[0]?.propertyName ?? 'id';\r\n}\r\n\r\nfunction normalizeProductSku(value: unknown): string | null {\r\n if (value == null) return null;\r\n const s = String(value).trim();\r\n return s === '' ? null : s;\r\n}\r\n\r\nasync function assertProductSkuUnique(\r\n repo: Repository<import('typeorm').ObjectLiteral>,\r\n sku: string,\r\n excludeId?: number\r\n): Promise<boolean> {\r\n const where: import('typeorm').ObjectLiteral =\r\n excludeId != null\r\n ? ({ sku, deleted: false, id: Not(excludeId) } as import('typeorm').ObjectLiteral)\r\n : ({ sku, deleted: false } as import('typeorm').ObjectLiteral);\r\n const row = await repo.findOne({ where });\r\n return row == null;\r\n}\r\n\r\nfunction buildSoftDeletePayload(meta: EntityMetadata, deletedBy: number | null): Record<string, unknown> {\r\n const payload: Record<string, unknown> = { deleted: true };\r\n if (meta.columns.some((c) => c.propertyName === 'deletedAt')) {\r\n payload.deletedAt = new Date();\r\n }\r\n if (deletedBy != null && meta.columns.some((c) => c.propertyName === 'deletedBy')) {\r\n payload.deletedBy = deletedBy;\r\n }\r\n return payload;\r\n}\r\n\r\nfunction makeContactErpSync(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n getCms: CrudHandlerOptions['getCms']\r\n): (row: import('typeorm').ObjectLiteral) => Promise<void> {\r\n return async function syncContactRowToErp(row: import('typeorm').ObjectLiteral): Promise<void> {\r\n if (!getCms) return;\r\n try {\r\n const cms = await getCms();\r\n const c = row as {\r\n name: string;\r\n email: string;\r\n phone?: string | null;\r\n type?: string | null;\r\n company?: string | null;\r\n notes?: string | null;\r\n };\r\n await queueErpCreateContactIfEnabled(cms, dataSource, entityMap, {\r\n name: c.name,\r\n email: c.email,\r\n phone: c.phone,\r\n type: c.type,\r\n company: c.company,\r\n notes: c.notes,\r\n });\r\n } catch {\r\n /* ignore */\r\n }\r\n };\r\n}\r\n\r\nexport function createCrudHandler(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n options: CrudHandlerOptions\r\n) {\r\n const { requireAuth, json, requireEntityPermission: reqPerm, getCms } = options;\r\n const syncContactRowToErp = makeContactErpSync(dataSource, entityMap, getCms);\r\n\r\n async function authz(req: Request, resource: string, action: EntityCrudAction): Promise<Response | null> {\r\n const authError = await requireAuth(req);\r\n if (authError) return authError;\r\n if (!reqPerm) {\r\n return json({ error: 'Forbidden', reason: 'entity_rbac_required', entity: resource, action }, { status: 403 });\r\n }\r\n const pe = await reqPerm(req, resource, action);\r\n if (pe) return pe;\r\n return null;\r\n }\r\n\r\n return {\r\n async GET(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'read');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('GET list', {\r\n reason: 'invalid_resource',\r\n resource,\r\n hasEntity: Boolean(entity),\r\n entityMapHasLlmAgents: Boolean(entityMap.llm_agents),\r\n entityMapKeyCount: Object.keys(entityMap).length,\r\n });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const { searchParams } = new URL(req.url);\r\n const page = Number(searchParams.get('page')) || 1;\r\n const limit = Math.min(Number(searchParams.get('limit')) || 10, 100);\r\n const skip = (page - 1) * limit;\r\n const sortFieldRaw = searchParams.get('sortField') || 'createdAt';\r\n const sortOrder = searchParams.get('sortOrder') === 'desc' ? 'DESC' : 'ASC';\r\n const search = searchParams.get('search');\r\n\r\n // Orders list: include contact + itemsSummary; search (order# + customer), status, date, paymentRef\r\n if (resource === 'orders') {\r\n const repo = dataSource.getRepository(entity);\r\n const allowedSort = ['id', 'orderNumber', 'contactId', 'status', 'total', 'currency', 'createdAt', 'updatedAt'];\r\n const sortField = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : 'createdAt';\r\n const sortOrderOrders = searchParams.get('sortOrder') === 'asc' ? 'ASC' : 'DESC';\r\n const statusFilter = searchParams.get('status')?.trim();\r\n const dateFrom = searchParams.get('dateFrom')?.trim();\r\n const dateTo = searchParams.get('dateTo')?.trim();\r\n const paymentRef = searchParams.get('paymentRef')?.trim();\r\n\r\n let orderIdsFromPayment: number[] | null = null;\r\n if (paymentRef && entityMap['payments']) {\r\n const paymentRepo = dataSource.getRepository(entityMap['payments']);\r\n const payments = await paymentRepo\r\n .createQueryBuilder('p')\r\n .select('p.orderId')\r\n .where('p.externalReference = :ref', { ref: paymentRef })\r\n .orWhere(\"p.metadata->>'razorpayPaymentId' = :ref\", { ref: paymentRef })\r\n .getRawMany<{ orderId: number }>();\r\n orderIdsFromPayment = payments.map((r) => r.orderId);\r\n if (orderIdsFromPayment.length === 0) {\r\n return json({ total: 0, page, limit, totalPages: 0, data: [] });\r\n }\r\n }\r\n\r\n const qb = repo\r\n .createQueryBuilder('order')\r\n .leftJoinAndSelect('order.contact', 'contact')\r\n .leftJoinAndSelect('order.items', 'items')\r\n .leftJoinAndSelect('items.product', 'product')\r\n .leftJoinAndSelect('product.collection', 'collection')\r\n .andWhere('order.deleted = :orderDel', { orderDel: false })\r\n .orderBy(`order.${sortField}`, sortOrderOrders)\r\n .skip(skip)\r\n .take(limit);\r\n\r\n if (search && typeof search === 'string' && search.trim()) {\r\n const term = `%${search.trim()}%`;\r\n qb.andWhere(\r\n '(order.orderNumber ILIKE :term OR contact.name ILIKE :term OR contact.email ILIKE :term)',\r\n { term }\r\n );\r\n }\r\n if (statusFilter) qb.andWhere('order.status = :status', { status: statusFilter });\r\n if (dateFrom) qb.andWhere('order.createdAt >= :dateFrom', { dateFrom: new Date(dateFrom + 'T00:00:00.000Z') });\r\n if (dateTo) qb.andWhere('order.createdAt <= :dateTo', { dateTo: new Date(dateTo + 'T23:59:59.999Z') });\r\n const totalMin = searchParams.get('totalMin')?.trim();\r\n const totalMax = searchParams.get('totalMax')?.trim();\r\n if (totalMin) {\r\n const n = Number(totalMin);\r\n if (Number.isFinite(n)) qb.andWhere('order.total >= :totalMin', { totalMin: n });\r\n }\r\n if (totalMax) {\r\n const n = Number(totalMax);\r\n if (Number.isFinite(n)) qb.andWhere('order.total <= :totalMax', { totalMax: n });\r\n }\r\n const currency = searchParams.get('currency')?.trim();\r\n if (currency) qb.andWhere('order.currency ILIKE :orderCurrency', { orderCurrency: `%${currency}%` });\r\n if (orderIdsFromPayment && orderIdsFromPayment.length) qb.andWhere('order.id IN (:...orderIds)', { orderIds: orderIdsFromPayment });\r\n\r\n const [rows, total] = await qb.getManyAndCount();\r\n const data = (rows as Record<string, unknown>[]).map((order: Record<string, unknown>) => {\r\n const contact = order.contact as Record<string, unknown> | undefined;\r\n const items = (order.items as Array<{ product?: { name?: string; collection?: { name?: string } }; quantity: number }>) ?? [];\r\n const itemsSummary = items\r\n .map((i) => {\r\n const label = i.product?.collection?.name ?? i.product?.name ?? 'Product';\r\n return `${label} × ${i.quantity}`;\r\n })\r\n .join(', ') || '—';\r\n return {\r\n ...order,\r\n contact: contact ? { id: contact.id, name: contact.name, email: contact.email, phone: contact.phone } : null,\r\n itemsSummary,\r\n };\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n // Payments list: include order + contact; search (customer), status, date, method, orderNumber\r\n if (resource === 'payments') {\r\n const repo = dataSource.getRepository(entity);\r\n const allowedSort = ['id', 'orderId', 'amount', 'currency', 'status', 'method', 'paidAt', 'createdAt', 'updatedAt'];\r\n const sortField = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : 'createdAt';\r\n const sortOrderPayments = searchParams.get('sortOrder') === 'asc' ? 'ASC' : 'DESC';\r\n const statusFilter = searchParams.get('status')?.trim();\r\n const dateFrom = searchParams.get('dateFrom')?.trim();\r\n const dateTo = searchParams.get('dateTo')?.trim();\r\n const methodFilter = searchParams.get('method')?.trim();\r\n const orderNumberParam = searchParams.get('orderNumber')?.trim();\r\n\r\n const qb = repo\r\n .createQueryBuilder('payment')\r\n .leftJoinAndSelect('payment.order', 'ord')\r\n .leftJoinAndSelect('ord.contact', 'orderContact')\r\n .leftJoinAndSelect('payment.contact', 'contact')\r\n .andWhere('payment.deleted = :payDel', { payDel: false })\r\n .orderBy(`payment.${sortField}`, sortOrderPayments)\r\n .skip(skip)\r\n .take(limit);\r\n\r\n if (search && typeof search === 'string' && search.trim()) {\r\n const term = `%${search.trim()}%`;\r\n qb.andWhere(\r\n '(orderContact.name ILIKE :term OR orderContact.email ILIKE :term OR contact.name ILIKE :term OR contact.email ILIKE :term)',\r\n { term }\r\n );\r\n }\r\n if (statusFilter) qb.andWhere('payment.status = :status', { status: statusFilter });\r\n if (dateFrom) qb.andWhere('payment.createdAt >= :dateFrom', { dateFrom: new Date(dateFrom + 'T00:00:00.000Z') });\r\n if (dateTo) qb.andWhere('payment.createdAt <= :dateTo', { dateTo: new Date(dateTo + 'T23:59:59.999Z') });\r\n const paidAtFrom = searchParams.get('paidAtFrom')?.trim();\r\n const paidAtTo = searchParams.get('paidAtTo')?.trim();\r\n if (paidAtFrom) {\r\n qb.andWhere('payment.paidAt >= :paidAtFrom', { paidAtFrom: new Date(paidAtFrom + 'T00:00:00.000Z') });\r\n }\r\n if (paidAtTo) {\r\n qb.andWhere('payment.paidAt <= :paidAtTo', { paidAtTo: new Date(paidAtTo + 'T23:59:59.999Z') });\r\n }\r\n if (methodFilter) qb.andWhere('payment.method = :method', { method: methodFilter });\r\n if (orderNumberParam) qb.andWhere('ord.orderNumber ILIKE :orderNumber', { orderNumber: `%${orderNumberParam}%` });\r\n const amountMin = searchParams.get('amountMin')?.trim();\r\n const amountMax = searchParams.get('amountMax')?.trim();\r\n if (amountMin) {\r\n const n = Number(amountMin);\r\n if (Number.isFinite(n)) qb.andWhere('payment.amount >= :amountMin', { amountMin: n });\r\n }\r\n if (amountMax) {\r\n const n = Number(amountMax);\r\n if (Number.isFinite(n)) qb.andWhere('payment.amount <= :amountMax', { amountMax: n });\r\n }\r\n const extRef = searchParams.get('externalReference')?.trim();\r\n if (extRef) {\r\n qb.andWhere('payment.externalReference ILIKE :extRef', { extRef: `%${extRef}%` });\r\n }\r\n\r\n const [rows, total] = await qb.getManyAndCount();\r\n const data = (rows as Record<string, unknown>[]).map((payment: Record<string, unknown>) => {\r\n const order = payment.order as Record<string, unknown> | undefined;\r\n const orderContact = order?.contact as Record<string, unknown> | undefined;\r\n const contact = payment.contact as Record<string, unknown> | undefined;\r\n const customer = orderContact ?? contact;\r\n return {\r\n ...payment,\r\n order: order ? { id: order.id, orderNumber: order.orderNumber, contact: orderContact ? { name: orderContact.name, email: orderContact.email } : null } : null,\r\n contact: customer ? { id: customer.id, name: customer.name, email: customer.email } : null,\r\n };\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n // Products list: status and inventory filters\r\n if (resource === 'products') {\r\n const repo = dataSource.getRepository(entity);\r\n const statusFilter = searchParams.get('status')?.trim();\r\n const inventory = searchParams.get('inventory')?.trim();\r\n const productWhere: Record<string, unknown> = {\r\n deleted: false,\r\n ...buildListFilterAndFromSearchParams(repo, searchParams),\r\n };\r\n if (statusFilter) productWhere.status = statusFilter;\r\n if (inventory === 'in_stock') productWhere.quantity = MoreThan(0);\r\n if (inventory === 'out_of_stock') productWhere.quantity = 0;\r\n for (const key of ['brandId', 'categoryId', 'collectionId'] as const) {\r\n const raw = searchParams.get(key)?.trim();\r\n if (raw) {\r\n const n = Number(raw);\r\n if (Number.isFinite(n)) productWhere[key] = n;\r\n }\r\n }\r\n const featuredRaw = searchParams.get('featured')?.trim();\r\n if (featuredRaw === 'true' || featuredRaw === 'false') {\r\n productWhere.featured = featuredRaw === 'true';\r\n }\r\n if (search && typeof search === 'string' && search.trim()) {\r\n productWhere.name = ILike(`%${search.trim()}%`);\r\n }\r\n const productColumnNames = new Set(repo.metadata.columns.map((c) => c.propertyName));\r\n const defaultProductSort = pickDefaultListSortField(productColumnNames, repo.metadata.columns);\r\n const sortParam = (searchParams.get('sortField') ?? '').trim();\r\n const productSortField =\r\n sortParam && productColumnNames.has(sortParam) ? sortParam : defaultProductSort;\r\n const [data, total] = await repo.findAndCount({\r\n where: Object.keys(productWhere).length ? productWhere : undefined,\r\n skip,\r\n take: limit,\r\n order: { [productSortField]: sortOrder },\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n // Contacts list: filters (type, orderId), optional includeSummary (orderCount, totalPaid)\r\n if (resource === 'contacts') {\r\n const repo = dataSource.getRepository(entity);\r\n const allowedSort = ['id', 'name', 'email', 'createdAt', 'type'];\r\n const sortField = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : 'createdAt';\r\n const sortOrderContacts = searchParams.get('sortOrder') === 'asc' ? 'ASC' : 'DESC';\r\n const typeFilter = searchParams.get('type')?.trim();\r\n const orderIdParam = searchParams.get('orderId')?.trim();\r\n const includeSummary = searchParams.get('includeSummary') === '1';\r\n\r\n const qb = repo\r\n .createQueryBuilder('contact')\r\n .andWhere('contact.deleted = :contactDel', { contactDel: false })\r\n .orderBy(`contact.${sortField}`, sortOrderContacts)\r\n .skip(skip)\r\n .take(limit);\r\n\r\n if (search && typeof search === 'string' && search.trim()) {\r\n const term = `%${search.trim()}%`;\r\n qb.andWhere('(contact.name ILIKE :term OR contact.email ILIKE :term OR contact.phone ILIKE :term)', { term });\r\n }\r\n if (typeFilter) qb.andWhere('contact.type = :type', { type: typeFilter });\r\n if (orderIdParam) {\r\n const orderId = Number(orderIdParam);\r\n if (!Number.isNaN(orderId)) {\r\n qb.andWhere('contact.id IN (SELECT \"contactId\" FROM orders WHERE id = :orderId)', { orderId });\r\n }\r\n }\r\n\r\n if (includeSummary && entityMap['orders'] && entityMap['payments']) {\r\n qb.loadRelationCountAndMap('contact._orderCount', 'contact.orders');\r\n const [rows, total] = await qb.getManyAndCount();\r\n const contactIds = (rows as { id: number }[]).map((c) => c.id);\r\n const paymentRepo = dataSource.getRepository(entityMap['payments']);\r\n const paidByContact = await paymentRepo\r\n .createQueryBuilder('p')\r\n .select('p.contactId', 'contactId')\r\n .addSelect('COALESCE(SUM(CAST(p.amount AS DECIMAL)), 0)', 'total')\r\n .where('p.contactId IN (:...ids)', { ids: contactIds.length ? contactIds : [0] })\r\n .andWhere('p.status = :status', { status: 'completed' })\r\n .groupBy('p.contactId')\r\n .getRawMany<{ contactId: number; total: string }>();\r\n const totalPaidMap = new Map<number, number>(paidByContact.map((r) => [r.contactId, Number(r.total)]));\r\n const data = (rows as Record<string, unknown>[]).map((c) => {\r\n const { _orderCount, ...rest } = c as { _orderCount?: number; id: number };\r\n return {\r\n ...rest,\r\n orderCount: _orderCount ?? 0,\r\n totalPaid: totalPaidMap.get((rest as { id: number }).id) ?? 0,\r\n };\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n const [data, total] = await qb.getManyAndCount();\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n const repo = dataSource.getRepository(entity);\r\n const typeFilter = searchParams.get('type');\r\n const columnNames = new Set(repo.metadata.columns.map((c) => c.propertyName));\r\n\r\n if (resource === 'media') {\r\n const qb = repo.createQueryBuilder('m');\r\n const parentIdParam = searchParams.get('parentId');\r\n if (parentIdParam != null && parentIdParam !== '') {\r\n const n = Number(parentIdParam);\r\n if (!Number.isFinite(n)) return json({ error: 'Invalid parentId' }, { status: 400 });\r\n qb.where('m.deleted = :mediaDel AND m.parentId = :pid', { mediaDel: false, pid: n });\r\n } else {\r\n qb.where('m.deleted = :mediaDel AND m.parentId IS NULL', { mediaDel: false });\r\n }\r\n if (search && typeof search === 'string' && search.trim()) {\r\n qb.andWhere('m.filename ILIKE :search', { search: `%${search.trim()}%` });\r\n }\r\n if (typeFilter) {\r\n if (typeFilter === 'folder') {\r\n qb.andWhere('m.kind = :folderKind', { folderKind: 'folder' });\r\n }\r\n else if (typeFilter === 'file') {\r\n qb.andWhere('m.kind = :fileKind', { fileKind: 'file' });\r\n }\r\n else if (typeFilter === 'image') {\r\n qb.andWhere('m.mimeType LIKE :imageMimeType', { imageMimeType: 'image/%' });\r\n }\r\n else if (typeFilter === 'video') {\r\n qb.andWhere('m.mimeType LIKE :videoMimeType', { videoMimeType: 'video/%' });\r\n }\r\n else if (typeFilter === 'audio') {\r\n qb.andWhere('m.mimeType LIKE :audioMimeType', { audioMimeType: 'audio/%' });\r\n }\r\n else if (typeFilter === 'Document') {\r\n qb.andWhere('m.mimeType LIKE :documentMimeType', { documentMimeType: 'application/pdf' });\r\n }\r\n else if (typeFilter === 'application') {\r\n qb.andWhere('m.kind = :folderKind', { folderKind: 'folder' });\r\n }\r\n }\r\n const allowedSort = ['filename', 'createdAt', 'id'];\r\n const sf = allowedSort.includes(sortFieldRaw) ? sortFieldRaw : 'filename';\r\n const so = sortOrder === 'DESC' ? 'DESC' : 'ASC';\r\n // qb.orderBy('CASE WHEN m.kind = :fk THEN 0 ELSE 1 END', 'ASC')\r\n // .addOrderBy(`m.${sf}`, so)\r\n // .setParameter('fk', 'folder')\r\n qb.orderBy(`m.${sf}`, so)\r\n .skip(skip)\r\n .take(limit);\r\n const [rows, total] = await qb.getManyAndCount();\r\n const mediaRows = rows as { id: number; kind?: string; size?: number }[];\r\n const folderIds = mediaRows.filter((m) => m.kind === 'folder').map((m) => m.id);\r\n let data: typeof rows = rows;\r\n if (folderIds.length > 0) {\r\n const sizeMap = await aggregateMediaFolderFileSizes(dataSource, folderIds);\r\n data = mediaRows.map((m) =>\r\n m.kind === 'folder' ? { ...m, size: sizeMap.get(m.id) ?? 0 } : m\r\n ) as typeof rows;\r\n }\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n }\r\n\r\n const defaultSortField = pickDefaultListSortField(columnNames, repo.metadata.columns);\r\n const sortParam = (searchParams.get('sortField') ?? '').trim();\r\n const sortField = sortParam && columnNames.has(sortParam) ? sortParam : defaultSortField;\r\n let where: Record<string, unknown>[] | Record<string, unknown> = {};\r\n if (search) {\r\n where = buildSearchWhereClause(repo, search);\r\n }\r\n where = mergeListWhereAnd(where, buildListFilterAndFromSearchParams(repo, searchParams));\r\n const exactParamWhere = buildExactListParamWhere(repo, searchParams);\r\n if (Object.keys(exactParamWhere).length > 0) {\r\n if (Array.isArray(where)) {\r\n where = where.map((w) => ({ ...w, ...exactParamWhere }));\r\n } else if (where && typeof where === 'object' && Object.keys(where).length > 0) {\r\n where = { ...where, ...exactParamWhere };\r\n } else {\r\n where = exactParamWhere;\r\n }\r\n }\r\n where = mergeDeletedFalseWhere(repo, where);\r\n let data: import('typeorm').ObjectLiteral[];\r\n let total: number;\r\n try {\r\n const r = await repo.findAndCount({\r\n skip,\r\n take: limit,\r\n order: { [sortField]: sortOrder },\r\n where,\r\n });\r\n data = r[0];\r\n total = r[1];\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : String(err);\r\n logCrudServerError('GET list query failed', { resource, sortField, sortOrder, message });\r\n throw err;\r\n }\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n },\r\n\r\n async POST(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'create');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('POST create', {\r\n reason: 'invalid_resource',\r\n resource,\r\n hasEntity: Boolean(entity),\r\n entityMapHasLlmAgents: Boolean(entityMap.llm_agents),\r\n });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const rawPostBody = await req.json();\r\n if (!rawPostBody || typeof rawPostBody !== 'object' || Object.keys(rawPostBody).length === 0) {\r\n logCrudClientError('POST create', {\r\n reason: 'invalid_request_payload',\r\n resource,\r\n rawType: rawPostBody == null ? 'nullish' : typeof rawPostBody,\r\n keyCount: rawPostBody && typeof rawPostBody === 'object' ? Object.keys(rawPostBody).length : 0,\r\n });\r\n return json({ error: 'Invalid request payload' }, { status: 400 });\r\n }\r\n const body = rawPostBody as Record<string, unknown>;\r\n if (resource === 'media') {\r\n const b = body;\r\n const kind = b.kind === 'folder' ? 'folder' : 'file';\r\n b.kind = kind;\r\n const fn = String(b.filename ?? '').trim().slice(0, 255);\r\n if (!fn) return json({ error: 'filename required' }, { status: 400 });\r\n b.filename = fn;\r\n let pid: number | null = null;\r\n if (b.parentId != null && b.parentId !== '') {\r\n const n = Number(b.parentId);\r\n if (!Number.isFinite(n)) return json({ error: 'Invalid parentId' }, { status: 400 });\r\n pid = n;\r\n }\r\n b.parentId = pid;\r\n const mediaRepo = dataSource.getRepository(entityMap.media);\r\n if (pid != null) {\r\n const parent = await mediaRepo.findOne({ where: { id: pid } });\r\n if (!parent || (parent as { kind: string }).kind !== 'folder') {\r\n return json({ error: 'parent must be a folder' }, { status: 400 });\r\n }\r\n }\r\n if (kind === 'folder') {\r\n b.url = null;\r\n b.mimeType = 'inode/directory';\r\n b.size = 0;\r\n } else {\r\n if (!b.url || typeof b.url !== 'string') return json({ error: 'url required for files' }, { status: 400 });\r\n if (!b.mimeType || typeof b.mimeType !== 'string') {\r\n b.mimeType = 'application/octet-stream';\r\n }\r\n }\r\n }\r\n const repo = dataSource.getRepository(entity);\r\n const persistBody = resource === 'media' ? body : pickColumnUpdates(repo, body);\r\n if (resource === 'contacts' && 'type' in persistBody) {\r\n const t = persistBody.type;\r\n if (t === '' || t === 'none' || t == null) persistBody.type = null;\r\n }\r\n if (resource !== 'media' && Object.keys(persistBody).length === 0) {\r\n logCrudClientError('POST create', {\r\n reason: 'no_scalar_columns_after_pick',\r\n resource,\r\n incomingKeys: Object.keys(body),\r\n });\r\n return json({ error: 'Invalid request payload' }, { status: 400 });\r\n }\r\n if (resource === 'products') {\r\n if ('sku' in persistBody) {\r\n const skuNorm = normalizeProductSku(persistBody.sku);\r\n if (skuNorm) {\r\n const ok = await assertProductSkuUnique(repo, skuNorm);\r\n if (!ok) {\r\n return json({ error: 'SKU already exists. Please use a unique SKU.' }, { status: 400 });\r\n }\r\n persistBody.sku = skuNorm;\r\n } else {\r\n persistBody.sku = null;\r\n }\r\n }\r\n }\r\n if (resource === 'addresses') {\r\n const cid = Number(persistBody.contactId);\r\n if (!Number.isFinite(cid)) {\r\n return json({ error: 'Valid contactId is required.' }, { status: 400 });\r\n }\r\n if (persistBody.tag === '') persistBody.tag = null;\r\n const addrErr = validateAndNormalizeAddressRow(persistBody);\r\n if (addrErr) {\r\n return json({ error: addrErr }, { status: 400 });\r\n }\r\n }\r\n sanitizeBodyForEntity(repo, persistBody);\r\n let created: import('typeorm').ObjectLiteral;\r\n try {\r\n created = await repo.save(repo.create(persistBody as object));\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : String(err);\r\n logCrudServerError('POST create save failed', { resource, message, persistKeys: Object.keys(persistBody) });\r\n throw err;\r\n }\r\n if (resource === 'contacts') {\r\n await syncContactRowToErp(created as import('typeorm').ObjectLiteral);\r\n }\r\n if (resource === 'products' && getCms) {\r\n const cms = await getCms();\r\n await queueErpProductUpsertIfEnabled(cms, dataSource, entityMap, created as import('typeorm').ObjectLiteral);\r\n }\r\n return json(created, { status: 201 });\r\n },\r\n\r\n async GET_METADATA(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'read');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('GET_METADATA', { reason: 'invalid_resource', resource });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const repo = dataSource.getRepository(entity);\r\n const meta = repo.metadata;\r\n\r\n // Collect unique column names from indices\r\n const uniqueFromIndices = new Set<string>();\r\n for (const idx of meta.indices) {\r\n if (idx.isUnique && idx.columns.length === 1) {\r\n uniqueFromIndices.add(idx.columns[0].propertyName);\r\n }\r\n }\r\n for (const uniq of meta.uniques) {\r\n if (uniq.columns.length === 1) {\r\n uniqueFromIndices.add(uniq.columns[0].propertyName);\r\n }\r\n }\r\n\r\n const columns = meta.columns.map((col) => ({\r\n name: col.propertyName,\r\n type: typeof col.type === 'string' ? col.type : (col.type as { name?: string })?.name ?? 'unknown',\r\n nullable: col.isNullable,\r\n isUnique: uniqueFromIndices.has(col.propertyName),\r\n isPrimary: col.isPrimary,\r\n default: col.default,\r\n }));\r\n\r\n const uniqueColumns = [...uniqueFromIndices];\r\n\r\n return json({ columns, uniqueColumns });\r\n },\r\n\r\n async BULK_POST(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'update');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('BULK_POST', { reason: 'invalid_resource', resource });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const body = await req.json();\r\n const { records, upsertKey = 'id' } = body as { records: object[]; upsertKey?: string };\r\n\r\n if (!Array.isArray(records) || records.length === 0) {\r\n logCrudClientError('BULK_POST', {\r\n reason: 'records_required',\r\n resource,\r\n recordsIsArray: Array.isArray(records),\r\n recordCount: Array.isArray(records) ? records.length : 0,\r\n });\r\n return json({ error: 'Records array is required' }, { status: 400 });\r\n }\r\n\r\n const repo = dataSource.getRepository(entity);\r\n\r\n // Sanitize each record\r\n for (const record of records) {\r\n sanitizeBodyForEntity(repo, record as Record<string, unknown>);\r\n }\r\n\r\n try {\r\n const result = await repo.upsert(records, {\r\n conflictPaths: [upsertKey],\r\n skipUpdateIfNoValuesChanged: true,\r\n });\r\n return json({\r\n success: true,\r\n imported: result.identifiers.length,\r\n identifiers: result.identifiers,\r\n });\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : 'Bulk import failed';\r\n logCrudClientError('BULK_POST upsert failed', { resource, upsertKey, message });\r\n return json({ error: message }, { status: 400 });\r\n }\r\n },\r\n\r\n async GET_EXPORT(req: Request, resource: string) {\r\n const authError = await authz(req, resource, 'read');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!resource || !entity) {\r\n logCrudClientError('GET_EXPORT', { reason: 'invalid_resource', resource });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n\r\n const { searchParams } = new URL(req.url);\r\n const format = searchParams.get('format') || 'csv';\r\n\r\n const repo = dataSource.getRepository(entity);\r\n const meta = repo.metadata;\r\n\r\n // Check if entity has 'deleted' column\r\n const hasDeleted = meta.columns.some((c) => c.propertyName === 'deleted');\r\n const where = hasDeleted ? { deleted: false } : {};\r\n\r\n const data = await repo.find({ where });\r\n\r\n // Get exportable columns (exclude soft-delete related)\r\n const excludeCols = new Set(['deletedAt', 'deletedBy', 'deleted']);\r\n const columns = meta.columns\r\n .filter((c) => !excludeCols.has(c.propertyName))\r\n .map((c) => c.propertyName);\r\n\r\n if (format === 'json') {\r\n return json(data);\r\n }\r\n\r\n // CSV format\r\n const escapeCSV = (val: unknown): string => {\r\n if (val === null || val === undefined) return '';\r\n const str = typeof val === 'object' ? JSON.stringify(val) : String(val);\r\n if (str.includes(',') || str.includes('\"') || str.includes('\\n')) {\r\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\r\n }\r\n return str;\r\n };\r\n\r\n const header = columns.join(',');\r\n const rows = data.map((row) =>\r\n columns.map((col) => escapeCSV((row as Record<string, unknown>)[col])).join(',')\r\n );\r\n const csv = [header, ...rows].join('\\n');\r\n\r\n return new Response(csv, {\r\n headers: {\r\n 'Content-Type': 'text/csv; charset=utf-8',\r\n 'Content-Disposition': `attachment; filename=\"${resource}.csv\"`,\r\n },\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport function createCrudByIdHandler(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n options: CrudHandlerOptions\r\n) {\r\n const { requireAuth, json, requireEntityPermission: reqPerm, getCms, getDeletedByUserId } = options;\r\n const syncContactRowToErp = makeContactErpSync(dataSource, entityMap, getCms);\r\n\r\n async function authz(req: Request, resource: string, action: EntityCrudAction): Promise<Response | null> {\r\n const authError = await requireAuth(req);\r\n if (authError) return authError;\r\n if (!reqPerm) {\r\n return json({ error: 'Forbidden', reason: 'entity_rbac_required', entity: resource, action }, { status: 403 });\r\n }\r\n const pe = await reqPerm(req, resource, action);\r\n if (pe) return pe;\r\n return null;\r\n }\r\n\r\n return {\r\n async GET(req: Request, resource: string, id: string) {\r\n const authError = await authz(req, resource, 'read');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!entity) {\r\n logCrudClientError('GET by id', { reason: 'invalid_resource', resource, id });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const repo = dataSource.getRepository(entity);\r\n\r\n if (resource === 'orders') {\r\n const order = await repo.findOne({\r\n where: { id: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n relations: ['contact', 'billingAddress', 'shippingAddress', 'items', 'items.product', 'items.product.collection', 'payments'],\r\n });\r\n if (!order) return json({ message: 'Not found' }, { status: 404 });\r\n const relatedOrders = await repo.find({\r\n where: { parentOrderId: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n order: { id: 'ASC' },\r\n });\r\n return json({ ...order, relatedOrders });\r\n }\r\n\r\n if (resource === 'contacts') {\r\n const contact = await repo.findOne({\r\n where: { id: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n relations: ['form_submissions', 'form_submissions.form', 'orders', 'payments', 'addresses'],\r\n });\r\n if (!contact) return json({ message: 'Not found' }, { status: 404 });\r\n const orders = (contact as { orders?: { total?: unknown; createdAt?: string }[] }).orders ?? [];\r\n const payments = (contact as { payments?: { status: string; amount?: number }[] }).payments ?? [];\r\n const totalPaid = payments\r\n .filter((p) => p.status === 'completed')\r\n .reduce((sum, p) => sum + Number(p.amount ?? 0), 0);\r\n const lastOrderAt =\r\n orders.length > 0\r\n ? orders.reduce((latest, o) => {\r\n const t = o.createdAt ? new Date(o.createdAt).getTime() : 0;\r\n return t > latest ? t : latest;\r\n }, 0)\r\n : null;\r\n return json({\r\n ...contact,\r\n summary: {\r\n totalOrders: orders.length,\r\n totalPaid,\r\n lastOrderAt: lastOrderAt ? new Date(lastOrderAt).toISOString() : null,\r\n },\r\n });\r\n }\r\n\r\n if (resource === 'payments') {\r\n const payment = await repo.findOne({\r\n where: { id: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n relations: ['order', 'order.contact', 'contact'],\r\n });\r\n if (!payment) return json({ message: 'Not found' }, { status: 404 });\r\n const p = payment as Record<string, unknown>;\r\n const order = p.order as Record<string, unknown> | undefined;\r\n const orderContact = order?.contact as Record<string, unknown> | undefined;\r\n const contact = p.contact as Record<string, unknown> | undefined;\r\n const customer = orderContact ?? contact;\r\n return json({\r\n ...p,\r\n order: order\r\n ? {\r\n id: order.id,\r\n orderNumber: order.orderNumber,\r\n contact: orderContact ? { name: orderContact.name, email: orderContact.email } : null,\r\n }\r\n : null,\r\n contact: customer\r\n ? { id: customer.id, name: customer.name, email: customer.email }\r\n : null,\r\n });\r\n }\r\n\r\n if (resource === 'blogs') {\r\n const blog = await repo.findOne({\r\n where: { id: Number(id), deleted: false } as import('typeorm').ObjectLiteral,\r\n relations: ['category', 'seo', 'tags'],\r\n });\r\n return blog ? json(blog) : json({ message: 'Not found' }, { status: 404 });\r\n }\r\n\r\n const idWhere: import('typeorm').ObjectLiteral = entityHasSoftDelete(repo)\r\n ? ({ id: Number(id), deleted: false } as import('typeorm').ObjectLiteral)\r\n : ({ id: Number(id) } as import('typeorm').ObjectLiteral);\r\n const item = await repo.findOne({ where: idWhere });\r\n return item ? json(item) : json({ message: 'Not found' }, { status: 404 });\r\n },\r\n\r\n async PUT(req: Request, resource: string, id: string) {\r\n const authError = await authz(req, resource, 'update');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!entity) {\r\n logCrudClientError('PUT by id', { reason: 'invalid_resource', resource, id });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const rawBody = (await req.json()) as Record<string, unknown> | null;\r\n const repo = dataSource.getRepository(entity);\r\n const numericId = Number(id);\r\n\r\n if (\r\n resource === 'blogs' &&\r\n rawBody &&\r\n typeof rawBody === 'object' &&\r\n entityMap.categories &&\r\n entityMap.seos &&\r\n entityMap.tags\r\n ) {\r\n const existing = await repo.findOne({\r\n where: { id: numericId, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!existing) return json({ message: 'Not found' }, { status: 404 });\r\n\r\n const updatePayload = pickColumnUpdates(repo, rawBody);\r\n\r\n if ('category' in rawBody) {\r\n const c = rawBody.category;\r\n if (typeof c === 'string' && c.trim()) {\r\n const cat = await dataSource\r\n .getRepository(entityMap.categories)\r\n .findOne({ where: { name: c.trim() } });\r\n updatePayload.categoryId = cat?.id ?? null;\r\n } else {\r\n updatePayload.categoryId = null;\r\n }\r\n }\r\n\r\n const blogSlug =\r\n (typeof updatePayload.slug === 'string' && updatePayload.slug) ||\r\n (existing as { slug: string }).slug;\r\n const seoRepo = dataSource.getRepository(entityMap.seos);\r\n const seoField = (k: string): string | null | undefined => {\r\n if (!(k in rawBody)) return undefined;\r\n const v = rawBody[k];\r\n if (v == null || v === '') return null;\r\n return String(v);\r\n };\r\n if (\r\n 'metaTitle' in rawBody ||\r\n 'metaDescription' in rawBody ||\r\n 'metaKeywords' in rawBody ||\r\n 'ogImage' in rawBody\r\n ) {\r\n const title = seoField('metaTitle');\r\n const description = seoField('metaDescription');\r\n const keywords = seoField('metaKeywords');\r\n const ogImage = seoField('ogImage');\r\n const exSeoId = (existing as { seoId: number | null }).seoId;\r\n if (exSeoId) {\r\n const seo = await seoRepo.findOne({ where: { id: exSeoId } });\r\n if (seo) {\r\n const s = seo as Record<string, unknown>;\r\n if (title !== undefined) s.title = title;\r\n if (description !== undefined) s.description = description;\r\n if (keywords !== undefined) s.keywords = keywords;\r\n if (ogImage !== undefined) s.ogImage = ogImage;\r\n s.slug = blogSlug;\r\n await seoRepo.save(seo);\r\n }\r\n } else {\r\n let seoSlug = blogSlug;\r\n const taken = await seoRepo.findOne({ where: { slug: seoSlug } });\r\n if (taken) seoSlug = `blog-${numericId}-${blogSlug}`;\r\n const seo = await seoRepo.save(\r\n seoRepo.create({\r\n slug: seoSlug,\r\n title: title ?? null,\r\n description: description ?? null,\r\n keywords: keywords ?? null,\r\n ogImage: ogImage ?? null,\r\n })\r\n );\r\n updatePayload.seoId = (seo as { id: number }).id;\r\n }\r\n }\r\n\r\n sanitizeBodyForEntity(repo, updatePayload);\r\n await repo.update(numericId, updatePayload as object);\r\n\r\n if (Array.isArray(rawBody.tags)) {\r\n const tagNames = (rawBody.tags as unknown[]).map((t) => String(t).trim()).filter(Boolean);\r\n const tagRepo = dataSource.getRepository(entityMap.tags);\r\n const tagEntities: import('typeorm').ObjectLiteral[] = [];\r\n for (const name of tagNames) {\r\n let tag = await tagRepo.findOne({ where: { name } });\r\n if (!tag) tag = await tagRepo.save(tagRepo.create({ name }));\r\n tagEntities.push(tag);\r\n }\r\n const blog = await repo.findOne({ where: { id: numericId }, relations: ['tags'] });\r\n if (blog) {\r\n (blog as Record<string, unknown>).tags = tagEntities;\r\n await repo.save(blog);\r\n }\r\n }\r\n\r\n const updated = await repo.findOne({\r\n where: { id: numericId },\r\n relations: ['tags', 'category', 'seo'],\r\n });\r\n return updated ? json(updated) : json({ message: 'Not found' }, { status: 404 });\r\n }\r\n\r\n if (entityHasSoftDelete(repo)) {\r\n const cur = await repo.findOne({\r\n where: { id: numericId, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!cur) return json({ message: 'Not found' }, { status: 404 });\r\n }\r\n\r\n const updatePayload = rawBody && typeof rawBody === 'object' ? pickColumnUpdates(repo, rawBody) : {};\r\n if (resource === 'contacts' && 'type' in updatePayload) {\r\n const t = updatePayload.type;\r\n if (t === '' || t === 'none' || t == null) updatePayload.type = null;\r\n }\r\n if (resource === 'media') {\r\n const u = updatePayload as Record<string, unknown>;\r\n delete u.kind;\r\n if (rawBody && typeof rawBody === 'object' && 'parentId' in rawBody) {\r\n let pid: number | null = null;\r\n const p = (rawBody as Record<string, unknown>).parentId;\r\n if (p != null && p !== '') {\r\n const n = Number(p);\r\n if (!Number.isFinite(n)) {\r\n return json({ error: 'Invalid parentId' }, { status: 400 });\r\n }\r\n pid = n;\r\n }\r\n if (pid != null) {\r\n const parent = await repo.findOne({\r\n where: { id: pid, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!parent || (parent as { kind: string }).kind !== 'folder') {\r\n return json({ error: 'parent must be a folder' }, { status: 400 });\r\n }\r\n }\r\n const row = await repo.findOne({\r\n where: { id: numericId, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!row) return json({ message: 'Not found' }, { status: 404 });\r\n if (pid === numericId) {\r\n return json({ error: 'Invalid parentId' }, { status: 400 });\r\n }\r\n if ((row as { kind: string }).kind === 'folder' && pid != null) {\r\n let walk: number | null = pid;\r\n const seen = new Set<number>();\r\n while (walk != null) {\r\n if (walk === numericId) {\r\n return json(\r\n { error: 'Cannot move a folder into itself or a descendant folder' },\r\n { status: 400 }\r\n );\r\n }\r\n if (seen.has(walk)) break;\r\n seen.add(walk);\r\n const anc = await repo.findOne({\r\n where: { id: walk, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n walk = anc ? ((anc as { parentId: number | null }).parentId ?? null) : null;\r\n }\r\n }\r\n u.parentId = pid;\r\n } else {\r\n delete u.parentId;\r\n }\r\n }\r\n if (resource === 'products') {\r\n const currentRow = await repo.findOne({\r\n where: { id: numericId, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!currentRow) return json({ message: 'Not found' }, { status: 404 });\r\n const merged: Record<string, unknown> = { ...(currentRow as Record<string, unknown>), ...updatePayload };\r\n const effSku = normalizeProductSku(merged.sku);\r\n if (effSku) {\r\n const ok = await assertProductSkuUnique(repo, effSku, numericId);\r\n if (!ok) {\r\n return json({ error: 'SKU already exists. Please use a unique SKU.' }, { status: 400 });\r\n }\r\n }\r\n if ('sku' in updatePayload) {\r\n updatePayload.sku = effSku;\r\n }\r\n }\r\n if (resource === 'addresses' && Object.keys(updatePayload).length > 0) {\r\n const currentRow = await repo.findOne({\r\n where: { id: numericId } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!currentRow) return json({ message: 'Not found' }, { status: 404 });\r\n const merged: Record<string, unknown> = {\r\n ...(currentRow as Record<string, unknown>),\r\n ...updatePayload,\r\n };\r\n if (merged.tag === '') merged.tag = null;\r\n const addrErr = validateAndNormalizeAddressRow(merged);\r\n if (addrErr) {\r\n return json({ error: addrErr }, { status: 400 });\r\n }\r\n for (const k of Object.keys(updatePayload)) {\r\n if (k in merged) {\r\n (updatePayload as Record<string, unknown>)[k] = merged[k];\r\n }\r\n }\r\n }\r\n if (Object.keys(updatePayload).length > 0) {\r\n sanitizeBodyForEntity(repo, updatePayload);\r\n await repo.update(numericId, updatePayload as object);\r\n }\r\n const updated = await repo.findOne({ where: { id: numericId } });\r\n if (resource === 'contacts' && updated) {\r\n await syncContactRowToErp(updated as import('typeorm').ObjectLiteral);\r\n }\r\n if (resource === 'products' && updated && getCms) {\r\n const cms = await getCms();\r\n await queueErpProductUpsertIfEnabled(cms, dataSource, entityMap, updated as import('typeorm').ObjectLiteral);\r\n }\r\n return updated ? json(updated) : json({ message: 'Not found' }, { status: 404 });\r\n },\r\n\r\n async DELETE(req: Request, resource: string, id: string) {\r\n const authError = await authz(req, resource, 'delete');\r\n if (authError) return authError;\r\n const entity = entityMap[resource];\r\n if (!entity) {\r\n logCrudClientError('DELETE by id', { reason: 'invalid_resource', resource, id });\r\n return json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n const repo = dataSource.getRepository(entity);\r\n const numericId = Number(id);\r\n if (entityHasSoftDelete(repo)) {\r\n const existing = await repo.findOne({\r\n where: { id: numericId, deleted: false } as import('typeorm').ObjectLiteral,\r\n });\r\n if (!existing) return json({ message: 'Not found' }, { status: 404 });\r\n if (resource === 'contacts') {\r\n const result = await repo.delete(numericId);\r\n if (result.affected === 0) return json({ message: 'Not found' }, { status: 404 });\r\n return json({ message: 'Deleted successfully' }, { status: 200 });\r\n }\r\n let deletedBy: number | null = null;\r\n if (getDeletedByUserId) {\r\n try {\r\n deletedBy = await getDeletedByUserId(req);\r\n } catch {\r\n deletedBy = null;\r\n }\r\n }\r\n await repo.update(numericId, buildSoftDeletePayload(repo.metadata, deletedBy) as object);\r\n return json({ message: 'Deleted successfully' }, { status: 200 });\r\n }\r\n const result = await repo.delete(numericId);\r\n if (result.affected === 0) return json({ message: 'Not found' }, { status: 404 });\r\n return json({ message: 'Deleted successfully' }, { status: 200 });\r\n },\r\n };\r\n}\r\n","import type { ObjectLiteral } from 'typeorm';\r\nimport { queueErp, type CmsAppLike } from './erp-queue';\r\nimport type { ErpPaidOrderDataSource, ErpPaidOrderEntityMap } from './paid-order-erp';\r\n\r\nexport interface ErpContactSyncInput {\r\n name: string;\r\n email: string;\r\n phone?: string | null;\r\n type?: string | null;\r\n company?: string | null;\r\n notes?: string | null;\r\n /** Passed to ERP as `tags` when non-empty (§7c). */\r\n tags?: string[];\r\n}\r\n\r\nfunction splitName(full: string): { firstName: string; lastName: string } {\r\n const t = (full || '').trim();\r\n if (!t) return { firstName: 'Contact', lastName: '' };\r\n const parts = t.split(/\\s+/);\r\n if (parts.length === 1) return { firstName: parts[0]!, lastName: '' };\r\n return { firstName: parts[0]!, lastName: parts.slice(1).join(' ') };\r\n}\r\n\r\n/**\r\n * When ERP is enabled and plugin loaded, enqueue `create-contact` (non-fatal on failure).\r\n * Used for admin CRUD and storefront contact paths — not form submissions (those use lead/opportunity).\r\n */\r\nexport async function queueErpCreateContactIfEnabled(\r\n cms: CmsAppLike,\r\n dataSource: ErpPaidOrderDataSource,\r\n entityMap: ErpPaidOrderEntityMap,\r\n input: ErpContactSyncInput\r\n): Promise<void> {\r\n try {\r\n const configRepo = dataSource.getRepository(entityMap.configs);\r\n const cfgRows = await configRepo.find({ where: { settings: 'erp', deleted: false } as ObjectLiteral });\r\n for (const row of cfgRows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'enabled' && r.value === 'false') return;\r\n }\r\n if (!cms.getPlugin('erp')) return;\r\n\r\n const email = (input.email ?? '').trim();\r\n if (!email) return;\r\n\r\n const { firstName, lastName } = splitName(input.name);\r\n\r\n await queueErp(cms, {\r\n kind: 'createContact',\r\n contact: {\r\n email,\r\n firstName,\r\n lastName,\r\n phone: input.phone?.trim() || undefined,\r\n companyName: input.company?.trim() || undefined,\r\n type: input.type?.trim() || undefined,\r\n notes: input.notes?.trim() || undefined,\r\n tags: input.tags?.length ? [...input.tags] : undefined,\r\n },\r\n });\r\n } catch {\r\n /* non-fatal */\r\n }\r\n}\r\n","import type { ObjectLiteral } from 'typeorm';\r\nimport { queueErp } from './erp-queue';\r\nimport { isErpIntegrationEnabled, type CmsAppLike, type ErpConfigDataSource } from './erp-config-enabled';\r\n\r\nexport async function queueErpProductUpsertIfEnabled(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>,\r\n product: ObjectLiteral\r\n): Promise<void> {\r\n try {\r\n const sku = typeof product.sku === 'string' ? product.sku.trim() : '';\r\n if (!sku) return;\r\n const on = await isErpIntegrationEnabled(cms, dataSource, entityMap);\r\n if (!on) return;\r\n const rawMeta = product.metadata;\r\n let metadata: Record<string, unknown> | undefined;\r\n if (rawMeta && typeof rawMeta === 'object' && !Array.isArray(rawMeta)) {\r\n const { description: _d, ...rest } = rawMeta as Record<string, unknown>;\r\n metadata = Object.keys(rest).length ? rest : undefined;\r\n }\r\n const payload: Record<string, unknown> = {\r\n sku,\r\n title: (product.name as string) || sku,\r\n name: product.name,\r\n hsn_number: product.hsn,\r\n uom: product.uom != null && String(product.uom).trim() ? String(product.uom).trim() : undefined,\r\n type: product.type === 'service' ? 'service' : 'product',\r\n is_active: product.status === 'available',\r\n metadata,\r\n };\r\n await queueErp(cms, { kind: 'productUpsert', product: payload });\r\n } catch {\r\n /* non-fatal */\r\n }\r\n}\r\n","import { Country, State, City } from 'country-state-city';\r\nimport type { ICity, ICountry, IState } from 'country-state-city';\r\n\r\nfunction norm(s: unknown): string {\r\n return typeof s === 'string' ? s.trim() : '';\r\n}\r\n\r\nfunction resolveCountry(input: string): ICountry | undefined {\r\n const t = input.trim();\r\n if (!t) return undefined;\r\n if (t.length === 2) {\r\n const byCode = Country.getCountryByCode(t.toUpperCase());\r\n if (byCode) return byCode;\r\n }\r\n const lower = t.toLowerCase();\r\n return Country.getAllCountries().find((c) => c.name.toLowerCase() === lower);\r\n}\r\n\r\nfunction resolveState(countryIso: string, input: string): IState | undefined {\r\n const t = input.trim();\r\n if (!t || !countryIso) return undefined;\r\n const states = State.getStatesOfCountry(countryIso);\r\n const lower = t.toLowerCase();\r\n return states.find((s) => s.isoCode.toLowerCase() === t.toLowerCase() || s.name.toLowerCase() === lower);\r\n}\r\n\r\nfunction resolveCity(countryIso: string, stateIso: string, input: string): ICity | undefined {\r\n const t = input.trim();\r\n if (!t || !countryIso || !stateIso) return undefined;\r\n const lower = t.toLowerCase();\r\n const cities = City.getCitiesOfState(countryIso, stateIso);\r\n return cities.find((c) => c.name.toLowerCase() === lower);\r\n}\r\n\r\n/** Validates required address fields and country → state → city hierarchy; returns canonical display names. */\r\nexport function assertValidAddressHierarchy(\r\n country: string,\r\n state: string,\r\n city: string\r\n): { ok: true; country: string; state: string; city: string } | { ok: false; error: string } {\r\n const c = resolveCountry(country);\r\n if (!c) return { ok: false, error: 'Invalid or unknown country.' };\r\n const st = resolveState(c.isoCode, state);\r\n if (!st) return { ok: false, error: 'State or province does not match the selected country.' };\r\n const ct = resolveCity(c.isoCode, st.isoCode, city);\r\n if (!ct) return { ok: false, error: 'City does not match the selected state.' };\r\n return { ok: true, country: c.name, state: st.name, city: ct.name };\r\n}\r\n\r\nexport type AddressScalarFields = {\r\n line1: unknown;\r\n line2?: unknown;\r\n postalCode: unknown;\r\n country: unknown;\r\n state: unknown;\r\n city: unknown;\r\n};\r\n\r\n/**\r\n * Ensures required address parts are present and geo data is consistent.\r\n * On success, mutates `row` with trimmed line1/line2/postalCode and canonical country/state/city names.\r\n */\r\nexport function validateAndNormalizeAddressRow(\r\n row: Record<string, unknown>\r\n): string | null {\r\n const line1 = norm(row.line1);\r\n const postalCode = norm(row.postalCode);\r\n const countryIn = norm(row.country);\r\n const stateIn = norm(row.state);\r\n const cityIn = norm(row.city);\r\n\r\n if (!line1) return 'Street address (line 1) is required.';\r\n if (!postalCode) return 'Postal code is required.';\r\n if (!countryIn || !stateIn || !cityIn) return 'Country, state, and city are required.';\r\n\r\n const geo = assertValidAddressHierarchy(countryIn, stateIn, cityIn);\r\n if (!geo.ok) return geo.error;\r\n\r\n row.line1 = line1;\r\n row.line2 = norm(row.line2) || null;\r\n row.postalCode = postalCode;\r\n row.country = geo.country;\r\n row.state = geo.state;\r\n row.city = geo.city;\r\n return null;\r\n}\r\n","import type { DataSource, EntityTarget, ObjectLiteral } from 'typeorm';\r\nimport { IsNull } from 'typeorm';\r\n\r\n/** Links an unclaimed contact (same email, no userId) to the new user after signup or invite. */\r\nexport async function linkUnclaimedContactToUser(\r\n dataSource: DataSource,\r\n contactsEntity: EntityTarget<ObjectLiteral>,\r\n userId: number,\r\n email: string\r\n): Promise<void> {\r\n const repo = dataSource.getRepository(contactsEntity);\r\n const found = await repo.findOne({\r\n where: { email, userId: IsNull(), deleted: false } as ObjectLiteral,\r\n });\r\n if (found) await repo.update((found as { id: number }).id, { userId });\r\n}\r\n","/**\r\n * Auth API handler factories. Inject dataSource + entityMap, sendEmail, hash/compare; optional hooks to customize.\r\n */\r\nimport type { DataSource } from 'typeorm';\r\nimport { linkUnclaimedContactToUser } from '../lib/link-contact-to-user';\r\nimport type { EntityMap } from './crud';\r\n\r\nexport interface AuthHandlersConfig {\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n baseUrl: string;\r\n hashPassword: (plain: string) => Promise<string>;\r\n comparePassword: (plain: string, hash: string) => Promise<boolean>;\r\n}\r\n\r\nexport interface ForgotPasswordConfig extends AuthHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n sendEmail?: (opts: {\r\n to: string;\r\n subject: string;\r\n html: string;\r\n text?: string;\r\n /** Plain reset URL for templated emails (preferred over parsing html). */\r\n resetLink?: string;\r\n }) => Promise<void>;\r\n resetExpiryHours?: number;\r\n afterCreateToken?: (email: string, resetLink: string) => Promise<void>;\r\n}\r\n\r\nexport function createForgotPasswordHandler(config: ForgotPasswordConfig) {\r\n const { dataSource, entityMap, json, baseUrl, sendEmail, resetExpiryHours = 1, afterCreateToken } = config;\r\n return async function POST(request: Request): Promise<Response> {\r\n try {\r\n const body = await request.json().catch(() => ({})) as { email?: string };\r\n const email = typeof body?.email === 'string' ? body.email.trim().toLowerCase() : '';\r\n if (!email) return json({ error: 'Email is required' }, { status: 400 });\r\n\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n const user = await userRepo.findOne({ where: { email }, select: ['email'] });\r\n const msg = 'If an account exists with this email, you will receive a reset link shortly.';\r\n if (!user) return json({ message: msg }, { status: 200 });\r\n\r\n const crypto = await import('crypto');\r\n const token = crypto.randomBytes(32).toString('hex');\r\n const expiresAt = new Date(Date.now() + (resetExpiryHours * 60 * 60 * 1000));\r\n const tokenRepo = dataSource.getRepository(entityMap.password_reset_tokens);\r\n await tokenRepo.save(tokenRepo.create({ email: user.email, token, expiresAt }));\r\n const resetLink = `${baseUrl}/admin/reset-password?token=${token}`;\r\n\r\n if (sendEmail)\r\n await sendEmail({\r\n to: user.email,\r\n subject: 'Password reset',\r\n html: `<a href=\"${resetLink}\">Reset password</a>`,\r\n text: resetLink,\r\n resetLink,\r\n });\r\n if (afterCreateToken) await afterCreateToken(user.email, resetLink);\r\n return json({ message: msg }, { status: 200 });\r\n } catch (err) {\r\n return json({ error: 'Something went wrong. Please try again.' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface SetPasswordConfig extends AuthHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n minPasswordLength?: number;\r\n beforeUpdate?: (email: string, userId: number) => Promise<void>;\r\n}\r\n\r\nexport function createSetPasswordHandler(config: SetPasswordConfig) {\r\n const { dataSource, entityMap, json, hashPassword, minPasswordLength = 6, beforeUpdate } = config;\r\n return async function POST(request: Request): Promise<Response> {\r\n try {\r\n const body = await request.json().catch(() => ({})) as { token?: string; newPassword?: string };\r\n const { token, newPassword } = body;\r\n if (!token || !newPassword) return json({ error: 'Token and new password are required' }, { status: 400 });\r\n if (newPassword.length < minPasswordLength) return json({ error: 'Password must be at least 6 characters' }, { status: 400 });\r\n\r\n const tokenRepo = dataSource.getRepository(entityMap.password_reset_tokens);\r\n const record = await tokenRepo.findOne({ where: { token } });\r\n if (!record || record.expiresAt < new Date()) return json({ error: 'Invalid or expired reset link. Please request a new one.' }, { status: 400 });\r\n\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n const user = await userRepo.findOne({ where: { email: record.email }, select: ['id'] });\r\n if (!user) return json({ error: 'User not found' }, { status: 400 });\r\n\r\n if (beforeUpdate) await beforeUpdate(record.email, user.id);\r\n const hashedPassword = await hashPassword(newPassword);\r\n await userRepo.update(user.id, { password: hashedPassword, updatedAt: new Date() });\r\n await tokenRepo.delete({ email: record.email });\r\n return json({ message: 'Password updated successfully. You can now sign in.' });\r\n } catch {\r\n return json({ error: 'Something went wrong. Please try again.' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface InviteAcceptConfig extends AuthHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n beforeActivate?: (email: string, userId: number) => Promise<void>;\r\n}\r\n\r\n/** Decode invite token (base64 email) and set password + unblock user */\r\nexport function createInviteAcceptHandler(config: InviteAcceptConfig) {\r\n const { dataSource, entityMap, json, hashPassword, beforeActivate } = config;\r\n return async function POST(request: Request): Promise<Response> {\r\n try {\r\n const body = await request.json().catch(() => ({})) as { token?: string; password?: string };\r\n const { token, password } = body;\r\n if (!token || !password) return json({ error: 'Missing required fields: token, password' }, { status: 400 });\r\n\r\n let email: string;\r\n try {\r\n email = Buffer.from(token, 'base64').toString('utf8');\r\n } catch {\r\n return json({ error: 'Invalid or expired invite token' }, { status: 400 });\r\n }\r\n\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n const user = await userRepo.findOne({ where: { email }, select: ['id', 'blocked'] });\r\n if (!user) return json({ error: 'User not found' }, { status: 400 });\r\n if (!user.blocked) return json({ error: 'User is already active' }, { status: 400 });\r\n\r\n if (entityMap.contacts) {\r\n await linkUnclaimedContactToUser(dataSource, entityMap.contacts, user.id, email);\r\n }\r\n if (beforeActivate) await beforeActivate(email, user.id);\r\n const hashedPassword = await hashPassword(password);\r\n await userRepo.update(user.id, { password: hashedPassword, blocked: false });\r\n return json({ message: 'User account activated successfully' }, { status: 200 });\r\n } catch (err) {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface ChangePasswordConfig extends AuthHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n getSession: () => Promise<{ user?: { email?: string | null } } | null>;\r\n minPasswordLength?: number;\r\n beforeUpdate?: (email: string) => Promise<void>;\r\n}\r\n\r\nexport function createChangePasswordHandler(config: ChangePasswordConfig) {\r\n const { dataSource, entityMap, json, comparePassword, hashPassword, getSession, minPasswordLength = 6, beforeUpdate } = config;\r\n return async function POST(request: Request): Promise<Response> {\r\n try {\r\n const session = await getSession();\r\n if (!session?.user?.email) return json({ error: 'Unauthorized' }, { status: 401 });\r\n\r\n const body = await request.json().catch(() => ({})) as { currentPassword?: string; newPassword?: string };\r\n const { currentPassword, newPassword } = body;\r\n if (!currentPassword || !newPassword) return json({ error: 'Current password and new password are required' }, { status: 400 });\r\n if (newPassword.length < minPasswordLength) return json({ error: 'New password must be at least 6 characters long' }, { status: 400 });\r\n\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n const user = await userRepo.findOne({ where: { email: session.user.email }, select: ['password'] });\r\n if (!user) return json({ error: 'User not found' }, { status: 404 });\r\n if (!user.password) return json({ error: 'Current password is incorrect' }, { status: 400 });\r\n const valid = await comparePassword(currentPassword, user.password);\r\n if (!valid) return json({ error: 'Current password is incorrect' }, { status: 400 });\r\n\r\n if (beforeUpdate) await beforeUpdate(session.user.email);\r\n const hashedPassword = await hashPassword(newPassword);\r\n await userRepo.update({ email: session.user.email }, { password: hashedPassword, updatedAt: new Date() });\r\n return json({ message: 'Password updated successfully' });\r\n } catch {\r\n return json({ error: 'Internal server error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface UserAuthApiConfig\r\n extends ForgotPasswordConfig,\r\n Omit<SetPasswordConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword'>,\r\n Omit<InviteAcceptConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword'>,\r\n Omit<ChangePasswordConfig, 'dataSource' | 'entityMap' | 'json' | 'baseUrl' | 'hashPassword' | 'comparePassword' | 'beforeUpdate' | 'getSession'> {\r\n getSession?: () => Promise<{ user?: { email?: string | null } } | null>;\r\n beforeChangePasswordUpdate?: (email: string) => Promise<void>;\r\n}\r\n\r\nconst USER_AUTH_PATHS = ['forgot-password', 'invite', 'set-password', 'reset-password'] as const;\r\n\r\n/**\r\n * Single router for all user-auth APIs. Mount in the app once.\r\n * Use when you have no users/[id] route (else Next.js gives [id] precedence and \"forgot-password\" would match as id).\r\n * Path is the segment after the mount (e.g. \"forgot-password\"). Returns 404 for unknown paths.\r\n */\r\nexport function createUserAuthApiRouter(config: UserAuthApiConfig) {\r\n const forgot = createForgotPasswordHandler(config);\r\n const setPass = createSetPasswordHandler(config);\r\n const invite = createInviteAcceptHandler(config);\r\n const changePass = config.getSession\r\n ? createChangePasswordHandler({\r\n ...config,\r\n getSession: config.getSession,\r\n beforeUpdate: config.beforeChangePasswordUpdate,\r\n })\r\n : null;\r\n\r\n return {\r\n async POST(req: Request, pathname: string): Promise<Response> {\r\n const path = pathname.replace(/\\/$/, '');\r\n if (!USER_AUTH_PATHS.includes(path as (typeof USER_AUTH_PATHS)[number])) {\r\n return config.json({ error: 'Not found' }, { status: 404 });\r\n }\r\n if (path === 'forgot-password') return forgot(req);\r\n if (path === 'set-password') return setPass(req);\r\n if (path === 'invite') return invite(req);\r\n if (path === 'reset-password' && changePass) return changePass(req);\r\n return config.json({ error: 'Not found' }, { status: 404 });\r\n },\r\n };\r\n}\r\n","/**\r\n * CMS API handlers: dashboard, analytics, upload, blog/form by slug, users (list/create/get/update/delete/regenerate-invite/avatar/profile).\r\n * All accept injectable deps; upload supports S3 or local.\r\n */\r\nimport type { DataSource, EntityTarget } from 'typeorm';\r\nimport { linkUnclaimedContactToUser } from '../lib/link-contact-to-user';\r\nimport { MoreThanOrEqual, ILike, In } from 'typeorm';\r\nimport type { EntityMap } from './crud';\r\nimport type { EntityCrudAction } from '../auth/permission-entities';\r\nimport type { SessionUser } from '../auth/helpers';\r\nimport { queueEmail } from '../plugins/email/email-queue';\r\nimport type { CompanyDetails } from '../plugins/email/templates/types';\r\nimport { queueErp } from '../plugins/erp/erp-queue';\r\nimport type { ERPSubmissionService } from '../plugins/erp/erp-submission';\r\nimport { assertCaptchaOk } from '../plugins/captcha/assert';\r\nimport { llmAgentToChatAgentOptions, type LlmAgent } from '../entities/llm-agent.entity';\r\nimport type { LlmAgentOptions, LlmMessage } from '../plugins/llm/llm-service';\r\n\r\nexport type RequireEntityPermissionFn = (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;\r\n\r\n/** Avoid duplicating the current user turn when the DB already includes it (see postMessage flow). */\r\nfunction historyBeforeCurrentUser(history: LlmMessage[], currentUserContent: string): LlmMessage[] {\r\n const last = history[history.length - 1];\r\n if (last?.role === 'user' && last.content === currentUserContent) {\r\n return history.slice(0, -1);\r\n }\r\n return [...history];\r\n}\r\n\r\n/**\r\n * Optional JSON in `LlmAgent.validationRules`. Used for programmatic checks before the LLM call.\r\n * For natural-language output rules, use `guardrails` / `outputRules` / `outputInstructions` (merged into system prompt).\r\n */\r\nexport type LlmAgentValidationRulesJson = {\r\n maxUserChars?: number;\r\n maxMessageLength?: number;\r\n minUserChars?: number;\r\n minMessageLength?: number;\r\n blockedSubstrings?: string[];\r\n /** Shown to the model as output guardrails (first non-empty of guardrails | outputRules | outputInstructions wins). */\r\n guardrails?: string;\r\n outputRules?: string;\r\n outputInstructions?: string;\r\n};\r\n\r\nexport type ParsedLlmAgentValidation = {\r\n /** Subset used for length / substring checks only. */\r\n structured: Pick<\r\n LlmAgentValidationRulesJson,\r\n 'maxUserChars' | 'maxMessageLength' | 'minUserChars' | 'minMessageLength' | 'blockedSubstrings'\r\n >;\r\n /** Appended to system prompt so the model follows output guardrails. */\r\n guardrailsForPrompt: string | null;\r\n};\r\n\r\nfunction pickStructuredRules(rules: LlmAgentValidationRulesJson): ParsedLlmAgentValidation['structured'] {\r\n return {\r\n maxUserChars: rules.maxUserChars,\r\n maxMessageLength: rules.maxMessageLength,\r\n minUserChars: rules.minUserChars,\r\n minMessageLength: rules.minMessageLength,\r\n blockedSubstrings: rules.blockedSubstrings,\r\n };\r\n}\r\n\r\nfunction guardrailsTextFromJsonObject(rules: LlmAgentValidationRulesJson): string | null {\r\n const g =\r\n (typeof rules.guardrails === 'string' && rules.guardrails.trim()) ||\r\n (typeof rules.outputRules === 'string' && rules.outputRules.trim()) ||\r\n (typeof rules.outputInstructions === 'string' && rules.outputInstructions.trim()) ||\r\n '';\r\n return g || null;\r\n}\r\n\r\n/**\r\n * - Valid JSON object: structural keys → validation; `guardrails` / `outputRules` / `outputInstructions` → prompt suffix.\r\n * - Not JSON: entire string is treated as prose guardrails for the prompt (no programmatic rules unless you use JSON).\r\n */\r\nexport function parseLlmAgentValidationRules(\r\n validationRulesText: string | null | undefined\r\n): ParsedLlmAgentValidation {\r\n const raw = validationRulesText?.trim();\r\n if (!raw) return { structured: {}, guardrailsForPrompt: null };\r\n try {\r\n const parsed = JSON.parse(raw) as unknown;\r\n if (typeof parsed === 'string') {\r\n const s = parsed.trim();\r\n return { structured: {}, guardrailsForPrompt: s || null };\r\n }\r\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\r\n return { structured: {}, guardrailsForPrompt: raw };\r\n }\r\n const rules = parsed as LlmAgentValidationRulesJson;\r\n return {\r\n structured: pickStructuredRules(rules),\r\n guardrailsForPrompt: guardrailsTextFromJsonObject(rules),\r\n };\r\n } catch {\r\n return { structured: {}, guardrailsForPrompt: raw };\r\n }\r\n}\r\n\r\nexport function validateUserMessageAgainstStructuredRules(\r\n message: string,\r\n structured: ParsedLlmAgentValidation['structured']\r\n): { ok: true } | { ok: false; error: string } {\r\n const maxLen = structured.maxUserChars ?? structured.maxMessageLength;\r\n if (typeof maxLen === 'number' && Number.isFinite(maxLen) && maxLen >= 0 && message.length > maxLen) {\r\n return { ok: false, error: `Message exceeds maximum length (${maxLen} characters)` };\r\n }\r\n\r\n const minLen = structured.minUserChars ?? structured.minMessageLength;\r\n if (typeof minLen === 'number' && Number.isFinite(minLen) && minLen > 0 && message.length < minLen) {\r\n return { ok: false, error: `Message is shorter than minimum length (${minLen} characters)` };\r\n }\r\n\r\n const blocked = structured.blockedSubstrings;\r\n if (Array.isArray(blocked) && blocked.length > 0) {\r\n const lower = message.toLowerCase();\r\n for (const s of blocked) {\r\n if (typeof s !== 'string' || !s.trim()) continue;\r\n if (lower.includes(s.toLowerCase())) {\r\n return { ok: false, error: 'Message contains disallowed content' };\r\n }\r\n }\r\n }\r\n\r\n return { ok: true };\r\n}\r\n\r\n/** Parses `validationRules` then runs programmatic checks only. */\r\nexport function validateUserMessageAgainstAgentRules(\r\n message: string,\r\n validationRulesText: string | null | undefined\r\n): { ok: true } | { ok: false; error: string } {\r\n const { structured } = parseLlmAgentValidationRules(validationRulesText);\r\n return validateUserMessageAgainstStructuredRules(message, structured);\r\n}\r\n\r\n/** Merges guardrails prose into the system instruction sent to the model. */\r\nexport function mergeGuardrailsIntoSystemPrompt(\r\n baseSystem: string | undefined,\r\n guardrailsForPrompt: string | null\r\n): string {\r\n const g = guardrailsForPrompt?.trim();\r\n const b = (baseSystem ?? '').trim();\r\n if (!g) return b;\r\n const block = `### Output guardrails (follow in every reply)\\n${g}`;\r\n return b ? `${b}\\n\\n${block}` : block;\r\n}\r\n\r\nexport interface CmsHandlersBase {\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n requireAuth: (req: Request) => Promise<Response | null>;\r\n requireEntityPermission?: RequireEntityPermissionFn;\r\n}\r\n\r\nexport interface DashboardStatsConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n requirePermission?: (req: Request, permission: string) => Promise<Response | null>;\r\n}\r\n\r\nexport function createDashboardStatsHandler(config: DashboardStatsConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requirePermission, requireEntityPermission } = config;\r\n return async function GET(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'dashboard', 'read');\r\n if (pe) return pe;\r\n }\r\n if (requirePermission) {\r\n const permErr = await requirePermission(req, 'view_dashboard');\r\n if (permErr) return permErr;\r\n }\r\n try {\r\n const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);\r\n const repo = (name: string) => entityMap[name] ? dataSource.getRepository(entityMap[name]) : undefined;\r\n const [contactsCount, formsCount, formSubmissionsCount, usersCount, blogsCount, recentContacts, recentSubmissions, contactTypeRows] = await Promise.all([\r\n repo('contacts')?.count({ where: { deleted: false } }) ?? 0,\r\n repo('forms')?.count({ where: { deleted: false } }) ?? 0,\r\n repo('form_submissions')?.count() ?? 0,\r\n repo('users')?.count({ where: { deleted: false } }) ?? 0,\r\n repo('blogs')?.count({ where: { deleted: false } }) ?? 0,\r\n repo('contacts')?.count({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(sevenDaysAgo) },\r\n }) ?? 0,\r\n repo('form_submissions')?.count({ where: { createdAt: MoreThanOrEqual(sevenDaysAgo) } }) ?? 0,\r\n repo('contacts')\r\n ?.createQueryBuilder('c')\r\n .select(\"COALESCE(NULLIF(TRIM(c.type), ''), 'unknown')\", 'type')\r\n .addSelect('COUNT(*)', 'count')\r\n .where('c.deleted = :deleted', { deleted: false })\r\n .groupBy(\"COALESCE(NULLIF(TRIM(c.type), ''), 'unknown')\")\r\n .getRawMany<{ type: string; count: string }>() ?? [],\r\n ]);\r\n return json({\r\n contacts: { total: contactsCount, recent: recentContacts },\r\n forms: { total: formsCount, submissions: formSubmissionsCount, recentSubmissions },\r\n users: usersCount,\r\n blogs: blogsCount,\r\n contactTypes: (contactTypeRows ?? []).map((row) => ({\r\n type: row.type || 'unknown',\r\n count: Number(row.count || 0),\r\n })),\r\n });\r\n } catch (err) {\r\n return json({ error: 'Failed to fetch dashboard stats' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface EcommerceAnalyticsConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n}\r\n\r\ntype SalesTrendPoint = { date: string; value: number; orders: number };\r\ntype ReturnsTrendPoint = { date: string; value: number; count: number };\r\n\r\nfunction toNum(v: unknown): number {\r\n const n = typeof v === 'number' ? v : Number(v ?? 0);\r\n return Number.isFinite(n) ? n : 0;\r\n}\r\n\r\nfunction toIsoDate(d: Date): string {\r\n return d.toISOString().slice(0, 10);\r\n}\r\n\r\nexport function createEcommerceAnalyticsHandler(config: EcommerceAnalyticsConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n return async function GET(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'analytics', 'read');\r\n if (pe) return pe;\r\n }\r\n if (!entityMap.orders || !entityMap.order_items || !entityMap.payments || !entityMap.products) {\r\n return json({ error: 'Store analytics unavailable' }, { status: 404 });\r\n }\r\n try {\r\n const url = new URL(req.url);\r\n const rawDays = parseInt(url.searchParams.get('days') || '30', 10);\r\n const days = Number.isFinite(rawDays) ? Math.min(365, Math.max(7, rawDays)) : 30;\r\n const end = new Date();\r\n const start = new Date(end.getTime() - days * 24 * 60 * 60 * 1000);\r\n\r\n const orderRepo = dataSource.getRepository(entityMap.orders);\r\n const paymentRepo = dataSource.getRepository(entityMap.payments);\r\n const itemRepo = dataSource.getRepository(entityMap.order_items);\r\n const productRepo = dataSource.getRepository(entityMap.products);\r\n\r\n const [salesOrders, returnOrders, replacementOrders, payments, products] = await Promise.all([\r\n orderRepo.find({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(start), orderKind: 'sale', status: In(['confirmed', 'processing', 'completed']) } as object,\r\n select: ['id', 'contactId', 'createdAt', 'subtotal', 'discount', 'tax', 'total', 'status'],\r\n }),\r\n orderRepo.find({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(start), orderKind: 'return' } as object,\r\n select: ['id', 'createdAt', 'total'],\r\n }),\r\n orderRepo.find({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(start), orderKind: 'replacement' } as object,\r\n select: ['id', 'createdAt', 'total'],\r\n }),\r\n paymentRepo.find({\r\n where: { deleted: false, createdAt: MoreThanOrEqual(start) } as object,\r\n select: ['id', 'status', 'method', 'amount', 'createdAt'],\r\n }),\r\n productRepo.find({\r\n where: { deleted: false } as object,\r\n select: ['id', 'name', 'quantity'],\r\n }),\r\n ]);\r\n\r\n const saleOrderIds = salesOrders.map((o) => o.id);\r\n const orderItems = saleOrderIds.length\r\n ? await itemRepo.find({\r\n where: { orderId: In(saleOrderIds) } as object,\r\n select: ['id', 'orderId', 'productId', 'quantity', 'total'],\r\n })\r\n : [];\r\n\r\n const grossSales = salesOrders.reduce((sum, o) => sum + toNum(o.subtotal), 0);\r\n const discounts = salesOrders.reduce((sum, o) => sum + toNum(o.discount), 0);\r\n const taxes = salesOrders.reduce((sum, o) => sum + toNum(o.tax), 0);\r\n const returnsValue = returnOrders.reduce((sum, o) => sum + toNum(o.total), 0);\r\n const replacementsValue = replacementOrders.reduce((sum, o) => sum + toNum(o.total), 0);\r\n const netSales = grossSales - discounts - returnsValue;\r\n const ordersCount = salesOrders.length;\r\n const aov = ordersCount > 0 ? netSales / ordersCount : 0;\r\n const returnRate = ordersCount > 0 ? (returnOrders.length / ordersCount) * 100 : 0;\r\n\r\n const salesByDate = new Map<string, { value: number; orders: number }>();\r\n const returnsByDate = new Map<string, { value: number; count: number }>();\r\n for (const o of salesOrders) {\r\n const key = toIsoDate(new Date(o.createdAt));\r\n const row = salesByDate.get(key) ?? { value: 0, orders: 0 };\r\n row.value += toNum(o.total);\r\n row.orders += 1;\r\n salesByDate.set(key, row);\r\n }\r\n for (const o of returnOrders) {\r\n const key = toIsoDate(new Date(o.createdAt));\r\n const row = returnsByDate.get(key) ?? { value: 0, count: 0 };\r\n row.value += toNum(o.total);\r\n row.count += 1;\r\n returnsByDate.set(key, row);\r\n }\r\n\r\n const salesOverTime: SalesTrendPoint[] = [];\r\n const returnsTrend: ReturnsTrendPoint[] = [];\r\n for (let i = days - 1; i >= 0; i--) {\r\n const d = new Date(end.getTime() - i * 24 * 60 * 60 * 1000);\r\n const key = toIsoDate(d);\r\n const sales = salesByDate.get(key) ?? { value: 0, orders: 0 };\r\n const returns = returnsByDate.get(key) ?? { value: 0, count: 0 };\r\n salesOverTime.push({ date: key, value: Number(sales.value.toFixed(2)), orders: sales.orders });\r\n returnsTrend.push({ date: key, value: Number(returns.value.toFixed(2)), count: returns.count });\r\n }\r\n\r\n const productNameMap = new Map<number, string>();\r\n for (const p of products) productNameMap.set(Number(p.id), (p.name || `Product #${p.id}`).trim());\r\n const productAgg = new Map<number, { name: string; units: number; sales: number }>();\r\n for (const item of orderItems) {\r\n const productId = Number(item.productId);\r\n const productName = productNameMap.get(productId) || `Product #${productId}`;\r\n const row = productAgg.get(productId) ?? { name: productName, units: 0, sales: 0 };\r\n row.units += toNum(item.quantity);\r\n row.sales += toNum(item.total);\r\n productAgg.set(productId, row);\r\n }\r\n const topProducts = Array.from(productAgg.values())\r\n .sort((a, b) => b.sales - a.sales)\r\n .slice(0, 5)\r\n .map((p) => ({ ...p, sales: Number(p.sales.toFixed(2)) }));\r\n\r\n const allSaleOrderContactIds = Array.from(new Set(salesOrders.map((o) => Number(o.contactId)).filter((n) => Number.isInteger(n) && n > 0)));\r\n const allTimeCounts = allSaleOrderContactIds.length\r\n ? await orderRepo\r\n .createQueryBuilder('o')\r\n .select('o.contactId', 'contactId')\r\n .addSelect('COUNT(*)', 'total')\r\n .where('o.deleted = :deleted', { deleted: false })\r\n .andWhere('o.orderKind = :orderKind', { orderKind: 'sale' })\r\n .andWhere('o.contactId IN (:...contactIds)', { contactIds: allSaleOrderContactIds })\r\n .groupBy('o.contactId')\r\n .getRawMany<{ contactId: string; total: string }>()\r\n : [];\r\n const countMap = new Map<number, number>();\r\n for (const c of allTimeCounts) countMap.set(Number(c.contactId), Number(c.total));\r\n const purchasingCustomers = allSaleOrderContactIds.length;\r\n const returningCustomers = allSaleOrderContactIds.filter((id) => (countMap.get(id) ?? 0) > 1).length;\r\n const newCustomers = Math.max(0, purchasingCustomers - returningCustomers);\r\n const returningCustomerRate = purchasingCustomers > 0 ? (returningCustomers / purchasingCustomers) * 100 : 0;\r\n\r\n const totalPayments = payments.length;\r\n const completedPayments = payments.filter((p) => p.status === 'completed').length;\r\n const failedPayments = payments.filter((p) => p.status === 'failed').length;\r\n const paymentSuccessRate = totalPayments > 0 ? (completedPayments / totalPayments) * 100 : 0;\r\n const paymentMethodMap = new Map<string, { method: string; count: number; amount: number }>();\r\n for (const p of payments) {\r\n const method = (p.method || 'unknown').toLowerCase();\r\n const row = paymentMethodMap.get(method) ?? { method, count: 0, amount: 0 };\r\n row.count += 1;\r\n row.amount += toNum(p.amount);\r\n paymentMethodMap.set(method, row);\r\n }\r\n const paymentMethods = Array.from(paymentMethodMap.values())\r\n .sort((a, b) => b.count - a.count)\r\n .map((p) => ({ ...p, amount: Number(p.amount.toFixed(2)) }));\r\n\r\n const totalInventory = products.reduce((sum, p) => sum + toNum(p.quantity), 0);\r\n const outOfStockCount = products.filter((p) => toNum(p.quantity) <= 0).length;\r\n const lowStockCount = products.filter((p) => toNum(p.quantity) > 0 && toNum(p.quantity) <= 5).length;\r\n const inventoryRisk = {\r\n outOfStockCount,\r\n lowStockCount,\r\n totalInventory,\r\n };\r\n\r\n return json({\r\n rangeDays: days,\r\n kpis: {\r\n netSales: Number(netSales.toFixed(2)),\r\n grossSales: Number(grossSales.toFixed(2)),\r\n ordersPlaced: ordersCount,\r\n averageOrderValue: Number(aov.toFixed(2)),\r\n returningCustomerRate: Number(returningCustomerRate.toFixed(2)),\r\n returnRate: Number(returnRate.toFixed(2)),\r\n returnValue: Number(returnsValue.toFixed(2)),\r\n discounts: Number(discounts.toFixed(2)),\r\n taxes: Number(taxes.toFixed(2)),\r\n paymentSuccessRate: Number(paymentSuccessRate.toFixed(2)),\r\n },\r\n salesOverTime,\r\n topProducts,\r\n customerMix: {\r\n newCustomers,\r\n returningCustomers,\r\n repeatPurchaseRate: Number(returningCustomerRate.toFixed(2)),\r\n },\r\n returnsTrend,\r\n paymentPerformance: {\r\n successCount: completedPayments,\r\n failedCount: failedPayments,\r\n successRate: Number(paymentSuccessRate.toFixed(2)),\r\n methods: paymentMethods,\r\n },\r\n conversionProxy: {\r\n sessions: 0,\r\n checkoutStarted: 0,\r\n ordersPlaced: ordersCount,\r\n },\r\n salesBreakdown: {\r\n sales: { count: ordersCount, value: Number(grossSales.toFixed(2)) },\r\n returns: { count: returnOrders.length, value: Number(returnsValue.toFixed(2)) },\r\n replacements: { count: replacementOrders.length, value: Number(replacementsValue.toFixed(2)) },\r\n },\r\n geoPerformance: [],\r\n inventoryRisk,\r\n });\r\n } catch {\r\n return json({ error: 'Failed to fetch ecommerce analytics' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface AnalyticsHandlerConfig extends CmsHandlersBase {\r\n getAnalyticsData?: (days: number) => Promise<unknown>;\r\n getPropertyId?: () => ({ currentViewId?: string; [k: string]: unknown });\r\n getPermissions?: () => ({ serviceAccountEmail?: string; currentViewId?: string; [k: string]: unknown });\r\n}\r\n\r\nexport function createAnalyticsHandlers(config: AnalyticsHandlerConfig) {\r\n const { json, getAnalyticsData, getPropertyId, getPermissions } = config;\r\n return {\r\n async GET(req: Request): Promise<Response> {\r\n if (!getAnalyticsData) return json({ error: 'Analytics not configured' }, { status: 404 });\r\n try {\r\n const url = new URL(req.url);\r\n const days = parseInt(url.searchParams.get('days') || '30', 10);\r\n const data = await getAnalyticsData(days);\r\n return json(data);\r\n } catch (err: unknown) {\r\n const msg = err instanceof Error ? err.message : '';\r\n if (msg.includes('authentication credential')) return json({ error: 'Google Analytics authentication failed.' }, { status: 401 });\r\n if (msg.includes('sufficient permissions')) return json({ error: 'Service account does not have access.' }, { status: 403 });\r\n return json({ error: 'Failed to fetch analytics data' }, { status: 500 });\r\n }\r\n },\r\n propertyId: async (): Promise<Response> => {\r\n const payload = getPropertyId ? getPropertyId() : { currentViewId: process.env.GOOGLE_ANALYTICS_VIEW_ID };\r\n return json({ message: 'Property ID Information', ...payload });\r\n },\r\n permissions: async (): Promise<Response> => {\r\n const payload = getPermissions ? getPermissions() : {\r\n serviceAccountEmail: process.env.GOOGLE_ANALYTICS_CLIENT_EMAIL,\r\n currentViewId: process.env.GOOGLE_ANALYTICS_VIEW_ID,\r\n };\r\n return json({ message: 'Permission Troubleshooting Guide', ...payload });\r\n },\r\n };\r\n}\r\n\r\nimport type { StorageService } from '../plugins/storage';\r\nimport { sanitizeMediaFolderPath } from '../lib/media-folder-path';\r\nimport { relativePathFromMediaParentId } from '../lib/media-parent-path';\r\nimport { extractZipMediaIntoParentTree } from '../lib/media-zip-extract';\r\n\r\nexport type { StorageService };\r\n\r\nexport interface UploadHandlerConfig extends CmsHandlersBase {\r\n /** Storage plugin instance or getter (e.g. () => getCms().then(c => c.getPlugin('storage'))). If not set, uses local fallback. */\r\n storage?: StorageService | (() => StorageService | undefined) | (() => Promise<StorageService | undefined>);\r\n /** Fallback when storage not set: dir relative to cwd (e.g. \"public/uploads\") */\r\n localUploadDir?: string;\r\n allowedTypes?: string[];\r\n maxSizeBytes?: number;\r\n /** Resolve folder chain for `parentId` (merged from createCmsApiHandler when omitted). */\r\n dataSource?: DataSource;\r\n entityMap?: EntityMap;\r\n}\r\n\r\nexport function createUploadHandler(config: UploadHandlerConfig) {\r\n const {\r\n json,\r\n requireAuth,\r\n requireEntityPermission,\r\n storage,\r\n localUploadDir = 'public/uploads',\r\n allowedTypes,\r\n maxSizeBytes = 10 * 1024 * 1024,\r\n dataSource,\r\n entityMap,\r\n } = config;\r\n const allowed = allowedTypes ?? [\r\n 'image/jpeg',\r\n 'image/png',\r\n 'image/gif',\r\n 'image/webp',\r\n 'application/pdf',\r\n 'text/plain',\r\n 'application/zip',\r\n 'application/x-zip-compressed',\r\n ];\r\n return async function POST(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'upload', 'create');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const formData = await req.formData();\r\n const file = formData.get('file') as File | null;\r\n if (!file) return json({ error: 'No file uploaded' }, { status: 400 });\r\n if (!allowed.includes(file.type)) return json({ error: 'File type not allowed' }, { status: 400 });\r\n const defaultMax = 10 * 1024 * 1024;\r\n const maxZipBytes = 80 * 1024 * 1024;\r\n const baseMax = maxSizeBytes ?? defaultMax;\r\n const effectiveMax =\r\n file.type === 'application/zip' || file.type === 'application/x-zip-compressed'\r\n ? Math.max(baseMax, maxZipBytes)\r\n : baseMax;\r\n if (file.size > effectiveMax) return json({ error: 'File size exceeds limit' }, { status: 400 });\r\n const parentRaw = formData.get('parentId');\r\n let parentId: number | null = null;\r\n if (parentRaw != null && String(parentRaw).trim() !== '') {\r\n const n = Number(parentRaw);\r\n if (!Number.isFinite(n)) return json({ error: 'Invalid parentId' }, { status: 400 });\r\n parentId = n;\r\n }\r\n let folder = '';\r\n if (parentId != null) {\r\n if (!dataSource || !entityMap?.media) {\r\n return json({ error: 'Upload handler needs dataSource and entityMap for folder uploads' }, { status: 400 });\r\n }\r\n const repo = dataSource.getRepository(entityMap.media);\r\n const p = await repo.findOne({ where: { id: parentId } });\r\n if (!p || (p as { kind: string }).kind !== 'folder') {\r\n return json({ error: 'parent must be a folder' }, { status: 400 });\r\n }\r\n folder = await relativePathFromMediaParentId(dataSource, entityMap, parentId);\r\n } else {\r\n const folderRawLegacy = formData.get('folder') ?? formData.get('folderPath');\r\n if (folderRawLegacy && typeof folderRawLegacy === 'string' && folderRawLegacy.trim()) {\r\n folder = sanitizeMediaFolderPath(folderRawLegacy);\r\n }\r\n }\r\n const buffer = Buffer.from(await file.arrayBuffer());\r\n const fileName = `${Date.now()}-${file.name}`;\r\n const contentType = file.type || 'application/octet-stream';\r\n const relativeUnderUploads = folder ? `${folder}/${fileName}` : fileName;\r\n const raw = typeof storage === 'function' ? storage() : storage;\r\n const storageService = raw instanceof Promise ? await raw : raw;\r\n if (storageService) {\r\n const fileUrl = await storageService.upload(buffer, `uploads/${relativeUnderUploads}`, contentType);\r\n return json({ filePath: fileUrl, parentId });\r\n }\r\n const fs = await import('fs/promises');\r\n const path = await import('path');\r\n const dir = path.join(process.cwd(), localUploadDir);\r\n const filePath = path.join(dir, relativeUnderUploads);\r\n await fs.mkdir(path.dirname(filePath), { recursive: true });\r\n await fs.writeFile(filePath, buffer);\r\n const urlRel = `${localUploadDir.replace(/^\\/+/, '').replace(/\\\\/g, '/')}/${relativeUnderUploads.replace(/\\\\/g, '/')}`;\r\n return json({ filePath: `/${urlRel}`, parentId });\r\n } catch (err) {\r\n return json({ error: 'File upload failed' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\n/** POST /api/media/extract/:id — expand a zip media row into folders/files under the zip’s parent folder. */\r\nexport function createMediaZipExtractHandler(config: UploadHandlerConfig) {\r\n const { json, requireAuth, requireEntityPermission, storage, localUploadDir = 'public/uploads', dataSource, entityMap } =\r\n config;\r\n return async function POST(_req: Request, zipMediaId: string): Promise<Response> {\r\n const authErr = await requireAuth(_req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(_req, 'media', 'create');\r\n if (pe) return pe;\r\n }\r\n if (!dataSource || !entityMap?.media) {\r\n return json({ error: 'Media extract requires dataSource and entityMap' }, { status: 500 });\r\n }\r\n const id = Number(zipMediaId);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const repo = dataSource.getRepository(entityMap.media);\r\n const row = await repo.findOne({ where: { id } });\r\n if (!row) return json({ error: 'Not found' }, { status: 404 });\r\n try {\r\n const raw = typeof storage === 'function' ? storage() : storage;\r\n const storageService = raw instanceof Promise ? await raw : raw;\r\n const result = await extractZipMediaIntoParentTree({\r\n dataSource,\r\n entityMap,\r\n zipMediaRow: row,\r\n storage: storageService,\r\n localUploadDir,\r\n });\r\n return json({ ok: true, ...result });\r\n } catch (e) {\r\n const msg = e instanceof Error ? e.message : 'Extract failed';\r\n return json({ error: msg }, { status: 400 });\r\n }\r\n };\r\n}\r\n\r\nexport interface BlogBySlugConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n}\r\n\r\nexport function createBlogBySlugHandler(config: BlogBySlugConfig) {\r\n const { dataSource, entityMap, json } = config;\r\n return async function GET(_req: Request, slug: string): Promise<Response> {\r\n try {\r\n const blogRepo = dataSource.getRepository(entityMap.blogs);\r\n const blog = await blogRepo.findOne({\r\n where: { slug, published: true },\r\n relations: ['author', 'category', 'tags', 'seo'],\r\n });\r\n if (!blog) return json({ error: 'Blog not found' }, { status: 404 });\r\n return json(blog);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface FormBySlugConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n}\r\n\r\nexport function createFormBySlugHandler(config: FormBySlugConfig) {\r\n const { dataSource, entityMap, json } = config;\r\n return async function GET(_req: Request, slug: string): Promise<Response> {\r\n try {\r\n const formRepo = dataSource.getRepository(entityMap.forms);\r\n const form = await formRepo.findOne({\r\n where: { slug, published: true, deleted: false },\r\n relations: ['fields'],\r\n order: { fields: { order: 'ASC' } },\r\n });\r\n if (!form) return json({ error: 'Form not found' }, { status: 404 });\r\n const out = form as { fields?: unknown[] };\r\n if (Array.isArray(out.fields)) out.fields = out.fields.filter((f) => !(f as { deleted?: boolean }).deleted);\r\n return json(form);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface FormSaveHandlersConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n}\r\n\r\n/** Normalize a field from payload for DB: only include columns that exist on form_fields. */\r\nfunction normalizeFieldRow(f: Record<string, unknown>, formId: number): Record<string, unknown> {\r\n const order = typeof f.order === 'number' ? f.order : Number(f.order) || 0;\r\n const groupId = typeof f.groupId === 'number' ? f.groupId : Number(f.groupId) || 1;\r\n const columnWidth = typeof f.columnWidth === 'number' ? f.columnWidth : Number(f.columnWidth) || 12;\r\n return {\r\n formId,\r\n label: f.label != null ? String(f.label) : '',\r\n type: f.type != null ? String(f.type) : 'text',\r\n placeholder: f.placeholder != null ? String(f.placeholder) : null,\r\n options: f.options != null ? (typeof f.options === 'string' ? f.options : JSON.stringify(f.options)) : null,\r\n required: Boolean(f.required),\r\n validation: f.validation != null ? (typeof f.validation === 'string' ? f.validation : JSON.stringify(f.validation)) : null,\r\n order,\r\n groupId,\r\n columnWidth,\r\n };\r\n}\r\n\r\nexport function createFormSaveHandlers(config: FormSaveHandlersConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n const formRepo = () => dataSource.getRepository(entityMap.forms);\r\n const fieldRepo = () => dataSource.getRepository(entityMap.form_fields);\r\n\r\n return {\r\n async GET(req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'forms', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const formId = Number(id);\r\n if (!Number.isInteger(formId) || formId <= 0) return json({ error: 'Invalid form id' }, { status: 400 });\r\n const form = await formRepo().findOne({\r\n where: { id: formId },\r\n relations: ['fields'],\r\n order: { fields: { order: 'ASC' } },\r\n });\r\n if (!form) return json({ message: 'Not found' }, { status: 404 });\r\n const out = form as { fields?: { deleted?: boolean }[] };\r\n if (Array.isArray(out.fields)) out.fields = out.fields.filter((f) => !f.deleted);\r\n return json(form);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async POST(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'forms', 'create');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const body = (await req.json()) as Record<string, unknown> | null;\r\n if (!body || typeof body !== 'object') return json({ error: 'Invalid request payload' }, { status: 400 });\r\n const fields = Array.isArray(body.fields) ? body.fields : [];\r\n const { fields: _f, ...formRow } = body;\r\n const form = await formRepo().save(formRepo().create(formRow as object));\r\n for (let i = 0; i < fields.length; i++) {\r\n const row = normalizeFieldRow(fields[i] as Record<string, unknown>, form.id);\r\n (row as Record<string, unknown>).order = i + 1;\r\n await fieldRepo().save(fieldRepo().create(row as object));\r\n }\r\n const saved = await formRepo().findOne({ where: { id: form.id }, relations: ['fields'], order: { fields: { order: 'ASC' } } });\r\n return json(saved ?? form, { status: 201 });\r\n } catch (e) {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async PUT(req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'forms', 'update');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const formId = Number(id);\r\n if (!Number.isInteger(formId) || formId <= 0) return json({ error: 'Invalid form id' }, { status: 400 });\r\n const body = (await req.json()) as Record<string, unknown> | null;\r\n if (!body || typeof body !== 'object') return json({ error: 'Invalid request payload' }, { status: 400 });\r\n const existing = await formRepo().findOne({ where: { id: formId } });\r\n if (!existing) return json({ message: 'Not found' }, { status: 404 });\r\n const fields = Array.isArray(body.fields) ? body.fields : [];\r\n const formRow: Record<string, unknown> = {};\r\n for (const key of ['name', 'description', 'campaign', 'slug', 'published']) {\r\n if (body[key] !== undefined) formRow[key] = body[key];\r\n }\r\n if (Object.keys(formRow).length > 0) await formRepo().update(formId, formRow as object);\r\n await fieldRepo().delete({ formId });\r\n for (let i = 0; i < fields.length; i++) {\r\n const row = normalizeFieldRow(fields[i] as Record<string, unknown>, formId);\r\n (row as Record<string, unknown>).order = i + 1;\r\n await fieldRepo().save(fieldRepo().create(row as object));\r\n }\r\n const saved = await formRepo().findOne({ where: { id: formId }, relations: ['fields'], order: { fields: { order: 'ASC' } } });\r\n return saved ? json(saved) : json({ message: 'Not found' }, { status: 404 });\r\n } catch (e) {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport interface FormSubmissionHandlerConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n /** When set, form submission notification email is queued (CRM recipient). */\r\n getCms?: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n getCompanyDetails?: () => Promise<CompanyDetails>;\r\n getRecipientForChannel?: (channel: 'crm' | 'sales' | 'fulfilment') => Promise<string | null>;\r\n}\r\n\r\nasync function isErpIntegrationEnabled(dataSource: DataSource, entityMap: EntityMap): Promise<boolean> {\r\n const repo = dataSource.getRepository(entityMap.configs);\r\n const rows = await repo.find({ where: { settings: 'erp', deleted: false } as object });\r\n for (const row of rows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'enabled') return r.value !== 'false';\r\n }\r\n return true;\r\n}\r\n\r\n/** Form IDs that use `form.submitted` (opportunity). `null` = config key absent (treat as no IDs → all submissions use lead). */\r\nasync function getErpOpportunityFormIds(dataSource: DataSource, entityMap: EntityMap): Promise<number[] | null> {\r\n const repo = dataSource.getRepository(entityMap.configs);\r\n const row = await repo.findOne({\r\n where: { settings: 'erp', key: 'opportunityFormIds', deleted: false } as object,\r\n });\r\n if (!row) return null;\r\n const raw = ((row as { value: string }).value ?? '').trim();\r\n if (!raw) return [];\r\n try {\r\n const parsed = JSON.parse(raw) as unknown;\r\n if (!Array.isArray(parsed)) return [];\r\n const ids = parsed\r\n .map((x) => (typeof x === 'number' ? x : Number(x)))\r\n .filter((n): n is number => Number.isInteger(n) && n > 0);\r\n return [...new Set(ids)];\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\nexport interface FormSubmissionGetByIdConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n}\r\n\r\nexport function createFormSubmissionGetByIdHandler(config: FormSubmissionGetByIdConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n return async function GET(req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'form_submissions', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const submissionId = Number(id);\r\n if (!Number.isInteger(submissionId) || submissionId <= 0) return json({ error: 'Invalid id' }, { status: 400 });\r\n const repo = dataSource.getRepository(entityMap.form_submissions);\r\n const submission = await repo.findOne({\r\n where: { id: submissionId },\r\n relations: ['form', 'contact'],\r\n });\r\n if (!submission) return json({ message: 'Not found' }, { status: 404 });\r\n const form = submission as { form?: { id: number; fields?: unknown[] } };\r\n if (form.form?.id) {\r\n const formRepo = dataSource.getRepository(entityMap.forms);\r\n const formWithFields = await formRepo.findOne({\r\n where: { id: form.form.id },\r\n relations: ['fields'],\r\n order: { fields: { order: 'ASC' as const } },\r\n });\r\n if (formWithFields) (submission as { form?: unknown }).form = formWithFields;\r\n }\r\n return json(submission);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface FormSubmissionListConfig extends FormSubmissionGetByIdConfig {}\r\n\r\nexport function createFormSubmissionListHandler(config: FormSubmissionListConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n return async function GET(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'form_submissions', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const repo = dataSource.getRepository(entityMap.form_submissions);\r\n const { searchParams } = new URL(req.url);\r\n const page = Number(searchParams.get('page')) || 1;\r\n const limit = Math.min(100, Number(searchParams.get('limit')) || 10);\r\n const skip = (page - 1) * limit;\r\n const sortField = searchParams.get('sortField') || 'createdAt';\r\n const sortOrder = searchParams.get('sortOrder') === 'desc' ? 'DESC' : 'ASC';\r\n const [data, total] = await repo.findAndCount({\r\n skip,\r\n take: limit,\r\n order: { [sortField]: sortOrder },\r\n relations: ['form', 'contact'],\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nfunction formatSubmissionFieldValue(raw: unknown): string {\r\n if (raw == null || raw === '') return '—';\r\n if (typeof raw === 'object') return JSON.stringify(raw);\r\n return String(raw);\r\n}\r\n\r\nfunction pickContactFromSubmission(\r\n fields: { id: number; type: string; label: string }[],\r\n data: Record<string, unknown>\r\n): { name: string; email: string; phone: string | null } | null {\r\n let email: string | null = null;\r\n let name: string | null = null;\r\n let phone: string | null = null;\r\n for (const f of fields) {\r\n const val = data[String(f.id)];\r\n if (val == null || val === '') continue;\r\n const str = String(val).trim();\r\n if (f.type === 'email' || (f.label && f.label.toLowerCase().includes('email'))) {\r\n if (str && !email) email = str;\r\n } else if (f.type === 'phone' || (f.label && f.label.toLowerCase().includes('phone'))) {\r\n if (str && !phone) phone = str;\r\n } else if (f.label && f.label.toLowerCase().includes('name') && (f.type === 'text' || !f.type)) {\r\n if (str && !name) name = str;\r\n }\r\n }\r\n if (!email) return null;\r\n return { name: name || email, email, phone: phone || null };\r\n}\r\n\r\nexport function createFormSubmissionHandler(config: FormSubmissionHandlerConfig) {\r\n const { dataSource, entityMap, json, getCms } = config;\r\n return async function POST(req: Request): Promise<Response> {\r\n try {\r\n const body = (await req.json()) as Record<string, unknown> | null;\r\n if (!body || typeof body !== 'object') {\r\n return json({ error: 'Invalid request payload' }, { status: 400 });\r\n }\r\n const captchaErr = await assertCaptchaOk(getCms, body, req, json);\r\n if (captchaErr) return captchaErr;\r\n const formId = typeof body.formId === 'number' ? body.formId : Number(body.formId);\r\n if (!Number.isInteger(formId) || formId <= 0) {\r\n return json({ error: 'formId is required and must be a positive integer' }, { status: 400 });\r\n }\r\n const data = body.data;\r\n if (!data || typeof data !== 'object' || Array.isArray(data)) {\r\n return json({ error: 'data is required and must be an object' }, { status: 400 });\r\n }\r\n const formRepo = dataSource.getRepository(entityMap.forms);\r\n const form = await formRepo.findOne({\r\n where: { id: formId, published: true, deleted: false },\r\n relations: ['fields'],\r\n });\r\n if (!form) {\r\n return json({ error: 'Form not found' }, { status: 404 });\r\n }\r\n const fields = (form as { fields?: { id: number; type: string; label: string; deleted?: boolean }[] }).fields ?? [];\r\n const activeFields = fields.filter((f) => !f.deleted);\r\n\r\n let contactId: number | null =\r\n body.contactId != null && body.contactId !== ''\r\n ? (typeof body.contactId === 'number' ? body.contactId : Number(body.contactId))\r\n : null;\r\n\r\n if (!contactId) {\r\n const contactData = pickContactFromSubmission(activeFields, data as Record<string, unknown>);\r\n if (contactData) {\r\n const contactRepo = dataSource.getRepository(entityMap.contacts);\r\n let contact = await contactRepo.findOne({ where: { email: contactData.email } });\r\n if (!contact) {\r\n const createdAt = new Date();\r\n contact = await contactRepo.save(\r\n contactRepo.create({\r\n name: contactData.name,\r\n email: contactData.email,\r\n phone: contactData.phone,\r\n createdAt,\r\n updatedAt: createdAt,\r\n })\r\n );\r\n }\r\n contactId = contact.id;\r\n }\r\n }\r\n\r\n const ipAddress = (req.headers.get('x-forwarded-for') ?? req.headers.get('x-real-ip') ?? null) as string | null;\r\n const userAgent = req.headers.get('user-agent') ?? null;\r\n const submissionRepo = dataSource.getRepository(entityMap.form_submissions);\r\n const created = await submissionRepo.save(\r\n submissionRepo.create({\r\n formId,\r\n contactId: Number.isInteger(contactId) ? contactId : null,\r\n data: data as Record<string, unknown>,\r\n ipAddress: ipAddress?.slice(0, 255) ?? null,\r\n userAgent: userAgent?.slice(0, 500) ?? null,\r\n })\r\n );\r\n\r\n const formWithName = form as { name?: string };\r\n const formName = formWithName.name ?? 'Form';\r\n let contactName = 'Unknown';\r\n let contactEmail = '';\r\n if (Number.isInteger(contactId)) {\r\n const contactRepo = dataSource.getRepository(entityMap.contacts);\r\n const contact = await contactRepo.findOne({ where: { id: contactId }, select: ['name', 'email'] });\r\n if (contact) {\r\n contactName = (contact as { name: string }).name ?? contactName;\r\n contactEmail = (contact as { email: string }).email ?? contactEmail;\r\n }\r\n } else {\r\n const contactData = pickContactFromSubmission(activeFields, data as Record<string, unknown>);\r\n if (contactData) {\r\n contactName = contactData.name;\r\n contactEmail = contactData.email;\r\n }\r\n }\r\n\r\n if (config.getCms) {\r\n try {\r\n const cms = await config.getCms();\r\n if (config.getCompanyDetails && config.getRecipientForChannel) {\r\n const to = await config.getRecipientForChannel('crm');\r\n if (to) {\r\n const companyDetails = await config.getCompanyDetails();\r\n const formFieldRows = activeFields.map((f) => ({\r\n label: (f.label && String(f.label).trim()) || `Field ${f.id}`,\r\n value: formatSubmissionFieldValue(data[String(f.id)]),\r\n }));\r\n await queueEmail(cms, {\r\n to,\r\n templateName: 'formSubmission',\r\n ctx: {\r\n formName,\r\n contactName,\r\n contactEmail,\r\n formData: data,\r\n formFieldRows,\r\n companyDetails: companyDetails ?? {},\r\n },\r\n });\r\n }\r\n }\r\n if (await isErpIntegrationEnabled(dataSource, entityMap)) {\r\n const erp = cms.getPlugin('erp') as { submission: ERPSubmissionService } | undefined;\r\n if (erp) {\r\n const contact = erp.submission.extractContactData(data as Record<string, unknown>, activeFields);\r\n if (contact?.email?.trim()) {\r\n const opportunityFormIds = await getErpOpportunityFormIds(dataSource, entityMap);\r\n const asOpportunity =\r\n opportunityFormIds != null &&\r\n opportunityFormIds.length > 0 &&\r\n opportunityFormIds.includes(formId);\r\n await queueErp(\r\n cms,\r\n asOpportunity ? { kind: 'formOpportunity', contact } : { kind: 'lead', contact }\r\n );\r\n }\r\n }\r\n }\r\n } catch {\r\n // do not fail the submission if notification / ERP queue fails\r\n }\r\n }\r\n\r\n return json(created, { status: 201 });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface UsersApiConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n baseUrl: string;\r\n /** When set with email queue/plugin, invite emails are sent on user create and regenerate-invite. */\r\n getCms?: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n getCompanyDetails?: () => Promise<CompanyDetails>;\r\n /** When set, soft-delete sets `deletedBy` on the user row. */\r\n getSessionUser?: () => Promise<SessionUser | null>;\r\n}\r\n\r\nexport function createUsersApiHandlers(config: UsersApiConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission, baseUrl, getCms, getCompanyDetails, getSessionUser } = config;\r\n\r\n async function trySendInviteEmail(toEmail: string, inviteLink: string, inviteeName: string): Promise<void> {\r\n if (!getCms) return;\r\n try {\r\n const cms = await getCms();\r\n const companyDetails = getCompanyDetails ? await getCompanyDetails() : {};\r\n await queueEmail(cms, {\r\n to: toEmail,\r\n templateName: 'invite',\r\n ctx: {\r\n inviteLink,\r\n email: toEmail,\r\n inviteeName: inviteeName.trim(),\r\n companyDetails: companyDetails ?? {},\r\n },\r\n });\r\n } catch {\r\n // do not fail user APIs if email fails\r\n }\r\n }\r\n const userRepo = () => dataSource.getRepository(entityMap.users);\r\n return {\r\n async list(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'users', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const url = new URL(req.url);\r\n const page = Math.max(1, parseInt(url.searchParams.get('page') || '1', 10));\r\n const limit = Math.min(100, parseInt(url.searchParams.get('limit') || '10', 10));\r\n const skip = (page - 1) * limit;\r\n const sortField = url.searchParams.get('sortField') || 'createdAt';\r\n const sortOrder = url.searchParams.get('sortOrder') === 'desc' ? 'DESC' : 'ASC';\r\n const search = url.searchParams.get('search');\r\n const where = search\r\n ? [\r\n { name: ILike(`%${search}%`), deleted: false },\r\n { email: ILike(`%${search}%`), deleted: false },\r\n ]\r\n : { deleted: false };\r\n const [data, total] = await userRepo().findAndCount({\r\n skip,\r\n take: limit,\r\n order: { [sortField]: sortOrder },\r\n where,\r\n relations: ['group'],\r\n select: ['id', 'name', 'email', 'blocked', 'createdAt', 'updatedAt', 'groupId'],\r\n });\r\n return json({ total, page, limit, totalPages: Math.ceil(total / limit), data });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async create(req: Request): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'users', 'create');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const body = await req.json() as Record<string, unknown>;\r\n if (!body?.name || !body?.email) return json({ error: 'Name and email are required' }, { status: 400 });\r\n const email = body.email as string;\r\n const existing = await userRepo().findOne({ where: { email } });\r\n if (existing && !existing.deleted) {\r\n return json({ error: 'User with this email already exists' }, { status: 400 });\r\n }\r\n const groupRepo = dataSource.getRepository(entityMap.user_groups);\r\n const customerG = await groupRepo.findOne({ where: { name: 'Customer', deleted: false } });\r\n const gid = (body.groupId as number) ?? null;\r\n const isCustomer = !!(customerG && gid === customerG.id);\r\n const adminAccess = isCustomer ? false : body.adminAccess === false ? false : true;\r\n const blocked =\r\n body.blocked === true ||\r\n body.blocked === 'true' ||\r\n body.blocked === 1 ||\r\n body.blocked === '1';\r\n const newUser = existing?.deleted\r\n ? await (async () => {\r\n await userRepo().update(existing.id, {\r\n deleted: false,\r\n deletedAt: null,\r\n deletedBy: null,\r\n name: body.name,\r\n email,\r\n password: null,\r\n blocked,\r\n groupId: gid,\r\n adminAccess,\r\n updatedAt: new Date(),\r\n } as object);\r\n const row = await userRepo().findOne({ where: { id: existing.id } });\r\n if (!row) throw new Error('user missing after restore');\r\n return row;\r\n })()\r\n : await userRepo().save(\r\n userRepo().create({\r\n name: body.name,\r\n email,\r\n password: null,\r\n blocked,\r\n groupId: gid,\r\n adminAccess,\r\n })\r\n );\r\n if (entityMap.contacts) {\r\n await linkUnclaimedContactToUser(dataSource, entityMap.contacts, newUser.id, newUser.email as string);\r\n }\r\n const emailToken = Buffer.from(newUser.email).toString('base64');\r\n const inviteLink = `${baseUrl}/admin/invite?token=${emailToken}`;\r\n await trySendInviteEmail(\r\n newUser.email as string,\r\n inviteLink,\r\n (newUser.name as string) ?? ''\r\n );\r\n return json(\r\n {\r\n message: blocked\r\n ? 'User created successfully (blocked until password is set)'\r\n : 'User created successfully',\r\n user: newUser,\r\n inviteLink,\r\n },\r\n { status: 201 }\r\n );\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async getById(_req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(new Request(_req.url));\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(_req, 'users', 'read');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const user = await userRepo().findOne({\r\n where: { id: parseInt(id, 10), deleted: false },\r\n relations: ['group'],\r\n select: ['id', 'name', 'email', 'blocked', 'createdAt', 'updatedAt', 'groupId'],\r\n });\r\n if (!user) return json({ error: 'User not found' }, { status: 404 });\r\n return json(user);\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async update(req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'users', 'update');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const uid = parseInt(id, 10);\r\n const existing = await userRepo().findOne({ where: { id: uid, deleted: false } });\r\n if (!existing) return json({ error: 'Not found' }, { status: 404 });\r\n const body = await req.json() as Record<string, unknown>;\r\n const { password: _p, ...safe } = body;\r\n await userRepo().update(uid, safe as object);\r\n const updated = await userRepo().findOne({\r\n where: { id: uid, deleted: false },\r\n relations: ['group'],\r\n select: ['id', 'name', 'email', 'blocked', 'createdAt', 'updatedAt', 'groupId'],\r\n });\r\n return updated ? json(updated) : json({ error: 'Not found' }, { status: 404 });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async delete(_req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(new Request(_req.url));\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(_req, 'users', 'delete');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const uid = parseInt(id, 10);\r\n const existing = await userRepo().findOne({ where: { id: uid, deleted: false } });\r\n if (!existing) return json({ error: 'User not found' }, { status: 404 });\r\n let deletedBy: number | null = null;\r\n if (getSessionUser) {\r\n try {\r\n const u = await getSessionUser();\r\n if (u?.id) {\r\n const n = Number(u.id);\r\n if (Number.isFinite(n)) deletedBy = n;\r\n }\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n const payload: Record<string, unknown> = { deleted: true, deletedAt: new Date() };\r\n if (deletedBy != null) payload.deletedBy = deletedBy;\r\n await userRepo().update(uid, payload as object);\r\n return json({ message: 'User deleted successfully' });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n async regenerateInvite(_req: Request, id: string): Promise<Response> {\r\n const authErr = await requireAuth(new Request(_req.url));\r\n if (authErr) return authErr;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(_req, 'users', 'update');\r\n if (pe) return pe;\r\n }\r\n try {\r\n const user = await userRepo().findOne({\r\n where: { id: parseInt(id, 10), deleted: false },\r\n select: ['email', 'name'],\r\n });\r\n if (!user) return json({ error: 'User not found' }, { status: 404 });\r\n const emailToken = Buffer.from(user.email).toString('base64');\r\n const inviteLink = `${baseUrl}/admin/invite?token=${emailToken}`;\r\n await trySendInviteEmail(user.email as string, inviteLink, (user.name as string) ?? '');\r\n return json({ message: 'New invite link generated successfully', inviteLink });\r\n } catch {\r\n return json({ error: 'Server Error' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport interface UserAvatarConfig extends CmsHandlersBase {\r\n getSession: () => Promise<{ user?: { email?: string | null } } | null>;\r\n /** Save avatar (buffer, fileName) => publicUrl. Default: local public/uploads/avatars */\r\n saveAvatar?: (buffer: Buffer, fileName: string) => Promise<string>;\r\n}\r\n\r\nexport function createUserAvatarHandler(config: UserAvatarConfig) {\r\n const { json, getSession, saveAvatar } = config;\r\n return async function POST(req: Request): Promise<Response> {\r\n const session = await getSession();\r\n if (!session?.user?.email) return json({ error: 'Unauthorized' }, { status: 401 });\r\n try {\r\n const formData = await req.formData();\r\n const file = formData.get('avatar') as File | null;\r\n if (!file) return json({ error: 'No file uploaded' }, { status: 400 });\r\n if (!file.type.startsWith('image/')) return json({ error: 'File must be an image' }, { status: 400 });\r\n if (file.size > 5 * 1024 * 1024) return json({ error: 'File size must be less than 5MB' }, { status: 400 });\r\n const buffer = Buffer.from(await file.arrayBuffer());\r\n const ext = file.name.split('.').pop() || 'jpg';\r\n const fileName = `avatar_${session.user.email}_${Date.now()}.${ext}`;\r\n const avatarUrl = saveAvatar\r\n ? await saveAvatar(buffer, fileName)\r\n : await (async () => {\r\n const fs = await import('fs/promises');\r\n const path = await import('path');\r\n const dir = path.join(process.cwd(), 'public', 'uploads', 'avatars');\r\n await fs.mkdir(dir, { recursive: true });\r\n await fs.writeFile(path.join(dir, fileName), buffer);\r\n return `/uploads/avatars/${fileName}`;\r\n })();\r\n return json({ message: 'Avatar uploaded successfully', avatarUrl });\r\n } catch {\r\n return json({ error: 'Internal server error' }, { status: 500 });\r\n }\r\n };\r\n}\r\n\r\nexport interface UserProfileConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n getSession: () => Promise<{\r\n user?: { id?: string; email?: string | null; name?: string | null };\r\n } | null>;\r\n /** Optional hook after a successful profile PUT (e.g. audit logging). */\r\n onProfileUpdated?: (\r\n req: Request,\r\n user: { id: number; name: string; email: string; phone: string | null }\r\n ) => Promise<void>;\r\n}\r\n\r\nconst PROFILE_EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n\r\n/**\r\n * GET / PUT handlers for `/api/users/profile` (current session user).\r\n * GET merges DB fields with the session; PUT updates the user row and callers should refresh the client session (e.g. `useSession().update()`).\r\n */\r\nexport function createUserProfileHandler(config: UserProfileConfig) {\r\n const { dataSource, entityMap, json, getSession, onProfileUpdated } = config;\r\n\r\n async function loadCurrentUser(): Promise<\r\n | { ok: false; response: Response }\r\n | { ok: true; user: import('typeorm').ObjectLiteral }\r\n > {\r\n const session = await getSession();\r\n const su = session?.user as { id?: string; email?: string | null } | undefined;\r\n if (!su?.email && su?.id == null) {\r\n return { ok: false, response: json({ error: 'Unauthorized' }, { status: 401 }) };\r\n }\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n let user: import('typeorm').ObjectLiteral | null = null;\r\n const uidRaw = su.id != null ? String(su.id).trim() : '';\r\n const uid = uidRaw && /^\\d+$/.test(uidRaw) ? parseInt(uidRaw, 10) : NaN;\r\n if (Number.isFinite(uid) && uid > 0) {\r\n user = await userRepo.findOne({\r\n where: { id: uid, deleted: false } as import('typeorm').ObjectLiteral,\r\n select: ['id', 'name', 'email', 'phone', 'createdAt'],\r\n });\r\n }\r\n if (!user && su.email) {\r\n const em = String(su.email).trim().toLowerCase();\r\n if (em) {\r\n user = await userRepo.findOne({\r\n where: { email: em, deleted: false } as import('typeorm').ObjectLiteral,\r\n select: ['id', 'name', 'email', 'phone', 'createdAt'],\r\n });\r\n }\r\n }\r\n if (!user) return { ok: false, response: json({ error: 'Not found' }, { status: 404 }) };\r\n return { ok: true, user };\r\n }\r\n\r\n return {\r\n async GET(_req: Request): Promise<Response> {\r\n try {\r\n const r = await loadCurrentUser();\r\n if (!r.ok) return r.response;\r\n const u = r.user as {\r\n id: number;\r\n name: string;\r\n email: string;\r\n phone: string | null;\r\n createdAt?: Date;\r\n };\r\n return json({\r\n id: u.id,\r\n name: u.name ?? '',\r\n email: u.email ?? '',\r\n phone: u.phone ?? null,\r\n createdAt: u.createdAt instanceof Date ? u.createdAt.toISOString() : u.createdAt ?? undefined,\r\n });\r\n } catch {\r\n return json({ error: 'Internal server error' }, { status: 500 });\r\n }\r\n },\r\n\r\n async PUT(req: Request): Promise<Response> {\r\n try {\r\n const r = await loadCurrentUser();\r\n if (!r.ok) return r.response;\r\n const current = r.user as { id: number; name: string; email: string; phone: string | null };\r\n\r\n let body: { name?: string; email?: string; phone?: string | null };\r\n try {\r\n body = (await req.json()) as typeof body;\r\n } catch {\r\n return json({ error: 'Invalid JSON' }, { status: 400 });\r\n }\r\n\r\n const name = typeof body.name === 'string' ? body.name.trim() : '';\r\n if (!name) return json({ error: 'Name is required' }, { status: 400 });\r\n\r\n const emailRaw = typeof body.email === 'string' ? body.email.trim().toLowerCase() : '';\r\n if (!emailRaw || !PROFILE_EMAIL_RE.test(emailRaw)) {\r\n return json({ error: 'Valid email is required' }, { status: 400 });\r\n }\r\n\r\n const phone =\r\n body.phone === null || body.phone === undefined\r\n ? null\r\n : typeof body.phone === 'string'\r\n ? body.phone.trim() || null\r\n : null;\r\n\r\n const userRepo = dataSource.getRepository(entityMap.users);\r\n\r\n if (emailRaw !== String(current.email ?? '').toLowerCase()) {\r\n const taken = await userRepo.findOne({\r\n where: { email: emailRaw, deleted: false } as import('typeorm').ObjectLiteral,\r\n select: ['id'],\r\n });\r\n if (taken && (taken as { id: number }).id !== current.id) {\r\n return json({ error: 'Email is already in use' }, { status: 409 });\r\n }\r\n }\r\n\r\n await userRepo.update(\r\n { id: current.id } as import('typeorm').ObjectLiteral,\r\n {\r\n name,\r\n email: emailRaw,\r\n phone,\r\n updatedAt: new Date(),\r\n } as import('typeorm').ObjectLiteral\r\n );\r\n\r\n const updated = await userRepo.findOne({\r\n where: { id: current.id } as import('typeorm').ObjectLiteral,\r\n select: ['id', 'name', 'email', 'phone'],\r\n });\r\n if (!updated) return json({ error: 'Not found' }, { status: 404 });\r\n\r\n const row = updated as { id: number; name: string; email: string; phone: string | null };\r\n\r\n if (onProfileUpdated) {\r\n try {\r\n await onProfileUpdated(req, row);\r\n } catch {\r\n /* optional */\r\n }\r\n }\r\n\r\n return json({\r\n message: 'Profile updated successfully',\r\n user: { id: row.id, name: row.name, email: row.email, phone: row.phone },\r\n });\r\n } catch {\r\n return json({ error: 'Internal server error' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport interface SettingsApiConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n encryptionKey?: string;\r\n /** Groups in this list are readable without auth (GET returns all keys for the group). */\r\n publicGetGroups?: string[];\r\n}\r\n\r\nfunction simpleEncrypt(text: string, key: string): string {\r\n const buf = Buffer.from(text, 'utf8');\r\n const keyBuf = Buffer.from(key.padEnd(32, '0').slice(0, 32), 'utf8');\r\n const out = Buffer.alloc(buf.length);\r\n for (let i = 0; i < buf.length; i++) out[i] = buf[i] ^ keyBuf[i % keyBuf.length];\r\n return out.toString('base64');\r\n}\r\n\r\nfunction simpleDecrypt(encoded: string, key: string): string {\r\n const buf = Buffer.from(encoded, 'base64');\r\n const keyBuf = Buffer.from(key.padEnd(32, '0').slice(0, 32), 'utf8');\r\n const out = Buffer.alloc(buf.length);\r\n for (let i = 0; i < buf.length; i++) out[i] = buf[i] ^ keyBuf[i % keyBuf.length];\r\n return out.toString('utf8');\r\n}\r\n\r\n/**\r\n * Structural types so apps with their own `typeorm` install (e.g. npm link) typecheck without duplicate-package errors.\r\n */\r\nexport type GetPublicSettingsGroupDataSource = {\r\n getRepository(entity: unknown): {\r\n find(options: object): Promise<unknown[]>;\r\n };\r\n};\r\n\r\nexport interface GetPublicSettingsGroupConfig {\r\n dataSource: GetPublicSettingsGroupDataSource;\r\n entityMap: Record<string, unknown>;\r\n encryptionKey?: string;\r\n}\r\n\r\n/** Same rows as unauthenticated GET /api/settings/:group when the group is in publicGetGroups. */\r\nexport async function getPublicSettingsGroup(\r\n config: GetPublicSettingsGroupConfig,\r\n group: string\r\n): Promise<Record<string, string>> {\r\n const { dataSource, entityMap, encryptionKey } = config;\r\n const repo = dataSource.getRepository(entityMap.configs);\r\n const rows = await repo.find({ where: { settings: group, deleted: false } });\r\n const result: Record<string, string> = {};\r\n for (const row of rows) {\r\n const r = row as { key: string; value: string; encrypted?: boolean };\r\n let val = r.value;\r\n if (r.encrypted && encryptionKey) {\r\n try {\r\n val = simpleDecrypt(val, encryptionKey);\r\n } catch {\r\n /* keep raw if decrypt fails */\r\n }\r\n }\r\n result[r.key] = val;\r\n }\r\n return result;\r\n}\r\n\r\nexport function createSettingsApiHandlers(config: SettingsApiConfig) {\r\n const { dataSource, entityMap, json, requireAuth, encryptionKey, publicGetGroups } = config;\r\n const configRepo = () => dataSource.getRepository(entityMap.configs);\r\n\r\n return {\r\n async GET(req: Request, group: string): Promise<Response> {\r\n const isPublicGroup = publicGetGroups?.includes(group);\r\n const authErr = isPublicGroup ? null : await requireAuth(req);\r\n const isAuthed = !authErr;\r\n\r\n try {\r\n if (isPublicGroup) {\r\n const result = await getPublicSettingsGroup(\r\n { dataSource, entityMap, encryptionKey },\r\n group\r\n );\r\n return json(result);\r\n }\r\n\r\n const where: Record<string, unknown> = { settings: group, deleted: false };\r\n if (!isAuthed && !isPublicGroup) where.type = 'public';\r\n\r\n const rows = await configRepo().find({ where });\r\n const result: Record<string, unknown> = {};\r\n for (const row of rows) {\r\n const r = row as { key: string; value: string; encrypted?: boolean; type?: string };\r\n let val = r.value;\r\n if (r.encrypted && encryptionKey) {\r\n try { val = simpleDecrypt(val, encryptionKey); } catch { /* return raw if decrypt fails */ }\r\n }\r\n result[r.key] = val;\r\n }\r\n return json(result);\r\n } catch {\r\n return json({ error: 'Failed to fetch settings' }, { status: 500 });\r\n }\r\n },\r\n\r\n async PUT(req: Request, group: string): Promise<Response> {\r\n const authErr = await requireAuth(req);\r\n if (authErr) return authErr;\r\n\r\n try {\r\n const body = await req.json() as Record<string, { value: string; type?: 'public' | 'private'; encrypted?: boolean }>;\r\n if (!body || typeof body !== 'object') return json({ error: 'Invalid payload' }, { status: 400 });\r\n\r\n const repo = configRepo();\r\n for (const [key, entry] of Object.entries(body)) {\r\n const val = typeof entry === 'string' ? entry : entry.value;\r\n const type = (typeof entry === 'object' && entry.type) || 'private';\r\n const encrypted = !!(typeof entry === 'object' && entry.encrypted);\r\n\r\n let storedValue = val;\r\n if (encrypted && encryptionKey) {\r\n storedValue = simpleEncrypt(val, encryptionKey);\r\n }\r\n\r\n const existing = await repo.findOne({ where: { settings: group, key } });\r\n if (existing) {\r\n await repo.update(existing.id, { value: storedValue, type, encrypted, updatedAt: new Date() } as object);\r\n } else {\r\n await repo.save(repo.create({ settings: group, key, value: storedValue, type, encrypted } as object));\r\n }\r\n }\r\n return json({ message: 'Settings saved' });\r\n } catch {\r\n return json({ error: 'Failed to save settings' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport interface ChatApiConfig extends CmsHandlersBase {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n getCms: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n}\r\n\r\nconst KB_CHUNK_LIMIT = 10;\r\nconst KB_CONTEXT_MAX_CHARS = 4000;\r\nconst RAG_LOG = '[rag-context]';\r\n\r\nfunction getQueryTerms(message: string): string[] {\r\n return message\r\n .replace(/[^\\w\\s]/g, ' ')\r\n .split(/\\s+/)\r\n .filter((w) => w.length > 2)\r\n .slice(0, 6);\r\n}\r\n\r\nfunction normalizeChatModeSetting(raw: string | undefined): 'whatsapp' | 'external' | 'llm' {\r\n if (raw === 'external' || raw === 'llm') return raw;\r\n return 'whatsapp';\r\n}\r\n\r\nasync function loadLlmSettingsMap(dataSource: DataSource, entityMap: EntityMap): Promise<Record<string, string>> {\r\n if (!entityMap.configs) return {};\r\n const repo = dataSource.getRepository(entityMap.configs);\r\n const rows = await repo.find({ where: { settings: 'llm', deleted: false } as object });\r\n const out: Record<string, string> = {};\r\n for (const row of rows as { key: string; value: string }[]) {\r\n out[row.key] = row.value;\r\n }\r\n return out;\r\n}\r\n\r\n/** Safe subset of `llm` settings for the storefront chat widget (`GET /api/chat/config`). */\r\nexport interface ChatPublicConfig {\r\n enabled: boolean;\r\n chatMode: 'whatsapp' | 'external' | 'llm';\r\n /** When `chatMode === 'llm'`, slug of the attached agent (from `attachedAgentSlug` setting). */\r\n agentSlug: string;\r\n botName: string;\r\n icon: string;\r\n iconImageUrl: string;\r\n iconBackgroundColor: string;\r\n headerColor: string;\r\n whatsappPhone: string;\r\n}\r\n\r\nexport function createChatHandlers(config: ChatApiConfig) {\r\n const { dataSource, entityMap, json, getCms } = config;\r\n const contactRepo = () => dataSource.getRepository(entityMap.contacts);\r\n const convRepo = () => dataSource.getRepository(entityMap.chat_conversations);\r\n const msgRepo = () => dataSource.getRepository(entityMap.chat_messages);\r\n const chunkRepo = () => dataSource.getRepository(entityMap.knowledge_base_chunks);\r\n\r\n return {\r\n async publicConfig(_req: Request): Promise<Response> {\r\n try {\r\n const map = await loadLlmSettingsMap(dataSource, entityMap);\r\n const mode = normalizeChatModeSetting(map.chatMode);\r\n const body: ChatPublicConfig = {\r\n enabled: map.enabled !== 'false',\r\n chatMode: mode,\r\n agentSlug: mode === 'llm' ? (map.attachedAgentSlug ?? '').trim() : '',\r\n botName: map.botName ?? '',\r\n icon: map.icon ?? '',\r\n iconImageUrl: map.iconImageUrl ?? '',\r\n iconBackgroundColor: map.iconBackgroundColor ?? '#6366f1',\r\n headerColor: map.headerColor ?? '#6366f1',\r\n whatsappPhone: map.whatsappPhone ?? '',\r\n };\r\n return json(body);\r\n } catch {\r\n return json({ error: 'Failed to load chat config' }, { status: 500 });\r\n }\r\n },\r\n async identify(req: Request): Promise<Response> {\r\n try {\r\n const body = (await req.json()) as { name?: string; email?: string; phone?: string };\r\n const name = body?.name?.trim();\r\n const email = body?.email?.trim();\r\n if (!name || !email) return json({ error: 'name and email required' }, { status: 400 });\r\n const repo = contactRepo();\r\n const phone = body.phone?.trim() || null;\r\n const existing = await repo.findOne({ where: { email } as import('typeorm').ObjectLiteral });\r\n let contact: import('typeorm').ObjectLiteral;\r\n if (!existing) {\r\n const createdAt = new Date();\r\n contact = (await repo.save(\r\n repo.create({ name, email, phone, createdAt, updatedAt: createdAt } as object)\r\n )) as import('typeorm').ObjectLiteral;\r\n } else {\r\n const row = existing as { id: number; deleted: boolean };\r\n if (row.deleted) {\r\n await repo.update(row.id, {\r\n deleted: false,\r\n deletedAt: null,\r\n deletedBy: null,\r\n name,\r\n phone,\r\n } as object);\r\n const refreshed = await repo.findOne({ where: { id: row.id } });\r\n if (!refreshed) return json({ error: 'Failed to identify', detail: 'contact missing after reactivate' }, { status: 500 });\r\n contact = refreshed as import('typeorm').ObjectLiteral;\r\n } else {\r\n contact = existing as import('typeorm').ObjectLiteral;\r\n }\r\n }\r\n const convRepoInst = convRepo();\r\n const contactId = (contact as { id: number }).id;\r\n const conv = await convRepoInst.save(convRepoInst.create({ contactId } as object));\r\n return json({\r\n contactId,\r\n conversationId: (conv as { id: number }).id,\r\n });\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Failed to identify';\r\n return json({ error: 'Failed to identify', detail: message }, { status: 500 });\r\n }\r\n },\r\n async getMessages(req: Request, conversationId: string): Promise<Response> {\r\n try {\r\n const conv = await convRepo().findOne({\r\n where: { id: parseInt(conversationId, 10) },\r\n relations: ['messages'],\r\n });\r\n if (!conv) return json({ error: 'Conversation not found' }, { status: 404 });\r\n const messages = ((conv as { messages?: Array<{ role: string; content: string; createdAt: string }> }).messages ?? [])\r\n .sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())\r\n .map((m) => ({ role: m.role, content: m.content }));\r\n return json({ messages });\r\n } catch {\r\n return json({ error: 'Failed to fetch messages' }, { status: 500 });\r\n }\r\n },\r\n async postMessage(req: Request): Promise<Response> {\r\n try {\r\n const body = (await req.json()) as { conversationId?: number; message?: string; agentSlug?: string };\r\n const conversationId = body?.conversationId;\r\n const message = body?.message?.trim();\r\n if (!conversationId || !message) return json({ error: 'conversationId and message required' }, { status: 400 });\r\n const conv = await convRepo().findOne({\r\n where: { id: conversationId },\r\n relations: ['messages'],\r\n });\r\n if (!conv) return json({ error: 'Conversation not found' }, { status: 404 });\r\n const cms = await getCms();\r\n const llm = cms.getPlugin('llm') as {\r\n chat: (messages: LlmMessage[], opts?: object) => Promise<{ content: string }>;\r\n chatAgent?: (opts: LlmAgentOptions) => Promise<{ content: string }>;\r\n embed?: (text: string) => Promise<number[]>;\r\n } | undefined;\r\n if (!llm?.chat) return json({ error: 'LLM not configured' }, { status: 503 });\r\n\r\n const llmSettings = await loadLlmSettingsMap(dataSource, entityMap);\r\n const supportMode = normalizeChatModeSetting(llmSettings.chatMode);\r\n let effectiveSlug = (body?.agentSlug ?? '').trim();\r\n if (!effectiveSlug && supportMode === 'llm' && entityMap.llm_agents) {\r\n effectiveSlug = (llmSettings.attachedAgentSlug ?? '').trim();\r\n }\r\n\r\n let agentRow: LlmAgent | null = null;\r\n if (effectiveSlug) {\r\n if (!entityMap.llm_agents) {\r\n return json({ error: 'LLM agents are not configured on this deployment' }, { status: 400 });\r\n }\r\n const agentRepo = dataSource.getRepository(\r\n entityMap.llm_agents as EntityTarget<LlmAgent>\r\n );\r\n agentRow = await agentRepo.findOne({\r\n where: { slug: effectiveSlug, deleted: false, enabled: true },\r\n });\r\n if (!agentRow && (body?.agentSlug ?? '').trim()) {\r\n return json({ error: 'Agent not found or disabled', agentSlug: effectiveSlug }, { status: 404 });\r\n }\r\n }\r\n console.info(RAG_LOG, 'step 1 | resolve agent', {\r\n agentSlug: effectiveSlug || '(none)',\r\n agentFound: !!agentRow,\r\n agentId: agentRow?.id ?? null,\r\n });\r\n\r\n const parsedValidation = agentRow\r\n ? parseLlmAgentValidationRules(agentRow.validationRules)\r\n : { structured: {} as ParsedLlmAgentValidation['structured'], guardrailsForPrompt: null as string | null };\r\n if (agentRow) {\r\n const v = validateUserMessageAgainstStructuredRules(message, parsedValidation.structured);\r\n if (!v.ok) return json({ error: v.error, reason: 'validation_failed' }, { status: 400 });\r\n }\r\n\r\n let kbDocumentScope: number[] | undefined;\r\n const Junction = entityMap.llm_agent_knowledge_documents as EntityTarget<import('typeorm').ObjectLiteral> | undefined;\r\n if (agentRow && Junction) {\r\n const linkRepo = dataSource.getRepository(Junction);\r\n const links = await linkRepo.find({ where: { agentId: agentRow.id } as object });\r\n const ids = [...new Set((links as Array<{ documentId: number }>).map((l) => l.documentId))];\r\n if (ids.length > 0) kbDocumentScope = ids;\r\n }\r\n console.info(RAG_LOG, 'step 2 | knowledge scope', {\r\n scopedDocumentIds: kbDocumentScope ?? '(all documents)',\r\n documentCount: kbDocumentScope?.length ?? 'all',\r\n });\r\n\r\n const msgRepoInst = msgRepo();\r\n await msgRepoInst.save(msgRepoInst.create({ conversationId, role: 'user', content: message } as object));\r\n let contextParts: string[] = [];\r\n console.info(RAG_LOG, 'step 3 | embed user query', {\r\n messageChars: message.length,\r\n embedAvailable: !!llm.embed,\r\n });\r\n const queryEmbedding = llm.embed ? await llm.embed(message) : null;\r\n console.info(RAG_LOG, 'step 4 | query embedding result', {\r\n dimensions: queryEmbedding?.length ?? 0,\r\n hasEmbedding: !!(queryEmbedding && queryEmbedding.length > 0),\r\n });\r\n if (queryEmbedding && queryEmbedding.length > 0) {\r\n const vectorStr = '[' + queryEmbedding.join(',') + ']';\r\n try {\r\n const rows = (kbDocumentScope?.length\r\n ? await dataSource.query(\r\n `SELECT id, content FROM knowledge_base_chunks WHERE embedding IS NOT NULL AND \"documentId\" = ANY($3::int[]) ORDER BY embedding <=> $1::vector LIMIT $2`,\r\n [vectorStr, KB_CHUNK_LIMIT, kbDocumentScope]\r\n )\r\n : await dataSource.query(\r\n `SELECT id, content FROM knowledge_base_chunks WHERE embedding IS NOT NULL ORDER BY embedding <=> $1::vector LIMIT $2`,\r\n [vectorStr, KB_CHUNK_LIMIT]\r\n )) as Array<{ id: number; content: string }>;\r\n console.info(RAG_LOG, 'step 5 | vector search results', {\r\n rowsReturned: rows.length,\r\n chunkIds: rows.map((r) => r.id),\r\n });\r\n let totalLen = 0;\r\n for (const r of rows) {\r\n const text = (r.content ?? '').trim();\r\n if (!text || totalLen + text.length > KB_CONTEXT_MAX_CHARS) continue;\r\n contextParts.push(text);\r\n totalLen += text.length;\r\n }\r\n console.info(RAG_LOG, 'step 5a | vector context selected', {\r\n chunksUsed: contextParts.length,\r\n totalChars: totalLen,\r\n });\r\n } catch (vecErr) {\r\n console.warn(RAG_LOG, 'step 5 | vector search failed; falling back to keyword', {\r\n err: vecErr instanceof Error ? vecErr.message : String(vecErr),\r\n });\r\n }\r\n }\r\n if (contextParts.length === 0) {\r\n const terms = getQueryTerms(message);\r\n console.info(RAG_LOG, 'step 6 | keyword fallback', {\r\n reason: !(queryEmbedding && queryEmbedding.length > 0) ? 'no embedding' : 'vector search returned nothing',\r\n searchTerms: terms,\r\n });\r\n if (terms.length > 0) {\r\n const conditions = kbDocumentScope?.length\r\n ? terms.map((t) => ({ content: ILike(`%${t}%`), documentId: In(kbDocumentScope) }))\r\n : terms.map((t) => ({ content: ILike(`%${t}%`) }));\r\n const chunks = await chunkRepo().find({\r\n where: conditions,\r\n take: KB_CHUNK_LIMIT,\r\n order: { id: 'ASC' },\r\n });\r\n const seen = new Set<string>();\r\n let totalLen = 0;\r\n for (const c of chunks as Array<{ content: string }>) {\r\n const text = c.content.trim();\r\n if (seen.has(text) || totalLen + text.length > KB_CONTEXT_MAX_CHARS) continue;\r\n seen.add(text);\r\n contextParts.push(text);\r\n totalLen += text.length;\r\n }\r\n console.info(RAG_LOG, 'step 6a | keyword results', {\r\n chunksFound: chunks.length,\r\n chunksUsed: contextParts.length,\r\n totalChars: totalLen,\r\n });\r\n }\r\n }\r\n const historyRaw = ((conv as { messages?: Array<{ role: string; content: string; createdAt?: string }> }).messages ?? [])\r\n .sort((a, b) => new Date(a.createdAt ?? 0).getTime() - new Date(b.createdAt ?? 0).getTime())\r\n .map((m) => ({ role: m.role as LlmMessage['role'], content: m.content }));\r\n const history = historyBeforeCurrentUser(historyRaw, message);\r\n\r\n let content: string;\r\n const ragContext = contextParts.length > 0 ? contextParts.join('\\n\\n') : undefined;\r\n console.info(RAG_LOG, 'step 7 | final context', {\r\n method: contextParts.length > 0 ? 'rag' : 'none',\r\n contextChunks: contextParts.length,\r\n contextChars: ragContext?.length ?? 0,\r\n contextPreview: ragContext ? ragContext.slice(0, 200) + (ragContext.length > 200 ? '…' : '') : '(no context)',\r\n });\r\n\r\n if (agentRow && llm.chatAgent) {\r\n const fromAgent = llmAgentToChatAgentOptions(agentRow);\r\n const systemPrompt = mergeGuardrailsIntoSystemPrompt(\r\n fromAgent.systemPrompt,\r\n parsedValidation.guardrailsForPrompt\r\n );\r\n const res = await llm.chatAgent({\r\n ...fromAgent,\r\n systemPrompt: systemPrompt || undefined,\r\n context: ragContext,\r\n history,\r\n userPrompt: message,\r\n });\r\n content = res.content;\r\n } else {\r\n const ragSystem = contextParts.length > 0\r\n ? `Use the following context about the company and its products to answer. If the answer is not in the context, say so.\\n\\nContext:\\n${contextParts.join('\\n\\n')}`\r\n : '';\r\n const defaultSystem = 'You are a helpful assistant for the company. If you do not have specific information, say so.';\r\n let systemContent: string;\r\n if (agentRow) {\r\n const base = agentRow.systemInstruction?.trim() || '';\r\n systemContent = mergeGuardrailsIntoSystemPrompt(\r\n [base, ragSystem].filter(Boolean).join('\\n\\n') || defaultSystem,\r\n parsedValidation.guardrailsForPrompt\r\n );\r\n } else {\r\n systemContent = ragSystem || defaultSystem;\r\n }\r\n const messages: LlmMessage[] = [\r\n { role: 'system', content: systemContent },\r\n ...history,\r\n { role: 'user', content: message },\r\n ];\r\n const chatOpts = agentRow\r\n ? {\r\n model: agentRow.model ?? undefined,\r\n temperature: agentRow.temperature ?? undefined,\r\n max_tokens: agentRow.maxTokens ?? undefined,\r\n }\r\n : {};\r\n const res = await llm.chat(messages, chatOpts);\r\n content = res.content;\r\n }\r\n await msgRepoInst.save(msgRepoInst.create({ conversationId, role: 'assistant', content } as object));\r\n return json({ content });\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : '';\r\n return json({ error: msg || 'Failed to send message' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n","import type { CaptchaService } from './captcha-service';\r\n\r\ntype JsonResponse = (body: unknown, init?: { status?: number; headers?: HeadersInit }) => Response;\r\n\r\nexport async function assertCaptchaOk(\r\n getCms: (() => Promise<{ getPlugin: (name: string) => unknown }>) | undefined,\r\n body: Record<string, unknown>,\r\n req: Request,\r\n json: JsonResponse\r\n): Promise<Response | null> {\r\n if (!getCms) return null;\r\n let cms: { getPlugin: (name: string) => unknown };\r\n try {\r\n cms = await getCms();\r\n } catch {\r\n return null;\r\n }\r\n const svc = cms.getPlugin('captcha') as CaptchaService | undefined;\r\n if (!svc || typeof (svc as CaptchaService).verify !== 'function') return null;\r\n const result = await svc.verify(body, req);\r\n if (result.ok) return null;\r\n return json({ error: result.message }, { status: result.status });\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\nimport type { LlmAgentOptions } from '../plugins/llm/llm-service';\r\n\r\n@Entity('llm_agents')\r\nexport class LlmAgent {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n /** Stable key for API / widgets (e.g. `support`, `sales`). */\r\n @Column('varchar')\r\n slug: string;\r\n\r\n /** Passed as `systemPrompt` to `LlmService.chatAgent`. */\r\n @Column('text', { name: 'system_instruction', default: '' })\r\n systemInstruction: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n model: string | null;\r\n\r\n @Column('double precision', { name: 'temperature', nullable: true })\r\n temperature: number | null;\r\n\r\n @Column('int', { name: 'max_tokens', nullable: true })\r\n maxTokens: number | null;\r\n\r\n /**\r\n * Rules string: plain prose → appended to system prompt as output guardrails; JSON → see `parseLlmAgentValidationRules` in cms-handlers\r\n * (structural checks + optional `guardrails` / `outputRules` / `outputInstructions` for the model).\r\n */\r\n @Column('text', { name: 'validation_rules', nullable: true })\r\n validationRules: string | null;\r\n\r\n @Column('boolean', { default: true })\r\n enabled: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n\r\n/** Partial {@link LlmAgentOptions} for merging with `userPrompt` / `history` / `context`. */\r\nexport function llmAgentToChatAgentOptions(\r\n agent: LlmAgent\r\n): Pick<LlmAgentOptions, 'systemPrompt' | 'model' | 'temperature' | 'max_tokens'> {\r\n return {\r\n systemPrompt: agent.systemInstruction?.trim() || undefined,\r\n model: agent.model?.trim() || undefined,\r\n temperature: agent.temperature ?? undefined,\r\n max_tokens: agent.maxTokens ?? undefined,\r\n };\r\n}\r\n","/** Normalize a logical media folder path: no leading/trailing slashes, no \"..\" segments, max length. */\r\nexport function sanitizeMediaFolderPath(input: unknown): string {\r\n if (input == null) return '';\r\n if (typeof input !== 'string') return '';\r\n const segments = input\r\n .replace(/\\\\/g, '/')\r\n .split('/')\r\n .map((s) => s.trim())\r\n .filter(Boolean)\r\n .filter((s) => s !== '..' && s !== '.');\r\n const joined = segments.join('/');\r\n return joined.length > 512 ? joined.slice(0, 512) : joined;\r\n}\r\n\r\n/** Single path segment for storage (folder name or legacy path segment). */\r\nexport function sanitizeStorageSegment(name: string): string {\r\n const s = name.replace(/[/\\\\]/g, '-').trim().slice(0, 255);\r\n return s || 'item';\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport type { ObjectLiteral } from 'typeorm';\r\nimport type { EntityTarget } from 'typeorm';\r\nimport { sanitizeStorageSegment } from './media-folder-path';\r\n\r\ntype EntityMap = Record<string, EntityTarget<ObjectLiteral>>;\r\n\r\n/** Build `a/b/c` path under `uploads/` from the chain of folder rows up to root. */\r\nexport async function relativePathFromMediaParentId(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n parentId: number | null\r\n): Promise<string> {\r\n if (parentId == null) return '';\r\n const repo = dataSource.getRepository(entityMap.media);\r\n const segments: string[] = [];\r\n let id: number | null = parentId;\r\n for (let d = 0; d < 64 && id != null; d++) {\r\n const row = await repo.findOne({ where: { id } as ObjectLiteral });\r\n if (!row) break;\r\n const m = row as { kind?: string; filename: string; parentId: number | null };\r\n if (m.kind !== 'folder') break;\r\n segments.unshift(sanitizeStorageSegment(m.filename));\r\n id = m.parentId ?? null;\r\n }\r\n return segments.join('/');\r\n}\r\n","import { IsNull } from 'typeorm';\r\nimport type { DataSource } from 'typeorm';\r\nimport type { ObjectLiteral } from 'typeorm';\r\nimport type { EntityTarget } from 'typeorm';\r\nimport type { StorageService } from '../plugins/storage';\r\nimport { relativePathFromMediaParentId } from './media-parent-path';\r\nimport { sanitizeStorageSegment } from './media-folder-path';\r\n\r\ntype EntityMap = Record<string, EntityTarget<ObjectLiteral>>;\r\n\r\nexport const ZIP_MIME_TYPES = new Set(['application/zip', 'application/x-zip-compressed']);\r\n\r\nconst MAX_ENTRIES = 2000;\r\nconst MAX_TOTAL_UNCOMPRESSED = 80 * 1024 * 1024;\r\n\r\nexport function isZipMedia(mime: string | null | undefined, filename: string): boolean {\r\n if (mime && ZIP_MIME_TYPES.has(mime)) return true;\r\n return filename.toLowerCase().endsWith('.zip');\r\n}\r\n\r\nexport async function readBufferFromPublicUrl(url: string): Promise<Buffer> {\r\n if (url.startsWith('http://') || url.startsWith('https://')) {\r\n const r = await fetch(url);\r\n if (!r.ok) throw new Error('Failed to download file');\r\n return Buffer.from(await r.arrayBuffer());\r\n }\r\n if (url.startsWith('/')) {\r\n const { readFile } = await import('fs/promises');\r\n const { join } = await import('path');\r\n const rel = url.replace(/^\\/+/, '');\r\n return readFile(join(process.cwd(), 'public', rel));\r\n }\r\n throw new Error('Unsupported media URL');\r\n}\r\n\r\nfunction sanitizeZipPath(entryName: string): string[] | null {\r\n const norm = entryName.replace(/\\\\/g, '/').split('/').filter(Boolean);\r\n for (const seg of norm) {\r\n if (seg === '..' || seg === '.') return null;\r\n }\r\n return norm;\r\n}\r\n\r\nfunction shouldSkipEntry(parts: string[]): boolean {\r\n if (parts[0] === '__MACOSX') return true;\r\n const last = parts[parts.length - 1];\r\n if (last === '.DS_Store') return true;\r\n return false;\r\n}\r\n\r\nfunction guessMimeType(fileName: string): string {\r\n const lower = fileName.toLowerCase();\r\n if (lower.endsWith('.png')) return 'image/png';\r\n if (lower.endsWith('.jpg') || lower.endsWith('.jpeg')) return 'image/jpeg';\r\n if (lower.endsWith('.gif')) return 'image/gif';\r\n if (lower.endsWith('.webp')) return 'image/webp';\r\n if (lower.endsWith('.svg')) return 'image/svg+xml';\r\n if (lower.endsWith('.pdf')) return 'application/pdf';\r\n if (lower.endsWith('.txt')) return 'text/plain';\r\n if (lower.endsWith('.json')) return 'application/json';\r\n if (lower.endsWith('.zip')) return 'application/zip';\r\n return 'application/octet-stream';\r\n}\r\n\r\nasync function findOrCreateFolder(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n parentId: number | null,\r\n name: string\r\n): Promise<number> {\r\n const safe = sanitizeStorageSegment(name);\r\n const repo = dataSource.getRepository(entityMap.media);\r\n const where: ObjectLiteral =\r\n parentId == null\r\n ? { kind: 'folder', filename: safe, parentId: IsNull() }\r\n : { kind: 'folder', filename: safe, parentId };\r\n const existing = await repo.findOne({ where });\r\n if (existing) return (existing as { id: number }).id;\r\n const row = await repo.save(\r\n repo.create({\r\n kind: 'folder',\r\n parentId,\r\n filename: safe,\r\n url: null,\r\n mimeType: 'inode/directory',\r\n size: 0,\r\n alt: null,\r\n isPublic: false,\r\n deleted: false,\r\n } as object)\r\n );\r\n return (row as { id: number }).id;\r\n}\r\n\r\nasync function ensureFolderChain(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n rootParentId: number | null,\r\n pathSegments: string[]\r\n): Promise<number | null> {\r\n let pid: number | null = rootParentId;\r\n for (const seg of pathSegments) {\r\n if (!seg) continue;\r\n pid = await findOrCreateFolder(dataSource, entityMap, pid, seg);\r\n }\r\n return pid;\r\n}\r\n\r\nexport async function extractZipMediaIntoParentTree(opts: {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n zipMediaRow: ObjectLiteral;\r\n storage: StorageService | undefined;\r\n localUploadDir: string;\r\n}): Promise<{ files: number; folderEntries: number }> {\r\n const { dataSource, entityMap, zipMediaRow } = opts;\r\n const row = zipMediaRow as {\r\n id: number;\r\n kind: string;\r\n parentId: number | null;\r\n url: string | null;\r\n mimeType: string | null;\r\n filename: string;\r\n };\r\n if (row.kind !== 'file' || !row.url) throw new Error('Not a file');\r\n if (!isZipMedia(row.mimeType, row.filename)) throw new Error('Not a zip archive');\r\n\r\n const buffer = await readBufferFromPublicUrl(row.url);\r\n const { default: AdmZip } = await import('adm-zip');\r\n const zip = new AdmZip(buffer);\r\n const entries = zip.getEntries();\r\n if (entries.length > MAX_ENTRIES) throw new Error(`Too many zip entries (max ${MAX_ENTRIES})`);\r\n\r\n const rootParentId = row.parentId;\r\n\r\n type Item = { parts: string[]; isDir: boolean; data: Buffer | null };\r\n const items: Item[] = [];\r\n let totalUncompressed = 0;\r\n\r\n for (const e of entries) {\r\n const raw = e.entryName;\r\n const parts = sanitizeZipPath(raw);\r\n if (!parts || shouldSkipEntry(parts)) continue;\r\n const isDir = e.isDirectory || /\\/$/.test(raw);\r\n let data: Buffer | null = null;\r\n if (!isDir) {\r\n data = e.getData();\r\n totalUncompressed += data.length;\r\n if (totalUncompressed > MAX_TOTAL_UNCOMPRESSED) {\r\n throw new Error(`Uncompressed content exceeds limit (${MAX_TOTAL_UNCOMPRESSED} bytes)`);\r\n }\r\n }\r\n items.push({ parts, isDir, data });\r\n }\r\n\r\n items.sort((a, b) => {\r\n const da = a.parts.length;\r\n const db = b.parts.length;\r\n if (da !== db) return da - db;\r\n return a.parts.join('/').localeCompare(b.parts.join('/'));\r\n });\r\n\r\n let files = 0;\r\n let folderEntries = 0;\r\n const repo = dataSource.getRepository(entityMap.media);\r\n\r\n for (const it of items) {\r\n if (it.isDir) {\r\n await ensureFolderChain(dataSource, entityMap, rootParentId, it.parts);\r\n folderEntries++;\r\n continue;\r\n }\r\n const fileName = it.parts[it.parts.length - 1]!;\r\n const dirParts = it.parts.slice(0, -1);\r\n const parentFolderId = await ensureFolderChain(dataSource, entityMap, rootParentId, dirParts);\r\n const buf = it.data!;\r\n const relBase = await relativePathFromMediaParentId(dataSource, entityMap, parentFolderId);\r\n const relativeUnderUploads = relBase ? `${relBase}/${fileName}` : fileName;\r\n const contentType = guessMimeType(fileName);\r\n\r\n let publicUrl: string;\r\n if (opts.storage) {\r\n publicUrl = await opts.storage.upload(buf, `uploads/${relativeUnderUploads}`, contentType);\r\n } else {\r\n const fs = await import('fs/promises');\r\n const pathMod = await import('path');\r\n const dir = pathMod.join(process.cwd(), opts.localUploadDir);\r\n const filePath = pathMod.join(dir, relativeUnderUploads);\r\n await fs.mkdir(pathMod.dirname(filePath), { recursive: true });\r\n await fs.writeFile(filePath, buf);\r\n publicUrl = `/${opts.localUploadDir.replace(/^\\/+/, '').replace(/\\\\/g, '/')}/${relativeUnderUploads.replace(/\\\\/g, '/')}`;\r\n }\r\n\r\n await repo.save(\r\n repo.create({\r\n kind: 'file',\r\n parentId: parentFolderId,\r\n filename: fileName,\r\n url: publicUrl,\r\n mimeType: contentType,\r\n size: buf.length,\r\n alt: null,\r\n isPublic: false,\r\n deleted: false,\r\n } as object)\r\n );\r\n files++;\r\n }\r\n\r\n return { files, folderEntries };\r\n}\r\n","/**\n * Admin API: attach knowledge base documents to an LLM agent, ingest text into chunks + embeddings.\n * Routes: GET/POST /api/llm_agents/:slug/knowledge, DELETE /api/llm_agents/:slug/knowledge/:documentId\n *\n * Pipeline logs (grep `[llm-agent-knowledge] pipeline`):\n * - 01_request — incoming POST, content-type preview\n * - 02_agent_loaded — agent id for slug\n * - 03_body_parsed — JSON vs multipart, sizes / documentId\n * - 04_* — file decode or PDF extract (multipart)\n * - 05_branch — link_existing_document | new_upload_ingest\n * - 06_* — KB row + junction (link create / exists)\n * - 06b_chunks_existing_count — link path: existing chunk rows\n * - 06_knowledge_document_saved — new ingest: document row id\n * - 07_chunk_split — split stats\n * - 07b_chunks_persisted — chunk rows saved\n * - 07_query_chunks_missing_embedding — link path: rows with NULL embedding\n * - 08_* — resolve LLM plugin, embed availability or skip\n * - 09_embedding_workers_start / 10_embedding_workers_finished — concurrent embed+DB update\n * - 11_response — final outcome summary\n * - 99_pipeline_error — uncaught exception\n */\nimport type { DataSource, EntityTarget, ObjectLiteral } from 'typeorm';\nimport { In } from 'typeorm';\nimport type { EntityMap } from './crud';\nimport type { RequireEntityPermissionFn } from './cms-handlers';\nimport type { LlmAgent } from '../entities/llm-agent.entity';\n\nconst INGEST_CHUNK_CHARS = 900;\n/** Avoid serverless / DB timeouts on huge uploads; ~400 × 900 ≈ 360k chars. */\nconst MAX_CHUNKS_PER_UPLOAD = 400;\nconst EMBED_CONCURRENCY = 5;\n/** Limit PDF buffer size before parsing (memory / CPU). */\nconst MAX_PDF_BYTES = 25 * 1024 * 1024;\n\nconst TEXT_FILE_TYPES = new Set(['text/plain', 'text/markdown', 'application/json']);\n\nconst KB_LOG = '[llm-agent-knowledge]';\n\n/** Ordered pipeline logs: upload → KB document → chunks → junction → embeddings. */\nfunction logKbPipeline(step: string, meta?: Record<string, unknown>): void {\n console.info(`${KB_LOG} pipeline`, { step, ...meta });\n}\n\nfunction llmEmbedDebug(): boolean {\n const v = process.env.LLM_EMBED_DEBUG?.toLowerCase();\n return v === '1' || v === 'true' || v === 'yes';\n}\n\nfunction isPdfUpload(mime: string, fileName: string): boolean {\n if (mime === 'application/pdf') return true;\n const n = fileName.toLowerCase();\n return n.endsWith('.pdf');\n}\n\nasync function extractTextFromPdf(buffer: Buffer): Promise<string> {\n const pdfParse = (await import('pdf-parse')) as unknown as (\n data: Buffer\n ) => Promise<{ text?: string }>;\n const data = await pdfParse(buffer);\n return (data?.text ?? '').trim();\n}\n\n/** Chunks that still need vectors (e.g. after a failed embed pass or CRUD-created documents). */\nasync function loadChunksMissingEmbeddings(\n dataSource: DataSource,\n documentId: number,\n slug: string\n): Promise<Array<{ id: number; content: string }>> {\n const rows = (await dataSource.query(\n `SELECT id, content FROM knowledge_base_chunks WHERE \"documentId\" = $1 AND embedding IS NULL ORDER BY \"chunkIndex\" ASC`,\n [documentId]\n )) as Array<{ id: number; content: string }>;\n const list = rows ?? [];\n logKbPipeline('07_query_chunks_missing_embedding', {\n slug,\n documentId,\n missingEmbeddingCount: list.length,\n });\n return list;\n}\n\nasync function writeEmbeddingsConcurrent(\n dataSource: DataSource,\n embed: (t: string) => Promise<number[]>,\n chunks: Array<{ id: number; content: string }>,\n concurrency: number,\n slug: string\n): Promise<{ written: number; failed: number }> {\n let next = 0;\n let written = 0;\n let failed = 0;\n let skippedEmpty = 0;\n\n logKbPipeline('09_embedding_workers_start', {\n slug,\n chunkCount: chunks.length,\n concurrency: Math.max(1, Math.min(concurrency, chunks.length)),\n });\n\n async function worker() {\n for (;;) {\n const i = next++;\n if (i >= chunks.length) return;\n const c = chunks[i]!;\n try {\n const emb = await embed(c.content);\n if (emb?.length) {\n const vectorStr = '[' + emb.join(',') + ']';\n await dataSource.query(\n `UPDATE knowledge_base_chunks SET embedding = $1::vector WHERE id = $2`,\n [vectorStr, c.id]\n );\n written++;\n } else {\n skippedEmpty++;\n if (llmEmbedDebug()) {\n console.warn(`${KB_LOG} embed() returned empty vector`, { chunkId: c.id });\n }\n }\n } catch (err) {\n failed++;\n console.error(`${KB_LOG} embedding DB update failed`, {\n chunkId: c.id,\n err: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n const n = Math.max(1, Math.min(concurrency, chunks.length));\n await Promise.all(Array.from({ length: n }, () => worker()));\n const summary: Record<string, unknown> = {\n chunkCount: chunks.length,\n written,\n failed,\n skippedEmpty,\n };\n if (skippedEmpty > 0 && written === 0) {\n summary.hint =\n 'embed() returned empty vectors — see [LLM embed] / [LLM embed HF] logs (OpenAI gateway vs @huggingface/inference + legacy HTTP).';\n }\n logKbPipeline('10_embedding_workers_finished', { slug, ...summary });\n if (failed > 0 || (skippedEmpty > 0 && written === 0)) {\n console.error(`${KB_LOG} embedding pass finished with issues`, summary);\n }\n return { written, failed };\n}\n\nexport interface LlmAgentKnowledgeApiConfig {\n dataSource: DataSource;\n entityMap: EntityMap;\n getCms: () => Promise<{ getPlugin: (name: string) => unknown }>;\n json: (body: unknown, init?: { status?: number }) => Response;\n requireAuth: (req: Request) => Promise<Response | null>;\n requireEntityPermission?: RequireEntityPermissionFn;\n}\n\nfunction splitIntoChunks(text: string, maxLen: number): string[] {\n const t = text.trim();\n if (!t) return [];\n const chunks: string[] = [];\n for (let i = 0; i < t.length; i += maxLen) {\n chunks.push(t.slice(i, i + maxLen));\n }\n return chunks;\n}\n\nasync function findAgentBySlug(\n dataSource: DataSource,\n llmAgents: EntityTarget<ObjectLiteral>,\n slug: string\n): Promise<LlmAgent | null> {\n const repo = dataSource.getRepository(llmAgents as EntityTarget<LlmAgent>);\n return repo.findOne({\n where: { slug, deleted: false } as object,\n });\n}\n\nexport function createLlmAgentKnowledgeHandlers(config: LlmAgentKnowledgeApiConfig) {\n const { dataSource, entityMap, getCms, json, requireAuth, requireEntityPermission } = config;\n\n const kbDoc = entityMap.knowledge_base_documents;\n const kbChunk = entityMap.knowledge_base_chunks;\n const llmAgents = entityMap.llm_agents;\n const junction = entityMap.llm_agent_knowledge_documents;\n\n if (!kbDoc || !kbChunk || !llmAgents || !junction) {\n return null;\n }\n\n async function gate(req: Request, action: 'read' | 'update'): Promise<Response | null> {\n const a = await requireAuth(req);\n if (a) return a;\n if (requireEntityPermission) {\n const pe = await requireEntityPermission(req, 'llm_agents', action);\n if (pe) return pe;\n }\n return null;\n }\n\n async function runEmbeddingPass(\n slug: string,\n savedChunks: Array<{ id: number; content: string }>\n ): Promise<{ embeddingsWritten: number; embeddingsFailed: number; embedError?: string }> {\n let embeddingsWritten = 0;\n let embeddingsFailed = 0;\n try {\n logKbPipeline('08_resolve_llm_plugin', { slug, chunkCount: savedChunks.length });\n const cms = await getCms();\n const llm = cms.getPlugin('llm') as { embed?: (t: string) => Promise<number[]> } | undefined;\n if (llm?.embed && savedChunks.length > 0) {\n logKbPipeline('08b_embed_fn_available', {\n slug,\n chunkCount: savedChunks.length,\n firstChunkId: savedChunks[0]?.id,\n lastChunkId: savedChunks[savedChunks.length - 1]?.id,\n });\n const embedBound = (text: string) => llm.embed!(text);\n const { written, failed } = await writeEmbeddingsConcurrent(\n dataSource,\n embedBound,\n savedChunks,\n EMBED_CONCURRENCY,\n slug\n );\n embeddingsWritten = written;\n embeddingsFailed = failed;\n } else {\n logKbPipeline('08c_embed_skipped', {\n slug,\n hasLlmPlugin: !!llm,\n hasEmbed: typeof llm?.embed === 'function',\n chunkCount: savedChunks.length,\n reason: savedChunks.length === 0 ? 'no_chunks' : !llm ? 'no_llm_plugin' : 'no_embed_method',\n });\n console.error(`${KB_LOG} embeddings skipped`, {\n slug,\n hasLlmPlugin: !!llm,\n hasEmbed: typeof llm?.embed === 'function',\n chunkCount: savedChunks.length,\n hint:\n !llm || typeof llm.embed !== 'function'\n ? 'LLM plugin missing or no embed(); check LLM_GATEWAY_URL + LLM_API_KEY so llm plugin initializes.'\n : undefined,\n });\n }\n } catch (embErr) {\n const detail = embErr instanceof Error ? embErr.message : String(embErr);\n logKbPipeline('08d_embed_pass_exception', { slug, detail });\n console.error(`${KB_LOG} embedding step threw before/during batch`, { slug, detail, embErr });\n return {\n embeddingsWritten: 0,\n embeddingsFailed: savedChunks.length,\n embedError: detail,\n };\n }\n return { embeddingsWritten, embeddingsFailed };\n }\n\n return {\n async list(req: Request, slug: string): Promise<Response> {\n const denied = await gate(req, 'read');\n if (denied) return denied;\n try {\n const agent = await findAgentBySlug(dataSource, llmAgents, slug);\n if (!agent) return json({ error: 'Agent not found' }, { status: 404 });\n const linkRepo = dataSource.getRepository(junction);\n const links = await linkRepo.find({ where: { agentId: agent.id } as object });\n const docIds = [...new Set((links as Array<{ documentId: number }>).map((l) => l.documentId))];\n if (docIds.length === 0) return json({ documents: [] });\n const docRepo = dataSource.getRepository(kbDoc);\n const docs = await docRepo.find({ where: { id: In(docIds) } as object });\n const byId = new Map((docs as Array<{ id: number; name: string }>).map((d) => [d.id, d]));\n const documents = docIds\n .map((id) => {\n const d = byId.get(id);\n return d ? { id: d.id, name: d.name } : null;\n })\n .filter(Boolean);\n return json({ documents });\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to list knowledge';\n return json({ error: msg }, { status: 500 });\n }\n },\n\n async post(req: Request, slug: string): Promise<Response> {\n const denied = await gate(req, 'update');\n if (denied) return denied;\n try {\n const ct0 = req.headers.get('content-type') || '';\n logKbPipeline('01_request', { slug, contentType: ct0.slice(0, 80) });\n\n const agent = await findAgentBySlug(dataSource, llmAgents, slug);\n if (!agent) return json({ error: 'Agent not found' }, { status: 404 });\n logKbPipeline('02_agent_loaded', { slug, agentId: agent.id });\n\n let name = '';\n let text = '';\n let sourceUrl: string | null = null;\n let existingDocumentId: number | null = null;\n\n const ct = req.headers.get('content-type') || '';\n if (ct.includes('application/json')) {\n const body = (await req.json()) as {\n name?: string;\n text?: string;\n sourceUrl?: string | null;\n documentId?: number;\n };\n existingDocumentId =\n typeof body?.documentId === 'number' && Number.isFinite(body.documentId) ? body.documentId : null;\n name = (body?.name ?? '').trim();\n text = (body?.text ?? '').trim();\n sourceUrl =\n typeof body?.sourceUrl === 'string' && body.sourceUrl.trim() ? body.sourceUrl.trim() : null;\n logKbPipeline('03_body_parsed', {\n slug,\n mode: 'json',\n existingDocumentId,\n nameLen: name.length,\n textChars: text.length,\n hasSourceUrl: !!sourceUrl,\n });\n } else if (ct.includes('multipart/form-data')) {\n const form = await req.formData();\n name = (form.get('name') as string | null)?.trim() ?? '';\n text = (form.get('text') as string | null)?.trim() ?? '';\n const file = form.get('file');\n if (file && typeof file !== 'string' && 'arrayBuffer' in file) {\n const f = file as File;\n const mime = (f.type || '').split(';')[0]!.trim().toLowerCase();\n const buf = Buffer.from(await f.arrayBuffer());\n logKbPipeline('03_body_parsed', {\n slug,\n mode: 'multipart',\n fileName: f.name || '(no name)',\n mime,\n fileBytes: buf.length,\n });\n if (TEXT_FILE_TYPES.has(mime)) {\n const decoded = buf.toString('utf8');\n if (!text) text = decoded;\n logKbPipeline('04_file_decoded_text', { slug, mime, textChars: text.length });\n } else if (isPdfUpload(mime, f.name || '')) {\n if (buf.length > MAX_PDF_BYTES) {\n return json(\n { error: `PDF too large (max ${Math.floor(MAX_PDF_BYTES / (1024 * 1024))}MB)` },\n { status: 413 }\n );\n }\n try {\n logKbPipeline('04_pdf_extract_start', { slug, fileBytes: buf.length });\n const extracted = await extractTextFromPdf(buf);\n if (!text) text = extracted;\n logKbPipeline('04_pdf_extract_done', { slug, textChars: text.length });\n } catch {\n return json(\n { error: 'Could not read PDF text (file may be encrypted, corrupt, or image-only)' },\n { status: 422 }\n );\n }\n } else {\n return json(\n {\n error:\n 'Unsupported file type; use text/plain, text/markdown, application/json, or application/pdf',\n },\n { status: 415 }\n );\n }\n if (!name && f.name) name = f.name.replace(/\\.[^/.]+$/, '') || f.name;\n } else {\n logKbPipeline('03_body_parsed', { slug, mode: 'multipart', hasFile: false, textChars: text.length });\n }\n } else {\n return json({ error: 'Use application/json or multipart/form-data' }, { status: 400 });\n }\n\n const linkRepo = dataSource.getRepository(junction);\n\n if (existingDocumentId != null) {\n logKbPipeline('05_branch', { slug, branch: 'link_existing_document', documentId: existingDocumentId });\n const docRepo = dataSource.getRepository(kbDoc);\n const existing = await docRepo.findOne({ where: { id: existingDocumentId } as object });\n if (!existing) return json({ error: 'documentId not found' }, { status: 404 });\n const dup = await linkRepo.findOne({\n where: { agentId: agent.id, documentId: existingDocumentId } as object,\n });\n if (!dup) {\n await linkRepo.save(linkRepo.create({ agentId: agent.id, documentId: existingDocumentId } as object));\n logKbPipeline('06_junction_link_created', {\n slug,\n agentId: agent.id,\n documentId: existingDocumentId,\n });\n } else {\n logKbPipeline('06_junction_link_exists', {\n slug,\n agentId: agent.id,\n documentId: existingDocumentId,\n });\n }\n\n const chunkRepo = dataSource.getRepository(kbChunk);\n const docRow = existing as { id: number; content: string };\n const chunkCount = await chunkRepo.count({ where: { documentId: existingDocumentId } as object });\n logKbPipeline('06b_chunks_existing_count', {\n slug,\n documentId: existingDocumentId,\n chunkCount,\n });\n\n let chunksToEmbed: Array<{ id: number; content: string }> = [];\n let chunksCreated = 0;\n\n if (chunkCount === 0) {\n const text = (docRow.content ?? '').trim();\n if (!text) {\n logKbPipeline('07_ingest_aborted_empty_document', { slug, documentId: existingDocumentId });\n return json({\n documentId: existingDocumentId,\n linked: true,\n created: false,\n chunkCount: 0,\n embeddingsWritten: 0,\n embeddingsFailed: 0,\n warning: 'Document has no text content; add content then attach again to build chunks and embeddings.',\n });\n }\n const parts = splitIntoChunks(text, INGEST_CHUNK_CHARS);\n if (parts.length > MAX_CHUNKS_PER_UPLOAD) {\n return json(\n {\n error: `Document is too large for one ingest (${parts.length} chunks; max ${MAX_CHUNKS_PER_UPLOAD}). Split into smaller files.`,\n },\n { status: 413 }\n );\n }\n logKbPipeline('07_chunk_split', {\n slug,\n documentId: existingDocumentId,\n partCount: parts.length,\n maxChunkChars: INGEST_CHUNK_CHARS,\n totalChars: text.length,\n });\n const now = new Date();\n const chunkRows = parts.map((content, i) =>\n chunkRepo.create({\n documentId: existingDocumentId,\n content,\n chunkIndex: i,\n createdAt: now,\n } as object)\n );\n const savedList = await chunkRepo.save(chunkRows);\n chunksCreated = savedList.length;\n chunksToEmbed = (savedList as Array<{ id: number }>).map((row, i) => ({\n id: row.id,\n content: parts[i]!,\n }));\n logKbPipeline('07b_chunks_persisted', {\n slug,\n documentId: existingDocumentId,\n rowsInserted: chunksCreated,\n });\n } else {\n chunksToEmbed = await loadChunksMissingEmbeddings(dataSource, existingDocumentId, slug);\n if (chunksToEmbed.length === 0) {\n logKbPipeline('08_skip_embed_all_chunks_have_vectors', {\n slug,\n documentId: existingDocumentId,\n existingChunkCount: chunkCount,\n });\n }\n }\n\n const embedResult =\n chunksToEmbed.length > 0\n ? await runEmbeddingPass(slug, chunksToEmbed)\n : { embeddingsWritten: 0, embeddingsFailed: 0 };\n if (embedResult.embedError) {\n logKbPipeline('11_response', {\n slug,\n branch: 'link',\n documentId: existingDocumentId,\n ok: false,\n embeddingError: true,\n });\n return json(\n {\n documentId: existingDocumentId,\n linked: true,\n created: false,\n chunkCount: chunkCount + chunksCreated,\n chunksCreated,\n embeddingAttempted: true,\n embeddingsWritten: 0,\n embeddingsFailed: chunksToEmbed.length,\n warning: 'Document linked; embedding step failed. Fix LLM/embed config and attach again (or unlink and re-attach) to retry NULL embeddings.',\n detail: embedResult.embedError,\n },\n { status: 201 }\n );\n }\n\n logKbPipeline('11_response', {\n slug,\n branch: 'link',\n documentId: existingDocumentId,\n ok: true,\n chunkCount: chunkCount + chunksCreated,\n chunksCreated,\n chunksQueuedForEmbedding: chunksToEmbed.length,\n embeddingsWritten: embedResult.embeddingsWritten,\n embeddingsFailed: embedResult.embeddingsFailed,\n });\n return json({\n documentId: existingDocumentId,\n linked: true,\n created: false,\n chunkCount: chunkCount + chunksCreated,\n chunksCreated: chunksCreated || undefined,\n chunksQueuedForEmbedding: chunksToEmbed.length,\n embeddingAttempted: chunksToEmbed.length > 0,\n embeddingsWritten: embedResult.embeddingsWritten,\n embeddingsFailed: embedResult.embeddingsFailed,\n });\n }\n\n logKbPipeline('05_branch', { slug, branch: 'new_upload_ingest' });\n\n if (!text) return json({ error: 'text or file with text content is required' }, { status: 400 });\n if (!name) name = 'Untitled';\n\n const parts = splitIntoChunks(text, INGEST_CHUNK_CHARS);\n if (parts.length === 0) {\n return json({ error: 'text or file with text content is required' }, { status: 400 });\n }\n if (parts.length > MAX_CHUNKS_PER_UPLOAD) {\n return json(\n {\n error: `Document is too large for one upload (${parts.length} chunks; max ${MAX_CHUNKS_PER_UPLOAD}). Split into smaller files.`,\n },\n { status: 413 }\n );\n }\n logKbPipeline('07_chunk_split', {\n slug,\n partCount: parts.length,\n maxChunkChars: INGEST_CHUNK_CHARS,\n totalChars: text.length,\n documentName: name,\n });\n\n const docRepo = dataSource.getRepository(kbDoc);\n const chunkRepo = dataSource.getRepository(kbChunk);\n const now = new Date();\n const doc = await docRepo.save(\n docRepo.create({ name, content: text, sourceUrl, createdAt: now, updatedAt: now } as object)\n );\n const docId = (doc as { id: number }).id;\n logKbPipeline('06_knowledge_document_saved', {\n slug,\n documentId: docId,\n name,\n contentChars: text.length,\n hasSourceUrl: !!sourceUrl,\n });\n\n const chunkRows = parts.map((content, i) =>\n chunkRepo.create({ documentId: docId, content, chunkIndex: i, createdAt: now } as object)\n );\n const savedList = await chunkRepo.save(chunkRows);\n const savedChunks: Array<{ id: number; content: string }> = (savedList as Array<{ id: number }>).map(\n (row, i) => ({\n id: row.id,\n content: parts[i]!,\n })\n );\n logKbPipeline('07b_chunks_persisted', {\n slug,\n documentId: docId,\n rowsInserted: savedChunks.length,\n firstChunkId: savedChunks[0]?.id,\n lastChunkId: savedChunks[savedChunks.length - 1]?.id,\n });\n\n const dup = await linkRepo.findOne({ where: { agentId: agent.id, documentId: docId } as object });\n if (!dup) {\n await linkRepo.save(linkRepo.create({ agentId: agent.id, documentId: docId } as object));\n logKbPipeline('06c_junction_link_created', { slug, agentId: agent.id, documentId: docId });\n } else {\n logKbPipeline('06c_junction_link_exists', { slug, agentId: agent.id, documentId: docId });\n }\n\n const embedResult = await runEmbeddingPass(slug, savedChunks);\n if (embedResult.embedError) {\n logKbPipeline('11_response', {\n slug,\n branch: 'ingest',\n documentId: docId,\n ok: false,\n embeddingError: true,\n });\n return json(\n {\n documentId: docId,\n chunkCount: savedChunks.length,\n embeddingAttempted: true,\n created: true,\n linked: true,\n embeddingsWritten: 0,\n embeddingsFailed: savedChunks.length,\n warning: 'Document saved and linked; embedding step failed.',\n detail: embedResult.embedError,\n },\n { status: 201 }\n );\n }\n\n logKbPipeline('11_response', {\n slug,\n branch: 'ingest',\n documentId: docId,\n ok: true,\n chunkCount: savedChunks.length,\n embeddingsWritten: embedResult.embeddingsWritten,\n embeddingsFailed: embedResult.embeddingsFailed,\n });\n return json({\n documentId: docId,\n chunkCount: savedChunks.length,\n embeddingAttempted: savedChunks.length > 0,\n created: true,\n linked: true,\n embeddingsWritten: embedResult.embeddingsWritten,\n embeddingsFailed: embedResult.embeddingsFailed,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to ingest knowledge';\n const name = err instanceof Error ? err.name : '';\n logKbPipeline('99_pipeline_error', { slug, errorName: name, message: msg });\n return json({ error: msg, errorName: name || undefined }, { status: 500 });\n }\n },\n\n async unlink(req: Request, slug: string, documentIdStr: string): Promise<Response> {\n const denied = await gate(req, 'update');\n if (denied) return denied;\n const documentId = parseInt(documentIdStr, 10);\n if (!Number.isFinite(documentId)) return json({ error: 'Invalid document id' }, { status: 400 });\n try {\n const agent = await findAgentBySlug(dataSource, llmAgents, slug);\n if (!agent) return json({ error: 'Agent not found' }, { status: 404 });\n logKbPipeline('unlink_junction', { slug, agentId: agent.id, documentId });\n const linkRepo = dataSource.getRepository(junction);\n await linkRepo.delete({ agentId: agent.id, documentId } as object);\n return json({ ok: true });\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Failed to unlink';\n return json({ error: msg }, { status: 500 });\n }\n },\n };\n}\n","export type SmsMessageTemplateDefault = {\r\n templateKey: string;\r\n name: string;\r\n body: string;\r\n externalTemplateRef?: string;\r\n providerMeta?: { otpVarKey?: string };\r\n};\r\n\r\nexport const SMS_MESSAGE_TEMPLATE_DEFAULTS: SmsMessageTemplateDefault[] = [\r\n {\r\n templateKey: 'auth.otp_login',\r\n name: 'Sign-in OTP (SMS)',\r\n body: 'Your sign-in code is {{code}}. Valid 10 minutes.',\r\n providerMeta: { otpVarKey: 'var1' },\r\n },\r\n {\r\n templateKey: 'auth.otp_verify_phone',\r\n name: 'Verify phone OTP (SMS)',\r\n body: 'Your verification code is {{code}}. Valid 10 minutes.',\r\n providerMeta: { otpVarKey: 'var1' },\r\n },\r\n];\r\n\r\nexport function getSmsTemplateDefault(templateKey: string): SmsMessageTemplateDefault | undefined {\r\n return SMS_MESSAGE_TEMPLATE_DEFAULTS.find((d) => d.templateKey === templateKey);\r\n}\r\n\r\nexport type ResolvedSmsTemplate = {\r\n body: string;\r\n externalTemplateRef: string | undefined;\r\n otpVarKey: string;\r\n};\r\n\r\nexport async function resolveSmsTemplateForSend(\r\n templateKey: string,\r\n getRow: (channel: string, key: string) => Promise<{\r\n body: string;\r\n externalTemplateRef: string | null;\r\n providerMeta: Record<string, unknown> | null;\r\n enabled: boolean;\r\n } | null>\r\n): Promise<ResolvedSmsTemplate | null> {\r\n const def = getSmsTemplateDefault(templateKey);\r\n if (!def) return null;\r\n\r\n const row = await getRow('sms', templateKey);\r\n let body = def.body;\r\n let ref = def.externalTemplateRef;\r\n let otpVarKey = def.providerMeta?.otpVarKey ?? 'var1';\r\n\r\n if (row && row.enabled !== false) {\r\n if (row.body.trim()) body = row.body;\r\n if (row.externalTemplateRef?.trim()) ref = row.externalTemplateRef.trim();\r\n const pm = row.providerMeta;\r\n const k = pm && typeof pm.otpVarKey === 'string' ? pm.otpVarKey.trim() : '';\r\n if (k) otpVarKey = k;\r\n }\r\n\r\n return {\r\n body,\r\n externalTemplateRef: ref?.trim() || undefined,\r\n otpVarKey: otpVarKey || 'var1',\r\n };\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport type { EntityMap } from './crud';\r\nimport { SMS_MESSAGE_TEMPLATE_DEFAULTS, getSmsTemplateDefault } from '../message-templates/sms-defaults';\r\nimport type { RequireEntityPermissionFn } from './cms-handlers';\r\n\r\nexport interface MessageTemplateAdminHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n requireAuth: (req: Request) => Promise<Response | null>;\r\n requireEntityPermission?: RequireEntityPermissionFn;\r\n}\r\n\r\nexport function createSmsMessageTemplateHandlers(config: MessageTemplateAdminHandlersConfig) {\r\n const { dataSource, entityMap, json, requireAuth, requireEntityPermission } = config;\r\n\r\n const repo = () => dataSource.getRepository(entityMap.message_templates);\r\n\r\n async function requireSettingsRead(req: Request): Promise<Response | null> {\r\n const a = await requireAuth(req);\r\n if (a) return a;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'settings', 'read');\r\n if (pe) return pe;\r\n }\r\n return null;\r\n }\r\n\r\n async function requireSettingsUpdate(req: Request): Promise<Response | null> {\r\n const a = await requireAuth(req);\r\n if (a) return a;\r\n if (requireEntityPermission) {\r\n const pe = await requireEntityPermission(req, 'settings', 'update');\r\n if (pe) return pe;\r\n }\r\n return null;\r\n }\r\n\r\n return {\r\n async GET(req: Request): Promise<Response> {\r\n const err = await requireSettingsRead(req);\r\n if (err) return err;\r\n try {\r\n const rows = await repo().find({ where: { channel: 'sms', deleted: false } as object });\r\n const byKey = new Map(rows.map((r) => [r.templateKey, r]));\r\n const items = SMS_MESSAGE_TEMPLATE_DEFAULTS.map((def) => {\r\n const row = byKey.get(def.templateKey);\r\n return {\r\n templateKey: def.templateKey,\r\n name: def.name,\r\n defaultBody: def.body,\r\n body: row?.body?.trim() ? row.body : def.body,\r\n externalTemplateRef: row?.externalTemplateRef?.trim() ?? '',\r\n otpVarKey:\r\n row?.providerMeta && typeof row.providerMeta.otpVarKey === 'string'\r\n ? String(row.providerMeta.otpVarKey)\r\n : def.providerMeta?.otpVarKey ?? 'var1',\r\n enabled: row ? row.enabled : false,\r\n dbId: row?.id ?? null,\r\n };\r\n });\r\n return json({ items });\r\n } catch {\r\n return json({ error: 'Failed to load templates' }, { status: 500 });\r\n }\r\n },\r\n\r\n async PUT(req: Request): Promise<Response> {\r\n const err = await requireSettingsUpdate(req);\r\n if (err) return err;\r\n try {\r\n const raw = (await req.json().catch(() => null)) as {\r\n items?: Array<{\r\n templateKey?: string;\r\n body?: string;\r\n externalTemplateRef?: string;\r\n otpVarKey?: string;\r\n enabled?: boolean;\r\n }>;\r\n } | null;\r\n if (!raw?.items || !Array.isArray(raw.items)) {\r\n return json({ error: 'Invalid payload' }, { status: 400 });\r\n }\r\n\r\n for (const item of raw.items) {\r\n const templateKey = typeof item.templateKey === 'string' ? item.templateKey.trim() : '';\r\n if (!getSmsTemplateDefault(templateKey)) continue;\r\n\r\n const body = typeof item.body === 'string' ? item.body : '';\r\n const externalTemplateRef =\r\n typeof item.externalTemplateRef === 'string' ? item.externalTemplateRef.trim() : '';\r\n const otpVarKey =\r\n typeof item.otpVarKey === 'string' && item.otpVarKey.trim()\r\n ? item.otpVarKey.trim()\r\n : 'var1';\r\n const enabled = item.enabled !== false;\r\n\r\n const existing = await repo().findOne({\r\n where: { channel: 'sms', templateKey, deleted: false } as object,\r\n });\r\n const def = getSmsTemplateDefault(templateKey)!;\r\n const providerMeta = { otpVarKey };\r\n\r\n if (existing) {\r\n await repo().update(existing.id, {\r\n name: def.name,\r\n body,\r\n externalTemplateRef: externalTemplateRef || null,\r\n providerMeta,\r\n enabled,\r\n updatedAt: new Date(),\r\n } as object);\r\n } else {\r\n await repo().save(\r\n repo().create({\r\n channel: 'sms',\r\n templateKey,\r\n name: def.name,\r\n subject: null,\r\n body,\r\n externalTemplateRef: externalTemplateRef || null,\r\n providerMeta,\r\n enabled,\r\n deleted: false,\r\n } as object)\r\n );\r\n }\r\n }\r\n return json({ ok: true });\r\n } catch {\r\n return json({ error: 'Failed to save templates' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n","/** API resource keys excluded from the permission matrix (internal / not admin-CRUD). */\r\nexport const PERMISSION_ENTITY_INTERNAL_EXCLUDE = new Set([\r\n 'users',\r\n 'password_reset_tokens',\r\n 'user_groups',\r\n 'permissions',\r\n 'comments',\r\n 'form_fields',\r\n 'configs',\r\n 'knowledge_base_chunks',\r\n 'carts',\r\n 'cart_items',\r\n 'wishlists',\r\n 'wishlist_items',\r\n 'message_templates',\r\n]);\r\n\r\n/** Non-CRUD admin surfaces mapped to entity keys for RBAC. */\r\nexport const PERMISSION_LOGICAL_ENTITIES = [\r\n 'users',\r\n 'forms',\r\n 'form_submissions',\r\n 'dashboard',\r\n 'upload',\r\n 'settings',\r\n 'analytics',\r\n 'chat',\r\n] as const;\r\n\r\n/** Canonical name for new installs / migrations */\r\nexport const ADMIN_GROUP_NAME = 'Administrator';\r\n\r\n/** System administrator group (roles UI + users / user_groups / permissions bypass). */\r\nexport function isSuperAdminGroupName(name: string | null | undefined): boolean {\r\n return name === ADMIN_GROUP_NAME;\r\n}\r\n\r\nexport type EntityCrudAction = 'create' | 'read' | 'update' | 'delete';\r\n\r\nexport type EntityPermissionFlags = { c: boolean; r: boolean; u: boolean; d: boolean };\r\n\r\nexport function getPermissionableEntityKeys(entityMap: Record<string, unknown>): string[] {\r\n const fromMap = Object.keys(entityMap).filter((k) => !PERMISSION_ENTITY_INTERNAL_EXCLUDE.has(k));\r\n const logical = PERMISSION_LOGICAL_ENTITIES.filter((k) => !fromMap.includes(k));\r\n return [...fromMap.sort(), ...logical].filter((k, i, a) => a.indexOf(k) === i);\r\n}\r\n\r\nexport function permissionRowsToRecord(\r\n rows: Array<{ entity: string; canCreate: boolean; canRead: boolean; canUpdate: boolean; canDelete: boolean }> | undefined\r\n): Record<string, EntityPermissionFlags> {\r\n const out: Record<string, EntityPermissionFlags> = {};\r\n if (!rows?.length) return out;\r\n for (const p of rows) {\r\n out[p.entity] = {\r\n c: !!p.canCreate,\r\n r: !!p.canRead,\r\n u: !!p.canUpdate,\r\n d: !!p.canDelete,\r\n };\r\n }\r\n return out;\r\n}\r\n\r\nexport function hasEntityPermission(\r\n record: Record<string, EntityPermissionFlags> | undefined,\r\n entity: string,\r\n action: EntityCrudAction\r\n): boolean {\r\n const p = record?.[entity];\r\n if (!p) return false;\r\n if (action === 'create') return p.c;\r\n if (action === 'read') return p.r;\r\n if (action === 'update') return p.u;\r\n return p.d;\r\n}\r\n","import type { EntityCrudAction, EntityPermissionFlags } from './permission-entities';\r\nimport { hasEntityPermission } from './permission-entities';\r\n\r\n/** isRBACAdmin bypasses entity checks only for these (users / roles plumbing). */\r\nexport const RBAC_ADMIN_ONLY_ENTITIES = new Set(['users', 'user_groups', 'permissions']);\r\n\r\nexport interface SessionUser {\r\n id?: string;\r\n email?: string | null;\r\n name?: string | null;\r\n groupId?: number;\r\n /** @deprecated use entityPerms / isRBACAdmin */\r\n permissions?: string[];\r\n /** Administrator group: full access only for users, user_groups, permissions */\r\n isRBACAdmin?: boolean;\r\n entityPerms?: Record<string, EntityPermissionFlags>;\r\n /** When false and not isRBACAdmin, admin API/UI is denied. */\r\n adminAccess?: boolean;\r\n}\r\n\r\nexport function sessionHasEntityAccess(\r\n user: SessionUser | null | undefined,\r\n entity: string,\r\n action: EntityCrudAction\r\n): boolean {\r\n if (!user?.email) return false;\r\n if (user.isRBACAdmin && RBAC_ADMIN_ONLY_ENTITIES.has(entity)) return true;\r\n return hasEntityPermission(user.entityPerms, entity, action);\r\n}\r\n\r\nexport function canManageRoles(user: SessionUser | null | undefined): boolean {\r\n return !!(user?.email && user.isRBACAdmin);\r\n}\r\n\r\nexport type GetSession = () => Promise<{ user?: SessionUser } | null>;\r\n\r\nexport const OPEN_ENDPOINTS: Array<Record<string, string[]>> = [\r\n { '/api/contacts': ['POST'] },\r\n { '/api/form-submissions': ['POST'] },\r\n { '/api/blogs': ['GET'] },\r\n];\r\n\r\nexport const PERMISSION_REQUIRED_ENDPOINTS: Record<string, string[]> = {};\r\n\r\nexport function isOpenEndpoint(pathname: string): boolean {\r\n return OPEN_ENDPOINTS.some((endpoint) => pathname.startsWith(Object.keys(endpoint)[0]));\r\n}\r\n\r\nexport function getRequiredPermission(pathname: string): string[] | null {\r\n return null;\r\n}\r\n\r\nexport function isPublicMethod(pathname: string, method: string): boolean {\r\n for (const endpoint of OPEN_ENDPOINTS) {\r\n const key = Object.keys(endpoint)[0];\r\n if (pathname.startsWith(key) && endpoint[key].includes(method)) return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport interface AuthHelpers {\r\n requireAuth(req: Request): Promise<Response | null>;\r\n requirePermission(req: Request, permission: string): Promise<Response | null>;\r\n requireEntityPermission(req: Request, entity: string, action: EntityCrudAction): Promise<Response | null>;\r\n requireAdminAccess(req: Request): Promise<Response | null>;\r\n getAuthenticatedUser(): Promise<SessionUser | null>;\r\n}\r\n\r\nexport function createAuthHelpers(getSession: GetSession, NextResponse: { json: (body: unknown, init?: { status?: number }) => Response }): AuthHelpers {\r\n return {\r\n async requireAuth() {\r\n const session = await getSession();\r\n if (!session?.user?.email) {\r\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });\r\n }\r\n return null;\r\n },\r\n async requirePermission() {\r\n const session = await getSession();\r\n if (!session?.user?.email) {\r\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });\r\n }\r\n return null;\r\n },\r\n async requireEntityPermission(_req: Request, entity: string, action: EntityCrudAction) {\r\n const session = await getSession();\r\n if (!session?.user?.email) {\r\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });\r\n }\r\n const u = session.user as SessionUser;\r\n if (sessionHasEntityAccess(u, entity, action)) return null;\r\n return NextResponse.json({ error: 'Forbidden', entity, action }, { status: 403 });\r\n },\r\n async requireAdminAccess() {\r\n const session = await getSession();\r\n if (!session?.user?.email) {\r\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });\r\n }\r\n const u = session.user as SessionUser;\r\n if (u.isRBACAdmin) return null;\r\n if (u.adminAccess === false) return NextResponse.json({ error: 'Forbidden', reason: 'admin_access' }, { status: 403 });\r\n return null;\r\n },\r\n async getAuthenticatedUser() {\r\n const session = await getSession();\r\n return (session?.user as SessionUser) ?? null;\r\n },\r\n };\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport type { EntityMap } from './crud';\r\nimport { getPermissionableEntityKeys, isSuperAdminGroupName } from '../auth/permission-entities';\r\nimport type { SessionUser } from '../auth/helpers';\r\nimport { canManageRoles } from '../auth/helpers';\r\n\r\nexport type GetSessionUser = () => Promise<SessionUser | null>;\r\n\r\nexport interface AdminRolesHandlersConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n getSessionUser: GetSessionUser;\r\n}\r\n\r\nexport function createAdminRolesHandlers(config: AdminRolesHandlersConfig) {\r\n const { dataSource, entityMap, json, getSessionUser } = config;\r\n const baseEntities = getPermissionableEntityKeys(entityMap as Record<string, unknown>);\r\n const allowEntities = new Set([...baseEntities, 'users']);\r\n const groupRepo = () => dataSource.getRepository(entityMap.user_groups);\r\n const permRepo = () => dataSource.getRepository(entityMap.permissions);\r\n const userRepo = () => dataSource.getRepository(entityMap.users);\r\n\r\n async function gate(): Promise<Response | null> {\r\n const u = await getSessionUser();\r\n if (!u?.email) return json({ error: 'Unauthorized' }, { status: 401 });\r\n if (!canManageRoles(u)) return json({ error: 'Forbidden' }, { status: 403 });\r\n return null;\r\n }\r\n\r\n return {\r\n async list(): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n const groups = await groupRepo().find({\r\n where: { deleted: false },\r\n order: { id: 'ASC' },\r\n relations: ['permissions'],\r\n });\r\n const entities = [...allowEntities].sort();\r\n return json({\r\n entities,\r\n groups: groups.map((g) => ({\r\n id: g.id,\r\n name: g.name,\r\n permissions: (g.permissions ?? [])\r\n .filter((p) => !p.deleted)\r\n .map((p) => ({\r\n entity: p.entity,\r\n canCreate: p.canCreate,\r\n canRead: p.canRead,\r\n canUpdate: p.canUpdate,\r\n canDelete: p.canDelete,\r\n })),\r\n })),\r\n });\r\n },\r\n\r\n async createGroup(req: Request): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n try {\r\n const body = (await req.json()) as { name?: string };\r\n const name = body?.name?.trim();\r\n if (!name) return json({ error: 'Name is required' }, { status: 400 });\r\n const repo = groupRepo();\r\n const existing = await repo.findOne({ where: { name } });\r\n if (existing) return json({ error: 'Group name already exists' }, { status: 400 });\r\n const g = await repo.save(repo.create({ name }));\r\n return json({ id: g.id, name: g.name, permissions: [] }, { status: 201 });\r\n } catch {\r\n return json({ error: 'Server error' }, { status: 500 });\r\n }\r\n },\r\n\r\n async patchGroup(req: Request, idStr: string): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n const id = parseInt(idStr, 10);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n try {\r\n const body = (await req.json()) as { name?: string };\r\n const name = body?.name?.trim();\r\n if (!name) return json({ error: 'Name is required' }, { status: 400 });\r\n const repo = groupRepo();\r\n const g = await repo.findOne({ where: { id, deleted: false } });\r\n if (!g) return json({ error: 'Not found' }, { status: 404 });\r\n if (isSuperAdminGroupName(g.name) && !isSuperAdminGroupName(name)) {\r\n return json({ error: 'Cannot rename the administrator group' }, { status: 400 });\r\n }\r\n const dup = await repo.findOne({ where: { name } });\r\n if (dup && dup.id !== id) return json({ error: 'Name already in use' }, { status: 400 });\r\n g.name = name;\r\n await repo.save(g);\r\n return json({ id: g.id, name: g.name });\r\n } catch {\r\n return json({ error: 'Server error' }, { status: 500 });\r\n }\r\n },\r\n\r\n async deleteGroup(idStr: string): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n const id = parseInt(idStr, 10);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const repo = groupRepo();\r\n const g = await repo.findOne({ where: { id, deleted: false } });\r\n if (!g) return json({ error: 'Not found' }, { status: 404 });\r\n if (isSuperAdminGroupName(g.name)) return json({ error: 'Cannot delete the administrator group' }, { status: 400 });\r\n const userCount = await userRepo().count({ where: { groupId: id } });\r\n if (userCount > 0) return json({ error: 'Reassign users before deleting this group' }, { status: 409 });\r\n await permRepo().delete({ groupId: id });\r\n await repo.update(id, { deleted: true, deletedAt: new Date() } as object);\r\n return json({ ok: true });\r\n },\r\n\r\n async putPermissions(req: Request, idStr: string): Promise<Response> {\r\n const err = await gate();\r\n if (err) return err;\r\n const groupId = parseInt(idStr, 10);\r\n if (!Number.isFinite(groupId)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const groupRepository = groupRepo();\r\n const g = await groupRepository.findOne({ where: { id: groupId, deleted: false } });\r\n if (!g) return json({ error: 'Group not found' }, { status: 404 });\r\n try {\r\n const body = (await req.json()) as {\r\n permissions?: Array<{\r\n entity: string;\r\n canCreate?: boolean;\r\n canRead?: boolean;\r\n canUpdate?: boolean;\r\n canDelete?: boolean;\r\n }>;\r\n };\r\n const rows = body?.permissions;\r\n if (!Array.isArray(rows)) return json({ error: 'permissions array required' }, { status: 400 });\r\n for (const r of rows) {\r\n if (!r?.entity || !allowEntities.has(r.entity)) {\r\n return json({ error: `Invalid entity: ${r?.entity ?? ''}` }, { status: 400 });\r\n }\r\n }\r\n await dataSource.transaction(async (em) => {\r\n await em.getRepository(entityMap.permissions).delete({ groupId });\r\n for (const r of rows) {\r\n await em.getRepository(entityMap.permissions).save(\r\n em.getRepository(entityMap.permissions).create({\r\n groupId,\r\n entity: r.entity,\r\n canCreate: !!r.canCreate,\r\n canRead: !!r.canRead,\r\n canUpdate: !!r.canUpdate,\r\n canDelete: !!r.canDelete,\r\n })\r\n );\r\n }\r\n });\r\n const updated = await groupRepository.findOne({\r\n where: { id: groupId },\r\n relations: ['permissions'],\r\n });\r\n return json({\r\n id: groupId,\r\n permissions: (updated?.permissions ?? []).map((p) => ({\r\n entity: p.entity,\r\n canCreate: p.canCreate,\r\n canRead: p.canRead,\r\n canUpdate: p.canUpdate,\r\n canDelete: p.canDelete,\r\n })),\r\n });\r\n } catch {\r\n return json({ error: 'Server error' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { UserGroup } from './user-group.entity';\r\n\r\n@Entity('users')\r\nexport class User {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n email: string;\r\n\r\n /** E.164 when set; unique among non-null values (partial index in DB). */\r\n @Column('varchar', { nullable: true })\r\n phone: string | null;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n phoneVerifiedAt: Date | null;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n emailVerifiedAt: Date | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n password: string | null;\r\n\r\n @Column('boolean', { default: false })\r\n blocked: boolean;\r\n\r\n @Column('boolean', { default: false })\r\n adminAccess: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n groupId: number | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => UserGroup, (g) => g.users, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'groupId' })\r\n group: UserGroup | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport { Permission } from './permission.entity';\r\nimport { User } from './user.entity';\r\n\r\n@Entity('user_groups')\r\nexport class UserGroup {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { unique: true })\r\n name: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @OneToMany(() => Permission, (p) => p.group)\r\n permissions: Permission[];\r\n\r\n @OneToMany(() => User, (u) => u.group)\r\n users: User[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { UserGroup } from './user-group.entity';\r\n\r\n@Entity('permissions')\r\nexport class Permission {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n groupId: number;\r\n\r\n @Column('varchar')\r\n entity: string;\r\n\r\n @Column('boolean', { default: false })\r\n canCreate: boolean;\r\n\r\n @Column('boolean', { default: false })\r\n canRead: boolean;\r\n\r\n @Column('boolean', { default: false })\r\n canUpdate: boolean;\r\n\r\n @Column('boolean', { default: false })\r\n canDelete: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => UserGroup, (g) => g.permissions, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'groupId' })\r\n group: UserGroup;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, Index } from 'typeorm';\r\n\r\n@Entity('otp_challenges')\r\n@Index(['purpose', 'identifier'])\r\nexport class OtpChallenge {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n purpose: string;\r\n\r\n @Column('varchar')\r\n channel: string;\r\n\r\n @Column('varchar')\r\n identifier: string;\r\n\r\n @Column('varchar')\r\n codeHash: string;\r\n\r\n @Column({ type: 'timestamp' })\r\n expiresAt: Date;\r\n\r\n @Column('int', { default: 0 })\r\n attempts: number;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n consumedAt: Date | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\n\r\n@Entity('password_reset_tokens')\r\nexport class PasswordResetToken {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n email: string;\r\n\r\n @Column('varchar', { unique: true })\r\n token: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n expiresAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n}\r\n","import {\r\n Entity,\r\n PrimaryGeneratedColumn,\r\n Column,\r\n ManyToOne,\r\n OneToMany,\r\n ManyToMany,\r\n JoinTable,\r\n JoinColumn,\r\n} from 'typeorm';\r\nimport { User } from './user.entity';\r\nimport { Category } from './category.entity';\r\nimport { Seo } from './seo.entity';\r\nimport { Comment } from './comment.entity';\r\nimport { Tag } from './tag.entity';\r\n\r\n@Entity('blogs')\r\nexport class Blog {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n title: string;\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n coverImage: string | null;\r\n\r\n @Column('int')\r\n authorId: number;\r\n\r\n @Column('int', { nullable: true })\r\n categoryId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @Column('boolean', { default: false })\r\n published: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @ManyToOne(() => User, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'authorId' })\r\n author: User;\r\n\r\n @ManyToOne(() => Category, (c) => c.blogs, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'categoryId' })\r\n category: Category | null;\r\n\r\n @ManyToOne(() => Seo, (s) => s.blogs, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @OneToMany(() => Comment, (c) => c.blog)\r\n comments: Comment[];\r\n\r\n @ManyToMany(() => Tag, (t) => t.blogs)\r\n @JoinTable({\r\n name: 'blog_tags',\r\n joinColumn: { name: 'blogId', referencedColumnName: 'id' },\r\n inverseJoinColumn: { name: 'tagId', referencedColumnName: 'id' },\r\n })\r\n tags: Tag[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport type { Blog } from './blog.entity';\r\n\r\n@Entity('categories')\r\nexport class Category {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { unique: true })\r\n name: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @OneToMany('Blog', 'category')\r\n blogs: Blog[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport { Blog } from './blog.entity';\r\n\r\n@Entity('seos')\r\nexport class Seo {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n title: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n keywords: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n ogTitle: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n ogDescription: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n ogImage: string | null;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @OneToMany(() => Blog, (blog) => blog.seo)\r\n blogs: Blog[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { User } from './user.entity';\r\nimport { Blog } from './blog.entity';\r\n\r\n@Entity('comments')\r\nexport class Comment {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column('int')\r\n blogId: number;\r\n\r\n @Column('int')\r\n authorId: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => User, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'authorId' })\r\n author: User;\r\n\r\n @ManyToOne(() => Blog, (b) => b.comments, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'blogId' })\r\n blog: Blog;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from 'typeorm';\r\nimport { Blog } from './blog.entity';\r\n\r\n@Entity('tags')\r\nexport class Tag {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { unique: true })\r\n name: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToMany(() => Blog, (blog) => blog.tags)\r\n blogs: Blog[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { User } from './user.entity';\r\nimport { FormSubmission } from './form-submission.entity';\r\nimport { Address } from './address.entity';\r\nimport { Order } from './order.entity';\r\nimport { Payment } from './payment.entity';\r\nimport { ChatConversation } from './chat-conversation.entity';\r\n\r\n@Entity('contacts')\r\nexport class Contact {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n email: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n phone: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n type: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n company: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n taxId: string | null;\r\n\r\n @Column('text', { nullable: true })\r\n notes: string | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n userId: number | null;\r\n\r\n @ManyToOne(() => User, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'userId' })\r\n user: User | null;\r\n\r\n @OneToMany(() => FormSubmission, (fs) => fs.contact)\r\n form_submissions: FormSubmission[];\r\n\r\n @OneToMany(() => Address, (a) => a.contact)\r\n addresses: Address[];\r\n\r\n @OneToMany(() => Order, (o) => o.contact)\r\n orders: Order[];\r\n\r\n @OneToMany(() => Payment, (p) => p.contact)\r\n payments: Payment[];\r\n\r\n @OneToMany(() => ChatConversation, (c) => c.contact)\r\n chatConversations: ChatConversation[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Form } from './form.entity';\r\nimport { Contact } from './contact.entity';\r\n\r\n@Entity('form_submissions')\r\nexport class FormSubmission {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n formId: number;\r\n\r\n @Column('int', { nullable: true })\r\n contactId: number | null;\r\n\r\n @Column('jsonb')\r\n data: Record<string, unknown>;\r\n\r\n @Column('varchar', { nullable: true })\r\n ipAddress: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n userAgent: string | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Form, (f) => f.submissions, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'formId' })\r\n form: Form;\r\n\r\n @ManyToOne(() => Contact, (c) => c.form_submissions, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport { FormField } from './form-field.entity';\r\nimport { FormSubmission } from './form-submission.entity';\r\n\r\n@Entity('forms')\r\nexport class Form {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n campaign: string | null;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('boolean', { default: false })\r\n published: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @OneToMany(() => FormField, (f) => f.form)\r\n fields: FormField[];\r\n\r\n @OneToMany(() => FormSubmission, (s) => s.form)\r\n submissions: FormSubmission[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Form } from './form.entity';\r\n\r\n@Entity('form_fields')\r\nexport class FormField {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n formId: number;\r\n\r\n @Column('varchar')\r\n label: string;\r\n\r\n @Column('varchar')\r\n type: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n placeholder: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n options: string | null;\r\n\r\n @Column('boolean', { default: false })\r\n required: boolean;\r\n\r\n @Column('varchar', { nullable: true })\r\n validation: string | null;\r\n\r\n @Column('int')\r\n order: number;\r\n\r\n @Column('int', { default: 1 })\r\n groupId: number;\r\n\r\n @Column('int', { default: 12 })\r\n columnWidth: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => Form, (f) => f.fields, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'formId' })\r\n form: Form;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\n\r\n@Entity('addresses')\r\nexport class Address {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n contactId: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n tag: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n line1: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n line2: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n city: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n state: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n postalCode: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n country: string | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Contact, (c) => c.addresses, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\nimport { Address } from './address.entity';\r\nimport type { OrderItem } from './order-item.entity';\r\nimport type { Payment } from './payment.entity';\r\n\r\nexport type OrderKind = 'sale' | 'return' | 'replacement';\r\n\r\n@Entity('orders')\r\nexport class Order {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { unique: true })\r\n orderNumber: string;\r\n\r\n @Column('varchar', { default: 'sale' })\r\n orderKind: OrderKind;\r\n\r\n @Column('int', { nullable: true })\r\n parentOrderId: number | null;\r\n\r\n @Column('int')\r\n contactId: number;\r\n\r\n @Column('int', { nullable: true })\r\n billingAddressId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n shippingAddressId: number | null;\r\n\r\n @Column('varchar', { default: 'pending' })\r\n status: 'pending' | 'confirmed' | 'processing' | 'completed' | 'cancelled';\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n subtotal: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n tax: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n discount: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n total: number;\r\n\r\n @Column('varchar', { default: 'INR' })\r\n currency: string;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => Order, (o) => o.children, { nullable: true, onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'parentOrderId' })\r\n parentOrder: Order | null;\r\n\r\n @OneToMany(() => Order, (o) => o.parentOrder)\r\n children: Order[];\r\n\r\n @ManyToOne(() => Contact, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact;\r\n\r\n @ManyToOne(() => Address, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'billingAddressId' })\r\n billingAddress: Address | null;\r\n\r\n @ManyToOne(() => Address, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'shippingAddressId' })\r\n shippingAddress: Address | null;\r\n\r\n @OneToMany('OrderItem', 'order')\r\n items: OrderItem[];\r\n\r\n @OneToMany('Payment', 'order')\r\n payments: Payment[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Order } from './order.entity';\r\nimport { Contact } from './contact.entity';\r\n\r\n@Entity('payments')\r\nexport class Payment {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n orderId: number;\r\n\r\n @Column('int', { nullable: true })\r\n contactId: number | null;\r\n\r\n @Column('decimal', { precision: 12, scale: 2 })\r\n amount: number;\r\n\r\n @Column('varchar', { default: 'INR' })\r\n currency: string;\r\n\r\n @Column('varchar', { default: 'pending' })\r\n status: 'pending' | 'processing' | 'completed' | 'failed' | 'refunded';\r\n\r\n @Column('varchar', { nullable: true })\r\n method: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n externalReference: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n paidAt: Date | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => Order, (o) => o.payments, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'orderId' })\r\n order: Order;\r\n\r\n @ManyToOne(() => Contact, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\nimport { ChatMessage } from './chat-message.entity';\r\n\r\n@Entity('chat_conversations')\r\nexport class ChatConversation {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n contactId: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Contact, (c) => c.chatConversations, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact;\r\n\r\n @OneToMany(() => ChatMessage, (m) => m.conversation)\r\n messages: ChatMessage[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { ChatConversation } from './chat-conversation.entity';\r\n\r\n@Entity('chat_messages')\r\nexport class ChatMessage {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n conversationId: number;\r\n\r\n @Column('varchar')\r\n role: 'user' | 'assistant' | 'system';\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @ManyToOne(() => ChatConversation, (c) => c.messages, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'conversationId' })\r\n conversation: ChatConversation;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, Unique } from 'typeorm';\r\n\r\n@Entity('configs')\r\n@Unique(['settings', 'key'])\r\nexport class Config {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n settings: string;\r\n\r\n @Column('varchar')\r\n key: string;\r\n\r\n @Column('varchar')\r\n value: string;\r\n\r\n @Column('varchar', { default: 'private' })\r\n type: 'public' | 'private';\r\n\r\n @Column('boolean', { default: false })\r\n encrypted: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\n\r\n@Entity('message_templates')\r\nexport class MessageTemplate {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n channel: string;\r\n\r\n @Column('varchar', { name: 'template_key' })\r\n templateKey: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n name: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n subject: string | null;\r\n\r\n @Column('text', { default: '' })\r\n body: string;\r\n\r\n @Column('varchar', { name: 'external_template_ref', nullable: true })\r\n externalTemplateRef: string | null;\r\n\r\n @Column({ type: 'jsonb', nullable: true })\r\n providerMeta: Record<string, unknown> | null;\r\n\r\n @Column('boolean', { default: true })\r\n enabled: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\n\r\n@Entity('media')\r\nexport class Media {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column({ type: 'varchar', length: 16, default: 'file' })\r\n kind: 'file' | 'folder';\r\n\r\n @Column({ type: 'int', nullable: true })\r\n parentId: number | null;\r\n\r\n @ManyToOne(() => Media, (m) => m.children, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'parentId' })\r\n parent: Media | null;\r\n\r\n @OneToMany(() => Media, (m) => m.parent)\r\n children: Media[];\r\n\r\n @Column('varchar')\r\n filename: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n url: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n mimeType: string | null;\r\n\r\n @Column('int', { default: 0 })\r\n size: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n alt: string | null;\r\n\r\n @Column('boolean', { default: false })\r\n isPublic: boolean;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Seo } from './seo.entity';\r\n\r\n@Entity('pages')\r\nexport class Page {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n title: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column({ type: 'jsonb', default: {} })\r\n content: object;\r\n\r\n @Column('boolean', { default: false })\r\n published: boolean;\r\n\r\n @Column('varchar', { default: 'default' })\r\n theme: string;\r\n\r\n @Column('int', { nullable: true })\r\n parentId: number | null;\r\n\r\n @ManyToOne(() => Page, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'parentId' })\r\n parent: Page | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @ManyToOne(() => Seo, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport type { Product } from './product.entity';\r\nimport type { Collection } from './collection.entity';\r\n\r\n@Entity('product_categories')\r\nexport class ProductCategory {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('int', { nullable: true })\r\n parentId: number | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n image: string | null;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('int', { default: 0 })\r\n sortOrder: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @ManyToOne(() => ProductCategory, (c) => c.children, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'parentId' })\r\n parent: ProductCategory | null;\r\n\r\n @OneToMany(() => ProductCategory, (c) => c.parent)\r\n children: ProductCategory[];\r\n\r\n @OneToMany('Product', 'category')\r\n products: Product[];\r\n\r\n @OneToMany('Collection', 'category')\r\n collections: Collection[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { ProductCategory } from './product-category.entity';\r\nimport { Brand } from './brand.entity';\r\nimport { Seo } from './seo.entity';\r\nimport type { Product } from './product.entity';\r\n\r\n@Entity('collections')\r\nexport class Collection {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int', { nullable: true })\r\n categoryId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n brandId: number | null;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n hsn: string | null;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n image: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n variants: Array<Record<string, unknown>> | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('int', { default: 0 })\r\n sortOrder: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @ManyToOne(() => Seo, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @ManyToOne(() => ProductCategory, (c) => c.collections, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'categoryId' })\r\n category: ProductCategory | null;\r\n\r\n @ManyToOne(() => Brand, (b) => b.collections, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'brandId' })\r\n brand: Brand | null;\r\n\r\n @OneToMany('Product', 'collection')\r\n products: Product[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Seo } from './seo.entity';\r\nimport type { Product } from './product.entity';\r\nimport type { Collection } from './collection.entity';\r\n\r\n@Entity('brands')\r\nexport class Brand {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n logo: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('int', { default: 0 })\r\n sortOrder: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @ManyToOne(() => Seo, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @OneToMany('Product', 'brand')\r\n products: Product[];\r\n\r\n @OneToMany('Collection', 'brand')\r\n collections: Collection[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Collection } from './collection.entity';\r\nimport { Brand } from './brand.entity';\r\nimport { ProductCategory } from './product-category.entity';\r\nimport { Seo } from './seo.entity';\r\nimport type { ProductAttribute } from './product-attribute.entity';\r\nimport type { ProductTax } from './product-tax.entity';\r\n\r\n@Entity('products')\r\nexport class Product {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int', { nullable: true })\r\n collectionId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n brandId: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n categoryId: number | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n sku: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n hsn: string | null;\r\n\r\n /** Unit of measure, e.g. pcs, kg, hrs */\r\n @Column('varchar', { nullable: true })\r\n uom: string | null;\r\n\r\n @Column('varchar', { default: 'product' })\r\n type: 'product' | 'service';\r\n\r\n @Column('varchar', { unique: true, nullable: true })\r\n slug: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n name: string | null;\r\n\r\n @Column('decimal', { precision: 12, scale: 2 })\r\n price: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, nullable: true })\r\n compareAtPrice: number | null;\r\n\r\n @Column('int', { default: 0 })\r\n quantity: number;\r\n\r\n @Column('varchar', { default: 'draft' })\r\n status: 'draft' | 'available' | 'reserved' | 'sold';\r\n\r\n @Column('boolean', { default: false })\r\n featured: boolean;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n seoId: number | null;\r\n\r\n @ManyToOne(() => Seo, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'seoId' })\r\n seo: Seo | null;\r\n\r\n @ManyToOne(() => Collection, (c) => c.products, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'collectionId' })\r\n collection: Collection | null;\r\n\r\n @ManyToOne(() => Brand, (b) => b.products, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'brandId' })\r\n brand: Brand | null;\r\n\r\n @ManyToOne(() => ProductCategory, (c) => c.products, { onDelete: 'SET NULL' })\r\n @JoinColumn({ name: 'categoryId' })\r\n category: ProductCategory | null;\r\n\r\n @OneToMany('ProductAttribute', 'product')\r\n attributes: ProductAttribute[];\r\n\r\n @OneToMany('ProductTax', 'product')\r\n taxes: ProductTax[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\n\r\n@Entity('attributes')\r\nexport class Attribute {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('varchar', { default: 'text' })\r\n type: 'text' | 'number' | 'select' | 'boolean';\r\n\r\n @Column('jsonb', { nullable: true })\r\n options: string[] | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('int', { default: 0 })\r\n sortOrder: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Product } from './product.entity';\r\nimport { Attribute } from './attribute.entity';\r\n\r\n@Entity('product_attributes')\r\nexport class ProductAttribute {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('int')\r\n attributeId: number;\r\n\r\n @Column('varchar')\r\n value: string;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Product, (p) => p.attributes, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n\r\n @ManyToOne(() => Attribute, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'attributeId' })\r\n attribute: Attribute;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';\r\n\r\n@Entity('taxes')\r\nexport class Tax {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { unique: true })\r\n slug: string;\r\n\r\n @Column('decimal', { precision: 5, scale: 2 })\r\n rate: number;\r\n\r\n @Column('boolean', { default: false })\r\n isDefault: boolean;\r\n\r\n @Column('text', { nullable: true })\r\n description: string | null;\r\n\r\n @Column('boolean', { default: true })\r\n active: boolean;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n deletedAt: Date | null;\r\n\r\n @Column('boolean', { default: false })\r\n deleted: boolean;\r\n\r\n @Column('int', { nullable: true })\r\n createdBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n updatedBy: number | null;\r\n\r\n @Column('int', { nullable: true })\r\n deletedBy: number | null;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Product } from './product.entity';\r\nimport { Tax } from './tax.entity';\r\n\r\n@Entity('product_taxes')\r\nexport class ProductTax {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('int')\r\n taxId: number;\r\n\r\n @Column('decimal', { precision: 5, scale: 2, nullable: true })\r\n rate: number | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Product, (p) => p.taxes, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n\r\n @ManyToOne(() => Tax, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'taxId' })\r\n tax: Tax;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Order } from './order.entity';\r\nimport { Product } from './product.entity';\r\n\r\n@Entity('order_items')\r\nexport class OrderItem {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n orderId: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('int', { default: 1 })\r\n quantity: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2 })\r\n unitPrice: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2, default: 0 })\r\n tax: number;\r\n\r\n @Column('decimal', { precision: 12, scale: 2 })\r\n total: number;\r\n\r\n /** Snapshot at order time */\r\n @Column('varchar', { nullable: true })\r\n hsn: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n uom: string | null;\r\n\r\n @Column('varchar', { nullable: true })\r\n productType: string | null;\r\n\r\n @Column('decimal', { precision: 5, scale: 2, nullable: true })\r\n taxRate: number | null;\r\n\r\n /** Tax slug snapshot (from taxes.slug) */\r\n @Column('varchar', { nullable: true })\r\n taxCode: string | null;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Order, (o) => o.items, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'orderId' })\r\n order: Order;\r\n\r\n @ManyToOne(() => Product, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';\r\nimport { KnowledgeBaseChunk } from './knowledge-base-chunk.entity';\r\n\r\n@Entity('knowledge_base_documents')\r\nexport class KnowledgeBaseDocument {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar')\r\n name: string;\r\n\r\n @Column('varchar', { nullable: true })\r\n sourceUrl: string | null;\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @OneToMany(() => KnowledgeBaseChunk, (c) => c.document)\r\n chunks: KnowledgeBaseChunk[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { KnowledgeBaseDocument } from './knowledge-base-document.entity';\r\n\r\n@Entity('knowledge_base_chunks')\r\nexport class KnowledgeBaseChunk {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n documentId: number;\r\n\r\n @Column('text')\r\n content: string;\r\n\r\n @Column('int', { default: 0 })\r\n chunkIndex: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @ManyToOne(() => KnowledgeBaseDocument, (d) => d.chunks, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'documentId' })\r\n document: KnowledgeBaseDocument;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\nimport type { CartItem } from './cart-item.entity';\r\n\r\n@Entity('carts')\r\nexport class Cart {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n guestToken: string | null;\r\n\r\n @Column('int', { nullable: true })\r\n contactId: number | null;\r\n\r\n @Column('varchar', { default: 'INR' })\r\n currency: string;\r\n\r\n @Column({ type: 'timestamp', nullable: true })\r\n expiresAt: Date | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Contact, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact | null;\r\n\r\n @OneToMany('CartItem', 'cart')\r\n items: CartItem[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Cart } from './cart.entity';\r\nimport { Product } from './product.entity';\r\n\r\n@Entity('cart_items')\r\nexport class CartItem {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n cartId: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('int', { default: 1 })\r\n quantity: number;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Cart, (c) => c.items, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'cartId' })\r\n cart: Cart;\r\n\r\n @ManyToOne(() => Product, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany, JoinColumn } from 'typeorm';\r\nimport { Contact } from './contact.entity';\r\nimport type { WishlistItem } from './wishlist-item.entity';\r\n\r\n@Entity('wishlists')\r\nexport class Wishlist {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('varchar', { nullable: true })\r\n guestId: string | null;\r\n\r\n @Column('int', { nullable: true })\r\n contactId: number | null;\r\n\r\n @Column('varchar', { default: 'default' })\r\n name: string;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Contact, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'contactId' })\r\n contact: Contact | null;\r\n\r\n @OneToMany('WishlistItem', 'wishlist')\r\n items: WishlistItem[];\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';\r\nimport { Wishlist } from './wishlist.entity';\r\nimport { Product } from './product.entity';\r\n\r\n@Entity('wishlist_items')\r\nexport class WishlistItem {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n wishlistId: number;\r\n\r\n @Column('int')\r\n productId: number;\r\n\r\n @Column('jsonb', { nullable: true })\r\n metadata: Record<string, unknown> | null;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n updatedAt: Date;\r\n\r\n @ManyToOne(() => Wishlist, (w) => w.items, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'wishlistId' })\r\n wishlist: Wishlist;\r\n\r\n @ManyToOne(() => Product, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'productId' })\r\n product: Product;\r\n}\r\n","import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn, Index, Unique } from 'typeorm';\r\nimport { LlmAgent } from './llm-agent.entity';\r\nimport { KnowledgeBaseDocument } from './knowledge-base-document.entity';\r\n\r\n@Entity('llm_agent_knowledge_documents')\r\n@Unique('UQ_llm_agent_knowledge_agent_document', ['agentId', 'documentId'])\r\n@Index('IDX_llm_agent_knowledge_agent', ['agentId'])\r\nexport class LlmAgentKnowledgeDocument {\r\n @PrimaryGeneratedColumn()\r\n id: number;\r\n\r\n @Column('int')\r\n agentId: number;\r\n\r\n @Column('int')\r\n documentId: number;\r\n\r\n @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })\r\n createdAt: Date;\r\n\r\n @ManyToOne(() => LlmAgent, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'agentId' })\r\n agent: LlmAgent;\r\n\r\n @ManyToOne(() => KnowledgeBaseDocument, { onDelete: 'CASCADE' })\r\n @JoinColumn({ name: 'documentId' })\r\n document: KnowledgeBaseDocument;\r\n}\r\n","import type { EntityTarget } from 'typeorm';\nimport { User } from './user.entity';\nimport { OtpChallenge } from './otp-challenge.entity';\nimport { PasswordResetToken } from './password-reset-token.entity';\nimport { UserGroup } from './user-group.entity';\nimport { Permission } from './permission.entity';\nimport { Blog } from './blog.entity';\nimport { Tag } from './tag.entity';\nimport { Category } from './category.entity';\nimport { Comment } from './comment.entity';\nimport { Contact } from './contact.entity';\nimport { Address } from './address.entity';\nimport { Form } from './form.entity';\nimport { FormField } from './form-field.entity';\nimport { FormSubmission } from './form-submission.entity';\nimport { Seo } from './seo.entity';\nimport { Config } from './config.entity';\nimport { MessageTemplate } from './message-template.entity';\nimport { Media } from './media.entity';\nimport { Page } from './page.entity';\nimport { ProductCategory } from './product-category.entity';\nimport { Collection } from './collection.entity';\nimport { Product } from './product.entity';\nimport { Attribute } from './attribute.entity';\nimport { ProductAttribute } from './product-attribute.entity';\nimport { Tax } from './tax.entity';\nimport { ProductTax } from './product-tax.entity';\nimport { Order } from './order.entity';\nimport { OrderItem } from './order-item.entity';\nimport { Payment } from './payment.entity';\nimport { Brand } from './brand.entity';\nimport { KnowledgeBaseDocument } from './knowledge-base-document.entity';\nimport { KnowledgeBaseChunk } from './knowledge-base-chunk.entity';\nimport { ChatConversation } from './chat-conversation.entity';\nimport { ChatMessage } from './chat-message.entity';\nimport { Cart } from './cart.entity';\nimport { CartItem } from './cart-item.entity';\nimport { Wishlist } from './wishlist.entity';\nimport { WishlistItem } from './wishlist-item.entity';\nimport { LlmAgent, llmAgentToChatAgentOptions } from './llm-agent.entity';\nimport { LlmAgentKnowledgeDocument } from './llm-agent-knowledge-document.entity';\n\nexport {\n User,\n OtpChallenge,\n PasswordResetToken,\n UserGroup,\n Permission,\n Blog,\n Tag,\n Category,\n Comment,\n Contact,\n Address,\n Form,\n FormField,\n FormSubmission,\n Seo,\n Config,\n MessageTemplate,\n Media,\n Page,\n ProductCategory,\n Collection,\n Product,\n Attribute,\n ProductAttribute,\n Tax,\n ProductTax,\n Order,\n OrderItem,\n Payment,\n Brand,\n KnowledgeBaseDocument,\n KnowledgeBaseChunk,\n ChatConversation,\n ChatMessage,\n Cart,\n CartItem,\n Wishlist,\n WishlistItem,\n LlmAgent,\n llmAgentToChatAgentOptions,\n};\n\n/** Map API resource segment (e.g. \"blogs\", \"form_submissions\") to entity. Used by CRUD handler. */\nexport const CMS_ENTITY_MAP: Record<string, EntityTarget<import('typeorm').ObjectLiteral>> = {\n users: User,\n otp_challenges: OtpChallenge,\n password_reset_tokens: PasswordResetToken,\n user_groups: UserGroup,\n permissions: Permission,\n blogs: Blog,\n tags: Tag,\n categories: Category,\n comments: Comment,\n contacts: Contact,\n addresses: Address,\n forms: Form,\n form_fields: FormField,\n form_submissions: FormSubmission,\n seos: Seo,\n configs: Config,\n message_templates: MessageTemplate,\n media: Media,\n pages: Page,\n product_categories: ProductCategory,\n collections: Collection,\n products: Product,\n attributes: Attribute,\n product_attributes: ProductAttribute,\n taxes: Tax,\n product_taxes: ProductTax,\n orders: Order,\n order_items: OrderItem,\n payments: Payment,\n brands: Brand,\n knowledge_base_documents: KnowledgeBaseDocument,\n knowledge_base_chunks: KnowledgeBaseChunk,\n chat_conversations: ChatConversation,\n chat_messages: ChatMessage,\n carts: Cart,\n cart_items: CartItem,\n wishlists: Wishlist,\n wishlist_items: WishlistItem,\n llm_agents: LlmAgent,\n llm_agent_knowledge_documents: LlmAgentKnowledgeDocument,\n};\n","/**\r\n * Single CMS API handler: dashboard, analytics, upload, media zip extract, blog/form by slug, users API, user auth, CRUD. Mount once (e.g. app/api/[[...path]]/route.ts).\r\n */\r\nimport type { DataSource } from 'typeorm';\r\nimport { createCrudHandler, createCrudByIdHandler } from './crud';\r\nimport type { CrudHandlerOptions, EntityMap } from './crud';\r\nimport { createUserAuthApiRouter } from './auth-handlers';\r\nimport type { UserAuthApiConfig } from './auth-handlers';\r\nimport {\r\n createDashboardStatsHandler,\r\n createAnalyticsHandlers,\r\n createEcommerceAnalyticsHandler,\r\n createUploadHandler,\r\n createMediaZipExtractHandler,\r\n createBlogBySlugHandler,\r\n createFormBySlugHandler,\r\n createFormSaveHandlers,\r\n createFormSubmissionHandler,\r\n createFormSubmissionGetByIdHandler,\r\n createFormSubmissionListHandler,\r\n createUsersApiHandlers,\r\n createUserAvatarHandler,\r\n createUserProfileHandler,\r\n createSettingsApiHandlers,\r\n createChatHandlers,\r\n} from './cms-handlers';\r\nimport { createLlmAgentKnowledgeHandlers } from './llm-agent-knowledge-handlers';\r\nimport type { LlmAgentKnowledgeApiConfig } from './llm-agent-knowledge-handlers';\r\nimport { createSmsMessageTemplateHandlers } from './message-template-admin-handlers';\r\nimport type {\r\n DashboardStatsConfig,\r\n AnalyticsHandlerConfig,\r\n EcommerceAnalyticsConfig,\r\n UploadHandlerConfig,\r\n BlogBySlugConfig,\r\n FormBySlugConfig,\r\n FormSaveHandlersConfig,\r\n FormSubmissionHandlerConfig,\r\n FormSubmissionGetByIdConfig,\r\n UsersApiConfig,\r\n UserAvatarConfig,\r\n UserProfileConfig,\r\n SettingsApiConfig,\r\n ChatApiConfig,\r\n} from './cms-handlers';\r\nimport type { EntityCrudAction } from '../auth/permission-entities';\r\nimport type { SessionUser } from '../auth/helpers';\r\nimport type { CompanyDetails } from '../plugins/email/templates/types';\r\nimport { createAdminRolesHandlers } from './admin-roles-handlers';\r\nimport { CMS_ENTITY_MAP } from '../entities';\r\nimport { LlmAgent } from '../entities/llm-agent.entity';\r\n\r\n/** CMS instance with getPlugin; when provided, analytics and userAuth.sendEmail can be resolved from plugins when not passed. */\r\nexport type CmsGetter = () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n\r\nconst KNOWLEDGE_SUFFIX = 'knowledge';\r\nconst CMS_API_LOG = '[cms-api]';\r\n\r\n/**\r\n * Some apps pass a subset of {@link CMS_ENTITY_MAP}. LLM plugins + knowledge CRUD need these keys;\r\n * merge missing ones from the core map so `/api/llm_agents` and knowledge routes do not return \"Invalid resource\".\r\n */\r\nfunction withLlmKnowledgeEntityFallbacks(base: EntityMap): EntityMap {\r\n const keys = [\r\n 'llm_agents',\r\n 'llm_agent_knowledge_documents',\r\n 'knowledge_base_documents',\r\n 'knowledge_base_chunks',\r\n ] as const;\r\n const patch: Partial<EntityMap> = {};\r\n for (const key of keys) {\r\n if (!(key in base) || base[key as keyof EntityMap] == null) {\r\n const fallback = CMS_ENTITY_MAP[key as keyof typeof CMS_ENTITY_MAP] as EntityMap[string] | undefined;\r\n if (fallback) (patch as Record<string, EntityMap[string]>)[key] = fallback;\r\n }\r\n }\r\n const merged = Object.keys(patch).length > 0 ? ({ ...base, ...patch } as EntityMap) : base;\r\n // Direct class fallback so POST/GET /api/llm_agents never loses the entity (e.g. odd bundling of CMS_ENTITY_MAP).\r\n if (!merged.llm_agents) {\r\n const agent = (CMS_ENTITY_MAP.llm_agents ?? LlmAgent) as EntityMap['llm_agents'];\r\n return { ...merged, llm_agents: agent };\r\n }\r\n return merged;\r\n}\r\n\r\n/**\r\n * Resolves LLM agent knowledge routes for {@link createCmsApiHandler}.\r\n * - Canonical: `llm_agents`, `:slug`, `knowledge` (optional 4th segment for DELETE).\r\n * - Some clients / path parsers merge slug + `knowledge` into one segment (`jm-assistantknowledge`); accept that shape too.\r\n */\r\nfunction matchLlmAgentKnowledgeRoute(path: string[]): { slug: string; documentId: string | undefined } | null {\r\n const p = path[0] === 'api' ? path.slice(1) : path;\r\n if (p[0] !== 'llm_agents' || p.length < 2) return null;\r\n const seg1 = p[1];\r\n if (!seg1) return null;\r\n\r\n if (p[2] === KNOWLEDGE_SUFFIX) {\r\n return {\r\n slug: seg1,\r\n documentId: p.length >= 4 ? p[3] : undefined,\r\n };\r\n }\r\n\r\n if (seg1.endsWith(KNOWLEDGE_SUFFIX) && seg1.length > KNOWLEDGE_SUFFIX.length) {\r\n const slug = seg1.slice(0, -KNOWLEDGE_SUFFIX.length);\r\n if (!slug) return null;\r\n if (p.length === 2) return { slug, documentId: undefined };\r\n if (p.length === 3) return { slug, documentId: p[2] };\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport interface CmsApiHandlerConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n requireAuth: (req: Request) => Promise<Response | null>;\r\n json: (body: unknown, init?: { status?: number }) => Response;\r\n pathToModel?: (segment: string) => string;\r\n crudResources?: string[];\r\n /** When set, analytics and userAuth.sendEmail can be derived from getPlugin('analytics') and getPlugin('email') when not provided. */\r\n getCms?: CmsGetter;\r\n /** Optional: used when deriving userAuth.sendEmail to pass company details into email templates (e.g. from settings). */\r\n getCompanyDetails?: () => Promise<CompanyDetails>;\r\n /** Optional: used for form submission and other channel-based email recipients (from settings group \"email\"). */\r\n getRecipientForChannel?: (channel: 'crm' | 'sales' | 'fulfilment') => Promise<string | null>;\r\n userAuth?: UserAuthApiConfig;\r\n /** GET /api/dashboard/stats */\r\n dashboard?: DashboardStatsConfig;\r\n /** GET /api/dashboard/ecommerce */\r\n ecommerceAnalytics?: EcommerceAnalyticsConfig;\r\n /** GET /api/analytics. If omitted and getCms is set, uses getCms().getPlugin('analytics'). */\r\n analytics?: AnalyticsHandlerConfig;\r\n /** POST /api/upload (S3 or local) */\r\n upload?: UploadHandlerConfig;\r\n /** GET /api/blogs/slug/:slug (public) */\r\n blogBySlug?: BlogBySlugConfig;\r\n /** GET /api/forms/slug/:slug (public) */\r\n formBySlug?: FormBySlugConfig;\r\n /** POST/PUT /api/forms (save form + fields; when set, overrides CRUD for forms) */\r\n formSave?: FormSaveHandlersConfig;\r\n /** POST /api/form-submissions (public, no auth) */\r\n formSubmission?: FormSubmissionHandlerConfig;\r\n /** GET /api/form-submissions/:id (auth) with form + contact relations */\r\n formSubmissionGetById?: FormSubmissionGetByIdConfig;\r\n /** GET/POST /api/users, GET/PUT/DELETE /api/users/:id, POST /api/users/:id/regenerate-invite */\r\n usersApi?: UsersApiConfig;\r\n /** POST /api/users/avatar */\r\n userAvatar?: UserAvatarConfig;\r\n /** GET/PUT /api/users/profile (current session user) */\r\n userProfile?: UserProfileConfig;\r\n /** GET/PUT /api/settings/:group */\r\n settings?: SettingsApiConfig;\r\n /** GET /api/chat/config (public); POST /api/chat/identify; GET /api/chat/conversations/:id/messages; POST /api/chat/messages */\r\n chat?: ChatApiConfig;\r\n /**\r\n * GET/POST /api/llm_agents/:slug/knowledge; DELETE …/knowledge/:documentId — agent KB ingest + links.\r\n * When omitted but `chat` is set, the same dataSource / entityMap / getCms / json / requireAuth are reused automatically.\r\n */\r\n llmAgentKnowledge?: LlmAgentKnowledgeApiConfig;\r\n /**\r\n * Entity-level RBAC (session `entityPerms` / Administrator). When omitted, admin routes that need it respond with 403\r\n * (`entity_rbac_required`) so CRUD cannot run as auth-only. Pass `createAuthHelpers(...).requireEntityPermission` from the app.\r\n */\r\n requireEntityPermission?: (req: Request, entity: string, action: EntityCrudAction) => Promise<Response | null>;\r\n /** Required for GET/POST/PATCH/DELETE /api/admin/roles */\r\n getSessionUser?: () => Promise<SessionUser | null>;\r\n}\r\n\r\nconst DEFAULT_EXCLUDE = new Set([\r\n 'users',\r\n 'password_reset_tokens',\r\n 'user_groups',\r\n 'permissions',\r\n 'comments',\r\n 'form_fields',\r\n 'configs',\r\n 'carts',\r\n 'cart_items',\r\n 'wishlists',\r\n 'wishlist_items',\r\n 'message_templates',\r\n 'llm_agent_knowledge_documents',\r\n]);\r\n\r\nexport function createCmsApiHandler(config: CmsApiHandlerConfig) {\r\n const {\r\n dataSource,\r\n entityMap: rawEntityMap,\r\n pathToModel = (s) => s,\r\n crudResources: crudResourcesOverride,\r\n getCms,\r\n userAuth: userAuthConfig,\r\n dashboard,\r\n ecommerceAnalytics,\r\n analytics: analyticsConfig,\r\n upload,\r\n blogBySlug,\r\n formBySlug,\r\n formSave: formSaveConfig,\r\n formSubmission: formSubmissionConfig,\r\n formSubmissionGetById: formSubmissionGetByIdConfig,\r\n usersApi,\r\n userAvatar,\r\n userProfile,\r\n settings: settingsConfig,\r\n chat: chatConfig,\r\n llmAgentKnowledge: llmAgentKnowledgeConfig,\r\n requireEntityPermission: userRequireEntityPermission,\r\n getSessionUser,\r\n } = config;\r\n\r\n const entityMap = withLlmKnowledgeEntityFallbacks(rawEntityMap);\r\n const baseCrudResources =\r\n crudResourcesOverride ?? Object.keys(entityMap).filter((k) => !DEFAULT_EXCLUDE.has(k));\r\n /** Plugins + dedicated routes use `llm_agents` even when the host app passes a narrow `crudResources` allowlist. */\r\n const crudResources =\r\n entityMap.llm_agents && !baseCrudResources.includes('llm_agents')\r\n ? [...baseCrudResources, 'llm_agents']\r\n : baseCrudResources;\r\n\r\n const requireEntityPermissionEffective =\r\n userRequireEntityPermission ??\r\n (async (_req: Request, entity: string, action: EntityCrudAction): Promise<Response | null> =>\r\n config.json({ error: 'Forbidden', reason: 'entity_rbac_required', entity, action }, { status: 403 }));\r\n\r\n const analytics: AnalyticsHandlerConfig | undefined =\r\n analyticsConfig ??\r\n (getCms\r\n ? {\r\n json: config.json,\r\n requireAuth: async () => null,\r\n getAnalyticsData: async (days) => {\r\n const cms = await getCms();\r\n const a = cms.getPlugin('analytics') as { getAnalyticsData?: (days: number) => Promise<unknown> } | undefined;\r\n if (!a?.getAnalyticsData) throw new Error('Analytics not configured');\r\n return a.getAnalyticsData(days);\r\n },\r\n getPropertyId: () => ({ currentViewId: process.env.GOOGLE_ANALYTICS_VIEW_ID }),\r\n getPermissions: () => ({\r\n serviceAccountEmail: process.env.GOOGLE_ANALYTICS_CLIENT_EMAIL,\r\n currentViewId: process.env.GOOGLE_ANALYTICS_VIEW_ID,\r\n }),\r\n }\r\n : undefined);\r\n\r\n const userAuth: UserAuthApiConfig | undefined =\r\n userAuthConfig && getCms && userAuthConfig.sendEmail === undefined\r\n ? {\r\n ...userAuthConfig,\r\n sendEmail: async (opts) => {\r\n const cms = await getCms();\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void> } | undefined;\r\n const companyDetails = config.getCompanyDetails ? await config.getCompanyDetails() : {};\r\n const resetLink =\r\n (typeof opts.resetLink === 'string' && opts.resetLink.trim()) ||\r\n (typeof opts.text === 'string' && opts.text.trim()) ||\r\n (typeof opts.html === 'string' ? (opts.html.match(/href\\s*=\\s*[\"']([^\"']+)[\"']/)?.[1] ?? '') : '');\r\n const ctx = { resetLink, companyDetails };\r\n if (queue) {\r\n const { queueEmail } = await import('../plugins/email/email-queue');\r\n await queueEmail(cms as { getPlugin: (name: string) => unknown }, { to: opts.to, templateName: 'passwordReset', ctx });\r\n return;\r\n }\r\n const email = cms.getPlugin('email') as { send: (data: { subject: string; html: string; text?: string; to?: string }) => Promise<boolean>; renderTemplate: (name: string, ctx: unknown) => { subject: string; html: string; text?: string } } | undefined;\r\n if (!email?.send) return;\r\n const rendered = email.renderTemplate('passwordReset', ctx);\r\n await email.send({ subject: rendered.subject, html: rendered.html, text: rendered.text, to: opts.to });\r\n },\r\n }\r\n : userAuthConfig;\r\n\r\n const crudOpts: CrudHandlerOptions = {\r\n requireAuth: config.requireAuth,\r\n json: config.json,\r\n requireEntityPermission: requireEntityPermissionEffective,\r\n getCms,\r\n ...(getSessionUser\r\n ? {\r\n getDeletedByUserId: async () => {\r\n const u = await getSessionUser();\r\n if (!u?.id) return null;\r\n const n = Number(u.id);\r\n return Number.isFinite(n) ? n : null;\r\n },\r\n }\r\n : {}),\r\n };\r\n const crud = createCrudHandler(dataSource, entityMap, crudOpts);\r\n const crudById = createCrudByIdHandler(dataSource, entityMap, crudOpts);\r\n\r\n const mergePerm = <T extends object>(c: T | undefined): T | undefined =>\r\n !c ? undefined : ({ ...c, requireEntityPermission: requireEntityPermissionEffective } as T);\r\n\r\n const adminRoles =\r\n getSessionUser &&\r\n createAdminRolesHandlers({\r\n dataSource,\r\n entityMap,\r\n json: config.json,\r\n getSessionUser,\r\n });\r\n const userAuthRouter = userAuth ? createUserAuthApiRouter(userAuth) : null;\r\n\r\n const dashboardGet = dashboard ? createDashboardStatsHandler(mergePerm(dashboard) ?? dashboard) : null;\r\n const ecommerceAnalyticsResolved: EcommerceAnalyticsConfig =\r\n mergePerm(\r\n ecommerceAnalytics ?? {\r\n dataSource,\r\n entityMap,\r\n json: config.json,\r\n requireAuth: config.requireAuth,\r\n }\r\n )!;\r\n const ecommerceAnalyticsGet = createEcommerceAnalyticsHandler(ecommerceAnalyticsResolved);\r\n const analyticsHandlers = analytics ? createAnalyticsHandlers(analytics) : null;\r\n const uploadMerged = upload\r\n ? {\r\n ...(mergePerm(upload) ?? upload),\r\n dataSource: upload.dataSource ?? dataSource,\r\n entityMap: upload.entityMap ?? entityMap,\r\n }\r\n : null;\r\n const uploadPost = uploadMerged ? createUploadHandler(uploadMerged) : null;\r\n const zipExtractPost = uploadMerged ? createMediaZipExtractHandler(uploadMerged) : null;\r\n const blogBySlugGet = blogBySlug ? createBlogBySlugHandler(blogBySlug) : null;\r\n const formBySlugGet = formBySlug ? createFormBySlugHandler(formBySlug) : null;\r\n const formSaveHandlers = formSaveConfig ? createFormSaveHandlers(mergePerm(formSaveConfig) ?? formSaveConfig) : null;\r\n const formSubmissionPost = formSubmissionConfig ? createFormSubmissionHandler(formSubmissionConfig) : null;\r\n const formSubmissionGetById = formSubmissionGetByIdConfig\r\n ? createFormSubmissionGetByIdHandler(mergePerm(formSubmissionGetByIdConfig) ?? formSubmissionGetByIdConfig)\r\n : null;\r\n const formSubmissionList = formSubmissionGetByIdConfig\r\n ? createFormSubmissionListHandler(mergePerm(formSubmissionGetByIdConfig) ?? formSubmissionGetByIdConfig)\r\n : null;\r\n const usersApiMerged =\r\n usersApi && getCms\r\n ? {\r\n ...usersApi,\r\n getCms: usersApi.getCms ?? getCms,\r\n getCompanyDetails: usersApi.getCompanyDetails ?? config.getCompanyDetails,\r\n ...(getSessionUser ? { getSessionUser: usersApi.getSessionUser ?? getSessionUser } : {}),\r\n }\r\n : usersApi\r\n ? {\r\n ...usersApi,\r\n ...(getSessionUser ? { getSessionUser: usersApi.getSessionUser ?? getSessionUser } : {}),\r\n }\r\n : usersApi;\r\n const usersHandlers = usersApiMerged ? createUsersApiHandlers(mergePerm(usersApiMerged) ?? usersApiMerged) : null;\r\n const avatarPost = userAvatar ? createUserAvatarHandler(userAvatar) : null;\r\n const profileHandlers = userProfile ? createUserProfileHandler(userProfile) : null;\r\n const settingsHandlers = settingsConfig ? createSettingsApiHandlers(settingsConfig) : null;\r\n const smsMessageTemplateHandlers = createSmsMessageTemplateHandlers({\r\n dataSource,\r\n entityMap,\r\n json: config.json,\r\n requireAuth: config.requireAuth,\r\n requireEntityPermission: requireEntityPermissionEffective,\r\n });\r\n const chatHandlers = chatConfig ? createChatHandlers(chatConfig) : null;\r\n\r\n const llmAgentKnowledgeMerged: LlmAgentKnowledgeApiConfig | undefined =\r\n llmAgentKnowledgeConfig ??\r\n (chatConfig\r\n ? {\r\n dataSource: chatConfig.dataSource,\r\n entityMap: withLlmKnowledgeEntityFallbacks(chatConfig.entityMap ?? rawEntityMap),\r\n getCms: chatConfig.getCms,\r\n json: chatConfig.json,\r\n requireAuth: chatConfig.requireAuth,\r\n }\r\n : undefined);\r\n\r\n const llmAgentKnowledgeHandlers = llmAgentKnowledgeMerged\r\n ? createLlmAgentKnowledgeHandlers({\r\n ...llmAgentKnowledgeMerged,\r\n requireEntityPermission: requireEntityPermissionEffective,\r\n })\r\n : null;\r\n\r\n function resolveResource(segment: string): string {\r\n const model = pathToModel(segment);\r\n return crudResources.includes(model) ? model : segment;\r\n }\r\n\r\n return {\r\n async handle(method: string, pathInput: string[], req: Request): Promise<Response> {\r\n const m = typeof method === 'string' ? method.toUpperCase() : 'GET';\r\n const path = pathInput.length > 0 && pathInput[0] === 'api' ? pathInput.slice(1) : pathInput;\r\n async function analyticsGate(): Promise<Response | null> {\r\n const a = await config.requireAuth(req);\r\n if (a) return a;\r\n return requireEntityPermissionEffective(req, 'analytics', 'read');\r\n }\r\n\r\n // Admin roles: [\"admin\", \"roles\"], [\"admin\", \"roles\", id], [\"admin\", \"roles\", id, \"permissions\"]\r\n if (path[0] === 'admin' && path[1] === 'roles') {\r\n if (!adminRoles) return config.json({ error: 'Not found' }, { status: 404 });\r\n if (path.length === 2 && m === 'GET') return adminRoles.list();\r\n if (path.length === 2 && m === 'POST') return adminRoles.createGroup(req);\r\n if (path.length === 3 && m === 'PATCH') return adminRoles.patchGroup(req, path[2]!);\r\n if (path.length === 3 && m === 'DELETE') return adminRoles.deleteGroup(path[2]!);\r\n if (path.length === 4 && path[3] === 'permissions' && m === 'PUT') return adminRoles.putPermissions(req, path[2]!);\r\n return config.json({ error: 'Not found' }, { status: 404 });\r\n }\r\n\r\n // Dashboard: [\"dashboard\", \"stats\"]\r\n if (path[0] === 'dashboard' && path[1] === 'stats' && path.length === 2 && m === 'GET' && dashboardGet) {\r\n return dashboardGet(req);\r\n }\r\n if (path[0] === 'dashboard' && path[1] === 'ecommerce' && path.length === 2 && m === 'GET' && ecommerceAnalyticsGet) {\r\n const g = await analyticsGate();\r\n if (g) return g;\r\n return ecommerceAnalyticsGet(req);\r\n }\r\n // Analytics: [\"analytics\"], [\"analytics\", \"property-id\"], [\"analytics\", \"permissions\"]\r\n if (path[0] === 'analytics' && analyticsHandlers) {\r\n if (path.length === 1 && m === 'GET') {\r\n const g = await analyticsGate();\r\n if (g) return g;\r\n return analyticsHandlers.GET(req);\r\n }\r\n if (path.length === 2 && path[1] === 'property-id' && m === 'GET') {\r\n const g = await analyticsGate();\r\n if (g) return g;\r\n return analyticsHandlers.propertyId();\r\n }\r\n if (path.length === 2 && path[1] === 'permissions' && m === 'GET') {\r\n const g = await analyticsGate();\r\n if (g) return g;\r\n return analyticsHandlers.permissions();\r\n }\r\n }\r\n // Upload: [\"upload\"]\r\n if (path[0] === 'upload' && path.length === 1 && m === 'POST' && uploadPost) return uploadPost(req);\r\n // Media zip extract: [\"media\", \"extract\", id] POST\r\n if (path[0] === 'media' && path[1] === 'extract' && path.length === 3 && m === 'POST' && zipExtractPost) {\r\n return zipExtractPost(req, path[2]!);\r\n }\r\n // Blog by slug: [\"blogs\", \"slug\", slug] (public)\r\n if (path[0] === 'blogs' && path[1] === 'slug' && path.length === 3 && m === 'GET' && blogBySlugGet) {\r\n return blogBySlugGet(req, path[2]);\r\n }\r\n // Form by slug: [\"forms\", \"slug\", slug] (public)\r\n if (path[0] === 'forms' && path[1] === 'slug' && path.length === 3 && m === 'GET' && formBySlugGet) {\r\n return formBySlugGet(req, path[2]);\r\n }\r\n // Form submission: [\"form-submissions\"] GET (auth, list with relations) or POST (public); [\"form-submissions\", id] GET (auth, with relations)\r\n if (path[0] === 'form-submissions') {\r\n if (path.length === 1) {\r\n if (m === 'GET' && formSubmissionList) return formSubmissionList(req);\r\n if (m === 'POST' && formSubmissionPost) return formSubmissionPost(req);\r\n }\r\n if (path.length === 2 && m === 'GET' && formSubmissionGetById) return formSubmissionGetById(req, path[1]);\r\n }\r\n // Form save: [\"forms\"] POST; [\"forms\", id] GET (with fields) or PUT/PATCH (saves form + fields)\r\n if (path[0] === 'forms' && formSaveHandlers) {\r\n if (path.length === 1 && m === 'POST') return formSaveHandlers.POST(req);\r\n if (path.length === 2) {\r\n if (m === 'GET') return formSaveHandlers.GET(req, path[1]);\r\n if (m === 'PUT' || m === 'PATCH') return formSaveHandlers.PUT(req, path[1]);\r\n }\r\n }\r\n // Users API\r\n if (path[0] === 'users' && usersHandlers) {\r\n if (path.length === 1) {\r\n if (m === 'GET') return usersHandlers.list(req);\r\n if (m === 'POST') return usersHandlers.create(req);\r\n }\r\n if (path.length === 2) {\r\n if (path[1] === 'avatar' && m === 'POST' && avatarPost) return avatarPost(req);\r\n if (path[1] === 'profile' && profileHandlers) {\r\n if (m === 'GET') return profileHandlers.GET(req);\r\n if (m === 'PUT') return profileHandlers.PUT(req);\r\n }\r\n // users/:id\r\n const id = path[1];\r\n if (m === 'GET') return usersHandlers.getById(req, id);\r\n if (m === 'PUT' || m === 'PATCH') return usersHandlers.update(req, id);\r\n if (m === 'DELETE') return usersHandlers.delete(req, id);\r\n }\r\n if (path.length === 3 && path[2] === 'regenerate-invite' && m === 'POST') {\r\n return usersHandlers.regenerateInvite(req, path[1]);\r\n }\r\n }\r\n // User auth: [\"users\", \"forgot-password\"] etc.\r\n if (path[0] === 'users' && path.length === 2 && userAuthRouter && m === 'POST') {\r\n return userAuthRouter.POST(req, path[1]);\r\n }\r\n // Settings: [\"settings\", group]\r\n if (path[0] === 'settings' && path.length === 2 && settingsHandlers) {\r\n const group = path[1]!;\r\n const isPublic = settingsConfig?.publicGetGroups?.includes(group);\r\n if (m === 'GET') {\r\n if (!isPublic) {\r\n const a = await config.requireAuth(req);\r\n if (a) return a;\r\n const pe = await requireEntityPermissionEffective(req, 'settings', 'read');\r\n if (pe) return pe;\r\n }\r\n return settingsHandlers.GET(req, group);\r\n }\r\n if (m === 'PUT') {\r\n const pe = await requireEntityPermissionEffective(req, 'settings', 'update');\r\n if (pe) return pe;\r\n return settingsHandlers.PUT(req, group);\r\n }\r\n }\r\n // SMS message templates (plugins page only): [\"message-templates\", \"sms\"]\r\n if (path[0] === 'message-templates' && path[1] === 'sms' && path.length === 2) {\r\n if (m === 'GET') return smsMessageTemplateHandlers.GET(req);\r\n if (m === 'PUT') return smsMessageTemplateHandlers.PUT(req);\r\n }\r\n // LLM agents CRUD: [\"llm_agents\"] GET/POST, [\"llm_agents\", id] GET/PUT/PATCH/DELETE\r\n // Handled before generic CRUD so it works even when crudResources is customised by the consuming app.\r\n if (path[0] === 'llm_agents') {\r\n if (!entityMap.llm_agents) {\r\n console.error(CMS_API_LOG, 'llm_agents route: entity missing after merge', {\r\n method: m,\r\n pathJoined: path.join('/'),\r\n entityMapKeyCount: Object.keys(entityMap).length,\r\n });\r\n return config.json(\r\n { error: 'LlmAgent entity is not registered', hint: 'Ensure migrations ran and entities include LlmAgent.' },\r\n { status: 503 }\r\n );\r\n }\r\n if (path.length === 1) {\r\n if (m === 'GET') return crud.GET(req, 'llm_agents');\r\n if (m === 'POST') return crud.POST(req, 'llm_agents');\r\n }\r\n if (path.length === 2 && !path[1]?.includes('knowledge')) {\r\n const id = path[1]!;\r\n if (m === 'GET') return crudById.GET(req, 'llm_agents', id);\r\n if (m === 'PUT' || m === 'PATCH') return crudById.PUT(req, 'llm_agents', id);\r\n if (m === 'DELETE') return crudById.DELETE(req, 'llm_agents', id);\r\n }\r\n }\r\n // LLM agent knowledge: canonical + merged-segment variants (see matchLlmAgentKnowledgeRoute)\r\n {\r\n const kbMatch = matchLlmAgentKnowledgeRoute(path);\r\n if (kbMatch) {\r\n if (!llmAgentKnowledgeHandlers) {\r\n return config.json(\r\n {\r\n error: 'LLM agent knowledge is not available',\r\n hint:\r\n 'With chat enabled, routes usually work automatically. Otherwise pass llmAgentKnowledge. If this persists, ensure entityMap includes knowledge_base_documents, knowledge_base_chunks, llm_agent_knowledge_documents, and run migrations.',\r\n },\r\n { status: 503 }\r\n );\r\n }\r\n const { slug, documentId } = kbMatch;\r\n if (m === 'DELETE' && documentId != null && documentId !== '') {\r\n return llmAgentKnowledgeHandlers.unlink(req, slug, documentId);\r\n }\r\n if (m === 'GET' && (documentId == null || documentId === '')) {\r\n return llmAgentKnowledgeHandlers.list(req, slug);\r\n }\r\n if (m === 'POST' && (documentId == null || documentId === '')) {\r\n return llmAgentKnowledgeHandlers.post(req, slug);\r\n }\r\n }\r\n }\r\n // Chat: [\"chat\", \"identify\"] POST; [\"chat\", \"conversations\", id, \"messages\"] GET; [\"chat\", \"messages\"] POST\r\n if (path[0] === 'chat' && chatHandlers) {\r\n if (path.length === 2 && path[1] === 'config' && m === 'GET') return chatHandlers.publicConfig(req);\r\n if (path.length === 2 && path[1] === 'identify' && m === 'POST') return chatHandlers.identify(req);\r\n if (path.length === 4 && path[1] === 'conversations' && path[3] === 'messages' && m === 'GET') return chatHandlers.getMessages(req, path[2]);\r\n if (path.length === 2 && path[1] === 'messages' && m === 'POST') return chatHandlers.postMessage(req);\r\n }\r\n\r\n // Invoice PDF: [\"orders\", id, \"invoice\"] (admin auth + orders:read)\r\n if (path[0] === 'orders' && path.length === 3 && path[2] === 'invoice' && m === 'GET' && getCms) {\r\n const a = await config.requireAuth(req);\r\n if (a) return a;\r\n const pe = await requireEntityPermissionEffective(req, 'orders', 'read');\r\n if (pe) return pe;\r\n const cms = await getCms();\r\n const { streamOrderInvoicePdf } = await import('../plugins/erp/erp-order-invoice');\r\n const oid = Number(path[1]);\r\n if (!Number.isFinite(oid)) return config.json({ error: 'Invalid id' }, { status: 400 });\r\n return streamOrderInvoicePdf(cms, dataSource, entityMap, oid, {});\r\n }\r\n // ERP repost: [\"orders\", id, \"repost-erp\"] (admin auth + orders:update)\r\n if (path[0] === 'orders' && path.length === 3 && path[2] === 'repost-erp' && getCms) {\r\n const a = await config.requireAuth(req);\r\n if (a) return a;\r\n const pe = await requireEntityPermissionEffective(req, 'orders', m === 'GET' ? 'read' : 'update');\r\n if (pe) return pe;\r\n const oid = Number(path[1]);\r\n if (!Number.isFinite(oid)) return config.json({ error: 'Invalid id' }, { status: 400 });\r\n const cms = await getCms();\r\n const { isErpIntegrationEnabled } = await import('../plugins/erp/erp-config-enabled');\r\n const enabled = await isErpIntegrationEnabled(cms, dataSource, entityMap);\r\n if (m === 'GET') {\r\n return config.json({ enabled });\r\n }\r\n if (m === 'POST') {\r\n if (!enabled) return config.json({ error: 'ERP integration is disabled' }, { status: 409 });\r\n const { queueErpPaidOrderForOrderId } = await import('../plugins/erp/paid-order-erp');\r\n await queueErpPaidOrderForOrderId(cms, dataSource, entityMap, oid);\r\n return config.json({ ok: true });\r\n }\r\n return config.json({ error: 'Method not allowed' }, { status: 405 });\r\n }\r\n\r\n // CRUD: [\"blogs\"] or [\"blogs\", \"123\"]\r\n if (path.length === 0) return config.json({ error: 'Not found' }, { status: 404 });\r\n const resource = resolveResource(path[0]);\r\n if (!crudResources.includes(resource)) {\r\n console.warn(CMS_API_LOG, 'generic CRUD gate: Invalid resource (not in crudResources)', {\r\n method: m,\r\n pathJoined: path.join('/'),\r\n pathSegments: path,\r\n resource,\r\n hasLlmAgentsEntity: Boolean(entityMap.llm_agents),\r\n crudResourcesHasResource: crudResources.includes(resource),\r\n crudResourcesLength: crudResources.length,\r\n });\r\n return config.json({ error: 'Invalid resource' }, { status: 400 });\r\n }\r\n\r\n // Bulk operations: [\"products\", \"metadata\"], [\"products\", \"bulk\"], [\"products\", \"export\"]\r\n if (path.length === 2) {\r\n if (path[1] === 'metadata' && m === 'GET') {\r\n return crud.GET_METADATA(req, resource);\r\n }\r\n if (path[1] === 'bulk' && m === 'POST') {\r\n return crud.BULK_POST(req, resource);\r\n }\r\n if (path[1] === 'export' && m === 'GET') {\r\n return crud.GET_EXPORT(req, resource);\r\n }\r\n }\r\n\r\n if (path.length === 1) {\r\n if (m === 'GET') return crud.GET(req, resource);\r\n if (m === 'POST') return crud.POST(req, resource);\r\n return config.json({ error: 'Method not allowed' }, { status: 405 });\r\n }\r\n if (path.length === 2) {\r\n const id = path[1];\r\n if (m === 'GET') return crudById.GET(req, resource, id);\r\n if (m === 'PUT' || m === 'PATCH') return crudById.PUT(req, resource, id);\r\n if (m === 'DELETE') return crudById.DELETE(req, resource, id);\r\n return config.json({ error: 'Method not allowed' }, { status: 405 });\r\n }\r\n return config.json({ error: 'Not found' }, { status: 404 });\r\n },\r\n };\r\n}\r\n","import type { DataSource } from 'typeorm';\r\nimport type { EntityTarget, ObjectLiteral } from 'typeorm';\r\nimport { In, IsNull } from 'typeorm';\r\nimport type { SessionUser } from '../auth/helpers';\r\nimport type { EntityMap } from './crud';\r\nimport { linkUnclaimedContactToUser } from '../lib/link-contact-to-user';\r\nimport { isValidSignupEmail } from '../lib/is-valid-signup-email';\r\nimport { queueEmail } from '../plugins/email/email-queue';\r\nimport { queueErpCreateContactIfEnabled } from '../plugins/erp/erp-contact-sync';\r\nimport { buildCanonicalOrderNumber, temporaryOrderNumberPlaceholder } from '../lib/order-number';\r\nimport { tryRefreshOrderFromErpForStorefront } from '../plugins/erp/erp-order-sync';\r\nimport { streamOrderInvoicePdf } from '../plugins/erp/erp-order-invoice';\r\nimport type { CompanyDetails } from '../plugins/email/templates/types';\r\nimport { assertCaptchaOk } from '../plugins/captcha/assert';\r\nimport { validateAndNormalizeAddressRow } from '../lib/address-geo-validation';\r\nimport { queueSms } from '../plugins/sms/sms-queue';\r\nimport {\r\n createOtpChallenge,\r\n verifyAndConsumeOtpChallenge,\r\n generateNumericOtp,\r\n normalizePhoneE164,\r\n type OtpPurpose,\r\n} from '../lib/otp-challenge';\r\nconst GUEST_COOKIE = 'guest_id';\r\nconst ONE_YEAR = 60 * 60 * 24 * 365;\r\n\r\nexport interface StorefrontOtpFlags {\r\n login?: boolean;\r\n verifyEmail?: boolean;\r\n verifyPhone?: boolean;\r\n}\r\n\r\nfunction parseCookies(header: string | null): Record<string, string> {\r\n const out: Record<string, string> = {};\r\n if (!header) return out;\r\n for (const part of header.split(';')) {\r\n const i = part.indexOf('=');\r\n if (i === -1) continue;\r\n const k = part.slice(0, i).trim();\r\n const v = part.slice(i + 1).trim();\r\n out[k] = decodeURIComponent(v);\r\n }\r\n return out;\r\n}\r\n\r\nfunction guestCookieHeader(name: string, token: string): string {\r\n return `${name}=${encodeURIComponent(token)}; Path=/; HttpOnly; SameSite=Lax; Max-Age=${ONE_YEAR}`;\r\n}\r\n\r\nexport interface StorefrontApiConfig {\r\n dataSource: DataSource;\r\n entityMap: EntityMap;\r\n json: (body: unknown, init?: { status?: number; headers?: HeadersInit }) => Response;\r\n getSessionUser: () => Promise<SessionUser | null>;\r\n guestCookieName?: string;\r\n /** Required for POST storefront/register */\r\n hashPassword?: (plain: string) => Promise<string>;\r\n /** When set, new registrations are blocked until email is verified and a signup email is sent. */\r\n getCms?: () => Promise<{ getPlugin: (name: string) => unknown }>;\r\n getCompanyDetails?: () => Promise<CompanyDetails>;\r\n /** Origin for verify links (e.g. process.env.NEXTAUTH_URL). Required with getCms for verification URLs. */\r\n publicSiteUrl?: string;\r\n /** When a flag is true, the corresponding OTP storefront route is enabled. */\r\n otpFlags?: StorefrontOtpFlags;\r\n /** Defaults to OTP_PEPPER or NEXTAUTH_SECRET. */\r\n otpPepper?: string;\r\n defaultPhoneCountryCode?: string;\r\n /** When false, login OTP send accepts email only (no phone). Default true. */\r\n otpAllowPhoneLogin?: boolean;\r\n}\r\n\r\nconst SIGNUP_VERIFY_EXPIRY_HOURS = 72;\r\n\r\nexport function createStorefrontApiHandler(config: StorefrontApiConfig) {\r\n const { dataSource, entityMap, json, getSessionUser, getCms, getCompanyDetails, publicSiteUrl } = config;\r\n const cookieName = config.guestCookieName ?? GUEST_COOKIE;\r\n const otpFlags = config.otpFlags;\r\n const otpPepper = config.otpPepper;\r\n const defaultPhoneCc = config.defaultPhoneCountryCode;\r\n const otpAllowPhoneLogin = config.otpAllowPhoneLogin !== false;\r\n\r\n function otpOff(key: keyof StorefrontOtpFlags) {\r\n return !otpFlags || otpFlags[key] !== true;\r\n }\r\n\r\n const cartRepo = () => dataSource.getRepository(entityMap.carts);\r\n const cartItemRepo = () => dataSource.getRepository(entityMap.cart_items);\r\n const productRepo = () => dataSource.getRepository(entityMap.products);\r\n const contactRepo = () => dataSource.getRepository(entityMap.contacts);\r\n const addressRepo = () => dataSource.getRepository(entityMap.addresses);\r\n const orderRepo = () => dataSource.getRepository(entityMap.orders);\r\n const orderItemRepo = () => dataSource.getRepository(entityMap.order_items);\r\n const wishlistRepo = () => dataSource.getRepository(entityMap.wishlists);\r\n const wishlistItemRepo = () => dataSource.getRepository(entityMap.wishlist_items);\r\n const userRepo = () => dataSource.getRepository(entityMap.users);\r\n const tokenRepo = () => dataSource.getRepository(entityMap.password_reset_tokens);\r\n const collectionRepo = () => dataSource.getRepository(entityMap.collections);\r\n const groupRepo = () => dataSource.getRepository(entityMap.user_groups);\r\n const configRepo = () => dataSource.getRepository(entityMap.configs);\r\n\r\n const CART_CHECKOUT_RELATIONS = ['items', 'items.product', 'items.product.taxes', 'items.product.taxes.tax'] as const;\r\n\r\n function roundMoney(n: number): number {\r\n return Math.round(n * 100) / 100;\r\n }\r\n\r\n type CheckoutDraftLine = {\r\n productId: number;\r\n quantity: number;\r\n unitPrice: number;\r\n tax: number;\r\n total: number;\r\n hsn: string | null;\r\n uom: string | null;\r\n productType: string | null;\r\n taxRate: number | null;\r\n taxCode: string | null;\r\n };\r\n\r\n async function getStoreDefaultTaxRate(): Promise<number | null> {\r\n const rows = await configRepo().find({ where: { settings: 'store', deleted: false } as ObjectLiteral });\r\n for (const row of rows) {\r\n const r = row as { key: string; value: string };\r\n if (r.key === 'defaultTaxRate') {\r\n const n = parseFloat(String(r.value ?? '').trim());\r\n return Number.isFinite(n) && n >= 0 ? n : null;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n function computeTaxForProductLine(\r\n p: ObjectLiteral,\r\n lineSubtotal: number,\r\n defaultRate: number | null\r\n ): { tax: number; taxRate: number | null; taxCode: string | null } {\r\n const pts = (p.taxes as ObjectLiteral[] | undefined) ?? [];\r\n const activePts = pts.filter((pt) => {\r\n const t = pt.tax as ObjectLiteral | undefined;\r\n return t != null && t.active !== false;\r\n });\r\n if (activePts.length) {\r\n let sumRate = 0;\r\n const slugs: string[] = [];\r\n for (const pt of activePts) {\r\n const t = pt.tax as ObjectLiteral;\r\n const r = Number(pt.rate != null && pt.rate !== '' ? pt.rate : (t.rate ?? 0));\r\n if (Number.isFinite(r)) sumRate += r;\r\n const slug = String(t.slug ?? '').trim();\r\n if (slug) slugs.push(slug);\r\n }\r\n const tax = roundMoney((lineSubtotal * sumRate) / 100);\r\n return {\r\n tax,\r\n taxRate: sumRate > 0 ? roundMoney(sumRate) : null,\r\n taxCode: slugs.length ? [...new Set(slugs)].sort().join(',') : null,\r\n };\r\n }\r\n if (defaultRate != null && defaultRate > 0) {\r\n return {\r\n tax: roundMoney((lineSubtotal * defaultRate) / 100),\r\n taxRate: roundMoney(defaultRate),\r\n taxCode: null,\r\n };\r\n }\r\n return { tax: 0, taxRate: null, taxCode: null };\r\n }\r\n\r\n function parseInlineAddress(raw: unknown): Record<string, string> | null {\r\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\r\n const o = raw as Record<string, unknown>;\r\n const line1 = String(o.line1 ?? '').trim();\r\n if (!line1) return null;\r\n return {\r\n line1,\r\n line2: o.line2 != null ? String(o.line2) : '',\r\n city: o.city != null ? String(o.city) : '',\r\n state: o.state != null ? String(o.state) : '',\r\n postalCode: o.postalCode != null ? String(o.postalCode) : '',\r\n country: o.country != null ? String(o.country) : '',\r\n };\r\n }\r\n\r\n function intFromBody(v: unknown): number | undefined {\r\n if (typeof v === 'number' && Number.isInteger(v)) return v;\r\n if (typeof v === 'string' && /^\\d+$/.test(v)) return parseInt(v, 10);\r\n return undefined;\r\n }\r\n\r\n async function resolveCheckoutAddress(\r\n contactId: number,\r\n idVal: unknown,\r\n inlineVal: unknown\r\n ): Promise<{ id: number | null; error?: string }> {\r\n const aid = intFromBody(idVal);\r\n if (aid != null) {\r\n const existing = await addressRepo().findOne({\r\n where: { id: aid, contactId } as ObjectLiteral,\r\n });\r\n if (!existing) return { id: null, error: 'Address not found' };\r\n return { id: aid };\r\n }\r\n const addr = parseInlineAddress(inlineVal);\r\n if (addr) {\r\n const saved = await addressRepo().save(\r\n addressRepo().create({\r\n contactId,\r\n line1: addr.line1,\r\n line2: addr.line2?.trim() ? addr.line2 : null,\r\n city: addr.city?.trim() ? addr.city : null,\r\n state: addr.state?.trim() ? addr.state : null,\r\n postalCode: addr.postalCode?.trim() ? addr.postalCode : null,\r\n country: addr.country?.trim() ? addr.country : null,\r\n } as ObjectLiteral)\r\n );\r\n return { id: (saved as { id: number }).id };\r\n }\r\n return { id: null };\r\n }\r\n\r\n async function prepareCheckoutFromCart(\r\n b: Record<string, unknown>,\r\n cart: ObjectLiteral,\r\n contactId: number\r\n ): Promise<\r\n | {\r\n ok: true;\r\n lines: CheckoutDraftLine[];\r\n subtotal: number;\r\n orderTax: number;\r\n orderTotal: number;\r\n billingAddressId: number;\r\n shippingAddressId: number | null;\r\n }\r\n | { ok: false; status: number; message: string }\r\n > {\r\n const defaultRate = await getStoreDefaultTaxRate();\r\n const lines: CheckoutDraftLine[] = [];\r\n let subtotal = 0;\r\n let orderTax = 0;\r\n let needsShipping = false;\r\n\r\n for (const it of (cart.items as ObjectLiteral[]) || []) {\r\n const p = it.product as ObjectLiteral | undefined;\r\n if (!p || p.deleted || p.status !== 'available') continue;\r\n const unit = Number(p.price);\r\n const qty = (it.quantity as number) || 1;\r\n const lineSubtotal = unit * qty;\r\n const pType = p.type === 'service' ? 'service' : 'product';\r\n if (pType === 'product') needsShipping = true;\r\n\r\n const { tax, taxRate, taxCode } = computeTaxForProductLine(p, lineSubtotal, defaultRate);\r\n const lineTotal = roundMoney(lineSubtotal + tax);\r\n subtotal = roundMoney(subtotal + lineSubtotal);\r\n orderTax = roundMoney(orderTax + tax);\r\n\r\n lines.push({\r\n productId: p.id as number,\r\n quantity: qty,\r\n unitPrice: unit,\r\n tax,\r\n total: lineTotal,\r\n hsn: (p.hsn as string | null) ?? null,\r\n uom: (p.uom as string | null) ?? null,\r\n productType: pType,\r\n taxRate,\r\n taxCode,\r\n });\r\n }\r\n\r\n if (!lines.length) return { ok: false, status: 400, message: 'No available items in cart' };\r\n\r\n const bill = await resolveCheckoutAddress(contactId, b.billingAddressId, b.billingAddress);\r\n if (bill.error) return { ok: false, status: 400, message: bill.error };\r\n if (bill.id == null) return { ok: false, status: 400, message: 'Billing address required' };\r\n\r\n const ship = await resolveCheckoutAddress(contactId, b.shippingAddressId, b.shippingAddress);\r\n if (ship.error) return { ok: false, status: 400, message: ship.error };\r\n\r\n let shippingAddressId: number | null = ship.id;\r\n if (needsShipping && shippingAddressId == null) shippingAddressId = bill.id;\r\n if (needsShipping && shippingAddressId == null) {\r\n return { ok: false, status: 400, message: 'Shipping address required' };\r\n }\r\n\r\n const orderTotal = roundMoney(subtotal + orderTax);\r\n\r\n return {\r\n ok: true,\r\n lines,\r\n subtotal,\r\n orderTax,\r\n orderTotal,\r\n billingAddressId: bill.id,\r\n shippingAddressId,\r\n };\r\n }\r\n\r\n async function syncContactToErp(contact: ObjectLiteral): Promise<void> {\r\n if (!getCms) return;\r\n try {\r\n const cms = await getCms();\r\n await queueErpCreateContactIfEnabled(cms, dataSource, entityMap, {\r\n name: String((contact as { name: string }).name ?? ''),\r\n email: String((contact as { email: string }).email ?? '').trim(),\r\n phone: (contact as { phone: string | null }).phone,\r\n type: (contact as { type: string | null }).type,\r\n company: (contact as { company: string | null }).company,\r\n notes: (contact as { notes: string | null }).notes,\r\n });\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n\r\n async function ensureContactForUser(userId: number): Promise<{ id: number } | null> {\r\n let c = await contactRepo().findOne({ where: { userId, deleted: false } as ObjectLiteral });\r\n if (c) return c as { id: number };\r\n const u = await userRepo().findOne({ where: { id: userId } });\r\n if (!u) return null;\r\n const unclaimed = await contactRepo().findOne({\r\n where: { email: u.email, userId: IsNull(), deleted: false } as ObjectLiteral,\r\n });\r\n if (unclaimed) {\r\n await contactRepo().update((unclaimed as { id: number }).id, { userId });\r\n return { id: (unclaimed as { id: number }).id };\r\n }\r\n const created = await contactRepo().save(\r\n contactRepo().create({\r\n name: u.name,\r\n email: u.email,\r\n phone: null,\r\n userId,\r\n deleted: false,\r\n } as ObjectLiteral)\r\n );\r\n await syncContactToErp(created as ObjectLiteral);\r\n return { id: (created as { id: number }).id };\r\n }\r\n\r\n async function getOrCreateCart(req: Request): Promise<{ cart: ObjectLiteral; setCookie: string | null; err: Response | null }> {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (Number.isFinite(uid)) {\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return { cart: {} as ObjectLiteral, setCookie: null, err: json({ error: 'User not found' }, { status: 400 }) };\r\n let cart = await cartRepo().findOne({\r\n where: { contactId: contact.id } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!cart) {\r\n cart = await cartRepo().save(\r\n cartRepo().create({ contactId: contact.id, guestToken: null, currency: 'INR' } as ObjectLiteral)\r\n );\r\n cart = await cartRepo().findOne({\r\n where: { id: (cart as { id: number }).id },\r\n relations: ['items', 'items.product'],\r\n });\r\n }\r\n return { cart: cart!, setCookie: null, err: null };\r\n }\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n let token = cookies[cookieName] || '';\r\n if (!token) {\r\n token = crypto.randomUUID();\r\n let cart = await cartRepo().findOne({\r\n where: { guestToken: token } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!cart) {\r\n cart = await cartRepo().save(\r\n cartRepo().create({ guestToken: token, contactId: null, currency: 'INR' } as ObjectLiteral)\r\n );\r\n cart = await cartRepo().findOne({\r\n where: { id: (cart as { id: number }).id },\r\n relations: ['items', 'items.product'],\r\n });\r\n }\r\n return { cart: cart!, setCookie: guestCookieHeader(cookieName, token), err: null };\r\n }\r\n let cart = await cartRepo().findOne({\r\n where: { guestToken: token } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!cart) {\r\n cart = await cartRepo().save(\r\n cartRepo().create({ guestToken: token, contactId: null, currency: 'INR' } as ObjectLiteral)\r\n );\r\n cart = await cartRepo().findOne({\r\n where: { id: (cart as { id: number }).id },\r\n relations: ['items', 'items.product'],\r\n });\r\n }\r\n return { cart: cart!, setCookie: null, err: null };\r\n }\r\n\r\n function primaryProductImageUrl(metadata: unknown): string | null {\r\n const meta = metadata as { images?: Array<{ url?: string; isDefault?: boolean }> } | null;\r\n const images = meta?.images;\r\n if (!Array.isArray(images) || !images.length) return null;\r\n const sorted = images.filter((i) => i?.url) as Array<{ url: string; isDefault?: boolean }>;\r\n if (!sorted.length) return null;\r\n const di = sorted.findIndex((i) => i.isDefault);\r\n if (di > 0) {\r\n const [d] = sorted.splice(di, 1);\r\n sorted.unshift(d!);\r\n }\r\n return sorted[0]!.url;\r\n }\r\n\r\n function serializeCart(cart: ObjectLiteral) {\r\n const items = (cart.items as ObjectLiteral[]) || [];\r\n return {\r\n id: cart.id,\r\n currency: cart.currency,\r\n items: items.map((it) => {\r\n const p = it.product as ObjectLiteral | undefined;\r\n return {\r\n id: it.id,\r\n productId: it.productId,\r\n quantity: it.quantity,\r\n metadata: it.metadata,\r\n product: p\r\n ? {\r\n id: p.id,\r\n name: p.name,\r\n slug: p.slug,\r\n price: p.price,\r\n sku: p.sku,\r\n type: p.type === 'service' ? 'service' : 'product',\r\n image: primaryProductImageUrl(p.metadata),\r\n }\r\n : null,\r\n };\r\n }),\r\n };\r\n }\r\n\r\n function serializeSeo(seo: unknown): ObjectLiteral | undefined {\r\n if (!seo || typeof seo !== 'object') return undefined;\r\n const s = seo as ObjectLiteral;\r\n return {\r\n title: s.title ?? null,\r\n description: s.description ?? null,\r\n keywords: s.keywords ?? null,\r\n ogTitle: s.ogTitle ?? null,\r\n ogDescription: s.ogDescription ?? null,\r\n ogImage: s.ogImage ?? null,\r\n slug: s.slug ?? null,\r\n };\r\n }\r\n\r\n function serializeProduct(p: ObjectLiteral) {\r\n const seo = serializeSeo(p.seo);\r\n return {\r\n id: p.id,\r\n name: p.name,\r\n slug: p.slug,\r\n sku: p.sku,\r\n hsn: p.hsn,\r\n uom: p.uom ?? null,\r\n type: p.type === 'service' ? 'service' : 'product',\r\n price: p.price,\r\n compareAtPrice: p.compareAtPrice,\r\n status: p.status,\r\n collectionId: p.collectionId,\r\n metadata: p.metadata,\r\n ...(seo ? { seo } : {}),\r\n };\r\n }\r\n\r\n return {\r\n async handle(method: string, path: string[], req: Request): Promise<Response> {\r\n try {\r\n // --- products GET list ---\r\n if (path[0] === 'products' && path.length === 1 && method === 'GET') {\r\n const url = new URL(req.url || '', 'http://localhost');\r\n const collectionSlug = url.searchParams.get('collection')?.trim();\r\n const collectionId = url.searchParams.get('collectionId');\r\n const limit = Math.min(100, Math.max(1, parseInt(url.searchParams.get('limit') || '20', 10)));\r\n const offset = Math.max(0, parseInt(url.searchParams.get('offset') || '0', 10));\r\n const where: ObjectLiteral = { status: 'available', deleted: false };\r\n let collectionFilter: { name: string | null; slug: string | null } | null = null;\r\n if (collectionSlug) {\r\n let col: ObjectLiteral | null = null;\r\n if (/^\\d+$/.test(collectionSlug)) {\r\n col = (await collectionRepo().findOne({\r\n where: {\r\n id: parseInt(collectionSlug, 10),\r\n active: true,\r\n deleted: false,\r\n } as ObjectLiteral,\r\n })) as ObjectLiteral | null;\r\n } else {\r\n col = (await collectionRepo()\r\n .createQueryBuilder('c')\r\n .where('LOWER(c.slug) = LOWER(:slug)', { slug: collectionSlug })\r\n .andWhere('c.active = :a', { a: true })\r\n .andWhere('c.deleted = :d', { d: false })\r\n .getOne()) as ObjectLiteral | null;\r\n }\r\n if (!col) {\r\n return json({ products: [], total: 0, collection: null });\r\n }\r\n where.collectionId = col.id;\r\n collectionFilter = { name: col.name as string | null, slug: col.slug as string | null };\r\n } else if (collectionId) {\r\n const cid = parseInt(collectionId, 10);\r\n if (Number.isFinite(cid)) where.collectionId = cid;\r\n }\r\n const [items, total] = await productRepo().findAndCount({\r\n where,\r\n order: { id: 'ASC' },\r\n take: limit,\r\n skip: offset,\r\n });\r\n return json({\r\n products: items.map(serializeProduct),\r\n total,\r\n ...(collectionFilter && { collection: collectionFilter }),\r\n });\r\n }\r\n\r\n // --- products GET by id or slug ---\r\n if (path[0] === 'products' && path.length === 2 && method === 'GET') {\r\n const idOrSlug = path[1]!;\r\n const byId = /^\\d+$/.test(idOrSlug);\r\n const product = await productRepo().findOne({\r\n where: byId\r\n ? { id: parseInt(idOrSlug, 10), status: 'available', deleted: false }\r\n : { slug: idOrSlug, status: 'available', deleted: false },\r\n relations: ['attributes', 'attributes.attribute', 'seo'],\r\n } as ObjectLiteral);\r\n if (!product) return json({ error: 'Not found' }, { status: 404 });\r\n const p = product as ObjectLiteral;\r\n const attrRows = (p.attributes as ObjectLiteral[] | undefined) ?? [];\r\n const attributeTags = attrRows.map((pa) => ({\r\n name: ((pa.attribute as ObjectLiteral)?.name as string) ?? '',\r\n value: String(pa.value ?? ''),\r\n })).filter((t) => t.name || t.value);\r\n return json({ ...serializeProduct(p), attributes: attributeTags });\r\n }\r\n\r\n // --- collections GET list ---\r\n if (path[0] === 'collections' && path.length === 1 && method === 'GET') {\r\n const items = await collectionRepo().find({\r\n where: { active: true, deleted: false } as ObjectLiteral,\r\n order: { sortOrder: 'ASC', id: 'ASC' },\r\n });\r\n const ids = items.map((c) => (c as ObjectLiteral).id as number);\r\n const countByCollection: Record<number, number> = {};\r\n if (ids.length > 0) {\r\n const rows = await productRepo()\r\n .createQueryBuilder('p')\r\n .select('p.collectionId', 'collectionId')\r\n .addSelect('COUNT(p.id)', 'cnt')\r\n .where('p.collectionId IN (:...ids)', { ids })\r\n .andWhere('p.status = :status', { status: 'available' })\r\n .andWhere('p.deleted = :del', { del: false })\r\n .groupBy('p.collectionId')\r\n .getRawMany();\r\n for (const r of rows) {\r\n const cid = (r as ObjectLiteral).collectionId;\r\n if (cid != null) countByCollection[Number(cid)] = parseInt(String((r as ObjectLiteral).cnt), 10);\r\n }\r\n }\r\n return json({\r\n collections: items.map((c) => {\r\n const col = c as ObjectLiteral;\r\n const id = col.id as number;\r\n return {\r\n id,\r\n name: col.name,\r\n slug: col.slug,\r\n description: col.description,\r\n image: col.image,\r\n productCount: countByCollection[id] ?? 0,\r\n };\r\n }),\r\n });\r\n }\r\n\r\n // --- collections GET by id or slug ---\r\n if (path[0] === 'collections' && path.length === 2 && method === 'GET') {\r\n const idOrSlug = path[1]!;\r\n const byId = /^\\d+$/.test(idOrSlug);\r\n const collection = await collectionRepo().findOne({\r\n where: byId\r\n ? { id: parseInt(idOrSlug, 10), active: true, deleted: false }\r\n : { slug: idOrSlug, active: true, deleted: false },\r\n relations: ['seo'],\r\n } as ObjectLiteral);\r\n if (!collection) return json({ error: 'Not found' }, { status: 404 });\r\n const col = collection as ObjectLiteral;\r\n const products = await productRepo().find({\r\n where: { collectionId: col.id, status: 'available', deleted: false } as ObjectLiteral,\r\n order: { id: 'ASC' },\r\n });\r\n const colSeo = serializeSeo(col.seo);\r\n return json({\r\n id: col.id,\r\n name: col.name,\r\n slug: col.slug,\r\n description: col.description,\r\n image: col.image,\r\n ...(colSeo ? { seo: colSeo } : {}),\r\n products: products.map((p) => serializeProduct(p as ObjectLiteral)),\r\n });\r\n }\r\n\r\n // --- profile GET (auth) ---\r\n if (path[0] === 'profile' && path.length === 1 && method === 'GET') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const user = await userRepo().findOne({ where: { id: uid }, select: ['id', 'name', 'email'] });\r\n if (!user) return json({ error: 'Not found' }, { status: 404 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n return json({\r\n user: { id: (user as ObjectLiteral).id, name: (user as ObjectLiteral).name, email: (user as ObjectLiteral).email },\r\n contact: contact\r\n ? {\r\n id: (contact as ObjectLiteral).id,\r\n name: (contact as ObjectLiteral).name,\r\n email: (contact as ObjectLiteral).email,\r\n phone: (contact as ObjectLiteral).phone,\r\n }\r\n : null,\r\n });\r\n }\r\n\r\n // --- profile PUT (auth) ---\r\n if (path[0] === 'profile' && path.length === 1 && method === 'PUT') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const b = (await req.json().catch(() => ({}))) as { name?: string; phone?: string };\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (contact) {\r\n const updates: ObjectLiteral = {};\r\n if (typeof b.name === 'string' && b.name.trim()) updates.name = b.name.trim();\r\n if (b.phone !== undefined) updates.phone = b.phone === null || b.phone === '' ? null : String(b.phone);\r\n if (Object.keys(updates).length) await contactRepo().update((contact as { id: number }).id, updates);\r\n }\r\n const user = await userRepo().findOne({ where: { id: uid }, select: ['id', 'name', 'email'] });\r\n if (user && typeof b.name === 'string' && b.name.trim()) {\r\n await userRepo().update(uid, { name: b.name.trim() });\r\n }\r\n const updatedContact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (updatedContact) await syncContactToErp(updatedContact as ObjectLiteral);\r\n const updatedUser = await userRepo().findOne({ where: { id: uid }, select: ['id', 'name', 'email'] });\r\n return json({\r\n user: updatedUser ? { id: (updatedUser as ObjectLiteral).id, name: (updatedUser as ObjectLiteral).name, email: (updatedUser as ObjectLiteral).email } : null,\r\n contact: updatedContact\r\n ? {\r\n id: (updatedContact as ObjectLiteral).id,\r\n name: (updatedContact as ObjectLiteral).name,\r\n email: (updatedContact as ObjectLiteral).email,\r\n phone: (updatedContact as ObjectLiteral).phone,\r\n }\r\n : null,\r\n });\r\n }\r\n\r\n // --- addresses (auth: contact's addresses) ---\r\n async function getContactForAddresses(): Promise<{ contactId: number } | Response> {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (!contact) return json({ error: 'Contact not found' }, { status: 404 });\r\n return { contactId: (contact as { id: number }).id };\r\n }\r\n function serializeAddress(a: ObjectLiteral) {\r\n return {\r\n id: a.id,\r\n contactId: a.contactId,\r\n tag: a.tag,\r\n line1: a.line1,\r\n line2: a.line2,\r\n city: a.city,\r\n state: a.state,\r\n postalCode: a.postalCode,\r\n country: a.country,\r\n };\r\n }\r\n if (path[0] === 'addresses' && path.length === 1 && method === 'GET') {\r\n const contactOrErr = await getContactForAddresses();\r\n if (contactOrErr instanceof Response) return contactOrErr;\r\n const list = await addressRepo().find({\r\n where: { contactId: contactOrErr.contactId },\r\n order: { id: 'ASC' },\r\n });\r\n return json({ addresses: list.map((a) => serializeAddress(a as ObjectLiteral)) });\r\n }\r\n if (path[0] === 'addresses' && path.length === 1 && method === 'POST') {\r\n const contactOrErr = await getContactForAddresses();\r\n if (contactOrErr instanceof Response) return contactOrErr;\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const row: Record<string, unknown> = {\r\n contactId: contactOrErr.contactId,\r\n tag: typeof b.tag === 'string' ? b.tag.trim() || null : null,\r\n line1: typeof b.line1 === 'string' ? b.line1 : '',\r\n line2: typeof b.line2 === 'string' ? b.line2.trim() || null : null,\r\n city: typeof b.city === 'string' ? b.city : '',\r\n state: typeof b.state === 'string' ? b.state : '',\r\n postalCode: typeof b.postalCode === 'string' ? b.postalCode : '',\r\n country: typeof b.country === 'string' ? b.country : '',\r\n };\r\n const addrErr = validateAndNormalizeAddressRow(row);\r\n if (addrErr) return json({ error: addrErr }, { status: 400 });\r\n const created = await addressRepo().save(addressRepo().create(row as ObjectLiteral));\r\n return json(serializeAddress(created as ObjectLiteral));\r\n }\r\n if (path[0] === 'addresses' && path.length === 2 && (method === 'PATCH' || method === 'PUT')) {\r\n const contactOrErr = await getContactForAddresses();\r\n if (contactOrErr instanceof Response) return contactOrErr;\r\n const id = parseInt(path[1]!, 10);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const existing = await addressRepo().findOne({ where: { id, contactId: contactOrErr.contactId } as ObjectLiteral });\r\n if (!existing) return json({ error: 'Not found' }, { status: 404 });\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const updates: ObjectLiteral = {};\r\n if (b.tag !== undefined) updates.tag = typeof b.tag === 'string' ? b.tag.trim() || null : null;\r\n if (b.line1 !== undefined) updates.line1 = typeof b.line1 === 'string' ? b.line1.trim() || null : null;\r\n if (b.line2 !== undefined) updates.line2 = typeof b.line2 === 'string' ? b.line2.trim() || null : null;\r\n if (b.city !== undefined) updates.city = typeof b.city === 'string' ? b.city.trim() || null : null;\r\n if (b.state !== undefined) updates.state = typeof b.state === 'string' ? b.state.trim() || null : null;\r\n if (b.postalCode !== undefined) updates.postalCode = typeof b.postalCode === 'string' ? b.postalCode.trim() || null : null;\r\n if (b.country !== undefined) updates.country = typeof b.country === 'string' ? b.country.trim() || null : null;\r\n if (Object.keys(updates).length) {\r\n const merged: Record<string, unknown> = { ...(existing as Record<string, unknown>), ...updates };\r\n if (merged.tag === '') merged.tag = null;\r\n const addrErr = validateAndNormalizeAddressRow(merged);\r\n if (addrErr) return json({ error: addrErr }, { status: 400 });\r\n for (const k of Object.keys(updates)) {\r\n if (k in merged) (updates as Record<string, unknown>)[k] = merged[k];\r\n }\r\n await addressRepo().update(id, updates);\r\n }\r\n const updated = await addressRepo().findOne({ where: { id } as ObjectLiteral });\r\n return json(serializeAddress(updated as ObjectLiteral));\r\n }\r\n if (path[0] === 'addresses' && path.length === 2 && method === 'DELETE') {\r\n const contactOrErr = await getContactForAddresses();\r\n if (contactOrErr instanceof Response) return contactOrErr;\r\n const id = parseInt(path[1]!, 10);\r\n if (!Number.isFinite(id)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const existing = await addressRepo().findOne({ where: { id, contactId: contactOrErr.contactId } as ObjectLiteral });\r\n if (!existing) return json({ error: 'Not found' }, { status: 404 });\r\n await addressRepo().delete(id);\r\n return json({ deleted: true });\r\n }\r\n\r\n // --- verify-email POST (public) ---\r\n if (path[0] === 'verify-email' && path.length === 1 && method === 'POST') {\r\n const b = (await req.json().catch(() => ({}))) as { token?: string };\r\n const token = typeof b.token === 'string' ? b.token.trim() : '';\r\n if (!token) return json({ error: 'token is required' }, { status: 400 });\r\n const record = await tokenRepo().findOne({ where: { token } as ObjectLiteral });\r\n if (!record || (record as { expiresAt: Date }).expiresAt < new Date()) {\r\n return json({ error: 'Invalid or expired link. Please sign up again or contact support.' }, { status: 400 });\r\n }\r\n const email = (record as { email: string }).email;\r\n const user = await userRepo().findOne({ where: { email }, select: ['id', 'blocked'] });\r\n if (!user) return json({ error: 'User not found' }, { status: 400 });\r\n await userRepo().update((user as { id: number }).id, {\r\n blocked: false,\r\n emailVerifiedAt: new Date(),\r\n updatedAt: new Date(),\r\n } as ObjectLiteral);\r\n await tokenRepo().delete({ email } as ObjectLiteral);\r\n return json({ success: true, message: 'Email verified. You can sign in.' });\r\n }\r\n\r\n // --- auth/otp/send POST ---\r\n if (path[0] === 'auth' && path[1] === 'otp' && path[2] === 'send' && path.length === 3 && method === 'POST') {\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const purposeRaw = typeof b.purpose === 'string' ? b.purpose.trim() : '';\r\n const purpose = (purposeRaw === 'login' || purposeRaw === 'verify_email' || purposeRaw === 'verify_phone'\r\n ? purposeRaw\r\n : '') as OtpPurpose | '';\r\n if (!purpose) return json({ error: 'purpose must be login, verify_email, or verify_phone' }, { status: 400 });\r\n if (purpose === 'login' && otpOff('login')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n if (purpose === 'verify_email' && otpOff('verifyEmail')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n if (purpose === 'verify_phone' && otpOff('verifyPhone')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n\r\n const capOtp = await assertCaptchaOk(getCms, b, req, json);\r\n if (capOtp) return capOtp;\r\n\r\n const emailIn = typeof b.email === 'string' ? b.email.trim().toLowerCase() : '';\r\n const phoneIn = typeof b.phone === 'string' ? b.phone.trim() : '';\r\n let identifier: string;\r\n let channel: 'email' | 'sms';\r\n\r\n if (purpose === 'login') {\r\n if (emailIn) {\r\n identifier = emailIn;\r\n channel = 'email';\r\n } else if (phoneIn) {\r\n if (!otpAllowPhoneLogin) {\r\n return json({ error: 'Phone sign-in is not enabled' }, { status: 403 });\r\n }\r\n const p = normalizePhoneE164(phoneIn, defaultPhoneCc);\r\n if (!p) return json({ error: 'Invalid phone' }, { status: 400 });\r\n identifier = p;\r\n channel = 'sms';\r\n } else {\r\n return json({ error: 'email or phone required' }, { status: 400 });\r\n }\r\n const user =\r\n channel === 'email'\r\n ? await userRepo().findOne({ where: { email: identifier } as ObjectLiteral })\r\n : await userRepo().findOne({ where: { phone: identifier } as ObjectLiteral });\r\n if (!user || (user as { deleted?: boolean }).deleted || (user as { blocked?: boolean }).blocked) {\r\n return json({ ok: true });\r\n }\r\n } else if (purpose === 'verify_email') {\r\n if (!emailIn || !isValidSignupEmail(emailIn)) return json({ error: 'Valid email required' }, { status: 400 });\r\n identifier = emailIn;\r\n channel = 'email';\r\n const user = await userRepo().findOne({ where: { email: identifier } as ObjectLiteral });\r\n if (!user || (user as { deleted?: boolean }).deleted) return json({ ok: true });\r\n } else {\r\n const su = await getSessionUser();\r\n const uid = su?.id ? parseInt(String(su.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const p = normalizePhoneE164(phoneIn, defaultPhoneCc);\r\n if (!p) return json({ error: 'Valid phone required' }, { status: 400 });\r\n identifier = p;\r\n channel = 'sms';\r\n const taken = await userRepo().findOne({\r\n where: { phone: identifier } as ObjectLiteral,\r\n select: ['id'],\r\n });\r\n if (taken && (taken as { id: number }).id !== uid) {\r\n return json({ error: 'Phone already in use' }, { status: 400 });\r\n }\r\n }\r\n\r\n const code = generateNumericOtp(6);\r\n const created = await createOtpChallenge(dataSource, entityMap, {\r\n purpose,\r\n channel,\r\n identifier,\r\n code,\r\n pepper: otpPepper,\r\n });\r\n if (!created.ok) return json({ error: created.error }, { status: created.status });\r\n\r\n if (!getCms) return json({ error: 'OTP delivery not configured' }, { status: 503 });\r\n\r\n try {\r\n const cms = await getCms();\r\n if (channel === 'email') {\r\n if (!cms.getPlugin('email')) return json({ error: 'Email not configured' }, { status: 503 });\r\n const companyDetails = getCompanyDetails ? await getCompanyDetails() : {};\r\n await queueEmail(cms, {\r\n to: identifier,\r\n templateName: 'otp',\r\n ctx: { code, companyDetails: companyDetails ?? {} },\r\n });\r\n } else {\r\n if (!cms.getPlugin('sms')) return json({ error: 'SMS not configured' }, { status: 503 });\r\n const templateKey = purpose === 'verify_phone' ? 'auth.otp_verify_phone' : 'auth.otp_login';\r\n await queueSms(cms, { to: identifier, templateKey, variables: { code } });\r\n }\r\n } catch {\r\n return json({ error: 'Failed to send code' }, { status: 500 });\r\n }\r\n return json({ ok: true });\r\n }\r\n\r\n // --- auth/otp/verify-email POST ---\r\n if (path[0] === 'auth' && path[1] === 'otp' && path[2] === 'verify-email' && path.length === 3 && method === 'POST') {\r\n if (otpOff('verifyEmail')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n const b = (await req.json().catch(() => ({}))) as { email?: string; code?: string };\r\n const email = typeof b.email === 'string' ? b.email.trim().toLowerCase() : '';\r\n const code = typeof b.code === 'string' ? b.code.trim() : '';\r\n if (!email || !code) return json({ error: 'email and code required' }, { status: 400 });\r\n const v = await verifyAndConsumeOtpChallenge(dataSource, entityMap, {\r\n purpose: 'verify_email',\r\n identifier: email,\r\n code,\r\n pepper: otpPepper,\r\n });\r\n if (!v.ok) return json({ error: v.error }, { status: v.status });\r\n const user = await userRepo().findOne({ where: { email } as ObjectLiteral });\r\n if (!user) return json({ error: 'User not found' }, { status: 400 });\r\n await userRepo().update((user as { id: number }).id, {\r\n blocked: false,\r\n emailVerifiedAt: new Date(),\r\n updatedAt: new Date(),\r\n } as ObjectLiteral);\r\n await tokenRepo().delete({ email } as ObjectLiteral);\r\n return json({ success: true, message: 'Email verified. You can sign in.' });\r\n }\r\n\r\n // --- auth/otp/verify-phone POST ---\r\n if (path[0] === 'auth' && path[1] === 'otp' && path[2] === 'verify-phone' && path.length === 3 && method === 'POST') {\r\n if (otpOff('verifyPhone')) return json({ error: 'otp_disabled' }, { status: 403 });\r\n const su = await getSessionUser();\r\n const uid = su?.id ? parseInt(String(su.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const b = (await req.json().catch(() => ({}))) as { phone?: string; code?: string };\r\n const phoneRaw = typeof b.phone === 'string' ? b.phone.trim() : '';\r\n const code = typeof b.code === 'string' ? b.code.trim() : '';\r\n const phone = normalizePhoneE164(phoneRaw, defaultPhoneCc);\r\n if (!phone || !code) return json({ error: 'phone and code required' }, { status: 400 });\r\n const v = await verifyAndConsumeOtpChallenge(dataSource, entityMap, {\r\n purpose: 'verify_phone',\r\n identifier: phone,\r\n code,\r\n pepper: otpPepper,\r\n });\r\n if (!v.ok) return json({ error: v.error }, { status: v.status });\r\n const taken = await userRepo().findOne({ where: { phone } as ObjectLiteral, select: ['id'] });\r\n if (taken && (taken as { id: number }).id !== uid) {\r\n return json({ error: 'Phone already in use' }, { status: 400 });\r\n }\r\n await userRepo().update(uid, { phone, phoneVerifiedAt: new Date(), updatedAt: new Date() } as ObjectLiteral);\r\n const contact = await ensureContactForUser(uid);\r\n if (contact) {\r\n await contactRepo().update(contact.id, { phone } as ObjectLiteral);\r\n }\r\n return json({ success: true });\r\n }\r\n\r\n // --- register POST ---\r\n if (path[0] === 'register' && path.length === 1 && method === 'POST') {\r\n if (!config.hashPassword) return json({ error: 'Registration not configured' }, { status: 501 });\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capReg = await assertCaptchaOk(getCms, b, req, json);\r\n if (capReg) return capReg;\r\n const name = typeof b.name === 'string' ? b.name.trim() : '';\r\n const email = typeof b.email === 'string' ? b.email.trim().toLowerCase() : '';\r\n const password = typeof b.password === 'string' ? b.password : '';\r\n if (!name || !email || !password) return json({ error: 'name, email and password are required' }, { status: 400 });\r\n if (!isValidSignupEmail(email)) return json({ error: 'Invalid email address' }, { status: 400 });\r\n const existing = await userRepo().findOne({ where: { email } });\r\n if (existing) return json({ error: 'User with this email already exists' }, { status: 400 });\r\n const customerG = await groupRepo().findOne({ where: { name: 'Customer', deleted: false } as ObjectLiteral });\r\n const groupId = customerG ? (customerG as { id: number }).id : null;\r\n const hashed = await config.hashPassword(password);\r\n const requireEmailVerification = Boolean(getCms);\r\n const newUser = await userRepo().save(\r\n userRepo().create({\r\n name,\r\n email,\r\n password: hashed,\r\n blocked: requireEmailVerification,\r\n groupId,\r\n adminAccess: false,\r\n } as ObjectLiteral)\r\n );\r\n const userId = (newUser as { id: number }).id;\r\n await linkUnclaimedContactToUser(dataSource, entityMap.contacts, userId, email);\r\n\r\n let emailVerificationSent = false;\r\n if (requireEmailVerification && getCms) {\r\n try {\r\n const crypto = await import('crypto');\r\n const rawToken = crypto.randomBytes(32).toString('hex');\r\n const expiresAt = new Date(Date.now() + SIGNUP_VERIFY_EXPIRY_HOURS * 60 * 60 * 1000);\r\n await tokenRepo().save(\r\n tokenRepo().create({ email, token: rawToken, expiresAt } as ObjectLiteral)\r\n );\r\n const cms = await getCms();\r\n const companyDetails = getCompanyDetails ? await getCompanyDetails() : {};\r\n const base = (publicSiteUrl || '').replace(/\\/$/, '').trim() || 'http://localhost:3000';\r\n const verifyEmailUrl = `${base}/verify-email?token=${encodeURIComponent(rawToken)}`;\r\n await queueEmail(cms, {\r\n to: email,\r\n templateName: 'signup',\r\n ctx: { name, verifyEmailUrl, companyDetails: companyDetails ?? {} },\r\n });\r\n emailVerificationSent = true;\r\n } catch {\r\n await userRepo().update(userId, { blocked: false, updatedAt: new Date() } as ObjectLiteral);\r\n }\r\n }\r\n\r\n return json({\r\n success: true,\r\n userId,\r\n emailVerificationSent,\r\n });\r\n }\r\n\r\n // --- cart GET ---\r\n if (path[0] === 'cart' && path.length === 1 && method === 'GET') {\r\n const { cart, setCookie, err } = await getOrCreateCart(req);\r\n if (err) return err;\r\n const body = serializeCart(cart);\r\n if (setCookie) return json(body, { headers: { 'Set-Cookie': setCookie } });\r\n return json(body);\r\n }\r\n\r\n // --- cart/items POST ---\r\n if (path[0] === 'cart' && path[1] === 'items' && path.length === 2 && method === 'POST') {\r\n const body = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capCart = await assertCaptchaOk(getCms, body, req, json);\r\n if (capCart) return capCart;\r\n const productId = Number(body.productId);\r\n const quantity = Math.max(1, Number(body.quantity) || 1);\r\n if (!Number.isFinite(productId)) return json({ error: 'productId required' }, { status: 400 });\r\n const product = await productRepo().findOne({ where: { id: productId, deleted: false } as ObjectLiteral });\r\n if (!product) return json({ error: 'Product not found' }, { status: 404 });\r\n const { cart, setCookie, err } = await getOrCreateCart(req);\r\n if (err) return err;\r\n const cartId = (cart as { id: number }).id;\r\n const existing = await cartItemRepo().findOne({ where: { cartId, productId } as ObjectLiteral });\r\n if (existing) {\r\n await cartItemRepo().update((existing as { id: number }).id, {\r\n quantity: (existing as { quantity: number }).quantity + quantity,\r\n });\r\n } else {\r\n await cartItemRepo().save(\r\n cartItemRepo().create({ cartId, productId, quantity } as ObjectLiteral)\r\n );\r\n }\r\n await cartRepo().update(cartId, { updatedAt: new Date() });\r\n const fresh = await cartRepo().findOne({\r\n where: { id: cartId },\r\n relations: ['items', 'items.product'],\r\n });\r\n const out = serializeCart(fresh!);\r\n if (setCookie) return json(out, { headers: { 'Set-Cookie': setCookie } });\r\n return json(out);\r\n }\r\n\r\n // --- cart/items/:id PATCH DELETE ---\r\n if (path[0] === 'cart' && path[1] === 'items' && path.length === 3) {\r\n const itemId = parseInt(path[2]!, 10);\r\n if (!Number.isFinite(itemId)) return json({ error: 'Invalid item id' }, { status: 400 });\r\n const { cart, setCookie, err } = await getOrCreateCart(req);\r\n if (err) return err;\r\n const cartId = (cart as { id: number }).id;\r\n const item = await cartItemRepo().findOne({ where: { id: itemId, cartId } as ObjectLiteral });\r\n if (!item) return json({ error: 'Not found' }, { status: 404 });\r\n if (method === 'DELETE') {\r\n await cartItemRepo().delete(itemId);\r\n await cartRepo().update(cartId, { updatedAt: new Date() });\r\n const fresh = await cartRepo().findOne({\r\n where: { id: cartId },\r\n relations: ['items', 'items.product'],\r\n });\r\n const out = serializeCart(fresh!);\r\n if (setCookie) return json(out, { headers: { 'Set-Cookie': setCookie } });\r\n return json(out);\r\n }\r\n if (method === 'PATCH') {\r\n const b = (await req.json().catch(() => ({}))) as { quantity?: number };\r\n const q = Math.max(0, Number(b.quantity) || 0);\r\n if (q === 0) await cartItemRepo().delete(itemId);\r\n else await cartItemRepo().update(itemId, { quantity: q });\r\n await cartRepo().update(cartId, { updatedAt: new Date() });\r\n const fresh = await cartRepo().findOne({\r\n where: { id: cartId },\r\n relations: ['items', 'items.product'],\r\n });\r\n const out = serializeCart(fresh!);\r\n if (setCookie) return json(out, { headers: { 'Set-Cookie': setCookie } });\r\n return json(out);\r\n }\r\n }\r\n\r\n // --- cart/merge POST (auth) ---\r\n if (path[0] === 'cart' && path[1] === 'merge' && method === 'POST') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return json({ error: 'Contact not found' }, { status: 400 });\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n const guestToken = cookies[cookieName];\r\n if (!guestToken) return json({ merged: false, message: 'No guest cart' });\r\n const guestCart = await cartRepo().findOne({\r\n where: { guestToken } as ObjectLiteral,\r\n relations: ['items'],\r\n });\r\n if (!guestCart || !((guestCart as { items?: unknown[] }).items || []).length) {\r\n let uc = await cartRepo().findOne({\r\n where: { contactId: contact.id } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!uc) uc = { items: [] } as ObjectLiteral;\r\n return json(\r\n { merged: false, cart: serializeCart(uc) },\r\n { headers: { 'Set-Cookie': `${cookieName}=; Path=/; Max-Age=0` } }\r\n );\r\n }\r\n let userCart = await cartRepo().findOne({ where: { contactId: contact.id } as ObjectLiteral });\r\n if (!userCart) {\r\n userCart = await cartRepo().save(\r\n cartRepo().create({ contactId: contact.id, guestToken: null, currency: (guestCart as { currency: string }).currency } as ObjectLiteral)\r\n );\r\n }\r\n const uidCart = (userCart as { id: number }).id;\r\n const gItems = ((guestCart as { items: ObjectLiteral[] }).items) || [];\r\n for (const gi of gItems) {\r\n const existing = await cartItemRepo().findOne({\r\n where: { cartId: uidCart, productId: (gi as { productId: number }).productId } as ObjectLiteral,\r\n });\r\n if (existing) {\r\n await cartItemRepo().update((existing as { id: number }).id, {\r\n quantity: (existing as { quantity: number }).quantity + (gi as { quantity: number }).quantity,\r\n });\r\n } else {\r\n await cartItemRepo().save(\r\n cartItemRepo().create({\r\n cartId: uidCart,\r\n productId: (gi as { productId: number }).productId,\r\n quantity: (gi as { quantity: number }).quantity,\r\n metadata: (gi as { metadata: unknown }).metadata,\r\n } as ObjectLiteral)\r\n );\r\n }\r\n }\r\n await cartRepo().delete((guestCart as { id: number }).id);\r\n await cartRepo().update(uidCart, { updatedAt: new Date() });\r\n const fresh = await cartRepo().findOne({\r\n where: { id: uidCart },\r\n relations: ['items', 'items.product'],\r\n });\r\n // Merge guest wishlist into contact wishlist (same guestId cookie)\r\n const guestWishlist = await wishlistRepo().findOne({\r\n where: { guestId: guestToken } as ObjectLiteral,\r\n relations: ['items'],\r\n });\r\n if (guestWishlist && ((guestWishlist as { items?: unknown[] }).items || []).length > 0) {\r\n const userWishlist = await getDefaultWishlist(contact.id);\r\n const gItems = ((guestWishlist as { items: ObjectLiteral[] }).items) || [];\r\n for (const gi of gItems) {\r\n const pid = (gi as { productId: number }).productId;\r\n const ex = await wishlistItemRepo().findOne({ where: { wishlistId: userWishlist.id, productId: pid } as ObjectLiteral });\r\n if (!ex) await wishlistItemRepo().save(wishlistItemRepo().create({ wishlistId: userWishlist.id, productId: pid } as ObjectLiteral));\r\n }\r\n await wishlistRepo().delete((guestWishlist as { id: number }).id);\r\n }\r\n return json({ merged: true, cart: serializeCart(fresh!) }, { headers: { 'Set-Cookie': `${cookieName}=; Path=/; Max-Age=0` } });\r\n }\r\n\r\n // --- wishlist (guest or auth: same guestId cookie as cart) ---\r\n async function getDefaultWishlist(contactId: number) {\r\n let w = await wishlistRepo().findOne({ where: { contactId, name: 'default' } as ObjectLiteral });\r\n if (!w) {\r\n w = await wishlistRepo().save(wishlistRepo().create({ contactId, guestId: null, name: 'default' } as ObjectLiteral));\r\n }\r\n return w as { id: number };\r\n }\r\n\r\n async function getOrCreateWishlist(req: Request): Promise<{ wishlist: ObjectLiteral; setCookie: string | null; err: Response | null }> {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (Number.isFinite(uid)) {\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return { wishlist: {} as ObjectLiteral, setCookie: null, err: json({ error: 'User not found' }, { status: 400 }) };\r\n const w = await getDefaultWishlist(contact.id);\r\n const wishlist = await wishlistRepo().findOne({ where: { id: w.id } as ObjectLiteral });\r\n return { wishlist: wishlist!, setCookie: null, err: null };\r\n }\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n let token = cookies[cookieName] || '';\r\n if (!token) {\r\n token = crypto.randomUUID();\r\n let w = await wishlistRepo().findOne({ where: { guestId: token } as ObjectLiteral });\r\n if (!w) {\r\n w = await wishlistRepo().save(wishlistRepo().create({ guestId: token, contactId: null, name: 'default' } as ObjectLiteral));\r\n }\r\n return { wishlist: w!, setCookie: guestCookieHeader(cookieName, token), err: null };\r\n }\r\n let w = await wishlistRepo().findOne({ where: { guestId: token } as ObjectLiteral });\r\n if (!w) {\r\n w = await wishlistRepo().save(wishlistRepo().create({ guestId: token, contactId: null, name: 'default' } as ObjectLiteral));\r\n }\r\n return { wishlist: w!, setCookie: null, err: null };\r\n }\r\n\r\n if (path[0] === 'wishlist' && path.length === 1 && method === 'GET') {\r\n const { wishlist, setCookie, err } = await getOrCreateWishlist(req);\r\n if (err) return err;\r\n const items = await wishlistItemRepo().find({\r\n where: { wishlistId: (wishlist as { id: number }).id } as ObjectLiteral,\r\n relations: ['product'],\r\n });\r\n const body = {\r\n wishlistId: (wishlist as { id: number }).id,\r\n items: items.map((it) => {\r\n const p = (it as ObjectLiteral).product as ObjectLiteral | undefined;\r\n return {\r\n id: (it as ObjectLiteral).id,\r\n productId: (it as ObjectLiteral).productId,\r\n product: p\r\n ? {\r\n id: p.id,\r\n name: p.name,\r\n slug: p.slug,\r\n price: p.price,\r\n sku: p.sku,\r\n image: primaryProductImageUrl(p.metadata),\r\n }\r\n : null,\r\n };\r\n }),\r\n };\r\n if (setCookie) return json(body, { headers: { 'Set-Cookie': setCookie } });\r\n return json(body);\r\n }\r\n\r\n if (path[0] === 'wishlist' && path[1] === 'items' && path.length === 2 && method === 'POST') {\r\n const { wishlist, setCookie, err } = await getOrCreateWishlist(req);\r\n if (err) return err;\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capWl = await assertCaptchaOk(getCms, b, req, json);\r\n if (capWl) return capWl;\r\n const productId = Number(b.productId);\r\n if (!Number.isFinite(productId)) return json({ error: 'productId required' }, { status: 400 });\r\n const wid = (wishlist as { id: number }).id;\r\n const ex = await wishlistItemRepo().findOne({ where: { wishlistId: wid, productId } as ObjectLiteral });\r\n if (!ex) await wishlistItemRepo().save(wishlistItemRepo().create({ wishlistId: wid, productId } as ObjectLiteral));\r\n if (setCookie) return json({ ok: true }, { headers: { 'Set-Cookie': setCookie } });\r\n return json({ ok: true });\r\n }\r\n\r\n if (path[0] === 'wishlist' && path[1] === 'items' && path.length === 3 && method === 'DELETE') {\r\n const { wishlist, setCookie, err } = await getOrCreateWishlist(req);\r\n if (err) return err;\r\n const productId = parseInt(path[2]!, 10);\r\n await wishlistItemRepo().delete({ wishlistId: (wishlist as { id: number }).id, productId } as ObjectLiteral);\r\n if (setCookie) return json({ ok: true }, { headers: { 'Set-Cookie': setCookie } });\r\n return json({ ok: true });\r\n }\r\n\r\n // --- checkout/order POST (create order only, for Razorpay; do not clear cart) ---\r\n if (path[0] === 'checkout' && path[1] === 'order' && path.length === 2 && method === 'POST') {\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capOrd = await assertCaptchaOk(getCms, b, req, json);\r\n if (capOrd) return capOrd;\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n let contactId: number;\r\n let cart: ObjectLiteral | null;\r\n if (Number.isFinite(uid)) {\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return json({ error: 'Contact required' }, { status: 400 });\r\n contactId = contact.id;\r\n cart = await cartRepo().findOne({\r\n where: { contactId } as ObjectLiteral,\r\n relations: [...CART_CHECKOUT_RELATIONS],\r\n });\r\n } else {\r\n const email = String(b.email ?? '').trim();\r\n const name = String(b.name ?? '').trim();\r\n if (!email || !name) return json({ error: 'name and email required for guest checkout' }, { status: 400 });\r\n let contact = await contactRepo().findOne({ where: { email, deleted: false } as ObjectLiteral });\r\n if (contact && (contact as { userId: number | null }).userId != null) {\r\n return json({ error: 'Please sign in to complete checkout' }, { status: 400 });\r\n }\r\n if (!contact) {\r\n contact = await contactRepo().save(\r\n contactRepo().create({\r\n name,\r\n email,\r\n phone: b.phone != null && b.phone !== '' ? String(b.phone) : null,\r\n userId: null,\r\n deleted: false,\r\n } as ObjectLiteral)\r\n );\r\n } else if (name)\r\n await contactRepo().update((contact as { id: number }).id, {\r\n name,\r\n phone: b.phone != null && b.phone !== '' ? String(b.phone) : (contact as { phone: string | null }).phone,\r\n });\r\n contactId = (contact as { id: number }).id;\r\n const guestForErp = await contactRepo().findOne({ where: { id: contactId } as ObjectLiteral });\r\n if (guestForErp) await syncContactToErp(guestForErp);\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n const guestToken = cookies[cookieName];\r\n if (!guestToken) return json({ error: 'Cart not found' }, { status: 400 });\r\n cart = await cartRepo().findOne({\r\n where: { guestToken } as ObjectLiteral,\r\n relations: [...CART_CHECKOUT_RELATIONS],\r\n });\r\n }\r\n if (!cart || !((cart.items as ObjectLiteral[]) || []).length) {\r\n return json({ error: 'Cart is empty' }, { status: 400 });\r\n }\r\n const prepOrd = await prepareCheckoutFromCart(b, cart, contactId);\r\n if (!prepOrd.ok) return json({ error: prepOrd.message }, { status: prepOrd.status });\r\n const cartId = (cart as { id: number }).id;\r\n const ord = await orderRepo().save(\r\n orderRepo().create({\r\n orderNumber: temporaryOrderNumberPlaceholder(),\r\n orderKind: 'sale',\r\n parentOrderId: null,\r\n contactId,\r\n billingAddressId: prepOrd.billingAddressId,\r\n shippingAddressId: prepOrd.shippingAddressId,\r\n status: 'pending',\r\n subtotal: prepOrd.subtotal,\r\n tax: prepOrd.orderTax,\r\n discount: 0,\r\n total: prepOrd.orderTotal,\r\n currency: (cart.currency as string) || 'INR',\r\n metadata: { cartId },\r\n } as ObjectLiteral)\r\n );\r\n const oid = (ord as { id: number }).id;\r\n await orderRepo().update(oid, {\r\n orderNumber: buildCanonicalOrderNumber('sale', oid, (ord as { createdAt?: Date }).createdAt ?? new Date()),\r\n } as ObjectLiteral);\r\n for (const line of prepOrd.lines) {\r\n await orderItemRepo().save(\r\n orderItemRepo().create({\r\n orderId: oid,\r\n productId: line.productId,\r\n quantity: line.quantity,\r\n unitPrice: line.unitPrice,\r\n tax: line.tax,\r\n total: line.total,\r\n hsn: line.hsn,\r\n uom: line.uom,\r\n productType: line.productType,\r\n taxRate: line.taxRate,\r\n taxCode: line.taxCode,\r\n } as ObjectLiteral)\r\n );\r\n }\r\n return json({\r\n orderId: oid,\r\n orderNumber: (ord as { orderNumber: string }).orderNumber,\r\n subtotal: prepOrd.subtotal,\r\n tax: prepOrd.orderTax,\r\n total: prepOrd.orderTotal,\r\n currency: (cart.currency as string) || 'INR',\r\n });\r\n }\r\n\r\n // --- checkout POST ---\r\n if (path[0] === 'checkout' && path.length === 1 && method === 'POST') {\r\n const b = (await req.json().catch(() => ({}))) as Record<string, unknown>;\r\n const capChk = await assertCaptchaOk(getCms, b, req, json);\r\n if (capChk) return capChk;\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n let contactId: number;\r\n let cart: ObjectLiteral | null;\r\n if (Number.isFinite(uid)) {\r\n const contact = await ensureContactForUser(uid);\r\n if (!contact) return json({ error: 'Contact required' }, { status: 400 });\r\n contactId = contact.id;\r\n cart = await cartRepo().findOne({\r\n where: { contactId } as ObjectLiteral,\r\n relations: [...CART_CHECKOUT_RELATIONS],\r\n });\r\n } else {\r\n const email = String(b.email ?? '').trim();\r\n const name = String(b.name ?? '').trim();\r\n if (!email || !name) return json({ error: 'name and email required for guest checkout' }, { status: 400 });\r\n let contact = await contactRepo().findOne({ where: { email, deleted: false } as ObjectLiteral });\r\n if (contact && (contact as { userId: number | null }).userId != null) {\r\n return json({ error: 'Please sign in to complete checkout' }, { status: 400 });\r\n }\r\n if (!contact) {\r\n contact = await contactRepo().save(\r\n contactRepo().create({\r\n name,\r\n email,\r\n phone: b.phone != null && b.phone !== '' ? String(b.phone) : null,\r\n userId: null,\r\n deleted: false,\r\n } as ObjectLiteral)\r\n );\r\n } else if (name)\r\n await contactRepo().update((contact as { id: number }).id, {\r\n name,\r\n phone: b.phone != null && b.phone !== '' ? String(b.phone) : (contact as { phone: string | null }).phone,\r\n });\r\n contactId = (contact as { id: number }).id;\r\n const guestForErp2 = await contactRepo().findOne({ where: { id: contactId } as ObjectLiteral });\r\n if (guestForErp2) await syncContactToErp(guestForErp2);\r\n const cookies = parseCookies(req.headers.get('cookie'));\r\n const guestToken = cookies[cookieName];\r\n if (!guestToken) return json({ error: 'Cart not found' }, { status: 400 });\r\n cart = await cartRepo().findOne({\r\n where: { guestToken } as ObjectLiteral,\r\n relations: [...CART_CHECKOUT_RELATIONS],\r\n });\r\n }\r\n if (!cart || !((cart.items as ObjectLiteral[]) || []).length) {\r\n return json({ error: 'Cart is empty' }, { status: 400 });\r\n }\r\n const prepChk = await prepareCheckoutFromCart(b, cart, contactId);\r\n if (!prepChk.ok) return json({ error: prepChk.message }, { status: prepChk.status });\r\n const ord = await orderRepo().save(\r\n orderRepo().create({\r\n orderNumber: temporaryOrderNumberPlaceholder(),\r\n orderKind: 'sale',\r\n parentOrderId: null,\r\n contactId,\r\n billingAddressId: prepChk.billingAddressId,\r\n shippingAddressId: prepChk.shippingAddressId,\r\n status: 'pending',\r\n subtotal: prepChk.subtotal,\r\n tax: prepChk.orderTax,\r\n discount: 0,\r\n total: prepChk.orderTotal,\r\n currency: (cart.currency as string) || 'INR',\r\n } as ObjectLiteral)\r\n );\r\n const oid = (ord as { id: number }).id;\r\n await orderRepo().update(oid, {\r\n orderNumber: buildCanonicalOrderNumber('sale', oid, (ord as { createdAt?: Date }).createdAt ?? new Date()),\r\n } as ObjectLiteral);\r\n for (const line of prepChk.lines) {\r\n await orderItemRepo().save(\r\n orderItemRepo().create({\r\n orderId: oid,\r\n productId: line.productId,\r\n quantity: line.quantity,\r\n unitPrice: line.unitPrice,\r\n tax: line.tax,\r\n total: line.total,\r\n hsn: line.hsn,\r\n uom: line.uom,\r\n productType: line.productType,\r\n taxRate: line.taxRate,\r\n taxCode: line.taxCode,\r\n } as ObjectLiteral)\r\n );\r\n }\r\n await cartItemRepo().delete({ cartId: (cart as { id: number }).id } as ObjectLiteral);\r\n await cartRepo().delete((cart as { id: number }).id);\r\n return json({\r\n orderId: oid,\r\n orderNumber: (ord as { orderNumber: string }).orderNumber,\r\n subtotal: prepChk.subtotal,\r\n tax: prepChk.orderTax,\r\n total: prepChk.orderTotal,\r\n });\r\n }\r\n\r\n // --- orders GET ---\r\n if (path[0] === 'orders' && path.length === 1 && method === 'GET') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (!contact) return json({ orders: [] });\r\n const orders = await orderRepo().find({\r\n where: { contactId: (contact as { id: number }).id, deleted: false, orderKind: 'sale' } as ObjectLiteral,\r\n order: { createdAt: 'DESC' },\r\n take: 50,\r\n });\r\n const orderIds = orders.map((o) => (o as ObjectLiteral).id as number);\r\n const previewByOrder: Record<number, string[]> = {};\r\n if (orderIds.length) {\r\n const oItems = await orderItemRepo().find({\r\n where: { orderId: In(orderIds) },\r\n relations: ['product'],\r\n order: { id: 'ASC' },\r\n });\r\n for (const oi of oItems) {\r\n const oid = (oi as ObjectLiteral).orderId as number;\r\n if (!previewByOrder[oid]) previewByOrder[oid] = [];\r\n if (previewByOrder[oid].length >= 4) continue;\r\n const url = primaryProductImageUrl(((oi as ObjectLiteral).product as ObjectLiteral)?.metadata);\r\n if (url && !previewByOrder[oid].includes(url)) previewByOrder[oid].push(url);\r\n }\r\n }\r\n return json({\r\n orders: orders.map((o) => {\r\n const ol = o as ObjectLiteral;\r\n return {\r\n id: ol.id,\r\n orderNumber: ol.orderNumber,\r\n status: ol.status,\r\n total: ol.total,\r\n currency: ol.currency,\r\n createdAt: ol.createdAt,\r\n previewImages: previewByOrder[ol.id as number] ?? [],\r\n };\r\n }),\r\n });\r\n }\r\n\r\n if (path[0] === 'orders' && path.length === 3 && path[2] === 'invoice' && method === 'GET') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n if (!getCms) return json({ error: 'Not found' }, { status: 404 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (!contact) return json({ error: 'Not found' }, { status: 404 });\r\n const orderId = parseInt(path[1]!, 10);\r\n if (!Number.isFinite(orderId)) return json({ error: 'Invalid id' }, { status: 400 });\r\n const cms = await getCms();\r\n return streamOrderInvoicePdf(cms, dataSource, entityMap, orderId, {\r\n ownerContactId: (contact as { id: number }).id,\r\n });\r\n }\r\n\r\n if (path[0] === 'orders' && path.length === 2 && method === 'GET') {\r\n const u = await getSessionUser();\r\n const uid = u?.id ? parseInt(String(u.id), 10) : NaN;\r\n if (!Number.isFinite(uid)) return json({ error: 'Unauthorized' }, { status: 401 });\r\n const contact = await contactRepo().findOne({ where: { userId: uid, deleted: false } as ObjectLiteral });\r\n if (!contact) return json({ error: 'Not found' }, { status: 404 });\r\n const orderId = parseInt(path[1]!, 10);\r\n let order = await orderRepo().findOne({\r\n where: { id: orderId, contactId: (contact as { id: number }).id, deleted: false } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n if (!order) return json({ error: 'Not found' }, { status: 404 });\r\n if (getCms) {\r\n const cms = await getCms();\r\n await tryRefreshOrderFromErpForStorefront(cms, dataSource, entityMap, order as ObjectLiteral);\r\n order = await orderRepo().findOne({\r\n where: { id: orderId, contactId: (contact as { id: number }).id, deleted: false } as ObjectLiteral,\r\n relations: ['items', 'items.product'],\r\n });\r\n }\r\n if (!order) return json({ error: 'Not found' }, { status: 404 });\r\n const o = order as ObjectLiteral;\r\n const lines = ((o.items as ObjectLiteral[]) || []).map((line) => {\r\n const p = line.product as ObjectLiteral | undefined;\r\n return {\r\n id: line.id,\r\n productId: line.productId,\r\n quantity: line.quantity,\r\n unitPrice: line.unitPrice,\r\n tax: line.tax,\r\n total: line.total,\r\n product: p\r\n ? {\r\n name: p.name,\r\n slug: p.slug,\r\n sku: p.sku,\r\n image: primaryProductImageUrl(p.metadata),\r\n }\r\n : null,\r\n };\r\n });\r\n const kind = (o.orderKind as string) || 'sale';\r\n let relatedOrders: ObjectLiteral[] = [];\r\n if (kind === 'sale') {\r\n relatedOrders = await orderRepo().find({\r\n where: { parentOrderId: orderId, deleted: false } as ObjectLiteral,\r\n order: { id: 'ASC' },\r\n });\r\n }\r\n const meta = o.metadata as Record<string, unknown> | null | undefined;\r\n const fulfillmentPreview =\r\n meta && typeof meta.fulfillment === 'object' && meta.fulfillment && 'status' in (meta.fulfillment as object)\r\n ? String((meta.fulfillment as { status?: string }).status ?? '')\r\n : '';\r\n return json({\r\n order: {\r\n id: o.id,\r\n orderNumber: o.orderNumber,\r\n orderKind: kind,\r\n parentOrderId: o.parentOrderId ?? null,\r\n status: o.status,\r\n subtotal: o.subtotal,\r\n tax: o.tax,\r\n discount: o.discount,\r\n total: o.total,\r\n currency: o.currency,\r\n createdAt: o.createdAt,\r\n metadata: o.metadata ?? null,\r\n items: lines,\r\n },\r\n relatedOrders: relatedOrders.map((r) => ({\r\n id: r.id,\r\n orderNumber: r.orderNumber,\r\n orderKind: r.orderKind ?? 'return',\r\n status: r.status,\r\n createdAt: r.createdAt,\r\n fulfillmentStatus:\r\n r.metadata &&\r\n typeof r.metadata === 'object' &&\r\n (r.metadata as { fulfillment?: { status?: string } }).fulfillment?.status,\r\n })),\r\n fulfillmentPreview: fulfillmentPreview || undefined,\r\n });\r\n }\r\n\r\n return json({ error: 'Not found' }, { status: 404 });\r\n } catch {\r\n return json({ error: 'Server error' }, { status: 500 });\r\n }\r\n },\r\n };\r\n}\r\n","/** Max lengths per RFC 5321 / 5322 (practical subset). */\r\nconst MAX_EMAIL = 254;\r\nconst MAX_LOCAL = 64;\r\n\r\n/**\r\n * Rejects obviously invalid signup addresses (format, length, missing TLD).\r\n * Used by storefront register so junk strings cannot create accounts.\r\n */\r\nexport function isValidSignupEmail(email: string): boolean {\r\n if (!email || email.length > MAX_EMAIL) return false;\r\n const at = email.indexOf('@');\r\n if (at <= 0 || at !== email.lastIndexOf('@')) return false;\r\n const local = email.slice(0, at);\r\n const domain = email.slice(at + 1);\r\n if (!local || local.length > MAX_LOCAL || !domain || domain.length > 253) return false;\r\n if (local.startsWith('.') || local.endsWith('.') || local.includes('..')) return false;\r\n if (domain.startsWith('.') || domain.endsWith('.') || domain.includes('..')) return false;\r\n if (!/^[a-z0-9._%+-]+$/i.test(local)) return false;\r\n if (!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/i.test(domain)) return false;\r\n const tld = domain.split('.').pop()!;\r\n return tld.length >= 2;\r\n}\r\n","export type OrderKind = 'sale' | 'return' | 'replacement';\r\n\r\nconst KIND_PREFIX: Record<OrderKind, string> = {\r\n sale: 'OSL',\r\n return: 'ORT',\r\n replacement: 'ORP',\r\n};\r\n\r\n/** YYMM in UTC (two-digit year + month). */\r\nexport function orderNumberYymmUtc(at: Date): string {\r\n const yy = String(at.getUTCFullYear()).slice(-2);\r\n const mm = String(at.getUTCMonth() + 1).padStart(2, '0');\r\n return yy + mm;\r\n}\r\n\r\n/** Stable 8-char mask from numeric id (not reversible as plain decimal). */\r\nexport function maskOrderIdSegment(id: number): string {\r\n let x = (id >>> 0) ^ 0xa5a5a5a5;\r\n x = Math.imul(x, 2654435761) >>> 0;\r\n return x.toString(36).toUpperCase().padStart(8, '0').slice(-8);\r\n}\r\n\r\nexport function buildCanonicalOrderNumber(kind: OrderKind, id: number, at: Date): string {\r\n return KIND_PREFIX[kind] + orderNumberYymmUtc(at) + maskOrderIdSegment(id);\r\n}\r\n\r\nexport function temporaryOrderNumberPlaceholder(): string {\r\n return `TMP${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`.toUpperCase();\r\n}\r\n","export interface OrderFulfillmentEvent {\r\n at?: string;\r\n label?: string;\r\n detail?: string;\r\n}\r\n\r\nexport interface OrderFulfillmentMetadata {\r\n status?: string;\r\n trackingId?: string;\r\n events?: OrderFulfillmentEvent[];\r\n}\r\n\r\nexport interface OrderInvoiceMetadata {\r\n invoiceNumber?: string;\r\n /** ERP invoice UUID for PDF fetch (no JWT). */\r\n invoiceId?: string;\r\n /** App path for invoice PDF (storefront or site-relative). */\r\n link?: string;\r\n}\r\n\r\nexport interface OrderStorefrontMetadataShape {\r\n fulfillment?: OrderFulfillmentMetadata;\r\n invoice?: OrderInvoiceMetadata;\r\n cartId?: number;\r\n platformRef?: string;\r\n [key: string]: unknown;\r\n}\r\n\r\nexport function mergeOrderMetadataPatch(\r\n existing: Record<string, unknown> | null | undefined,\r\n patch: { fulfillment?: OrderFulfillmentMetadata | null; invoice?: OrderInvoiceMetadata | null }\r\n): Record<string, unknown> {\r\n const base =\r\n existing && typeof existing === 'object' && !Array.isArray(existing) ? { ...existing } : {};\r\n if (patch.fulfillment !== undefined) {\r\n if (patch.fulfillment === null) delete base.fulfillment;\r\n else base.fulfillment = patch.fulfillment;\r\n }\r\n if (patch.invoice !== undefined) {\r\n if (patch.invoice === null) delete base.invoice;\r\n else base.invoice = patch.invoice;\r\n }\r\n return base;\r\n}\r\n","import type { Order } from '../../entities/order.entity';\r\n\r\n/** Map ERP sale-order status labels into CMS `Order.status`. Unknown → undefined (caller keeps existing). */\r\nexport function mapErpSaleStatusToOrderStatus(erpLabel: string | undefined): Order['status'] | undefined {\r\n if (!erpLabel || typeof erpLabel !== 'string') return undefined;\r\n const k = erpLabel.trim().toLowerCase().replace(/\\s+/g, '_');\r\n const map: Record<string, Order['status']> = {\r\n draft: 'pending',\r\n pending: 'pending',\r\n open: 'pending',\r\n new: 'pending',\r\n unconfirmed: 'pending',\r\n confirmed: 'confirmed',\r\n processing: 'processing',\r\n packed: 'processing',\r\n shipped: 'processing',\r\n in_transit: 'processing',\r\n out_for_delivery: 'processing',\r\n delivered: 'completed',\r\n completed: 'completed',\r\n closed: 'completed',\r\n fulfilled: 'completed',\r\n cancelled: 'cancelled',\r\n canceled: 'cancelled',\r\n void: 'cancelled',\r\n };\r\n return map[k];\r\n}\r\n","import type { ObjectLiteral, Repository } from 'typeorm';\r\nimport { buildCanonicalOrderNumber, temporaryOrderNumberPlaceholder, type OrderKind } from '../../lib/order-number';\r\nimport { mergeOrderMetadataPatch, type OrderFulfillmentMetadata, type OrderInvoiceMetadata } from '../../lib/order-storefront-metadata';\r\nimport { mapErpSaleStatusToOrderStatus } from './erp-order-status-map';\r\nimport {\r\n extractChildOrderRefsFromSalePayload,\r\n mapErpPayloadToFulfillment,\r\n mapErpPayloadToInvoiceNumber,\r\n unwrapErpReadData,\r\n} from './erp-response-map';\r\nimport type { ERPSubmissionService } from './erp-submission';\r\nimport { isErpIntegrationEnabled, type CmsAppLike, type ErpConfigDataSource } from './erp-config-enabled';\r\n\r\nfunction pickInvoiceId(data: Record<string, unknown>): string | undefined {\r\n const nested =\r\n data.invoice && typeof data.invoice === 'object' && !Array.isArray(data.invoice)\r\n ? (data.invoice as Record<string, unknown>)\r\n : null;\r\n const src = nested || data;\r\n for (const k of ['invoiceId', 'invoice_id', 'id']) {\r\n const v = src[k];\r\n if (typeof v === 'string' && v.trim()) return v.trim();\r\n }\r\n return undefined;\r\n}\r\n\r\nasync function ensureChildOrdersFromRefs(\r\n orderRepo: Repository<ObjectLiteral>,\r\n parent: ObjectLiteral,\r\n refs: ReturnType<typeof extractChildOrderRefsFromSalePayload>,\r\n contactId: number,\r\n currency: string\r\n): Promise<void> {\r\n for (const { ref, orderKind } of refs) {\r\n const existing = await orderRepo\r\n .createQueryBuilder('o')\r\n .where('o.parentOrderId = :pid', { pid: parent.id as number })\r\n .andWhere('o.deleted = :d', { d: false })\r\n .andWhere(\"o.metadata->>'platformRef' = :ref\", { ref })\r\n .getOne();\r\n if (existing) continue;\r\n const tmp = temporaryOrderNumberPlaceholder();\r\n const row = await orderRepo.save(\r\n orderRepo.create({\r\n orderNumber: tmp,\r\n orderKind,\r\n parentOrderId: parent.id as number,\r\n contactId,\r\n billingAddressId: null,\r\n shippingAddressId: null,\r\n status: 'pending',\r\n subtotal: 0,\r\n tax: 0,\r\n discount: 0,\r\n total: 0,\r\n currency,\r\n metadata: { platformRef: ref },\r\n deleted: false,\r\n } as ObjectLiteral)\r\n );\r\n const r = row as { id: number; createdAt: Date };\r\n await orderRepo.update(r.id, {\r\n orderNumber: buildCanonicalOrderNumber(orderKind as OrderKind, r.id, r.createdAt ?? new Date()),\r\n } as ObjectLiteral);\r\n }\r\n}\r\n\r\nfunction deepMergeFulfillment(\r\n a: OrderFulfillmentMetadata | undefined,\r\n b: OrderFulfillmentMetadata | undefined\r\n): OrderFulfillmentMetadata | undefined {\r\n if (!a) return b;\r\n if (!b) return a;\r\n return {\r\n ...a,\r\n ...b,\r\n events: b.events?.length ? b.events : a.events,\r\n };\r\n}\r\n\r\n/**\r\n * Calls ERP §7d reads for the given order row, updates `status` + `metadata` (fulfillment / invoice),\r\n * and upserts child return/replacement rows when the sale payload lists them.\r\n */\r\nexport async function refreshOrderFromErp(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>,\r\n submission: ERPSubmissionService,\r\n order: ObjectLiteral\r\n): Promise<void> {\r\n const orderRepo = dataSource.getRepository(entityMap.orders) as Repository<ObjectLiteral>;\r\n\r\n const kind = (order.orderKind as string) || 'sale';\r\n const meta =\r\n order.metadata && typeof order.metadata === 'object' && !Array.isArray(order.metadata)\r\n ? { ...(order.metadata as Record<string, unknown>) }\r\n : {};\r\n\r\n if (kind === 'sale') {\r\n const refId = String(order.orderNumber || '');\r\n let fulfillment: OrderFulfillmentMetadata | undefined;\r\n let invoiceNumber: string | undefined;\r\n let invoiceId: string | undefined;\r\n let newStatus: string | undefined;\r\n\r\n const r1 = await submission.postErpReadAction('get-order-status', { platformOrderId: refId });\r\n const d1 = r1.ok ? unwrapErpReadData(r1.json) : null;\r\n if (d1) {\r\n const mapped = mapErpSaleStatusToOrderStatus(\r\n typeof d1.status === 'string'\r\n ? d1.status\r\n : typeof d1.orderStatus === 'string'\r\n ? d1.orderStatus\r\n : typeof d1.state === 'string'\r\n ? d1.state\r\n : undefined\r\n );\r\n if (mapped) newStatus = mapped;\r\n fulfillment = mapErpPayloadToFulfillment(d1);\r\n const refs = extractChildOrderRefsFromSalePayload(d1);\r\n if (refs.length) {\r\n await ensureChildOrdersFromRefs(\r\n orderRepo,\r\n order,\r\n refs,\r\n order.contactId as number,\r\n String(order.currency || 'INR')\r\n );\r\n }\r\n }\r\n\r\n const r2 = await submission.postErpReadAction('get-fulfillment-status', { platformOrderId: refId });\r\n const d2 = r2.ok ? unwrapErpReadData(r2.json) : null;\r\n if (d2) {\r\n fulfillment = deepMergeFulfillment(fulfillment, mapErpPayloadToFulfillment(d2));\r\n }\r\n\r\n const r3 = await submission.postErpReadAction('get-invoice', { platformOrderId: refId });\r\n const d3 = r3.ok ? unwrapErpReadData(r3.json) : null;\r\n if (d3) {\r\n invoiceNumber = mapErpPayloadToInvoiceNumber(d3);\r\n invoiceId = pickInvoiceId(d3);\r\n }\r\n\r\n const oid = order.id as number;\r\n const prevInv =\r\n meta.invoice && typeof meta.invoice === 'object' && !Array.isArray(meta.invoice)\r\n ? { ...(meta.invoice as Record<string, unknown>) }\r\n : {};\r\n const nextInvoice: OrderInvoiceMetadata = {\r\n ...prevInv,\r\n link: `/api/storefront/orders/${oid}/invoice`,\r\n ...(invoiceNumber ? { invoiceNumber } : {}),\r\n ...(invoiceId ? { invoiceId } : {}),\r\n };\r\n\r\n const patch: {\r\n fulfillment?: OrderFulfillmentMetadata | null;\r\n invoice?: OrderInvoiceMetadata | null;\r\n } = { invoice: nextInvoice };\r\n if (fulfillment !== undefined) patch.fulfillment = fulfillment;\r\n\r\n const nextMeta = mergeOrderMetadataPatch(meta, patch);\r\n\r\n await orderRepo.update(oid, {\r\n ...(newStatus ? { status: newStatus } : {}),\r\n metadata: nextMeta,\r\n updatedAt: new Date(),\r\n } as ObjectLiteral);\r\n return;\r\n }\r\n\r\n if (kind === 'return' || kind === 'replacement') {\r\n const platformReturnId = String(order.orderNumber || '');\r\n const r = await submission.postErpReadAction('get-return-status', { platformReturnId });\r\n const d = r.ok ? unwrapErpReadData(r.json) : null;\r\n if (!d) return;\r\n const mapped = mapErpSaleStatusToOrderStatus(\r\n typeof d.status === 'string' ? d.status : typeof d.returnStatus === 'string' ? d.returnStatus : undefined\r\n );\r\n const fulfillment = mapErpPayloadToFulfillment(d);\r\n const patch: { fulfillment?: OrderFulfillmentMetadata | null } = {};\r\n if (fulfillment !== undefined) patch.fulfillment = fulfillment;\r\n const nextMeta = Object.keys(patch).length ? mergeOrderMetadataPatch(meta, patch) : meta;\r\n await orderRepo.update(order.id as number, {\r\n ...(mapped ? { status: mapped } : {}),\r\n metadata: nextMeta,\r\n updatedAt: new Date(),\r\n } as ObjectLiteral);\r\n }\r\n}\r\n\r\nexport async function tryRefreshOrderFromErpForStorefront(\r\n cms: CmsAppLike,\r\n dataSource: ErpConfigDataSource,\r\n entityMap: Record<string, unknown>,\r\n order: ObjectLiteral\r\n): Promise<void> {\r\n try {\r\n const on = await isErpIntegrationEnabled(cms, dataSource, entityMap);\r\n if (!on) return;\r\n const erp = cms.getPlugin('erp') as { submission: ERPSubmissionService } | undefined;\r\n if (!erp?.submission) return;\r\n await refreshOrderFromErp(cms, dataSource, entityMap, erp.submission, order);\r\n } catch {\r\n /* non-fatal */\r\n }\r\n}\r\n","const SMS_QUEUE_NAME = 'sms';\r\n\r\nexport interface CmsAppLike {\r\n getPlugin(name: string): unknown;\r\n}\r\n\r\nexport interface SmsJobPayload {\r\n to: string;\r\n /** Legacy / Twilio / sendhttp plain text. */\r\n body?: string;\r\n templateKey?: string;\r\n variables?: Record<string, string>;\r\n otpCode?: string;\r\n}\r\n\r\nexport function registerSmsQueueProcessor(cms: CmsAppLike): void {\r\n const queue = cms.getPlugin('queue') as\r\n | { add: (name: string, data: object) => Promise<void>; registerProcessor: (name: string, fn: (data: object) => Promise<void>) => void }\r\n | undefined;\r\n const sms = cms.getPlugin('sms') as\r\n | {\r\n send: (opts: {\r\n to: string;\r\n body?: string;\r\n templateKey?: string;\r\n variables?: Record<string, string>;\r\n otpCode?: string;\r\n }) => Promise<boolean>;\r\n }\r\n | undefined;\r\n if (!queue || !sms || typeof sms.send !== 'function') return;\r\n queue.registerProcessor(SMS_QUEUE_NAME, async (data: object) => {\r\n const payload = data as SmsJobPayload;\r\n if (!payload.to) return;\r\n if (payload.templateKey?.trim()) {\r\n await sms.send({\r\n to: payload.to,\r\n templateKey: payload.templateKey.trim(),\r\n variables: payload.variables,\r\n otpCode: payload.otpCode,\r\n });\r\n return;\r\n }\r\n if (!payload.body?.trim()) return;\r\n await sms.send({\r\n to: payload.to,\r\n body: payload.body,\r\n otpCode: payload.otpCode,\r\n variables: payload.variables,\r\n });\r\n });\r\n}\r\n\r\nexport async function queueSms(cms: CmsAppLike, payload: SmsJobPayload): Promise<void> {\r\n const queue = cms.getPlugin('queue') as { add: (name: string, data: object) => Promise<void> } | undefined;\r\n const sms = cms.getPlugin('sms') as\r\n | {\r\n send: (opts: {\r\n to: string;\r\n body?: string;\r\n templateKey?: string;\r\n variables?: Record<string, string>;\r\n otpCode?: string;\r\n }) => Promise<boolean>;\r\n }\r\n | undefined;\r\n if (queue) {\r\n await queue.add(SMS_QUEUE_NAME, payload);\r\n return;\r\n }\r\n if (sms && typeof sms.send === 'function') {\r\n if (payload.templateKey?.trim()) {\r\n await sms.send({\r\n to: payload.to,\r\n templateKey: payload.templateKey.trim(),\r\n variables: payload.variables,\r\n otpCode: payload.otpCode,\r\n });\r\n return;\r\n }\r\n if (payload.body?.trim()) {\r\n await sms.send({\r\n to: payload.to,\r\n body: payload.body,\r\n otpCode: payload.otpCode,\r\n variables: payload.variables,\r\n });\r\n }\r\n }\r\n}\r\n","import { createHmac, randomInt, timingSafeEqual } from 'crypto';\r\nimport type { DataSource } from 'typeorm';\r\nimport type { EntityTarget, ObjectLiteral } from 'typeorm';\r\nimport { IsNull, MoreThan } from 'typeorm';\r\n\r\nexport type OtpPurpose = 'login' | 'verify_email' | 'verify_phone';\r\nexport type OtpChannel = 'email' | 'sms';\r\n\r\nconst OTP_TTL_MS = 10 * 60 * 1000;\r\nconst MAX_SENDS_PER_HOUR = 5;\r\nconst MAX_VERIFY_ATTEMPTS = 8;\r\n\r\nfunction getPepper(explicit?: string): string {\r\n return (explicit || process.env.OTP_PEPPER || process.env.NEXTAUTH_SECRET || 'dev-otp-pepper').trim();\r\n}\r\n\r\nexport function hashOtpCode(code: string, purpose: string, identifier: string, pepper?: string): string {\r\n return createHmac('sha256', getPepper(pepper)).update(`${purpose}|${identifier}|${code}`).digest('hex');\r\n}\r\n\r\nexport function verifyOtpCodeHash(code: string, storedHash: string, purpose: string, identifier: string, pepper?: string): boolean {\r\n const h = hashOtpCode(code, purpose, identifier, pepper);\r\n try {\r\n return timingSafeEqual(Buffer.from(h, 'utf8'), Buffer.from(storedHash, 'utf8'));\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport function generateNumericOtp(length = 6): string {\r\n const max = 10 ** length;\r\n return randomInt(0, max).toString().padStart(length, '0');\r\n}\r\n\r\n/** Normalize to E.164-like +digits */\r\nexport function normalizePhoneE164(raw: string, defaultCountryCode?: string): string | null {\r\n const t = raw.trim();\r\n const digitsOnly = t.replace(/\\D/g, '');\r\n if (digitsOnly.length < 10) return null;\r\n if (t.startsWith('+')) return `+${digitsOnly}`;\r\n const cc = (defaultCountryCode || process.env.DEFAULT_PHONE_COUNTRY_CODE || '91').replace(/\\D/g, '');\r\n if (digitsOnly.length > 10) return `+${digitsOnly}`;\r\n return `+${cc}${digitsOnly}`;\r\n}\r\n\r\ntype EntityMap = Record<string, EntityTarget<ObjectLiteral>>;\r\n\r\nexport async function countRecentOtpSends(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n purpose: OtpPurpose,\r\n identifier: string,\r\n since: Date\r\n): Promise<number> {\r\n const repo = dataSource.getRepository(entityMap.otp_challenges);\r\n return repo.count({\r\n where: { purpose, identifier, createdAt: MoreThan(since) } as ObjectLiteral,\r\n });\r\n}\r\n\r\nexport async function createOtpChallenge(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n input: { purpose: OtpPurpose; channel: OtpChannel; identifier: string; code: string; pepper?: string }\r\n): Promise<{ ok: true } | { ok: false; error: string; status: number }> {\r\n const { purpose, channel, identifier, code, pepper } = input;\r\n const since = new Date(Date.now() - 60 * 60 * 1000);\r\n const recent = await countRecentOtpSends(dataSource, entityMap, purpose, identifier, since);\r\n if (recent >= MAX_SENDS_PER_HOUR) {\r\n return { ok: false, error: 'Too many codes sent. Try again later.', status: 429 };\r\n }\r\n\r\n const repo = dataSource.getRepository(entityMap.otp_challenges);\r\n await repo.delete({\r\n purpose,\r\n identifier,\r\n consumedAt: IsNull(),\r\n } as ObjectLiteral);\r\n\r\n const expiresAt = new Date(Date.now() + OTP_TTL_MS);\r\n const codeHash = hashOtpCode(code, purpose, identifier, pepper);\r\n await repo.save(\r\n repo.create({\r\n purpose,\r\n channel,\r\n identifier,\r\n codeHash,\r\n expiresAt,\r\n attempts: 0,\r\n consumedAt: null,\r\n } as ObjectLiteral)\r\n );\r\n return { ok: true };\r\n}\r\n\r\nexport async function verifyAndConsumeOtpChallenge(\r\n dataSource: DataSource,\r\n entityMap: EntityMap,\r\n input: { purpose: OtpPurpose; identifier: string; code: string; pepper?: string }\r\n): Promise<{ ok: true } | { ok: false; error: string; status: number }> {\r\n const { purpose, identifier, code, pepper } = input;\r\n const repo = dataSource.getRepository(entityMap.otp_challenges);\r\n const row = await repo.findOne({\r\n where: { purpose, identifier, consumedAt: IsNull() } as ObjectLiteral,\r\n order: { id: 'DESC' },\r\n });\r\n if (!row) {\r\n return { ok: false, error: 'Invalid or expired code', status: 400 };\r\n }\r\n const r = row as ObjectLiteral;\r\n if (new Date(r.expiresAt as Date) < new Date()) {\r\n await repo.delete((row as { id: number }).id);\r\n return { ok: false, error: 'Invalid or expired code', status: 400 };\r\n }\r\n const attempts = (r.attempts as number) || 0;\r\n if (attempts >= MAX_VERIFY_ATTEMPTS) {\r\n await repo.delete((row as { id: number }).id);\r\n return { ok: false, error: 'Too many attempts', status: 400 };\r\n }\r\n\r\n const valid = verifyOtpCodeHash(code, r.codeHash as string, purpose, identifier, pepper);\r\n if (!valid) {\r\n await repo.update((row as { id: number }).id, { attempts: attempts + 1 } as ObjectLiteral);\r\n return { ok: false, error: 'Invalid or expired code', status: 400 };\r\n }\r\n\r\n await repo.update((row as { id: number }).id, { consumedAt: new Date(), attempts: attempts + 1 } as ObjectLiteral);\r\n return { ok: true };\r\n}\r\n"],"mappings":"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","names":["repo","sortField","total","data","sortParam","typeFilter","updatePayload","updated","result","crypto","MoreThanOrEqual","ILike","IsNull","norm","IsNull","MoreThanOrEqual","isErpIntegrationEnabled","ILike","result","In","docRepo","dup","chunkRepo","text","parts","now","chunkRows","savedList","embedResult","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","PrimaryGeneratedColumn","Column","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","ManyToMany","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","PrimaryGeneratedColumn","Column","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","OneToMany","PrimaryGeneratedColumn","Column","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","ManyToMany","Entity","Entity","PrimaryGeneratedColumn","Column","OneToMany","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","PrimaryGeneratedColumn","Column","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","OneToMany","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","PrimaryGeneratedColumn","Column","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","OneToMany","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","OneToMany","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Entity","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Index","Unique","PrimaryGeneratedColumn","Column","ManyToOne","JoinColumn","Entity","Unique","Index","queueEmail","streamOrderInvoicePdf","isErpIntegrationEnabled","queueErpPaidOrderForOrderId","In","IsNull","pickInvoiceId","IsNull","MoreThan","roundMoney","IsNull","cart","serializeAddress","crypto","gItems","req","w","In"]}