@open-mercato/core 0.4.11-develop.1299.78ca9c88e2 → 0.4.11-develop.1347.c693e6dfee
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/modules/customers/api/companies/[id]/route.js +3 -2
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +59 -91
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/tasks/route.js +115 -0
- package/dist/modules/customers/api/interactions/tasks/route.js.map +7 -0
- package/dist/modules/customers/api/people/[id]/route.js +3 -2
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/todos/route.js +14 -134
- package/dist/modules/customers/api/todos/route.js.map +2 -2
- package/dist/modules/customers/backend/customer-tasks/page.js +10 -0
- package/dist/modules/customers/backend/customer-tasks/page.js.map +7 -0
- package/dist/modules/customers/backend/customer-tasks/page.meta.js +25 -0
- package/dist/modules/customers/backend/customer-tasks/page.meta.js.map +7 -0
- package/dist/modules/customers/commands/interactions.js +40 -4
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/components/CustomerTodosTable.js +77 -47
- package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
- package/dist/modules/customers/components/detail/TasksSection.js +4 -4
- package/dist/modules/customers/components/detail/TasksSection.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +2 -1
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
- package/dist/modules/customers/components/detail/utils.js +3 -0
- package/dist/modules/customers/components/detail/utils.js.map +2 -2
- package/dist/modules/customers/data/entities.js +2 -2
- package/dist/modules/customers/data/entities.js.map +2 -2
- package/dist/modules/customers/data/validators.js +2 -2
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/lib/interactionCompatibility.js +12 -2
- package/dist/modules/customers/lib/interactionCompatibility.js.map +2 -2
- package/dist/modules/customers/lib/todoCompatibility.js +167 -4
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/customers/migrations/Migration20260401172819.js +45 -0
- package/dist/modules/customers/migrations/Migration20260401172819.js.map +7 -0
- package/dist/modules/customers/search.js +3 -2
- package/dist/modules/customers/search.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js +10 -2
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js.map +2 -2
- package/package.json +3 -3
- package/src/modules/customers/api/companies/[id]/route.ts +6 -5
- package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +69 -126
- package/src/modules/customers/api/interactions/tasks/route.ts +122 -0
- package/src/modules/customers/api/people/[id]/route.ts +3 -2
- package/src/modules/customers/api/todos/route.ts +13 -181
- package/src/modules/customers/backend/customer-tasks/page.meta.ts +23 -0
- package/src/modules/customers/backend/customer-tasks/page.tsx +12 -0
- package/src/modules/customers/commands/interactions.ts +50 -2
- package/src/modules/customers/components/CustomerTodosTable.tsx +91 -66
- package/src/modules/customers/components/detail/TasksSection.tsx +8 -8
- package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +2 -1
- package/src/modules/customers/components/detail/types.ts +6 -0
- package/src/modules/customers/components/detail/utils.ts +3 -0
- package/src/modules/customers/data/entities.ts +2 -2
- package/src/modules/customers/data/validators.ts +2 -2
- package/src/modules/customers/lib/interactionCompatibility.ts +16 -0
- package/src/modules/customers/lib/todoCompatibility.ts +229 -10
- package/src/modules/customers/migrations/.snapshot-open-mercato.json +1 -1
- package/src/modules/customers/migrations/Migration20260401172819.ts +45 -0
- package/src/modules/customers/search.ts +3 -2
- package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +24 -23
|
@@ -14,16 +14,16 @@ import { todoLinkWithTodoCreateSchema } from "../../data/validators.js";
|
|
|
14
14
|
import { resolveCustomerInteractionFeatureFlags } from "../../lib/interactionFeatureFlags.js";
|
|
15
15
|
import { resolveCustomersRequestContext } from "../../lib/interactionRequestContext.js";
|
|
16
16
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} from "../../lib/interactionReadModel.js";
|
|
20
|
-
import {
|
|
21
|
-
CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,
|
|
22
|
-
CUSTOMER_INTERACTION_TASK_SOURCE
|
|
17
|
+
EXAMPLE_TODO_SOURCE,
|
|
18
|
+
CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE
|
|
23
19
|
} from "../../lib/interactionCompatibility.js";
|
|
24
20
|
import {
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
filterTodoRows,
|
|
22
|
+
listCanonicalTodoRows,
|
|
23
|
+
listLegacyTodoRows,
|
|
24
|
+
normalizeTodoSearch,
|
|
25
|
+
paginateTodoRows,
|
|
26
|
+
sortTodoRows,
|
|
27
27
|
resolveLegacyTodoDetails
|
|
28
28
|
} from "../../lib/todoCompatibility.js";
|
|
29
29
|
const querySchema = z.object({
|
|
@@ -88,52 +88,6 @@ async function legacyAdaptersDisabledResponse() {
|
|
|
88
88
|
{ status: 410 }
|
|
89
89
|
));
|
|
90
90
|
}
|
|
91
|
-
function normalizeSearch(value) {
|
|
92
|
-
if (typeof value !== "string") return null;
|
|
93
|
-
const trimmed = value.trim().toLowerCase();
|
|
94
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
95
|
-
}
|
|
96
|
-
function sortTodoRows(rows) {
|
|
97
|
-
return [...rows].sort((left, right) => {
|
|
98
|
-
const leftTime = new Date(left.createdAt).getTime();
|
|
99
|
-
const rightTime = new Date(right.createdAt).getTime();
|
|
100
|
-
if (leftTime === rightTime) {
|
|
101
|
-
return right.id.localeCompare(left.id);
|
|
102
|
-
}
|
|
103
|
-
return rightTime - leftTime;
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
function filterTodoRows(rows, search) {
|
|
107
|
-
if (!search) return rows;
|
|
108
|
-
return rows.filter((row) => {
|
|
109
|
-
const haystack = [
|
|
110
|
-
row.customer.displayName,
|
|
111
|
-
row.todoTitle,
|
|
112
|
-
row.todoDescription
|
|
113
|
-
].filter((value) => typeof value === "string" && value.trim().length > 0).join(" ").toLowerCase();
|
|
114
|
-
return haystack.includes(search);
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
function paginateTodoRows(rows, page, pageSize, exportAll) {
|
|
118
|
-
const total = rows.length;
|
|
119
|
-
if (exportAll) {
|
|
120
|
-
return {
|
|
121
|
-
items: rows,
|
|
122
|
-
total,
|
|
123
|
-
page: 1,
|
|
124
|
-
pageSize: total,
|
|
125
|
-
totalPages: 1
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
const start = (page - 1) * pageSize;
|
|
129
|
-
return {
|
|
130
|
-
items: rows.slice(start, start + pageSize),
|
|
131
|
-
total,
|
|
132
|
-
page,
|
|
133
|
-
pageSize,
|
|
134
|
-
totalPages: Math.max(1, Math.ceil(total / pageSize))
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
91
|
function normalizeTodoStatusInput(body) {
|
|
138
92
|
if (typeof body.isDone === "boolean") return body.isDone;
|
|
139
93
|
if (typeof body.is_done === "boolean") return body.is_done;
|
|
@@ -149,80 +103,6 @@ function collectTodoCustomValues(body) {
|
|
|
149
103
|
}
|
|
150
104
|
return Object.keys(direct).length > 0 ? direct : void 0;
|
|
151
105
|
}
|
|
152
|
-
async function listLegacyTodoRows(em, queryEngine, tenantId, organizationIds, entityId) {
|
|
153
|
-
const where = { tenantId };
|
|
154
|
-
if (organizationIds && organizationIds.length > 0) {
|
|
155
|
-
where.organizationId = { $in: organizationIds };
|
|
156
|
-
}
|
|
157
|
-
if (entityId) {
|
|
158
|
-
where.entity = entityId;
|
|
159
|
-
}
|
|
160
|
-
const links = await em.find(CustomerTodoLink, where, {
|
|
161
|
-
populate: ["entity"],
|
|
162
|
-
orderBy: { createdAt: "desc" }
|
|
163
|
-
});
|
|
164
|
-
const details = await resolveLegacyTodoDetails(
|
|
165
|
-
queryEngine,
|
|
166
|
-
links,
|
|
167
|
-
tenantId,
|
|
168
|
-
organizationIds ?? []
|
|
169
|
-
);
|
|
170
|
-
return links.map((link) => {
|
|
171
|
-
const source = typeof link.todoSource === "string" && link.todoSource.trim().length > 0 ? link.todoSource : "example:todo";
|
|
172
|
-
return mapLegacyTodoLinkToRow(
|
|
173
|
-
link,
|
|
174
|
-
details.get(`${source}:${link.todoId}`) ?? null
|
|
175
|
-
);
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
async function listCanonicalTodoRows(em, queryEngine, container, auth, selectedOrganizationId, organizationIds, query, options) {
|
|
179
|
-
const where = {
|
|
180
|
-
tenantId: auth.tenantId,
|
|
181
|
-
interactionType: "task"
|
|
182
|
-
};
|
|
183
|
-
if (!options?.includeDeleted) {
|
|
184
|
-
where.deletedAt = null;
|
|
185
|
-
}
|
|
186
|
-
if (organizationIds && organizationIds.length > 0) {
|
|
187
|
-
where.organizationId = { $in: organizationIds };
|
|
188
|
-
}
|
|
189
|
-
if (query.entityId) {
|
|
190
|
-
where.entity = query.entityId;
|
|
191
|
-
}
|
|
192
|
-
if (options?.source) {
|
|
193
|
-
where.source = Array.isArray(options.source) ? { $in: options.source } : options.source;
|
|
194
|
-
}
|
|
195
|
-
const interactions = await em.find(CustomerInteraction, where, {
|
|
196
|
-
orderBy: { createdAt: "desc" }
|
|
197
|
-
});
|
|
198
|
-
const activeInteractions = interactions.filter((interaction) => !interaction.deletedAt);
|
|
199
|
-
const hydrated = await hydrateCanonicalInteractions({
|
|
200
|
-
em,
|
|
201
|
-
container,
|
|
202
|
-
auth,
|
|
203
|
-
selectedOrganizationId,
|
|
204
|
-
interactions: activeInteractions
|
|
205
|
-
});
|
|
206
|
-
const customerIds = Array.from(
|
|
207
|
-
new Set(
|
|
208
|
-
hydrated.map((interaction) => interaction.entityId ?? null).filter((value) => !!value)
|
|
209
|
-
)
|
|
210
|
-
);
|
|
211
|
-
const customerSummaries = await loadCustomerSummaries(em, customerIds, auth.tenantId, selectedOrganizationId);
|
|
212
|
-
const items = hydrated.map(
|
|
213
|
-
(interaction) => mapInteractionRecordToTodoRow(
|
|
214
|
-
interaction,
|
|
215
|
-
interaction.entityId ? customerSummaries.get(interaction.entityId) ?? null : null,
|
|
216
|
-
{
|
|
217
|
-
todoSource: interaction.source === CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE ? CUSTOMER_INTERACTION_TASK_SOURCE : CUSTOMER_INTERACTION_TASK_SOURCE
|
|
218
|
-
}
|
|
219
|
-
)
|
|
220
|
-
);
|
|
221
|
-
return {
|
|
222
|
-
items,
|
|
223
|
-
bridgeIds: new Set(interactions.map((interaction) => interaction.id))
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
106
|
async function findLegacyTodoLink(em, target) {
|
|
227
107
|
if (target.linkId) {
|
|
228
108
|
const byLinkId = await em.findOne(CustomerTodoLink, { id: target.linkId }, { populate: ["entity"] });
|
|
@@ -242,7 +122,7 @@ async function ensureCanonicalTodoBridge(em, queryEngine, commandBus, commandCon
|
|
|
242
122
|
link.tenantId,
|
|
243
123
|
[link.organizationId]
|
|
244
124
|
);
|
|
245
|
-
const source = typeof link.todoSource === "string" && link.todoSource.trim().length > 0 ? link.todoSource :
|
|
125
|
+
const source = typeof link.todoSource === "string" && link.todoSource.trim().length > 0 ? link.todoSource : EXAMPLE_TODO_SOURCE;
|
|
246
126
|
const detail = detailMap.get(`${source}:${link.todoId}`) ?? null;
|
|
247
127
|
const entityId = typeof link.entity === "string" ? link.entity : link.entity.id;
|
|
248
128
|
await commandBus.execute("customers.interactions.create", {
|
|
@@ -290,26 +170,24 @@ async function GET(request) {
|
|
|
290
170
|
}
|
|
291
171
|
const queryEngine = container.resolve("queryEngine");
|
|
292
172
|
const exportAll = parseBooleanToken(query.all) === true;
|
|
293
|
-
const search =
|
|
173
|
+
const search = normalizeTodoSearch(query.search);
|
|
294
174
|
const mergedRows = flags.unified ? (await listCanonicalTodoRows(
|
|
295
175
|
em,
|
|
296
|
-
queryEngine,
|
|
297
176
|
container,
|
|
298
177
|
auth,
|
|
299
178
|
selectedOrganizationId,
|
|
300
179
|
organizationIds,
|
|
301
|
-
query
|
|
180
|
+
{ entityId: query.entityId }
|
|
302
181
|
)).items : await Promise.all([
|
|
303
182
|
listLegacyTodoRows(em, queryEngine, auth.tenantId, organizationIds, query.entityId),
|
|
304
183
|
listCanonicalTodoRows(
|
|
305
184
|
em,
|
|
306
|
-
queryEngine,
|
|
307
185
|
container,
|
|
308
186
|
auth,
|
|
309
187
|
selectedOrganizationId,
|
|
310
188
|
organizationIds,
|
|
311
|
-
query,
|
|
312
189
|
{
|
|
190
|
+
entityId: query.entityId,
|
|
313
191
|
includeDeleted: true,
|
|
314
192
|
source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE
|
|
315
193
|
}
|
|
@@ -586,6 +464,8 @@ const todoItemSchema = z.object({
|
|
|
586
464
|
organizationId: z.string(),
|
|
587
465
|
tenantId: z.string(),
|
|
588
466
|
createdAt: z.string(),
|
|
467
|
+
externalHref: z.string().nullable().optional(),
|
|
468
|
+
_integrations: z.record(z.string(), z.unknown()).optional(),
|
|
589
469
|
customer: z.object({
|
|
590
470
|
id: z.string().nullable(),
|
|
591
471
|
displayName: z.string().nullable(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/customers/api/todos/route.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @deprecated Use /api/customers/interactions instead. This route is maintained\n * as a compatibility bridge per SPEC-046b. Will be removed in a future release.\n */\nimport { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport type { QueryEngine } from '@open-mercato/shared/lib/query/types'\nimport { createCustomersCrudOpenApi, createPagedListResponseSchema, defaultOkResponseSchema } from '../openapi'\nimport { CustomerInteraction, CustomerTodoLink } from '../../data/entities'\nimport { todoLinkWithTodoCreateSchema } from '../../data/validators'\nimport { resolveCustomerInteractionFeatureFlags } from '../../lib/interactionFeatureFlags'\nimport { resolveCustomersRequestContext } from '../../lib/interactionRequestContext'\nimport {\n hydrateCanonicalInteractions,\n loadCustomerSummaries,\n} from '../../lib/interactionReadModel'\nimport {\n CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n CUSTOMER_INTERACTION_TASK_SOURCE,\n} from '../../lib/interactionCompatibility'\nimport {\n type CustomerTodoRow,\n mapInteractionRecordToTodoRow,\n mapLegacyTodoLinkToRow,\n resolveLegacyTodoDetails,\n} from '../../lib/todoCompatibility'\n\nconst querySchema = z.object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n search: z.string().optional(),\n all: z.string().optional(),\n entityId: z.string().uuid().optional(),\n})\n\nconst todoCreateBodySchema = todoLinkWithTodoCreateSchema.omit({\n tenantId: true,\n organizationId: true,\n}).passthrough()\n\nconst todoUpdateBodySchema = z\n .object({\n id: z.string().uuid(),\n linkId: z.string().uuid().optional(),\n title: z.string().trim().min(1).max(200).optional(),\n isDone: z.boolean().optional(),\n is_done: z.boolean().optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n customValues: z.record(z.string(), z.unknown()).optional(),\n })\n .passthrough()\n\nconst todoDeleteBodySchema = z.object({\n id: z.string().uuid(),\n todoId: z.string().uuid().optional(),\n})\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['customers.view'] },\n POST: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n}\n\nconst DEPRECATION_HEADERS = {\n Deprecation: 'true',\n Sunset: 'Tue, 30 Jun 2026 00:00:00 GMT',\n Link: '</api/customers/interactions>; rel=\"successor-version\"',\n}\n\ntype CanonicalTodoListResult = {\n items: CustomerTodoRow[]\n bridgeIds: Set<string>\n}\n\nfunction resolveGuardUserId(auth: {\n sub?: string | null\n userId?: string | null\n keyId?: string | null\n}): string {\n if (typeof auth.sub === 'string' && auth.sub.trim().length > 0) return auth.sub\n if (typeof auth.userId === 'string' && auth.userId.trim().length > 0) return auth.userId\n if (typeof auth.keyId === 'string' && auth.keyId.trim().length > 0) return auth.keyId\n return 'system'\n}\n\nfunction withAdapterHeaders(response: Response): Response {\n const headers = new Headers(response.headers)\n Object.entries(DEPRECATION_HEADERS).forEach(([key, value]) => headers.set(key, value))\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n })\n}\n\nasync function legacyAdaptersDisabledResponse(): Promise<Response> {\n const { translate } = await resolveTranslations()\n return withAdapterHeaders(NextResponse.json(\n {\n error: translate(\n 'customers.interactions.legacyAdapters.disabled',\n 'This legacy adapter has been disabled. Use /api/customers/interactions instead.',\n ),\n },\n { status: 410 },\n ))\n}\n\nfunction normalizeSearch(value: string | undefined): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim().toLowerCase()\n return trimmed.length > 0 ? trimmed : null\n}\n\nfunction sortTodoRows(rows: CustomerTodoRow[]): CustomerTodoRow[] {\n return [...rows].sort((left, right) => {\n const leftTime = new Date(left.createdAt).getTime()\n const rightTime = new Date(right.createdAt).getTime()\n if (leftTime === rightTime) {\n return right.id.localeCompare(left.id)\n }\n return rightTime - leftTime\n })\n}\n\nfunction filterTodoRows(rows: CustomerTodoRow[], search: string | null): CustomerTodoRow[] {\n if (!search) return rows\n return rows.filter((row) => {\n const haystack = [\n row.customer.displayName,\n row.todoTitle,\n row.todoDescription,\n ]\n .filter((value): value is string => typeof value === 'string' && value.trim().length > 0)\n .join(' ')\n .toLowerCase()\n return haystack.includes(search)\n })\n}\n\nfunction paginateTodoRows(\n rows: CustomerTodoRow[],\n page: number,\n pageSize: number,\n exportAll: boolean,\n): { items: CustomerTodoRow[]; total: number; page: number; pageSize: number; totalPages: number } {\n const total = rows.length\n if (exportAll) {\n return {\n items: rows,\n total,\n page: 1,\n pageSize: total,\n totalPages: 1,\n }\n }\n const start = (page - 1) * pageSize\n return {\n items: rows.slice(start, start + pageSize),\n total,\n page,\n pageSize,\n totalPages: Math.max(1, Math.ceil(total / pageSize)),\n }\n}\n\nfunction normalizeTodoStatusInput(body: z.infer<typeof todoUpdateBodySchema>): boolean | undefined {\n if (typeof body.isDone === 'boolean') return body.isDone\n if (typeof body.is_done === 'boolean') return body.is_done\n return undefined\n}\n\nfunction collectTodoCustomValues(\n body: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const direct =\n body.customValues && typeof body.customValues === 'object'\n ? { ...(body.customValues as Record<string, unknown>) }\n : {}\n if (body.todoCustom && typeof body.todoCustom === 'object') {\n Object.assign(direct, body.todoCustom as Record<string, unknown>)\n }\n if (body.customFields && typeof body.customFields === 'object') {\n Object.assign(direct, body.customFields as Record<string, unknown>)\n }\n return Object.keys(direct).length > 0 ? direct : undefined\n}\n\nasync function listLegacyTodoRows(\n em: EntityManager,\n queryEngine: QueryEngine,\n tenantId: string,\n organizationIds: string[] | null,\n entityId: string | undefined,\n): Promise<CustomerTodoRow[]> {\n const where: Record<string, unknown> = { tenantId }\n if (organizationIds && organizationIds.length > 0) {\n where.organizationId = { $in: organizationIds }\n }\n if (entityId) {\n where.entity = entityId\n }\n\n const links = await em.find(CustomerTodoLink, where, {\n populate: ['entity'],\n orderBy: { createdAt: 'desc' },\n })\n const details = await resolveLegacyTodoDetails(\n queryEngine,\n links,\n tenantId,\n organizationIds ?? [],\n )\n\n return links.map((link) => {\n const source =\n typeof link.todoSource === 'string' && link.todoSource.trim().length > 0\n ? link.todoSource\n : 'example:todo'\n return mapLegacyTodoLinkToRow(\n link,\n details.get(`${source}:${link.todoId}`) ?? null,\n )\n })\n}\n\nasync function listCanonicalTodoRows(\n em: EntityManager,\n queryEngine: QueryEngine,\n container: { resolve: (name: string) => unknown },\n auth: { tenantId: string | null; orgId: string | null; sub?: string | null; userId?: string | null; keyId?: string | null },\n selectedOrganizationId: string | null,\n organizationIds: string[] | null,\n query: z.infer<typeof querySchema>,\n options?: { includeDeleted?: boolean; source?: string | string[] | null },\n): Promise<CanonicalTodoListResult> {\n const where: Record<string, unknown> = {\n tenantId: auth.tenantId,\n interactionType: 'task',\n }\n if (!options?.includeDeleted) {\n where.deletedAt = null\n }\n if (organizationIds && organizationIds.length > 0) {\n where.organizationId = { $in: organizationIds }\n }\n if (query.entityId) {\n where.entity = query.entityId\n }\n if (options?.source) {\n where.source = Array.isArray(options.source) ? { $in: options.source } : options.source\n }\n\n const interactions = await em.find(CustomerInteraction, where, {\n orderBy: { createdAt: 'desc' },\n })\n const activeInteractions = interactions.filter((interaction) => !interaction.deletedAt)\n const hydrated = await hydrateCanonicalInteractions({\n em,\n container,\n auth,\n selectedOrganizationId,\n interactions: activeInteractions,\n })\n const customerIds = Array.from(\n new Set(\n hydrated\n .map((interaction) => interaction.entityId ?? null)\n .filter((value): value is string => !!value),\n ),\n )\n const customerSummaries = await loadCustomerSummaries(em, customerIds, auth.tenantId, selectedOrganizationId)\n\n const items = hydrated.map((interaction) =>\n mapInteractionRecordToTodoRow(\n interaction,\n interaction.entityId ? customerSummaries.get(interaction.entityId) ?? null : null,\n {\n todoSource:\n interaction.source === CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE\n ? CUSTOMER_INTERACTION_TASK_SOURCE\n : CUSTOMER_INTERACTION_TASK_SOURCE,\n },\n ),\n )\n\n return {\n items,\n bridgeIds: new Set(interactions.map((interaction) => interaction.id)),\n }\n}\n\nasync function findLegacyTodoLink(\n em: EntityManager,\n target: { linkId?: string; todoId?: string },\n): Promise<CustomerTodoLink | null> {\n if (target.linkId) {\n const byLinkId = await em.findOne(CustomerTodoLink, { id: target.linkId }, { populate: ['entity'] })\n if (byLinkId) return byLinkId\n }\n if (target.todoId) {\n return await em.findOne(CustomerTodoLink, { todoId: target.todoId }, { populate: ['entity'] })\n }\n return null\n}\n\nasync function ensureCanonicalTodoBridge(\n em: EntityManager,\n queryEngine: QueryEngine,\n commandBus: CommandBus,\n commandContext: Parameters<CommandBus['execute']>[1]['ctx'],\n link: CustomerTodoLink,\n): Promise<string> {\n const existing = await em.findOne(CustomerInteraction, { id: link.todoId })\n if (existing) return existing.id\n\n const detailMap = await resolveLegacyTodoDetails(\n queryEngine,\n [link],\n link.tenantId,\n [link.organizationId],\n )\n const source =\n typeof link.todoSource === 'string' && link.todoSource.trim().length > 0\n ? link.todoSource\n : 'example:todo'\n const detail = detailMap.get(`${source}:${link.todoId}`) ?? null\n const entityId = typeof link.entity === 'string' ? link.entity : link.entity.id\n\n await commandBus.execute('customers.interactions.create', {\n input: {\n id: link.todoId,\n entityId,\n interactionType: 'task',\n title: detail?.title ?? null,\n body: detail?.description ?? null,\n status: detail?.isDone ? 'done' : 'planned',\n scheduledAt: detail?.dueAt ?? null,\n priority: detail?.priority ?? null,\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n ...(detail?.customValues ? { customValues: detail.customValues } : {}),\n },\n ctx: commandContext,\n })\n\n return link.todoId\n}\n\nasync function resolveCanonicalTodoTargetId(\n em: EntityManager,\n queryEngine: QueryEngine,\n commandBus: CommandBus,\n commandContext: Parameters<CommandBus['execute']>[1]['ctx'],\n target: { todoId?: string; linkId?: string },\n): Promise<string> {\n if (target.todoId) {\n const interaction = await em.findOne(CustomerInteraction, { id: target.todoId })\n if (interaction) return interaction.id\n }\n\n const legacyLink = await findLegacyTodoLink(em, target)\n if (!legacyLink) {\n if (!target.todoId) throw new CrudHttpError(404, { error: 'Todo not found' })\n return target.todoId\n }\n\n return ensureCanonicalTodoBridge(\n em,\n queryEngine,\n commandBus,\n commandContext,\n legacyLink,\n )\n}\n\nexport async function GET(request: Request): Promise<Response> {\n try {\n const { auth, em, organizationIds, container, selectedOrganizationId } =\n await resolveCustomersRequestContext(request)\n const query = querySchema.parse(Object.fromEntries(new URL(request.url).searchParams))\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const exportAll = parseBooleanToken(query.all) === true\n const search = normalizeSearch(query.search)\n\n const mergedRows = flags.unified\n ? (await listCanonicalTodoRows(\n em,\n queryEngine,\n container,\n auth,\n selectedOrganizationId,\n organizationIds,\n query,\n )).items\n : await Promise.all([\n listLegacyTodoRows(em, queryEngine, auth.tenantId, organizationIds, query.entityId),\n listCanonicalTodoRows(\n em,\n queryEngine,\n container,\n auth,\n selectedOrganizationId,\n organizationIds,\n query,\n {\n includeDeleted: true,\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n },\n ),\n ]).then(([legacyRows, canonicalRows]) => [\n ...legacyRows.filter((row) => !canonicalRows.bridgeIds.has(row.todoId)),\n ...canonicalRows.items,\n ])\n\n const filteredRows = filterTodoRows(sortTodoRows(mergedRows), search)\n const paged = paginateTodoRows(filteredRows, query.page, query.pageSize, exportAll)\n\n return withAdapterHeaders(\n NextResponse.json({\n items: paged.items,\n total: paged.total,\n page: paged.page,\n pageSize: paged.pageSize,\n totalPages: paged.totalPages,\n }),\n )\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n console.error('customers.todos.get failed', err)\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function POST(request: Request): Promise<Response> {\n try {\n const { commandContext, container, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const body = todoCreateBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.entityId,\n operation: 'create',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const customValues = collectTodoCustomValues(body as Record<string, unknown>)\n\n const { result } = await commandBus.execute('customers.interactions.create', {\n input: {\n entityId: body.entityId,\n interactionType: 'task',\n title: body.title,\n status: body.is_done === true || body.isDone === true ? 'done' : 'planned',\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n ...(customValues ? {\n customValues,\n priority: typeof customValues.priority === 'number' ? customValues.priority : null,\n body: typeof customValues.description === 'string' ? customValues.description : null,\n scheduledAt:\n typeof customValues.due_at === 'string'\n ? customValues.due_at\n : typeof customValues.dueAt === 'string'\n ? customValues.dueAt\n : null,\n } : {}),\n },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.entityId,\n operation: 'create',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n const interactionId =\n result &&\n typeof result === 'object' &&\n 'interactionId' in result &&\n typeof result.interactionId === 'string'\n ? result.interactionId\n : result &&\n typeof result === 'object' &&\n 'id' in result &&\n typeof result.id === 'string'\n ? result.id\n : null\n return withAdapterHeaders(\n NextResponse.json(\n {\n linkId: interactionId,\n todoId: interactionId,\n },\n { status: 201 },\n ),\n )\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n console.error('customers.todos.post failed', err)\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function PUT(request: Request): Promise<Response> {\n try {\n const { commandContext, container, em, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const body = todoUpdateBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.linkId ?? body.id,\n operation: 'update',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const interactionId = flags.unified\n ? body.id\n : await resolveCanonicalTodoTargetId(\n em,\n queryEngine,\n commandBus,\n commandContext,\n {\n todoId: body.id,\n linkId: body.linkId,\n },\n )\n const customValues = collectTodoCustomValues(body as Record<string, unknown>)\n const nextDone = normalizeTodoStatusInput(body)\n\n await commandBus.execute('customers.interactions.update', {\n input: {\n id: interactionId,\n ...(body.title !== undefined ? { title: body.title } : {}),\n ...(nextDone !== undefined ? { status: nextDone ? 'done' : 'planned' } : {}),\n ...(customValues ? {\n customValues,\n priority: typeof customValues.priority === 'number' ? customValues.priority : null,\n body: typeof customValues.description === 'string' ? customValues.description : null,\n scheduledAt:\n typeof customValues.due_at === 'string'\n ? customValues.due_at\n : typeof customValues.dueAt === 'string'\n ? customValues.dueAt\n : null,\n } : {}),\n },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.linkId ?? body.id,\n operation: 'update',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return withAdapterHeaders(NextResponse.json({ ok: true }))\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n console.error('customers.todos.put failed', err)\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function DELETE(request: Request): Promise<Response> {\n try {\n const { commandContext, container, em, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const body = todoDeleteBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.id,\n operation: 'delete',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const interactionId = flags.unified\n ? body.todoId ?? body.id\n : await resolveCanonicalTodoTargetId(\n em,\n queryEngine,\n commandBus,\n commandContext,\n {\n linkId: body.id,\n todoId: body.todoId ?? body.id,\n },\n )\n\n await commandBus.execute('customers.interactions.delete', {\n input: { id: interactionId },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.id,\n operation: 'delete',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return withAdapterHeaders(NextResponse.json({ ok: true }))\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n console.error('customers.todos.delete failed', err)\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nconst todoItemSchema = z.object({\n id: z.string(),\n todoId: z.string(),\n todoSource: z.string(),\n todoTitle: z.string().nullable(),\n todoIsDone: z.boolean().nullable(),\n todoPriority: z.number().nullable().optional(),\n todoSeverity: z.string().nullable().optional(),\n todoDescription: z.string().nullable().optional(),\n todoDueAt: z.string().nullable().optional(),\n todoCustomValues: z.record(z.string(), z.unknown()).nullable().optional(),\n todoOrganizationId: z.string().nullable(),\n organizationId: z.string(),\n tenantId: z.string(),\n createdAt: z.string(),\n customer: z.object({\n id: z.string().nullable(),\n displayName: z.string().nullable(),\n kind: z.string().nullable(),\n }),\n})\n\nconst todoCreateResponseSchema = z.object({\n linkId: z.string().uuid().nullable(),\n todoId: z.string().uuid().nullable(),\n})\n\nexport const openApi: OpenApiRouteDoc = createCustomersCrudOpenApi({\n resourceName: 'CustomerTodo',\n querySchema,\n listResponseSchema: createPagedListResponseSchema(todoItemSchema),\n create: {\n schema: todoCreateBodySchema,\n responseSchema: todoCreateResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Creates a customer task. Use POST /api/customers/interactions instead.',\n },\n update: {\n schema: todoUpdateBodySchema,\n responseSchema: defaultOkResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Updates a customer task. Use PUT /api/customers/interactions instead.',\n },\n del: {\n schema: todoDeleteBodySchema,\n responseSchema: defaultOkResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Deletes a customer task. Use DELETE /api/customers/interactions instead.',\n },\n})\n"],
|
|
5
|
-
"mappings": "AAIA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAIlB,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAE7B,SAAS,4BAA4B,+BAA+B,+BAA+B;AACnG,SAAS,qBAAqB,wBAAwB;AACtD,SAAS,oCAAoC;AAC7C,SAAS,8CAA8C;AACvD,SAAS,sCAAsC;AAC/C;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,cAAc,EAAE,OAAO;AAAA,EAC3B,MAAM,EAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;AAAA,EACxC,UAAU,EAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACtD,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,KAAK,EAAE,OAAO,EAAE,SAAS;AAAA,EACzB,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AACvC,CAAC;AAED,MAAM,uBAAuB,6BAA6B,KAAK;AAAA,EAC7D,UAAU;AAAA,EACV,gBAAgB;AAClB,CAAC,EAAE,YAAY;AAEf,MAAM,uBAAuB,EAC1B,OAAO;AAAA,EACN,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAClD,QAAQ,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACzD,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAC3D,CAAC,EACA,YAAY;AAEf,MAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AACrC,CAAC;AAEM,MAAM,WAAW;AAAA,EACtB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,gBAAgB,EAAE;AAAA,EAC9D,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,+BAA+B,EAAE;AAAA,EAC9E,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,+BAA+B,EAAE;AAAA,EAC7E,QAAQ,EAAE,aAAa,MAAM,iBAAiB,CAAC,+BAA+B,EAAE;AAClF;AAEA,MAAM,sBAAsB;AAAA,EAC1B,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,MAAM;AACR;AAOA,SAAS,mBAAmB,MAIjB;AACT,MAAI,OAAO,KAAK,QAAQ,YAAY,KAAK,IAAI,KAAK,EAAE,SAAS,EAAG,QAAO,KAAK;AAC5E,MAAI,OAAO,KAAK,WAAW,YAAY,KAAK,OAAO,KAAK,EAAE,SAAS,EAAG,QAAO,KAAK;AAClF,MAAI,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,KAAK,EAAE,SAAS,EAAG,QAAO,KAAK;AAChF,SAAO;AACT;AAEA,SAAS,mBAAmB,UAA8B;AACxD,QAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,SAAO,QAAQ,mBAAmB,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM,QAAQ,IAAI,KAAK,KAAK,CAAC;AACrF,SAAO,IAAI,SAAS,SAAS,MAAM;AAAA,IACjC,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB;AAAA,EACF,CAAC;AACH;AAEA,eAAe,iCAAoD;AACjE,QAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,SAAO,mBAAmB,aAAa;AAAA,IACrC;AAAA,MACE,OAAO;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,QAAQ,IAAI;AAAA,EAChB,CAAC;AACH;AAEA,SAAS,gBAAgB,OAA0C;AACjE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK,EAAE,YAAY;AACzC,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAEA,SAAS,aAAa,MAA4C;AAChE,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,UAAU;AACrC,UAAM,WAAW,IAAI,KAAK,KAAK,SAAS,EAAE,QAAQ;AAClD,UAAM,YAAY,IAAI,KAAK,MAAM,SAAS,EAAE,QAAQ;AACpD,QAAI,aAAa,WAAW;AAC1B,aAAO,MAAM,GAAG,cAAc,KAAK,EAAE;AAAA,IACvC;AACA,WAAO,YAAY;AAAA,EACrB,CAAC;AACH;AAEA,SAAS,eAAe,MAAyB,QAA0C;AACzF,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,KAAK,OAAO,CAAC,QAAQ;AAC1B,UAAM,WAAW;AAAA,MACf,IAAI,SAAS;AAAA,MACb,IAAI;AAAA,MACJ,IAAI;AAAA,IACN,EACG,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,CAAC,EACvF,KAAK,GAAG,EACR,YAAY;AACf,WAAO,SAAS,SAAS,MAAM;AAAA,EACjC,CAAC;AACH;AAEA,SAAS,iBACP,MACA,MACA,UACA,WACiG;AACjG,QAAM,QAAQ,KAAK;AACnB,MAAI,WAAW;AACb,WAAO;AAAA,MACL,OAAO;AAAA,MACP;AAAA,MACA,MAAM;AAAA,MACN,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,EACF;AACA,QAAM,SAAS,OAAO,KAAK;AAC3B,SAAO;AAAA,IACL,OAAO,KAAK,MAAM,OAAO,QAAQ,QAAQ;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,QAAQ,CAAC;AAAA,EACrD;AACF;AAEA,SAAS,yBAAyB,MAAiE;AACjG,MAAI,OAAO,KAAK,WAAW,UAAW,QAAO,KAAK;AAClD,MAAI,OAAO,KAAK,YAAY,UAAW,QAAO,KAAK;AACnD,SAAO;AACT;AAEA,SAAS,wBACP,MACqC;AACrC,QAAM,SACJ,KAAK,gBAAgB,OAAO,KAAK,iBAAiB,WAC9C,EAAE,GAAI,KAAK,aAAyC,IACpD,CAAC;AACP,MAAI,KAAK,cAAc,OAAO,KAAK,eAAe,UAAU;AAC1D,WAAO,OAAO,QAAQ,KAAK,UAAqC;AAAA,EAClE;AACA,MAAI,KAAK,gBAAgB,OAAO,KAAK,iBAAiB,UAAU;AAC9D,WAAO,OAAO,QAAQ,KAAK,YAAuC;AAAA,EACpE;AACA,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,SAAS;AACnD;AAEA,eAAe,mBACb,IACA,aACA,UACA,iBACA,UAC4B;AAC5B,QAAM,QAAiC,EAAE,SAAS;AAClD,MAAI,mBAAmB,gBAAgB,SAAS,GAAG;AACjD,UAAM,iBAAiB,EAAE,KAAK,gBAAgB;AAAA,EAChD;AACA,MAAI,UAAU;AACZ,UAAM,SAAS;AAAA,EACjB;AAEA,QAAM,QAAQ,MAAM,GAAG,KAAK,kBAAkB,OAAO;AAAA,IACnD,UAAU,CAAC,QAAQ;AAAA,IACnB,SAAS,EAAE,WAAW,OAAO;AAAA,EAC/B,CAAC;AACD,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,CAAC;AAAA,EACtB;AAEA,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,SACJ,OAAO,KAAK,eAAe,YAAY,KAAK,WAAW,KAAK,EAAE,SAAS,IACnE,KAAK,aACL;AACN,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,IAAI,GAAG,MAAM,IAAI,KAAK,MAAM,EAAE,KAAK;AAAA,IAC7C;AAAA,EACF,CAAC;AACH;AAEA,eAAe,sBACb,IACA,aACA,WACA,MACA,wBACA,iBACA,OACA,SACkC;AAClC,QAAM,QAAiC;AAAA,IACrC,UAAU,KAAK;AAAA,IACf,iBAAiB;AAAA,EACnB;AACA,MAAI,CAAC,SAAS,gBAAgB;AAC5B,UAAM,YAAY;AAAA,EACpB;AACA,MAAI,mBAAmB,gBAAgB,SAAS,GAAG;AACjD,UAAM,iBAAiB,EAAE,KAAK,gBAAgB;AAAA,EAChD;AACA,MAAI,MAAM,UAAU;AAClB,UAAM,SAAS,MAAM;AAAA,EACvB;AACA,MAAI,SAAS,QAAQ;AACnB,UAAM,SAAS,MAAM,QAAQ,QAAQ,MAAM,IAAI,EAAE,KAAK,QAAQ,OAAO,IAAI,QAAQ;AAAA,EACnF;AAEA,QAAM,eAAe,MAAM,GAAG,KAAK,qBAAqB,OAAO;AAAA,IAC7D,SAAS,EAAE,WAAW,OAAO;AAAA,EAC/B,CAAC;AACD,QAAM,qBAAqB,aAAa,OAAO,CAAC,gBAAgB,CAAC,YAAY,SAAS;AACtF,QAAM,WAAW,MAAM,6BAA6B;AAAA,IAClD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,EAChB,CAAC;AACD,QAAM,cAAc,MAAM;AAAA,IACxB,IAAI;AAAA,MACF,SACG,IAAI,CAAC,gBAAgB,YAAY,YAAY,IAAI,EACjD,OAAO,CAAC,UAA2B,CAAC,CAAC,KAAK;AAAA,IAC/C;AAAA,EACF;AACA,QAAM,oBAAoB,MAAM,sBAAsB,IAAI,aAAa,KAAK,UAAU,sBAAsB;AAE5G,QAAM,QAAQ,SAAS;AAAA,IAAI,CAAC,gBAC1B;AAAA,MACE;AAAA,MACA,YAAY,WAAW,kBAAkB,IAAI,YAAY,QAAQ,KAAK,OAAO;AAAA,MAC7E;AAAA,QACE,YACE,YAAY,WAAW,2CACnB,mCACA;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,WAAW,IAAI,IAAI,aAAa,IAAI,CAAC,gBAAgB,YAAY,EAAE,CAAC;AAAA,EACtE;AACF;AAEA,eAAe,mBACb,IACA,QACkC;AAClC,MAAI,OAAO,QAAQ;AACjB,UAAM,WAAW,MAAM,GAAG,QAAQ,kBAAkB,EAAE,IAAI,OAAO,OAAO,GAAG,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;AACnG,QAAI,SAAU,QAAO;AAAA,EACvB;AACA,MAAI,OAAO,QAAQ;AACjB,WAAO,MAAM,GAAG,QAAQ,kBAAkB,EAAE,QAAQ,OAAO,OAAO,GAAG,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;AAAA,EAC/F;AACA,SAAO;AACT;AAEA,eAAe,0BACb,IACA,aACA,YACA,gBACA,MACiB;AACjB,QAAM,WAAW,MAAM,GAAG,QAAQ,qBAAqB,EAAE,IAAI,KAAK,OAAO,CAAC;AAC1E,MAAI,SAAU,QAAO,SAAS;AAE9B,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,IACA,CAAC,IAAI;AAAA,IACL,KAAK;AAAA,IACL,CAAC,KAAK,cAAc;AAAA,EACtB;AACA,QAAM,SACJ,OAAO,KAAK,eAAe,YAAY,KAAK,WAAW,KAAK,EAAE,SAAS,IACnE,KAAK,aACL;AACN,QAAM,SAAS,UAAU,IAAI,GAAG,MAAM,IAAI,KAAK,MAAM,EAAE,KAAK;AAC5D,QAAM,WAAW,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS,KAAK,OAAO;AAE7E,QAAM,WAAW,QAAQ,iCAAiC;AAAA,IACxD,OAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT;AAAA,MACA,iBAAiB;AAAA,MACjB,OAAO,QAAQ,SAAS;AAAA,MACxB,MAAM,QAAQ,eAAe;AAAA,MAC7B,QAAQ,QAAQ,SAAS,SAAS;AAAA,MAClC,aAAa,QAAQ,SAAS;AAAA,MAC9B,UAAU,QAAQ,YAAY;AAAA,MAC9B,QAAQ;AAAA,MACR,GAAI,QAAQ,eAAe,EAAE,cAAc,OAAO,aAAa,IAAI,CAAC;AAAA,IACtE;AAAA,IACA,KAAK;AAAA,EACP,CAAC;AAED,SAAO,KAAK;AACd;AAEA,eAAe,6BACb,IACA,aACA,YACA,gBACA,QACiB;AACjB,MAAI,OAAO,QAAQ;AACjB,UAAM,cAAc,MAAM,GAAG,QAAQ,qBAAqB,EAAE,IAAI,OAAO,OAAO,CAAC;AAC/E,QAAI,YAAa,QAAO,YAAY;AAAA,EACtC;AAEA,QAAM,aAAa,MAAM,mBAAmB,IAAI,MAAM;AACtD,MAAI,CAAC,YAAY;AACf,QAAI,CAAC,OAAO,OAAQ,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,iBAAiB,CAAC;AAC5E,WAAO,OAAO;AAAA,EAChB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,IAAI,SAAqC;AAC7D,MAAI;AACF,UAAM,EAAE,MAAM,IAAI,iBAAiB,WAAW,uBAAuB,IACnE,MAAM,+BAA+B,OAAO;AAC9C,UAAM,QAAQ,YAAY,MAAM,OAAO,YAAY,IAAI,IAAI,QAAQ,GAAG,EAAE,YAAY,CAAC;AACrF,UAAM,QAAQ,MAAM,uCAAuC,WAAW,KAAK,QAAQ;AACnF,QAAI,CAAC,MAAM,gBAAgB;AACzB,aAAO,MAAM,+BAA+B;AAAA,IAC9C;AACA,UAAM,cAAc,UAAU,QAAQ,aAAa;AACnD,UAAM,YAAY,kBAAkB,MAAM,GAAG,MAAM;AACnD,UAAM,SAAS,gBAAgB,MAAM,MAAM;AAE3C,UAAM,aAAa,MAAM,WACpB,MAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,GAAG,QACH,MAAM,QAAQ,IAAI;AAAA,MAClB,mBAAmB,IAAI,aAAa,KAAK,UAAU,iBAAiB,MAAM,QAAQ;AAAA,MAClF;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,UACE,gBAAgB;AAAA,UAChB,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF,CAAC,EAAE,KAAK,CAAC,CAAC,YAAY,aAAa,MAAM;AAAA,MACvC,GAAG,WAAW,OAAO,CAAC,QAAQ,CAAC,cAAc,UAAU,IAAI,IAAI,MAAM,CAAC;AAAA,MACtE,GAAG,cAAc;AAAA,IACnB,CAAC;AAEH,UAAM,eAAe,eAAe,aAAa,UAAU,GAAG,MAAM;AACpE,UAAM,QAAQ,iBAAiB,cAAc,MAAM,MAAM,MAAM,UAAU,SAAS;AAElF,WAAO;AAAA,MACL,aAAa,KAAK;AAAA,QAChB,OAAO,MAAM;AAAA,QACb,OAAO,MAAM;AAAA,QACb,MAAM,MAAM;AAAA,QACZ,UAAU,MAAM;AAAA,QAChB,YAAY,MAAM;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,eAAe,eAAe;AAChC,aAAO,mBAAmB,aAAa,KAAK,IAAI,MAAM,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC;AAAA,IAC/E;AACA,QAAI,eAAe,EAAE,UAAU;AAC7B,aAAO;AAAA,QACL,aAAa,KAAK,EAAE,OAAO,qBAAqB,SAAS,IAAI,OAAO,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACxF;AAAA,IACF;AACA,YAAQ,MAAM,8BAA8B,GAAG;AAC/C,WAAO;AAAA,MACL,aAAa,KAAK,EAAE,OAAO,wBAAwB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACvE;AAAA,EACF;AACF;AAEA,eAAsB,KAAK,SAAqC;AAC9D,MAAI;AACF,UAAM,EAAE,gBAAgB,WAAW,MAAM,uBAAuB,IAAI,MAAM,+BAA+B,OAAO;AAChH,UAAM,QAAQ,MAAM,uCAAuC,WAAW,KAAK,QAAQ;AACnF,QAAI,CAAC,MAAM,gBAAgB;AACzB,aAAO,MAAM,+BAA+B;AAAA,IAC9C;AACA,UAAM,aAAa,UAAU,QAAQ,YAAY;AACjD,UAAM,OAAO,qBAAqB,MAAM,MAAM,aAAsC,SAAS,CAAC,CAAC,CAAC;AAChG,UAAM,cAAc,mBAAmB,IAAI;AAC3C,UAAM,cAAc,MAAM,0BAA0B,WAAW;AAAA,MAC7D,UAAU,KAAK;AAAA,MACf,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,YAAY,KAAK;AAAA,MACjB,WAAW;AAAA,MACX,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ;AAAA,MACxB,iBAAiB;AAAA,IACnB,CAAC;AACD,QAAI,eAAe,CAAC,YAAY,IAAI;AAClC,aAAO,mBAAmB,aAAa,KAAK,YAAY,MAAM,EAAE,QAAQ,YAAY,OAAO,CAAC,CAAC;AAAA,IAC/F;AACA,UAAM,eAAe,wBAAwB,IAA+B;AAE5E,UAAM,EAAE,OAAO,IAAI,MAAM,WAAW,QAAQ,iCAAiC;AAAA,MAC3E,OAAO;AAAA,QACL,UAAU,KAAK;AAAA,QACf,iBAAiB;AAAA,QACjB,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK,YAAY,QAAQ,KAAK,WAAW,OAAO,SAAS;AAAA,QACjE,QAAQ;AAAA,QACR,GAAI,eAAe;AAAA,UACjB;AAAA,UACA,UAAU,OAAO,aAAa,aAAa,WAAW,aAAa,WAAW;AAAA,UAC9E,MAAM,OAAO,aAAa,gBAAgB,WAAW,aAAa,cAAc;AAAA,UAChF,aACE,OAAO,aAAa,WAAW,WAC3B,aAAa,SACb,OAAO,aAAa,UAAU,WAC5B,aAAa,QACb;AAAA,QACV,IAAI,CAAC;AAAA,MACP;AAAA,MACA,KAAK;AAAA,IACP,CAAC;AACD,QAAI,aAAa,MAAM,YAAY,uBAAuB;AACxD,YAAM,iCAAiC,WAAW;AAAA,QAChD,UAAU,KAAK;AAAA,QACf,gBAAgB;AAAA,QAChB,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,eAAe,QAAQ;AAAA,QACvB,gBAAgB,QAAQ;AAAA,QACxB,UAAU,YAAY,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AAEA,UAAM,gBACJ,UACA,OAAO,WAAW,YAClB,mBAAmB,UACnB,OAAO,OAAO,kBAAkB,WAC5B,OAAO,gBACP,UACE,OAAO,WAAW,YAClB,QAAQ,UACR,OAAO,OAAO,OAAO,WACrB,OAAO,KACP;AACR,WAAO;AAAA,MACL,aAAa;AAAA,QACX;AAAA,UACE,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,eAAe,eAAe;AAChC,aAAO,mBAAmB,aAAa,KAAK,IAAI,MAAM,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC;AAAA,IAC/E;AACA,QAAI,eAAe,EAAE,UAAU;AAC7B,aAAO;AAAA,QACL,aAAa,KAAK,EAAE,OAAO,qBAAqB,SAAS,IAAI,OAAO,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACxF;AAAA,IACF;AACA,YAAQ,MAAM,+BAA+B,GAAG;AAChD,WAAO;AAAA,MACL,aAAa,KAAK,EAAE,OAAO,wBAAwB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACvE;AAAA,EACF;AACF;AAEA,eAAsB,IAAI,SAAqC;AAC7D,MAAI;AACF,UAAM,EAAE,gBAAgB,WAAW,IAAI,MAAM,uBAAuB,IAAI,MAAM,+BAA+B,OAAO;AACpH,UAAM,QAAQ,MAAM,uCAAuC,WAAW,KAAK,QAAQ;AACnF,QAAI,CAAC,MAAM,gBAAgB;AACzB,aAAO,MAAM,+BAA+B;AAAA,IAC9C;AACA,UAAM,aAAa,UAAU,QAAQ,YAAY;AACjD,UAAM,cAAc,UAAU,QAAQ,aAAa;AACnD,UAAM,OAAO,qBAAqB,MAAM,MAAM,aAAsC,SAAS,CAAC,CAAC,CAAC;AAChG,UAAM,cAAc,mBAAmB,IAAI;AAC3C,UAAM,cAAc,MAAM,0BAA0B,WAAW;AAAA,MAC7D,UAAU,KAAK;AAAA,MACf,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,YAAY,KAAK,UAAU,KAAK;AAAA,MAChC,WAAW;AAAA,MACX,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ;AAAA,MACxB,iBAAiB;AAAA,IACnB,CAAC;AACD,QAAI,eAAe,CAAC,YAAY,IAAI;AAClC,aAAO,mBAAmB,aAAa,KAAK,YAAY,MAAM,EAAE,QAAQ,YAAY,OAAO,CAAC,CAAC;AAAA,IAC/F;AACA,UAAM,gBAAgB,MAAM,UACxB,KAAK,KACL,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,MACf;AAAA,IACF;AACJ,UAAM,eAAe,wBAAwB,IAA+B;AAC5E,UAAM,WAAW,yBAAyB,IAAI;AAE9C,UAAM,WAAW,QAAQ,iCAAiC;AAAA,MACxD,OAAO;AAAA,QACL,IAAI;AAAA,QACJ,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,QACxD,GAAI,aAAa,SAAY,EAAE,QAAQ,WAAW,SAAS,UAAU,IAAI,CAAC;AAAA,QAC1E,GAAI,eAAe;AAAA,UACjB;AAAA,UACA,UAAU,OAAO,aAAa,aAAa,WAAW,aAAa,WAAW;AAAA,UAC9E,MAAM,OAAO,aAAa,gBAAgB,WAAW,aAAa,cAAc;AAAA,UAChF,aACE,OAAO,aAAa,WAAW,WAC3B,aAAa,SACb,OAAO,aAAa,UAAU,WAC5B,aAAa,QACb;AAAA,QACV,IAAI,CAAC;AAAA,MACP;AAAA,MACA,KAAK;AAAA,IACP,CAAC;AACD,QAAI,aAAa,MAAM,YAAY,uBAAuB;AACxD,YAAM,iCAAiC,WAAW;AAAA,QAChD,UAAU,KAAK;AAAA,QACf,gBAAgB;AAAA,QAChB,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,YAAY,KAAK,UAAU,KAAK;AAAA,QAChC,WAAW;AAAA,QACX,eAAe,QAAQ;AAAA,QACvB,gBAAgB,QAAQ;AAAA,QACxB,UAAU,YAAY,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AAEA,WAAO,mBAAmB,aAAa,KAAK,EAAE,IAAI,KAAK,CAAC,CAAC;AAAA,EAC3D,SAAS,KAAK;AACZ,QAAI,eAAe,eAAe;AAChC,aAAO,mBAAmB,aAAa,KAAK,IAAI,MAAM,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC;AAAA,IAC/E;AACA,QAAI,eAAe,EAAE,UAAU;AAC7B,aAAO;AAAA,QACL,aAAa,KAAK,EAAE,OAAO,qBAAqB,SAAS,IAAI,OAAO,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACxF;AAAA,IACF;AACA,YAAQ,MAAM,8BAA8B,GAAG;AAC/C,WAAO;AAAA,MACL,aAAa,KAAK,EAAE,OAAO,wBAAwB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACvE;AAAA,EACF;AACF;AAEA,eAAsB,OAAO,SAAqC;AAChE,MAAI;AACF,UAAM,EAAE,gBAAgB,WAAW,IAAI,MAAM,uBAAuB,IAAI,MAAM,+BAA+B,OAAO;AACpH,UAAM,QAAQ,MAAM,uCAAuC,WAAW,KAAK,QAAQ;AACnF,QAAI,CAAC,MAAM,gBAAgB;AACzB,aAAO,MAAM,+BAA+B;AAAA,IAC9C;AACA,UAAM,aAAa,UAAU,QAAQ,YAAY;AACjD,UAAM,cAAc,UAAU,QAAQ,aAAa;AACnD,UAAM,OAAO,qBAAqB,MAAM,MAAM,aAAsC,SAAS,CAAC,CAAC,CAAC;AAChG,UAAM,cAAc,mBAAmB,IAAI;AAC3C,UAAM,cAAc,MAAM,0BAA0B,WAAW;AAAA,MAC7D,UAAU,KAAK;AAAA,MACf,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,YAAY,KAAK;AAAA,MACjB,WAAW;AAAA,MACX,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ;AAAA,MACxB,iBAAiB;AAAA,IACnB,CAAC;AACD,QAAI,eAAe,CAAC,YAAY,IAAI;AAClC,aAAO,mBAAmB,aAAa,KAAK,YAAY,MAAM,EAAE,QAAQ,YAAY,OAAO,CAAC,CAAC;AAAA,IAC/F;AACA,UAAM,gBAAgB,MAAM,UACxB,KAAK,UAAU,KAAK,KACpB,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK,UAAU,KAAK;AAAA,MAC9B;AAAA,IACF;AAEJ,UAAM,WAAW,QAAQ,iCAAiC;AAAA,MACxD,OAAO,EAAE,IAAI,cAAc;AAAA,MAC3B,KAAK;AAAA,IACP,CAAC;AACD,QAAI,aAAa,MAAM,YAAY,uBAAuB;AACxD,YAAM,iCAAiC,WAAW;AAAA,QAChD,UAAU,KAAK;AAAA,QACf,gBAAgB;AAAA,QAChB,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,eAAe,QAAQ;AAAA,QACvB,gBAAgB,QAAQ;AAAA,QACxB,UAAU,YAAY,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AAEA,WAAO,mBAAmB,aAAa,KAAK,EAAE,IAAI,KAAK,CAAC,CAAC;AAAA,EAC3D,SAAS,KAAK;AACZ,QAAI,eAAe,eAAe;AAChC,aAAO,mBAAmB,aAAa,KAAK,IAAI,MAAM,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC;AAAA,IAC/E;AACA,QAAI,eAAe,EAAE,UAAU;AAC7B,aAAO;AAAA,QACL,aAAa,KAAK,EAAE,OAAO,qBAAqB,SAAS,IAAI,OAAO,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACxF;AAAA,IACF;AACA,YAAQ,MAAM,iCAAiC,GAAG;AAClD,WAAO;AAAA,MACL,aAAa,KAAK,EAAE,OAAO,wBAAwB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACvE;AAAA,EACF;AACF;AAEA,MAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,IAAI,EAAE,OAAO;AAAA,EACb,QAAQ,EAAE,OAAO;AAAA,EACjB,YAAY,EAAE,OAAO;AAAA,EACrB,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,YAAY,EAAE,QAAQ,EAAE,SAAS;AAAA,EACjC,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC7C,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC7C,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAChD,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC1C,kBAAkB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS;AAAA,EACxE,oBAAoB,EAAE,OAAO,EAAE,SAAS;AAAA,EACxC,gBAAgB,EAAE,OAAO;AAAA,EACzB,UAAU,EAAE,OAAO;AAAA,EACnB,WAAW,EAAE,OAAO;AAAA,EACpB,UAAU,EAAE,OAAO;AAAA,IACjB,IAAI,EAAE,OAAO,EAAE,SAAS;AAAA,IACxB,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,IACjC,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,CAAC;AACH,CAAC;AAED,MAAM,2BAA2B,EAAE,OAAO;AAAA,EACxC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACnC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AACrC,CAAC;AAEM,MAAM,UAA2B,2BAA2B;AAAA,EACjE,cAAc;AAAA,EACd;AAAA,EACA,oBAAoB,8BAA8B,cAAc;AAAA,EAChE,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,aAAa;AAAA,EACf;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,aAAa;AAAA,EACf;AAAA,EACA,KAAK;AAAA,IACH,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,aAAa;AAAA,EACf;AACF,CAAC;",
|
|
4
|
+
"sourcesContent": ["/**\n * @deprecated Use /api/customers/interactions instead. This route is maintained\n * as a compatibility bridge per SPEC-046b. Will be removed in a future release.\n */\nimport { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport type { QueryEngine } from '@open-mercato/shared/lib/query/types'\nimport { createCustomersCrudOpenApi, createPagedListResponseSchema, defaultOkResponseSchema } from '../openapi'\nimport { CustomerInteraction, CustomerTodoLink } from '../../data/entities'\nimport { todoLinkWithTodoCreateSchema } from '../../data/validators'\nimport { resolveCustomerInteractionFeatureFlags } from '../../lib/interactionFeatureFlags'\nimport { resolveCustomersRequestContext } from '../../lib/interactionRequestContext'\nimport {\n EXAMPLE_TODO_SOURCE,\n CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n} from '../../lib/interactionCompatibility'\nimport {\n filterTodoRows,\n listCanonicalTodoRows,\n listLegacyTodoRows,\n normalizeTodoSearch,\n paginateTodoRows,\n sortTodoRows,\n resolveLegacyTodoDetails,\n} from '../../lib/todoCompatibility'\n\nconst querySchema = z.object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n search: z.string().optional(),\n all: z.string().optional(),\n entityId: z.string().uuid().optional(),\n})\n\nconst todoCreateBodySchema = todoLinkWithTodoCreateSchema.omit({\n tenantId: true,\n organizationId: true,\n}).passthrough()\n\nconst todoUpdateBodySchema = z\n .object({\n id: z.string().uuid(),\n linkId: z.string().uuid().optional(),\n title: z.string().trim().min(1).max(200).optional(),\n isDone: z.boolean().optional(),\n is_done: z.boolean().optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n customValues: z.record(z.string(), z.unknown()).optional(),\n })\n .passthrough()\n\nconst todoDeleteBodySchema = z.object({\n id: z.string().uuid(),\n todoId: z.string().uuid().optional(),\n})\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['customers.view'] },\n POST: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n}\n\nconst DEPRECATION_HEADERS = {\n Deprecation: 'true',\n Sunset: 'Tue, 30 Jun 2026 00:00:00 GMT',\n Link: '</api/customers/interactions>; rel=\"successor-version\"',\n}\n\nfunction resolveGuardUserId(auth: {\n sub?: string | null\n userId?: string | null\n keyId?: string | null\n}): string {\n if (typeof auth.sub === 'string' && auth.sub.trim().length > 0) return auth.sub\n if (typeof auth.userId === 'string' && auth.userId.trim().length > 0) return auth.userId\n if (typeof auth.keyId === 'string' && auth.keyId.trim().length > 0) return auth.keyId\n return 'system'\n}\n\nfunction withAdapterHeaders(response: Response): Response {\n const headers = new Headers(response.headers)\n Object.entries(DEPRECATION_HEADERS).forEach(([key, value]) => headers.set(key, value))\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n })\n}\n\nasync function legacyAdaptersDisabledResponse(): Promise<Response> {\n const { translate } = await resolveTranslations()\n return withAdapterHeaders(NextResponse.json(\n {\n error: translate(\n 'customers.interactions.legacyAdapters.disabled',\n 'This legacy adapter has been disabled. Use /api/customers/interactions instead.',\n ),\n },\n { status: 410 },\n ))\n}\n\nfunction normalizeTodoStatusInput(body: z.infer<typeof todoUpdateBodySchema>): boolean | undefined {\n if (typeof body.isDone === 'boolean') return body.isDone\n if (typeof body.is_done === 'boolean') return body.is_done\n return undefined\n}\n\nfunction collectTodoCustomValues(\n body: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const direct =\n body.customValues && typeof body.customValues === 'object'\n ? { ...(body.customValues as Record<string, unknown>) }\n : {}\n if (body.todoCustom && typeof body.todoCustom === 'object') {\n Object.assign(direct, body.todoCustom as Record<string, unknown>)\n }\n if (body.customFields && typeof body.customFields === 'object') {\n Object.assign(direct, body.customFields as Record<string, unknown>)\n }\n return Object.keys(direct).length > 0 ? direct : undefined\n}\n\nasync function findLegacyTodoLink(\n em: EntityManager,\n target: { linkId?: string; todoId?: string },\n): Promise<CustomerTodoLink | null> {\n if (target.linkId) {\n const byLinkId = await em.findOne(CustomerTodoLink, { id: target.linkId }, { populate: ['entity'] })\n if (byLinkId) return byLinkId\n }\n if (target.todoId) {\n return await em.findOne(CustomerTodoLink, { todoId: target.todoId }, { populate: ['entity'] })\n }\n return null\n}\n\nasync function ensureCanonicalTodoBridge(\n em: EntityManager,\n queryEngine: QueryEngine,\n commandBus: CommandBus,\n commandContext: Parameters<CommandBus['execute']>[1]['ctx'],\n link: CustomerTodoLink,\n): Promise<string> {\n const existing = await em.findOne(CustomerInteraction, { id: link.todoId })\n if (existing) return existing.id\n\n const detailMap = await resolveLegacyTodoDetails(\n queryEngine,\n [link],\n link.tenantId,\n [link.organizationId],\n )\n const source =\n typeof link.todoSource === 'string' && link.todoSource.trim().length > 0\n ? link.todoSource\n : EXAMPLE_TODO_SOURCE\n const detail = detailMap.get(`${source}:${link.todoId}`) ?? null\n const entityId = typeof link.entity === 'string' ? link.entity : link.entity.id\n\n await commandBus.execute('customers.interactions.create', {\n input: {\n id: link.todoId,\n entityId,\n interactionType: 'task',\n title: detail?.title ?? null,\n body: detail?.description ?? null,\n status: detail?.isDone ? 'done' : 'planned',\n scheduledAt: detail?.dueAt ?? null,\n priority: detail?.priority ?? null,\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n ...(detail?.customValues ? { customValues: detail.customValues } : {}),\n },\n ctx: commandContext,\n })\n\n return link.todoId\n}\n\nasync function resolveCanonicalTodoTargetId(\n em: EntityManager,\n queryEngine: QueryEngine,\n commandBus: CommandBus,\n commandContext: Parameters<CommandBus['execute']>[1]['ctx'],\n target: { todoId?: string; linkId?: string },\n): Promise<string> {\n if (target.todoId) {\n const interaction = await em.findOne(CustomerInteraction, { id: target.todoId })\n if (interaction) return interaction.id\n }\n\n const legacyLink = await findLegacyTodoLink(em, target)\n if (!legacyLink) {\n if (!target.todoId) throw new CrudHttpError(404, { error: 'Todo not found' })\n return target.todoId\n }\n\n return ensureCanonicalTodoBridge(\n em,\n queryEngine,\n commandBus,\n commandContext,\n legacyLink,\n )\n}\n\nexport async function GET(request: Request): Promise<Response> {\n try {\n const { auth, em, organizationIds, container, selectedOrganizationId } =\n await resolveCustomersRequestContext(request)\n const query = querySchema.parse(Object.fromEntries(new URL(request.url).searchParams))\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const exportAll = parseBooleanToken(query.all) === true\n const search = normalizeTodoSearch(query.search)\n\n const mergedRows = flags.unified\n ? (await listCanonicalTodoRows(\n em,\n container,\n auth,\n selectedOrganizationId,\n organizationIds,\n { entityId: query.entityId },\n )).items\n : await Promise.all([\n listLegacyTodoRows(em, queryEngine, auth.tenantId, organizationIds, query.entityId),\n listCanonicalTodoRows(\n em,\n container,\n auth,\n selectedOrganizationId,\n organizationIds,\n {\n entityId: query.entityId,\n includeDeleted: true,\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n },\n ),\n ]).then(([legacyRows, canonicalRows]) => [\n ...legacyRows.filter((row) => !canonicalRows.bridgeIds.has(row.todoId)),\n ...canonicalRows.items,\n ])\n\n const filteredRows = filterTodoRows(sortTodoRows(mergedRows), search)\n const paged = paginateTodoRows(filteredRows, query.page, query.pageSize, exportAll)\n\n return withAdapterHeaders(\n NextResponse.json({\n items: paged.items,\n total: paged.total,\n page: paged.page,\n pageSize: paged.pageSize,\n totalPages: paged.totalPages,\n }),\n )\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n console.error('customers.todos.get failed', err)\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function POST(request: Request): Promise<Response> {\n try {\n const { commandContext, container, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const body = todoCreateBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.entityId,\n operation: 'create',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const customValues = collectTodoCustomValues(body as Record<string, unknown>)\n\n const { result } = await commandBus.execute('customers.interactions.create', {\n input: {\n entityId: body.entityId,\n interactionType: 'task',\n title: body.title,\n status: body.is_done === true || body.isDone === true ? 'done' : 'planned',\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n ...(customValues ? {\n customValues,\n priority: typeof customValues.priority === 'number' ? customValues.priority : null,\n body: typeof customValues.description === 'string' ? customValues.description : null,\n scheduledAt:\n typeof customValues.due_at === 'string'\n ? customValues.due_at\n : typeof customValues.dueAt === 'string'\n ? customValues.dueAt\n : null,\n } : {}),\n },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.entityId,\n operation: 'create',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n const interactionId =\n result &&\n typeof result === 'object' &&\n 'interactionId' in result &&\n typeof result.interactionId === 'string'\n ? result.interactionId\n : result &&\n typeof result === 'object' &&\n 'id' in result &&\n typeof result.id === 'string'\n ? result.id\n : null\n return withAdapterHeaders(\n NextResponse.json(\n {\n linkId: interactionId,\n todoId: interactionId,\n },\n { status: 201 },\n ),\n )\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n console.error('customers.todos.post failed', err)\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function PUT(request: Request): Promise<Response> {\n try {\n const { commandContext, container, em, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const body = todoUpdateBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.linkId ?? body.id,\n operation: 'update',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const interactionId = flags.unified\n ? body.id\n : await resolveCanonicalTodoTargetId(\n em,\n queryEngine,\n commandBus,\n commandContext,\n {\n todoId: body.id,\n linkId: body.linkId,\n },\n )\n const customValues = collectTodoCustomValues(body as Record<string, unknown>)\n const nextDone = normalizeTodoStatusInput(body)\n\n await commandBus.execute('customers.interactions.update', {\n input: {\n id: interactionId,\n ...(body.title !== undefined ? { title: body.title } : {}),\n ...(nextDone !== undefined ? { status: nextDone ? 'done' : 'planned' } : {}),\n ...(customValues ? {\n customValues,\n priority: typeof customValues.priority === 'number' ? customValues.priority : null,\n body: typeof customValues.description === 'string' ? customValues.description : null,\n scheduledAt:\n typeof customValues.due_at === 'string'\n ? customValues.due_at\n : typeof customValues.dueAt === 'string'\n ? customValues.dueAt\n : null,\n } : {}),\n },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.linkId ?? body.id,\n operation: 'update',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return withAdapterHeaders(NextResponse.json({ ok: true }))\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n console.error('customers.todos.put failed', err)\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function DELETE(request: Request): Promise<Response> {\n try {\n const { commandContext, container, em, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const body = todoDeleteBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.id,\n operation: 'delete',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const interactionId = flags.unified\n ? body.todoId ?? body.id\n : await resolveCanonicalTodoTargetId(\n em,\n queryEngine,\n commandBus,\n commandContext,\n {\n linkId: body.id,\n todoId: body.todoId ?? body.id,\n },\n )\n\n await commandBus.execute('customers.interactions.delete', {\n input: { id: interactionId },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.id,\n operation: 'delete',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return withAdapterHeaders(NextResponse.json({ ok: true }))\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n console.error('customers.todos.delete failed', err)\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nconst todoItemSchema = z.object({\n id: z.string(),\n todoId: z.string(),\n todoSource: z.string(),\n todoTitle: z.string().nullable(),\n todoIsDone: z.boolean().nullable(),\n todoPriority: z.number().nullable().optional(),\n todoSeverity: z.string().nullable().optional(),\n todoDescription: z.string().nullable().optional(),\n todoDueAt: z.string().nullable().optional(),\n todoCustomValues: z.record(z.string(), z.unknown()).nullable().optional(),\n todoOrganizationId: z.string().nullable(),\n organizationId: z.string(),\n tenantId: z.string(),\n createdAt: z.string(),\n externalHref: z.string().nullable().optional(),\n _integrations: z.record(z.string(), z.unknown()).optional(),\n customer: z.object({\n id: z.string().nullable(),\n displayName: z.string().nullable(),\n kind: z.string().nullable(),\n }),\n})\n\nconst todoCreateResponseSchema = z.object({\n linkId: z.string().uuid().nullable(),\n todoId: z.string().uuid().nullable(),\n})\n\nexport const openApi: OpenApiRouteDoc = createCustomersCrudOpenApi({\n resourceName: 'CustomerTodo',\n querySchema,\n listResponseSchema: createPagedListResponseSchema(todoItemSchema),\n create: {\n schema: todoCreateBodySchema,\n responseSchema: todoCreateResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Creates a customer task. Use POST /api/customers/interactions instead.',\n },\n update: {\n schema: todoUpdateBodySchema,\n responseSchema: defaultOkResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Updates a customer task. Use PUT /api/customers/interactions instead.',\n },\n del: {\n schema: todoDeleteBodySchema,\n responseSchema: defaultOkResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Deletes a customer task. Use DELETE /api/customers/interactions instead.',\n },\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
3
|
+
import { CustomerTodosTable } from "../../components/CustomerTodosTable.js";
|
|
4
|
+
function CustomerTasksPage() {
|
|
5
|
+
return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(CustomerTodosTable, {}) }) });
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
CustomerTasksPage as default
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=page.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/customers/backend/customer-tasks/page.tsx"],
|
|
4
|
+
"sourcesContent": ["import { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { CustomerTodosTable } from '../../components/CustomerTodosTable'\n\nexport default function CustomerTasksPage() {\n return (\n <Page>\n <PageBody>\n <CustomerTodosTable />\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "AAOQ;AAPR,SAAS,MAAM,gBAAgB;AAC/B,SAAS,0BAA0B;AAEpB,SAAR,oBAAqC;AAC1C,SACE,oBAAC,QACC,8BAAC,YACC,8BAAC,sBAAmB,GACtB,GACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
const tasksIcon = React.createElement(
|
|
3
|
+
"svg",
|
|
4
|
+
{ width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2 },
|
|
5
|
+
React.createElement("rect", { x: 9, y: 3, width: 6, height: 4, rx: 1 }),
|
|
6
|
+
React.createElement("path", { d: "M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2" }),
|
|
7
|
+
React.createElement("path", { d: "M9 12h6" }),
|
|
8
|
+
React.createElement("path", { d: "M9 16h4" })
|
|
9
|
+
);
|
|
10
|
+
const metadata = {
|
|
11
|
+
requireAuth: true,
|
|
12
|
+
requireFeatures: ["customers.interactions.view"],
|
|
13
|
+
pageTitle: "Customer related tasks",
|
|
14
|
+
pageTitleKey: "customers.workPlan.customerTodos.page.title",
|
|
15
|
+
pageGroup: "Customers",
|
|
16
|
+
pageGroupKey: "customers.nav.group",
|
|
17
|
+
pagePriority: 10,
|
|
18
|
+
pageOrder: 120,
|
|
19
|
+
icon: tasksIcon,
|
|
20
|
+
breadcrumb: [{ label: "Customer related tasks", labelKey: "customers.workPlan.customerTodos.page.title" }]
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
metadata
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=page.meta.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/customers/backend/customer-tasks/page.meta.ts"],
|
|
4
|
+
"sourcesContent": ["import React from 'react'\n\nconst tasksIcon = React.createElement(\n 'svg',\n { width: 16, height: 16, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2 },\n React.createElement('rect', { x: 9, y: 3, width: 6, height: 4, rx: 1 }),\n React.createElement('path', { d: 'M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2' }),\n React.createElement('path', { d: 'M9 12h6' }),\n React.createElement('path', { d: 'M9 16h4' }),\n)\n\nexport const metadata = {\n requireAuth: true,\n requireFeatures: ['customers.interactions.view'],\n pageTitle: 'Customer related tasks',\n pageTitleKey: 'customers.workPlan.customerTodos.page.title',\n pageGroup: 'Customers',\n pageGroupKey: 'customers.nav.group',\n pagePriority: 10,\n pageOrder: 120,\n icon: tasksIcon,\n breadcrumb: [{ label: 'Customer related tasks', labelKey: 'customers.workPlan.customerTodos.page.title' }],\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,WAAW;AAElB,MAAM,YAAY,MAAM;AAAA,EACtB;AAAA,EACA,EAAE,OAAO,IAAI,QAAQ,IAAI,SAAS,aAAa,MAAM,QAAQ,QAAQ,gBAAgB,aAAa,EAAE;AAAA,EACpG,MAAM,cAAc,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,EAAE,CAAC;AAAA,EACtE,MAAM,cAAc,QAAQ,EAAE,GAAG,4EAA4E,CAAC;AAAA,EAC9G,MAAM,cAAc,QAAQ,EAAE,GAAG,UAAU,CAAC;AAAA,EAC5C,MAAM,cAAc,QAAQ,EAAE,GAAG,UAAU,CAAC;AAC9C;AAEO,MAAM,WAAW;AAAA,EACtB,aAAa;AAAA,EACb,iBAAiB,CAAC,6BAA6B;AAAA,EAC/C,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,cAAc;AAAA,EACd,cAAc;AAAA,EACd,WAAW;AAAA,EACX,MAAM;AAAA,EACN,YAAY,CAAC,EAAE,OAAO,0BAA0B,UAAU,8CAA8C,CAAC;AAC3G;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -42,7 +42,15 @@ const interactionCrudEvents = {
|
|
|
42
42
|
buildPayload: (ctx) => ({
|
|
43
43
|
id: ctx.identifiers.id,
|
|
44
44
|
organizationId: ctx.identifiers.organizationId,
|
|
45
|
-
tenantId: ctx.identifiers.tenantId
|
|
45
|
+
tenantId: ctx.identifiers.tenantId,
|
|
46
|
+
entityId: ctx.entity && typeof ctx.entity === "object" && "entity" in ctx.entity ? (() => {
|
|
47
|
+
const entityRef = ctx.entity.entity;
|
|
48
|
+
return typeof entityRef === "string" ? entityRef : entityRef?.id ?? null;
|
|
49
|
+
})() : null,
|
|
50
|
+
interactionType: ctx.entity && typeof ctx.entity === "object" && "interactionType" in ctx.entity ? ctx.entity.interactionType : null,
|
|
51
|
+
status: ctx.entity && typeof ctx.entity === "object" && "status" in ctx.entity ? ctx.entity.status : null,
|
|
52
|
+
source: ctx.entity && typeof ctx.entity === "object" && "source" in ctx.entity ? ctx.entity.source ?? null : null,
|
|
53
|
+
...ctx.syncOrigin ? { syncOrigin: ctx.syncOrigin } : {}
|
|
46
54
|
})
|
|
47
55
|
};
|
|
48
56
|
async function loadInteractionSnapshot(em, id) {
|
|
@@ -107,8 +115,12 @@ async function emitInteractionRevertedEvent(ctx, interaction) {
|
|
|
107
115
|
id: interaction.id,
|
|
108
116
|
organizationId: interaction.organizationId,
|
|
109
117
|
tenantId: interaction.tenantId,
|
|
118
|
+
entityId: interaction.entityId,
|
|
119
|
+
interactionType: interaction.interactionType,
|
|
120
|
+
source: interaction.source ?? null,
|
|
110
121
|
status: interaction.status,
|
|
111
|
-
occurredAt: interaction.occurredAt?.toISOString() ?? null
|
|
122
|
+
occurredAt: interaction.occurredAt?.toISOString() ?? null,
|
|
123
|
+
...ctx.syncOrigin ? { syncOrigin: ctx.syncOrigin } : {}
|
|
112
124
|
});
|
|
113
125
|
}
|
|
114
126
|
function createTransactionalDataEngine(ctx, em) {
|
|
@@ -194,6 +206,7 @@ const createInteractionCommand = {
|
|
|
194
206
|
organizationId: interaction.organizationId,
|
|
195
207
|
tenantId: interaction.tenantId
|
|
196
208
|
},
|
|
209
|
+
syncOrigin: ctx.syncOrigin,
|
|
197
210
|
indexer: interactionCrudIndexer,
|
|
198
211
|
events: interactionCrudEvents
|
|
199
212
|
});
|
|
@@ -310,6 +323,7 @@ const updateInteractionCommand = {
|
|
|
310
323
|
organizationId: interaction.organizationId,
|
|
311
324
|
tenantId: interaction.tenantId
|
|
312
325
|
},
|
|
326
|
+
syncOrigin: ctx.syncOrigin,
|
|
313
327
|
indexer: interactionCrudIndexer,
|
|
314
328
|
events: interactionCrudEvents
|
|
315
329
|
});
|
|
@@ -423,6 +437,7 @@ const updateInteractionCommand = {
|
|
|
423
437
|
organizationId: interaction.organizationId,
|
|
424
438
|
tenantId: interaction.tenantId
|
|
425
439
|
},
|
|
440
|
+
syncOrigin: ctx.syncOrigin,
|
|
426
441
|
indexer: interactionCrudIndexer,
|
|
427
442
|
events: interactionCrudEvents
|
|
428
443
|
});
|
|
@@ -471,10 +486,19 @@ const completeInteractionCommand = {
|
|
|
471
486
|
action: "updated",
|
|
472
487
|
entity: interaction,
|
|
473
488
|
identifiers,
|
|
489
|
+
syncOrigin: ctx.syncOrigin,
|
|
474
490
|
indexer: interactionCrudIndexer,
|
|
475
491
|
events: interactionCrudEvents
|
|
476
492
|
});
|
|
477
|
-
await emitLifecycleEvent(ctx, "customers.interaction.completed",
|
|
493
|
+
await emitLifecycleEvent(ctx, "customers.interaction.completed", {
|
|
494
|
+
...identifiers,
|
|
495
|
+
entityId,
|
|
496
|
+
interactionType: interaction.interactionType,
|
|
497
|
+
status: interaction.status,
|
|
498
|
+
source: interaction.source ?? null,
|
|
499
|
+
occurredAt: interaction.occurredAt?.toISOString() ?? null,
|
|
500
|
+
...ctx.syncOrigin ? { syncOrigin: ctx.syncOrigin } : {}
|
|
501
|
+
});
|
|
478
502
|
await emitNextInteractionUpdatedEvent(ctx, { entityId, nextInteractionId }, identifiers);
|
|
479
503
|
return { interactionId: interaction.id };
|
|
480
504
|
},
|
|
@@ -533,6 +557,7 @@ const completeInteractionCommand = {
|
|
|
533
557
|
organizationId: result.interaction.organizationId,
|
|
534
558
|
tenantId: result.interaction.tenantId
|
|
535
559
|
},
|
|
560
|
+
syncOrigin: ctx.syncOrigin,
|
|
536
561
|
indexer: interactionCrudIndexer,
|
|
537
562
|
events: interactionCrudEvents
|
|
538
563
|
});
|
|
@@ -581,10 +606,18 @@ const cancelInteractionCommand = {
|
|
|
581
606
|
action: "updated",
|
|
582
607
|
entity: interaction,
|
|
583
608
|
identifiers,
|
|
609
|
+
syncOrigin: ctx.syncOrigin,
|
|
584
610
|
indexer: interactionCrudIndexer,
|
|
585
611
|
events: interactionCrudEvents
|
|
586
612
|
});
|
|
587
|
-
await emitLifecycleEvent(ctx, "customers.interaction.canceled",
|
|
613
|
+
await emitLifecycleEvent(ctx, "customers.interaction.canceled", {
|
|
614
|
+
...identifiers,
|
|
615
|
+
entityId,
|
|
616
|
+
interactionType: interaction.interactionType,
|
|
617
|
+
status: interaction.status,
|
|
618
|
+
source: interaction.source ?? null,
|
|
619
|
+
...ctx.syncOrigin ? { syncOrigin: ctx.syncOrigin } : {}
|
|
620
|
+
});
|
|
588
621
|
await emitNextInteractionUpdatedEvent(ctx, { entityId, nextInteractionId }, identifiers);
|
|
589
622
|
return { interactionId: interaction.id };
|
|
590
623
|
},
|
|
@@ -642,6 +675,7 @@ const cancelInteractionCommand = {
|
|
|
642
675
|
organizationId: result.interaction.organizationId,
|
|
643
676
|
tenantId: result.interaction.tenantId
|
|
644
677
|
},
|
|
678
|
+
syncOrigin: ctx.syncOrigin,
|
|
645
679
|
indexer: interactionCrudIndexer,
|
|
646
680
|
events: interactionCrudEvents
|
|
647
681
|
});
|
|
@@ -689,6 +723,7 @@ const deleteInteractionCommand = {
|
|
|
689
723
|
organizationId: interaction.organizationId,
|
|
690
724
|
tenantId: interaction.tenantId
|
|
691
725
|
},
|
|
726
|
+
syncOrigin: ctx.syncOrigin,
|
|
692
727
|
indexer: interactionCrudIndexer,
|
|
693
728
|
events: interactionCrudEvents
|
|
694
729
|
});
|
|
@@ -796,6 +831,7 @@ const deleteInteractionCommand = {
|
|
|
796
831
|
organizationId: interaction.organizationId,
|
|
797
832
|
tenantId: interaction.tenantId
|
|
798
833
|
},
|
|
834
|
+
syncOrigin: ctx.syncOrigin,
|
|
799
835
|
indexer: interactionCrudIndexer,
|
|
800
836
|
events: interactionCrudEvents
|
|
801
837
|
});
|