@open-mercato/core 0.6.3-develop.3771.1.1788990f9e → 0.6.3-develop.3797.1.9d6338d7cd

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.
Files changed (55) hide show
  1. package/dist/modules/catalog/api/offers/route.js +1 -0
  2. package/dist/modules/catalog/api/offers/route.js.map +2 -2
  3. package/dist/modules/catalog/api/option-schemas/route.js +1 -0
  4. package/dist/modules/catalog/api/option-schemas/route.js.map +2 -2
  5. package/dist/modules/catalog/api/price-kinds/route.js +1 -0
  6. package/dist/modules/catalog/api/price-kinds/route.js.map +2 -2
  7. package/dist/modules/catalog/api/variants/route.js +1 -0
  8. package/dist/modules/catalog/api/variants/route.js.map +2 -2
  9. package/dist/modules/customer_accounts/api/admin/users.js +42 -9
  10. package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
  11. package/dist/modules/customers/ai-agents.js +1 -0
  12. package/dist/modules/customers/ai-agents.js.map +2 -2
  13. package/dist/modules/customers/api/people/route.js +1 -0
  14. package/dist/modules/customers/api/people/route.js.map +2 -2
  15. package/dist/modules/customers/api/tags/route.js +1 -0
  16. package/dist/modules/customers/api/tags/route.js.map +2 -2
  17. package/dist/modules/feature_toggles/api/global/route.js +1 -0
  18. package/dist/modules/feature_toggles/api/global/route.js.map +2 -2
  19. package/dist/modules/sales/api/adjustment-kinds/route.js +1 -0
  20. package/dist/modules/sales/api/adjustment-kinds/route.js.map +2 -2
  21. package/dist/modules/sales/api/channels/route.js +1 -0
  22. package/dist/modules/sales/api/channels/route.js.map +2 -2
  23. package/dist/modules/sales/api/delivery-windows/route.js +1 -0
  24. package/dist/modules/sales/api/delivery-windows/route.js.map +2 -2
  25. package/dist/modules/sales/api/document-addresses/route.js +1 -0
  26. package/dist/modules/sales/api/document-addresses/route.js.map +2 -2
  27. package/dist/modules/sales/api/payment-methods/route.js +1 -0
  28. package/dist/modules/sales/api/payment-methods/route.js.map +2 -2
  29. package/dist/modules/sales/api/price-kinds/route.js +1 -0
  30. package/dist/modules/sales/api/price-kinds/route.js.map +2 -2
  31. package/dist/modules/sales/api/quote-adjustments/route.js +1 -0
  32. package/dist/modules/sales/api/quote-adjustments/route.js.map +2 -2
  33. package/dist/modules/sales/api/shipping-methods/route.js +1 -0
  34. package/dist/modules/sales/api/shipping-methods/route.js.map +2 -2
  35. package/dist/modules/sales/api/tax-rates/route.js +1 -0
  36. package/dist/modules/sales/api/tax-rates/route.js.map +2 -2
  37. package/package.json +7 -7
  38. package/src/modules/catalog/api/offers/route.ts +1 -0
  39. package/src/modules/catalog/api/option-schemas/route.ts +1 -0
  40. package/src/modules/catalog/api/price-kinds/route.ts +1 -0
  41. package/src/modules/catalog/api/variants/route.ts +1 -0
  42. package/src/modules/customer_accounts/api/admin/users.ts +66 -12
  43. package/src/modules/customers/ai-agents.ts +1 -0
  44. package/src/modules/customers/api/people/route.ts +1 -0
  45. package/src/modules/customers/api/tags/route.ts +1 -0
  46. package/src/modules/feature_toggles/api/global/route.ts +1 -0
  47. package/src/modules/sales/api/adjustment-kinds/route.ts +1 -0
  48. package/src/modules/sales/api/channels/route.ts +1 -0
  49. package/src/modules/sales/api/delivery-windows/route.ts +1 -0
  50. package/src/modules/sales/api/document-addresses/route.ts +1 -0
  51. package/src/modules/sales/api/payment-methods/route.ts +1 -0
  52. package/src/modules/sales/api/price-kinds/route.ts +1 -0
  53. package/src/modules/sales/api/quote-adjustments/route.ts +1 -0
  54. package/src/modules/sales/api/shipping-methods/route.ts +1 -0
  55. package/src/modules/sales/api/tax-rates/route.ts +1 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/sales/api/tax-rates/route.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { splitCustomFieldPayload } from '@open-mercato/shared/lib/crud/custom-fields'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { SalesTaxRate } from '../../data/entities'\nimport { taxRateCreateSchema, taxRateUpdateSchema } from '../../data/validators'\nimport { buildAggregateSearchFilter, parseScopedCommandInput, resolveCrudRecordId } from '../utils'\nimport { E } from '#generated/entities.ids.generated'\nimport * as F from '#generated/entities/sales_tax_rate'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst listSchema = z\n .object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(200).default(50),\n search: z.string().optional(),\n country: z.string().optional(),\n region: z.string().optional(),\n channelId: z.string().uuid().optional(),\n isCompound: z.string().optional(),\n sortField: z.string().optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n withDeleted: z.coerce.boolean().optional(),\n })\n .passthrough()\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n POST: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n}\n\nexport const metadata = routeMetadata\n\nconst taxRateResponseItemSchema = z.object({\n id: z.string().uuid(),\n name: z.string(),\n code: z.string().nullable(),\n rate: z.number(),\n countryCode: z.string().nullable(),\n regionCode: z.string().nullable(),\n postalCode: z.string().nullable(),\n city: z.string().nullable(),\n customerGroupId: z.string().uuid().nullable(),\n productCategoryId: z.string().uuid().nullable(),\n channelId: z.string().uuid().nullable(),\n priority: z.number().nullable(),\n isCompound: z.boolean(),\n isDefault: z.boolean(),\n metadata: z.record(z.string(), z.any()).nullable().optional(),\n startsAt: z.string().nullable(),\n endsAt: z.string().nullable(),\n organizationId: z.string().uuid().nullable(),\n tenantId: z.string().uuid().nullable(),\n createdAt: z.string(),\n updatedAt: z.string(),\n customFields: z.record(z.string(), z.any()).optional(),\n})\n\nconst taxRateListResponseSchema = z.object({\n items: z.array(taxRateResponseItemSchema),\n total: z.number(),\n page: z.number(),\n pageSize: z.number(),\n totalPages: z.number(),\n})\n\nconst taxRateDeleteSchema = z.object({\n id: z.string().uuid(),\n})\n\nfunction buildFilters(query: z.infer<typeof listSchema>): Record<string, unknown> {\n const filters: Record<string, unknown> = {}\n const searchFilter = buildAggregateSearchFilter(query.search)\n if (searchFilter) Object.assign(filters, searchFilter)\n if (query.country && query.country.trim().length > 0) {\n filters.country_code = query.country.trim().toUpperCase()\n }\n if (query.region && query.region.trim().length > 0) {\n filters.region_code = query.region.trim()\n }\n if (query.channelId) {\n filters.channel_id = query.channelId\n }\n const isCompound = parseBooleanToken(query.isCompound)\n if (isCompound !== null) filters.is_compound = isCompound\n return filters\n}\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: SalesTaxRate,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n list: {\n schema: listSchema,\n entityId: E.sales.sales_tax_rate,\n fields: [\n F.id,\n F.name,\n F.code,\n F.rate,\n F.country_code,\n F.region_code,\n F.postal_code,\n F.city,\n F.customer_group_id,\n F.product_category_id,\n F.channel_id,\n F.priority,\n F.is_compound,\n F.is_default,\n F.metadata,\n F.starts_at,\n F.ends_at,\n F.organization_id,\n F.tenant_id,\n F.created_at,\n F.updated_at,\n ],\n sortFieldMap: {\n id: F.id,\n name: F.name,\n code: F.code,\n rate: F.rate,\n priority: F.priority,\n createdAt: F.created_at,\n updatedAt: F.updated_at,\n },\n buildFilters: async (query) => buildFilters(query),\n decorateCustomFields: { entityIds: [E.sales.sales_tax_rate] },\n transformItem: (item: any) => {\n const base = {\n id: item.id,\n name: item.name,\n code: item.code,\n rate: item.rate,\n countryCode: item.country_code ?? null,\n regionCode: item.region_code ?? null,\n postalCode: item.postal_code ?? null,\n city: item.city ?? null,\n customerGroupId: item.customer_group_id ?? null,\n productCategoryId: item.product_category_id ?? null,\n channelId: item.channel_id ?? null,\n priority: item.priority ?? 0,\n isCompound: item.is_compound ?? false,\n isDefault: item.is_default ?? false,\n metadata: item.metadata ?? null,\n startsAt: item.starts_at ?? null,\n endsAt: item.ends_at ?? null,\n organizationId: item.organization_id ?? null,\n tenantId: item.tenant_id ?? null,\n createdAt: item.created_at,\n updatedAt: item.updated_at,\n }\n const { custom } = splitCustomFieldPayload(item)\n return Object.keys(custom).length ? { ...base, customFields: custom } : base\n },\n },\n actions: {\n create: {\n commandId: 'sales.tax-rates.create',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n return parseScopedCommandInput(taxRateCreateSchema, raw ?? {}, ctx, translate)\n },\n response: ({ result }) => ({ id: result?.taxRateId ?? result?.id ?? null }),\n status: 201,\n },\n update: {\n commandId: 'sales.tax-rates.update',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n return parseScopedCommandInput(taxRateUpdateSchema, raw ?? {}, ctx, translate)\n },\n response: () => ({ ok: true }),\n },\n delete: {\n commandId: 'sales.tax-rates.delete',\n schema: rawBodySchema,\n mapInput: async ({ parsed, ctx }) => {\n const { translate } = await resolveTranslations()\n const id = resolveCrudRecordId(parsed, ctx, translate)\n return { id }\n },\n response: () => ({ ok: true }),\n },\n },\n})\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Sales',\n summary: 'Manage tax rates',\n methods: {\n GET: {\n summary: 'List tax rates',\n description: 'Returns a paginated list of sales tax rates for the current organization.',\n query: listSchema,\n responses: [{ status: 200, description: 'Paginated list of tax rates', schema: taxRateListResponseSchema }],\n },\n POST: {\n summary: 'Create tax rate',\n description: 'Creates a new tax rate record.',\n requestBody: {\n schema: taxRateCreateSchema,\n description: 'Payload describing the tax rate to create.',\n },\n responses: [\n {\n status: 201,\n description: 'Identifier of the created tax rate',\n schema: z.object({ id: z.string().uuid().nullable() }),\n },\n ],\n },\n PUT: {\n summary: 'Update tax rate',\n description: 'Updates an existing tax rate by identifier.',\n requestBody: {\n schema: taxRateUpdateSchema,\n description: 'Fields to update on the target tax rate.',\n },\n responses: [{ status: 200, description: 'Update acknowledgement', schema: z.object({ ok: z.boolean() }) }],\n },\n DELETE: {\n summary: 'Delete tax rate',\n description: 'Deletes a tax rate identified by `id`.',\n requestBody: {\n schema: taxRateDeleteSchema,\n description: 'Identifier payload for the tax rate to delete.',\n },\n responses: [{ status: 200, description: 'Deletion acknowledgement', schema: z.object({ ok: z.boolean() }) }],\n },\n },\n}\n\nexport const GET = crud.GET\nexport const POST = crud.POST\nexport const PUT = crud.PUT\nexport const DELETE = crud.DELETE\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from 'zod'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { splitCustomFieldPayload } from '@open-mercato/shared/lib/crud/custom-fields'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { SalesTaxRate } from '../../data/entities'\nimport { taxRateCreateSchema, taxRateUpdateSchema } from '../../data/validators'\nimport { buildAggregateSearchFilter, parseScopedCommandInput, resolveCrudRecordId } from '../utils'\nimport { E } from '#generated/entities.ids.generated'\nimport * as F from '#generated/entities/sales_tax_rate'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst listSchema = z\n .object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(200).default(50),\n search: z.string().optional(),\n country: z.string().optional(),\n region: z.string().optional(),\n channelId: z.string().uuid().optional(),\n isCompound: z.string().optional(),\n sortField: z.string().optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n withDeleted: z.coerce.boolean().optional(),\n })\n .passthrough()\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n POST: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['sales.settings.manage'] },\n}\n\nexport const metadata = routeMetadata\n\nconst taxRateResponseItemSchema = z.object({\n id: z.string().uuid(),\n name: z.string(),\n code: z.string().nullable(),\n rate: z.number(),\n countryCode: z.string().nullable(),\n regionCode: z.string().nullable(),\n postalCode: z.string().nullable(),\n city: z.string().nullable(),\n customerGroupId: z.string().uuid().nullable(),\n productCategoryId: z.string().uuid().nullable(),\n channelId: z.string().uuid().nullable(),\n priority: z.number().nullable(),\n isCompound: z.boolean(),\n isDefault: z.boolean(),\n metadata: z.record(z.string(), z.any()).nullable().optional(),\n startsAt: z.string().nullable(),\n endsAt: z.string().nullable(),\n organizationId: z.string().uuid().nullable(),\n tenantId: z.string().uuid().nullable(),\n createdAt: z.string(),\n updatedAt: z.string(),\n customFields: z.record(z.string(), z.any()).optional(),\n})\n\nconst taxRateListResponseSchema = z.object({\n items: z.array(taxRateResponseItemSchema),\n total: z.number(),\n page: z.number(),\n pageSize: z.number(),\n totalPages: z.number(),\n})\n\nconst taxRateDeleteSchema = z.object({\n id: z.string().uuid(),\n})\n\nfunction buildFilters(query: z.infer<typeof listSchema>): Record<string, unknown> {\n const filters: Record<string, unknown> = {}\n const searchFilter = buildAggregateSearchFilter(query.search)\n if (searchFilter) Object.assign(filters, searchFilter)\n if (query.country && query.country.trim().length > 0) {\n filters.country_code = query.country.trim().toUpperCase()\n }\n if (query.region && query.region.trim().length > 0) {\n filters.region_code = query.region.trim()\n }\n if (query.channelId) {\n filters.channel_id = query.channelId\n }\n const isCompound = parseBooleanToken(query.isCompound)\n if (isCompound !== null) filters.is_compound = isCompound\n return filters\n}\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: SalesTaxRate,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n indexer: { entityType: E.sales.sales_tax_rate },\n list: {\n schema: listSchema,\n entityId: E.sales.sales_tax_rate,\n fields: [\n F.id,\n F.name,\n F.code,\n F.rate,\n F.country_code,\n F.region_code,\n F.postal_code,\n F.city,\n F.customer_group_id,\n F.product_category_id,\n F.channel_id,\n F.priority,\n F.is_compound,\n F.is_default,\n F.metadata,\n F.starts_at,\n F.ends_at,\n F.organization_id,\n F.tenant_id,\n F.created_at,\n F.updated_at,\n ],\n sortFieldMap: {\n id: F.id,\n name: F.name,\n code: F.code,\n rate: F.rate,\n priority: F.priority,\n createdAt: F.created_at,\n updatedAt: F.updated_at,\n },\n buildFilters: async (query) => buildFilters(query),\n decorateCustomFields: { entityIds: [E.sales.sales_tax_rate] },\n transformItem: (item: any) => {\n const base = {\n id: item.id,\n name: item.name,\n code: item.code,\n rate: item.rate,\n countryCode: item.country_code ?? null,\n regionCode: item.region_code ?? null,\n postalCode: item.postal_code ?? null,\n city: item.city ?? null,\n customerGroupId: item.customer_group_id ?? null,\n productCategoryId: item.product_category_id ?? null,\n channelId: item.channel_id ?? null,\n priority: item.priority ?? 0,\n isCompound: item.is_compound ?? false,\n isDefault: item.is_default ?? false,\n metadata: item.metadata ?? null,\n startsAt: item.starts_at ?? null,\n endsAt: item.ends_at ?? null,\n organizationId: item.organization_id ?? null,\n tenantId: item.tenant_id ?? null,\n createdAt: item.created_at,\n updatedAt: item.updated_at,\n }\n const { custom } = splitCustomFieldPayload(item)\n return Object.keys(custom).length ? { ...base, customFields: custom } : base\n },\n },\n actions: {\n create: {\n commandId: 'sales.tax-rates.create',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n return parseScopedCommandInput(taxRateCreateSchema, raw ?? {}, ctx, translate)\n },\n response: ({ result }) => ({ id: result?.taxRateId ?? result?.id ?? null }),\n status: 201,\n },\n update: {\n commandId: 'sales.tax-rates.update',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n return parseScopedCommandInput(taxRateUpdateSchema, raw ?? {}, ctx, translate)\n },\n response: () => ({ ok: true }),\n },\n delete: {\n commandId: 'sales.tax-rates.delete',\n schema: rawBodySchema,\n mapInput: async ({ parsed, ctx }) => {\n const { translate } = await resolveTranslations()\n const id = resolveCrudRecordId(parsed, ctx, translate)\n return { id }\n },\n response: () => ({ ok: true }),\n },\n },\n})\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Sales',\n summary: 'Manage tax rates',\n methods: {\n GET: {\n summary: 'List tax rates',\n description: 'Returns a paginated list of sales tax rates for the current organization.',\n query: listSchema,\n responses: [{ status: 200, description: 'Paginated list of tax rates', schema: taxRateListResponseSchema }],\n },\n POST: {\n summary: 'Create tax rate',\n description: 'Creates a new tax rate record.',\n requestBody: {\n schema: taxRateCreateSchema,\n description: 'Payload describing the tax rate to create.',\n },\n responses: [\n {\n status: 201,\n description: 'Identifier of the created tax rate',\n schema: z.object({ id: z.string().uuid().nullable() }),\n },\n ],\n },\n PUT: {\n summary: 'Update tax rate',\n description: 'Updates an existing tax rate by identifier.',\n requestBody: {\n schema: taxRateUpdateSchema,\n description: 'Fields to update on the target tax rate.',\n },\n responses: [{ status: 200, description: 'Update acknowledgement', schema: z.object({ ok: z.boolean() }) }],\n },\n DELETE: {\n summary: 'Delete tax rate',\n description: 'Deletes a tax rate identified by `id`.',\n requestBody: {\n schema: taxRateDeleteSchema,\n description: 'Identifier payload for the tax rate to delete.',\n },\n responses: [{ status: 200, description: 'Deletion acknowledgement', schema: z.object({ ok: z.boolean() }) }],\n },\n },\n}\n\nexport const GET = crud.GET\nexport const POST = crud.POST\nexport const PUT = crud.PUT\nexport const DELETE = crud.DELETE\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.6.3-develop.3771.1.1788990f9e",
