@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.
- package/dist/modules/catalog/api/offers/route.js +1 -0
- package/dist/modules/catalog/api/offers/route.js.map +2 -2
- package/dist/modules/catalog/api/option-schemas/route.js +1 -0
- package/dist/modules/catalog/api/option-schemas/route.js.map +2 -2
- package/dist/modules/catalog/api/price-kinds/route.js +1 -0
- package/dist/modules/catalog/api/price-kinds/route.js.map +2 -2
- package/dist/modules/catalog/api/variants/route.js +1 -0
- package/dist/modules/catalog/api/variants/route.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users.js +42 -9
- package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
- package/dist/modules/customers/ai-agents.js +1 -0
- package/dist/modules/customers/ai-agents.js.map +2 -2
- package/dist/modules/customers/api/people/route.js +1 -0
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/api/tags/route.js +1 -0
- package/dist/modules/customers/api/tags/route.js.map +2 -2
- package/dist/modules/feature_toggles/api/global/route.js +1 -0
- package/dist/modules/feature_toggles/api/global/route.js.map +2 -2
- package/dist/modules/sales/api/adjustment-kinds/route.js +1 -0
- package/dist/modules/sales/api/adjustment-kinds/route.js.map +2 -2
- package/dist/modules/sales/api/channels/route.js +1 -0
- package/dist/modules/sales/api/channels/route.js.map +2 -2
- package/dist/modules/sales/api/delivery-windows/route.js +1 -0
- package/dist/modules/sales/api/delivery-windows/route.js.map +2 -2
- package/dist/modules/sales/api/document-addresses/route.js +1 -0
- package/dist/modules/sales/api/document-addresses/route.js.map +2 -2
- package/dist/modules/sales/api/payment-methods/route.js +1 -0
- package/dist/modules/sales/api/payment-methods/route.js.map +2 -2
- package/dist/modules/sales/api/price-kinds/route.js +1 -0
- package/dist/modules/sales/api/price-kinds/route.js.map +2 -2
- package/dist/modules/sales/api/quote-adjustments/route.js +1 -0
- package/dist/modules/sales/api/quote-adjustments/route.js.map +2 -2
- package/dist/modules/sales/api/shipping-methods/route.js +1 -0
- package/dist/modules/sales/api/shipping-methods/route.js.map +2 -2
- package/dist/modules/sales/api/tax-rates/route.js +1 -0
- package/dist/modules/sales/api/tax-rates/route.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/catalog/api/offers/route.ts +1 -0
- package/src/modules/catalog/api/option-schemas/route.ts +1 -0
- package/src/modules/catalog/api/price-kinds/route.ts +1 -0
- package/src/modules/catalog/api/variants/route.ts +1 -0
- package/src/modules/customer_accounts/api/admin/users.ts +66 -12
- package/src/modules/customers/ai-agents.ts +1 -0
- package/src/modules/customers/api/people/route.ts +1 -0
- package/src/modules/customers/api/tags/route.ts +1 -0
- package/src/modules/feature_toggles/api/global/route.ts +1 -0
- package/src/modules/sales/api/adjustment-kinds/route.ts +1 -0
- package/src/modules/sales/api/channels/route.ts +1 -0
- package/src/modules/sales/api/delivery-windows/route.ts +1 -0
- package/src/modules/sales/api/document-addresses/route.ts +1 -0
- package/src/modules/sales/api/payment-methods/route.ts +1 -0
- package/src/modules/sales/api/price-kinds/route.ts +1 -0
- package/src/modules/sales/api/quote-adjustments/route.ts +1 -0
- package/src/modules/sales/api/shipping-methods/route.ts +1 -0
- 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.
|
|
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.
|
|
247
|
-
"@open-mercato/shared": "0.6.3-develop.
|
|
248
|
-
"@open-mercato/ui": "0.6.3-develop.
|
|
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.
|
|
254
|
-
"@open-mercato/shared": "0.6.3-develop.
|
|
255
|
-
"@open-mercato/ui": "0.6.3-develop.
|
|
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",
|
|
@@ -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
|
|
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.
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
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.',
|