3
+ "version": "0.6.3-develop.3797.1.9d6338d7cd",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -243,16 +243,16 @@
243
243
  "zod": "^4.4.3"
244
244
  },
245
245
  "peerDependencies": {
246
- "@open-mercato/ai-assistant": "0.6.3-develop.3771.1.1788990f9e",
247
- "@open-mercato/shared": "0.6.3-develop.3771.1.1788990f9e",
248
- "@open-mercato/ui": "0.6.3-develop.3771.1.1788990f9e",
246
+ "@open-mercato/ai-assistant": "0.6.3-develop.3797.1.9d6338d7cd",
247
+ "@open-mercato/shared": "0.6.3-develop.3797.1.9d6338d7cd",
248
+ "@open-mercato/ui": "0.6.3-develop.3797.1.9d6338d7cd",
249
249
  "react": "^19.0.0",
250
250
  "react-dom": "^19.0.0"
251
251
  },
252
252
  "devDependencies": {
253
- "@open-mercato/ai-assistant": "0.6.3-develop.3771.1.1788990f9e",
254
- "@open-mercato/shared": "0.6.3-develop.3771.1.1788990f9e",
255
- "@open-mercato/ui": "0.6.3-develop.3771.1.1788990f9e",
253
+ "@open-mercato/ai-assistant": "0.6.3-develop.3797.1.9d6338d7cd",
254
+ "@open-mercato/shared": "0.6.3-develop.3797.1.9d6338d7cd",
255
+ "@open-mercato/ui": "0.6.3-develop.3797.1.9d6338d7cd",
256
256
  "@testing-library/dom": "^10.4.1",
257
257
  "@testing-library/jest-dom": "^6.9.1",
258
258
  "@testing-library/react": "^16.3.1",
@@ -330,6 +330,7 @@ const crud = makeCrudRoute({
330
330
  tenantField: 'tenantId',
331
331
  softDeleteField: 'deletedAt',
332
332
  },
333
+ indexer: { entityType: E.catalog.catalog_offer },
333
334
  list: {
334
335
  schema: listSchema,
335
336
  entityId: E.catalog.catalog_offer,
@@ -89,6 +89,7 @@ const crud = makeCrudRoute({
89
89
  tenantField: 'tenantId',
90
90
  softDeleteField: 'deletedAt',
91
91
  },
92
+ indexer: { entityType: E.catalog.catalog_option_schema_template },
92
93
  list: {
93
94
  schema: listSchema,
94
95
  entityId: E.catalog.catalog_option_schema_template,
@@ -47,6 +47,7 @@ const crud = makeCrudRoute({
47
47
  tenantField: 'tenantId',
48
48
  softDeleteField: 'deletedAt',
49
49
  },
50
+ indexer: { entityType: E.catalog.catalog_price_kind },
50
51
  list: {
51
52
  schema: listSchema,
52
53
  entityId: E.catalog.catalog_price_kind,
@@ -103,6 +103,7 @@ const crud = makeCrudRoute({
103
103
  tenantField: 'tenantId',
104
104
  softDeleteField: 'deletedAt',
105
105
  },
106
+ indexer: { entityType: E.catalog.catalog_product_variant },
106
107
  list: {
107
108
  schema: listSchema,
108
109
  entityId: E.catalog.catalog_product_variant,
@@ -11,6 +11,10 @@ import { adminCreateUserSchema } from '@open-mercato/core/modules/customer_accou
11
11
  import { emitCustomerAccountsEvent } from '@open-mercato/core/modules/customer_accounts/events'
12
12
  import { findAndCountWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
13
13
  import { hashForLookup } from '@open-mercato/shared/lib/encryption/aes'
14
+ import { E } from '#generated/entities.ids.generated'
15
+ import { resolveSearchConfig } from '@open-mercato/shared/lib/search/config'
16
+ import { tokenizeText } from '@open-mercato/shared/lib/search/tokenize'
17
+ import { sql } from 'kysely'
14
18
 
15
19
  const EMAIL_LIKE_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
16
20
 
@@ -64,23 +68,39 @@ export async function GET(req: Request) {
64
68
  }
65
69
 
66
70
  if (search) {
67
- const escapedSearch = search.replace(/[%_\\]/g, '\\$&')
71
+ const trimmedSearch = search.trim()
68
72
  // email/displayName are stored encrypted, so SQL ILIKE on the ciphertext
69
- // never matches a plaintext search term. Match the deterministic emailHash
70
- // (used by CustomerUser as a blind index) when the query looks like an
71
- // email so administrators can still look users up by exact address.
72
- const searchFilter: Record<string, unknown>[] = [
73
- { email: { $ilike: `%${escapedSearch}%` } },
74
- { displayName: { $ilike: `%${escapedSearch}%` } },
75
- ]
73
+ // never matches a plaintext search term. Use search_tokens table for partial
74
+ // matches and emailHash for exact email lookups.
75
+ const searchFilter: Record<string, unknown>[] = []
76
+
77
+ // Search encrypted fields via search_tokens
78
+ const matchedIds = await findCustomerUserIdsBySearchTokens(em, E.customer_accounts.customer_user, trimmedSearch, auth.tenantId)
79
+ if (matchedIds && matchedIds.length > 0) {
80
+ searchFilter.push({ id: { $in: matchedIds } })
81
+ }
82
+
83
+ // Also support exact email lookup via emailHash
76
84
  if (EMAIL_LIKE_PATTERN.test(search)) {
77
85
  searchFilter.push({ emailHash: hashForLookup(search) })
78
86
  }
79
- if (where.$or) {
80
- where.$and = [{ $or: where.$or }, { $or: searchFilter }]
81
- delete where.$or
87
+
88
+ if (searchFilter.length > 0) {
89
+ if (where.$or) {
90
+ where.$and = [{ $or: where.$or }, { $or: searchFilter }]
91
+ delete where.$or
92
+ } else {
93
+ where.$or = searchFilter
94
+ }
82
95
  } else {
83
- where.$or = searchFilter
96
+ // No search results found, return empty
97
+ return NextResponse.json({
98
+ ok: true,
99
+ items: [],
100
+ total: 0,
101
+ totalPages: 1,
102
+ page,
103
+ })
84
104
  }
85
105
  }
86
106
 
@@ -270,6 +290,40 @@ const successSchema = z.object({
270
290
  })
271
291
  const errorSchema = z.object({ ok: z.literal(false), error: z.string() })
272
292
 
293
+ async function findCustomerUserIdsBySearchTokens(
294
+ em: EntityManager,
295
+ entityType: string,
296
+ search: string,
297
+ tenantScope: string | null | undefined,
298
+ field?: string,
299
+ ): Promise<string[] | null> {
300
+ const trimmed = search.trim()
301
+ if (!trimmed) return null
302
+ const searchConfig = resolveSearchConfig()
303
+ if (!searchConfig.enabled) return []
304
+ const { hashes } = tokenizeText(trimmed, searchConfig)
305
+ if (!hashes.length) return []
306
+
307
+ const db = (em as any).getKysely() as any
308
+ let query = db
309
+ .selectFrom('search_tokens')
310
+ .select('entity_id')
311
+ .where('entity_type', '=', entityType)
312
+ .where('token_hash', 'in', hashes)
313
+ .groupBy('entity_id')
314
+ .having(sql<boolean>`count(distinct token_hash) >= ${hashes.length}`)
315
+ if (field) {
316
+ query = query.where('field', '=', field)
317
+ }
318
+ if (tenantScope !== undefined) {
319
+ query = query.where(sql<boolean>`tenant_id is not distinct from ${tenantScope}`)
320
+ }
321
+ const rows = (await query.execute()) as Array<{ entity_id?: unknown }>
322
+ return rows
323
+ .map((row) => (typeof row.entity_id === 'string' ? row.entity_id : null))
324
+ .filter((id): id is string => typeof id === 'string' && id.length > 0)
325
+ }
326
+
273
327
  const getMethodDoc: OpenApiMethodDoc = {
274
328
  summary: 'List customer users (admin)',
275
329
  description: 'Returns a paginated list of customer users with roles. Supports filtering by status, company, role, and search.',
@@ -452,6 +452,7 @@ function buildDealAnalyzerPrepareStep() {
452
452
  return {
453
453
  activeTools: [
454
454
  'customers.analyze_deals',
455
+ 'customers.update_deal_stage',
455
456
  'customers.list_deals',
456
457
  'customers.get_deal',
457
458
  'customers.list_activities',
@@ -82,6 +82,7 @@ const crud = makeCrudRoute({
82
82
  softDeleteField: 'deletedAt',
83
83
  },
84
84
  enrichers: { entityId: 'customers.person' },
85
+ indexer: { entityType: E.customers.customer_entity },
85
86
  list: {
86
87
  schema: listSchema,
87
88
  entityId: E.customers.customer_entity,
@@ -43,6 +43,7 @@ const crud = makeCrudRoute({
43
43
  orgField: 'organizationId',
44
44
  tenantField: 'tenantId',
45
45
  },
46
+ indexer: { entityType: E.customers.customer_tag },
46
47
  list: {
47
48
  schema: listSchema,
48
49
  entityId: E.customers.customer_tag,
@@ -89,6 +89,7 @@ const crud = makeCrudRoute({
89
89
  tenantField: "tenantId",
90
90
  softDeleteField: 'deletedAt'
91
91
  },
92
+ indexer: { entityType: E.feature_toggles.feature_toggle },
92
93
  list: {
93
94
  schema: listQuerySchema,
94
95
  entityId: E.feature_toggles.feature_toggle,
@@ -116,6 +116,7 @@ const crud = makeCrudRoute({
116
116
  tenantField: 'tenantId',
117
117
  softDeleteField: null,
118
118
  },
119
+ indexer: { entityType: E.dictionaries.dictionary_entry },
119
120
  list: {
120
121
  schema: listSchema,
121
122
  entityId: E.dictionaries.dictionary_entry,
@@ -91,6 +91,7 @@ const crud = makeCrudRoute({
91
91
  tenantField: 'tenantId',
92
92
  softDeleteField: 'deletedAt',
93
93
  },
94
+ indexer: { entityType: E.sales.sales_channel },
94
95
  list: {
95
96
  schema: listSchema,
96
97
  entityId: E.sales.sales_channel,
@@ -74,6 +74,7 @@ const crud = makeCrudRoute({
74
74
  tenantField: 'tenantId',
75
75
  softDeleteField: 'deletedAt',
76
76
  },
77
+ indexer: { entityType: E.sales.sales_delivery_window },
77
78
  list: {
78
79
  schema: listSchema,
79
80
  entityId: E.sales.sales_delivery_window,
@@ -43,6 +43,7 @@ const crud = makeCrudRoute({
43
43
  tenantField: 'tenantId',
44
44
  softDeleteField: 'deletedAt',
45
45
  },
46
+ indexer: { entityType: E.sales.sales_document_address },
46
47
  list: {
47
48
  schema: listSchema,
48
49
  entityId: E.sales.sales_document_address,
@@ -74,6 +74,7 @@ const crud = makeCrudRoute({
74
74
  tenantField: 'tenantId',
75
75
  softDeleteField: 'deletedAt',
76
76
  },
77
+ indexer: { entityType: E.sales.sales_payment_method },
77
78
  list: {
78
79
  schema: listSchema,
79
80
  entityId: E.sales.sales_payment_method,
@@ -31,6 +31,7 @@ const crud = makeCrudRoute({
31
31
  tenantField: 'tenantId',
32
32
  softDeleteField: 'deletedAt',
33
33
  },
34
+ indexer: { entityType: E.catalog.catalog_price_kind },
34
35
  list: {
35
36
  schema: listSchema,
36
37
  entityId: E.catalog.catalog_price_kind,
@@ -51,6 +51,7 @@ const crud = makeCrudRoute({
51
51
  tenantField: 'tenantId',
52
52
  softDeleteField: 'deletedAt',
53
53
  },
54
+ indexer: { entityType: E.sales.sales_quote_adjustment },
54
55
  list: {
55
56
  schema: listSchema,
56
57
  entityId: E.sales.sales_quote_adjustment,
@@ -83,6 +83,7 @@ const crud = makeCrudRoute({
83
83
  tenantField: 'tenantId',
84
84
  softDeleteField: 'deletedAt',
85
85
  },
86
+ indexer: { entityType: E.sales.sales_shipping_method },
86
87
  list: {
87
88
  schema: listSchema,
88
89
  entityId: E.sales.sales_shipping_method,
@@ -100,6 +100,7 @@ const crud = makeCrudRoute({
100
100
  tenantField: 'tenantId',
101
101
  softDeleteField: 'deletedAt',
102
102
  },
103
+ indexer: { entityType: E.sales.sales_tax_rate },
103
104
  list: {
104
105
  schema: listSchema,
105
106
  entityId: E.sales.sales_tax_rate,