@open-mercato/core 0.8.1-develop.7266.1.8e520bbe03 → 0.8.1-develop.7268.1.033c0546d5

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 (128) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities.ids.generated.js +0 -4
  3. package/dist/generated/entities.ids.generated.js.map +2 -2
  4. package/dist/generated/entity-fields-registry.js +0 -21
  5. package/dist/generated/entity-fields-registry.js.map +2 -2
  6. package/dist/modules/customers/backend/customers/companies/create/page.js +5 -0
  7. package/dist/modules/customers/backend/customers/companies/create/page.js.map +2 -2
  8. package/dist/modules/wms/di.js +0 -3
  9. package/dist/modules/wms/di.js.map +2 -2
  10. package/generated/entities.ids.generated.ts +0 -4
  11. package/generated/entity-fields-registry.ts +0 -21
  12. package/package.json +7 -7
  13. package/src/modules/auth/i18n/de.json +0 -3
  14. package/src/modules/auth/i18n/en.json +0 -3
  15. package/src/modules/auth/i18n/es.json +0 -3
  16. package/src/modules/auth/i18n/ko.json +0 -3
  17. package/src/modules/auth/i18n/pl.json +0 -3
  18. package/src/modules/customer_accounts/AGENTS.md +1 -1
  19. package/src/modules/customers/backend/customers/companies/create/page.tsx +6 -0
  20. package/src/modules/wms/di.ts +0 -6
  21. package/dist/generated/entities/availability_policy/index.js +0 -41
  22. package/dist/generated/entities/availability_policy/index.js.map +0 -7
  23. package/dist/modules/availability/acl.js +0 -16
  24. package/dist/modules/availability/acl.js.map +0 -7
  25. package/dist/modules/availability/api/check/route.js +0 -95
  26. package/dist/modules/availability/api/check/route.js.map +0 -7
  27. package/dist/modules/availability/api/openapi.js +0 -27
  28. package/dist/modules/availability/api/openapi.js.map +0 -7
  29. package/dist/modules/availability/api/policies/resolve-preview/route.js +0 -58
  30. package/dist/modules/availability/api/policies/resolve-preview/route.js.map +0 -7
  31. package/dist/modules/availability/api/policies/route.js +0 -188
  32. package/dist/modules/availability/api/policies/route.js.map +0 -7
  33. package/dist/modules/availability/backend/availability/check/page.js +0 -185
  34. package/dist/modules/availability/backend/availability/check/page.js.map +0 -7
  35. package/dist/modules/availability/backend/availability/check/page.meta.js +0 -16
  36. package/dist/modules/availability/backend/availability/check/page.meta.js.map +0 -7
  37. package/dist/modules/availability/backend/availability/policies/ResolutionPreviewPanel.js +0 -79
  38. package/dist/modules/availability/backend/availability/policies/ResolutionPreviewPanel.js.map +0 -7
  39. package/dist/modules/availability/backend/availability/policies/ScopeFields.js +0 -53
  40. package/dist/modules/availability/backend/availability/policies/ScopeFields.js.map +0 -7
  41. package/dist/modules/availability/backend/availability/policies/[id]/page.js +0 -152
  42. package/dist/modules/availability/backend/availability/policies/[id]/page.js.map +0 -7
  43. package/dist/modules/availability/backend/availability/policies/[id]/page.meta.js +0 -12
  44. package/dist/modules/availability/backend/availability/policies/[id]/page.meta.js.map +0 -7
  45. package/dist/modules/availability/backend/availability/policies/create/page.js +0 -94
  46. package/dist/modules/availability/backend/availability/policies/create/page.js.map +0 -7
  47. package/dist/modules/availability/backend/availability/policies/create/page.meta.js +0 -12
  48. package/dist/modules/availability/backend/availability/policies/create/page.meta.js.map +0 -7
  49. package/dist/modules/availability/backend/availability/policies/formGroups.js +0 -75
  50. package/dist/modules/availability/backend/availability/policies/formGroups.js.map +0 -7
  51. package/dist/modules/availability/backend/availability/policies/page.js +0 -176
  52. package/dist/modules/availability/backend/availability/policies/page.js.map +0 -7
  53. package/dist/modules/availability/backend/availability/policies/page.meta.js +0 -16
  54. package/dist/modules/availability/backend/availability/policies/page.meta.js.map +0 -7
  55. package/dist/modules/availability/commands/policies.js +0 -312
  56. package/dist/modules/availability/commands/policies.js.map +0 -7
  57. package/dist/modules/availability/commands/scope.js +0 -19
  58. package/dist/modules/availability/commands/scope.js.map +0 -7
  59. package/dist/modules/availability/data/entities.js +0 -95
  60. package/dist/modules/availability/data/entities.js.map +0 -7
  61. package/dist/modules/availability/data/validators.js +0 -53
  62. package/dist/modules/availability/data/validators.js.map +0 -7
  63. package/dist/modules/availability/di.js +0 -41
  64. package/dist/modules/availability/di.js.map +0 -7
  65. package/dist/modules/availability/events.js +0 -18
  66. package/dist/modules/availability/events.js.map +0 -7
  67. package/dist/modules/availability/index.js +0 -15
  68. package/dist/modules/availability/index.js.map +0 -7
  69. package/dist/modules/availability/lib/policyResolution.js +0 -155
  70. package/dist/modules/availability/lib/policyResolution.js.map +0 -7
  71. package/dist/modules/availability/lib/tryResolve.js +0 -11
  72. package/dist/modules/availability/lib/tryResolve.js.map +0 -7
  73. package/dist/modules/availability/migrations/Migration20260922095844_availability.js +0 -16
  74. package/dist/modules/availability/migrations/Migration20260922095844_availability.js.map +0 -7
  75. package/dist/modules/availability/setup.js +0 -12
  76. package/dist/modules/availability/setup.js.map +0 -7
  77. package/dist/modules/wms/lib/availabilityCache.js +0 -85
  78. package/dist/modules/wms/lib/availabilityCache.js.map +0 -7
  79. package/dist/modules/wms/lib/availabilityCalculation.js +0 -178
  80. package/dist/modules/wms/lib/availabilityCalculation.js.map +0 -7
  81. package/dist/modules/wms/lib/availabilityProvider.js +0 -14
  82. package/dist/modules/wms/lib/availabilityProvider.js.map +0 -7
  83. package/dist/modules/wms/lib/sqlInClause.js +0 -9
  84. package/dist/modules/wms/lib/sqlInClause.js.map +0 -7
  85. package/dist/modules/wms/lib/tryResolve.js +0 -11
  86. package/dist/modules/wms/lib/tryResolve.js.map +0 -7
  87. package/dist/modules/wms/subscribers/invalidate-availability-cache.js +0 -16
  88. package/dist/modules/wms/subscribers/invalidate-availability-cache.js.map +0 -7
  89. package/generated/entities/availability_policy/index.ts +0 -19
  90. package/src/modules/availability/acl.ts +0 -12
  91. package/src/modules/availability/api/check/route.ts +0 -114
  92. package/src/modules/availability/api/openapi.ts +0 -28
  93. package/src/modules/availability/api/policies/resolve-preview/route.ts +0 -67
  94. package/src/modules/availability/api/policies/route.ts +0 -224
  95. package/src/modules/availability/backend/availability/check/page.meta.ts +0 -12
  96. package/src/modules/availability/backend/availability/check/page.tsx +0 -223
  97. package/src/modules/availability/backend/availability/policies/ResolutionPreviewPanel.tsx +0 -106
  98. package/src/modules/availability/backend/availability/policies/ScopeFields.tsx +0 -55
  99. package/src/modules/availability/backend/availability/policies/[id]/page.meta.ts +0 -8
  100. package/src/modules/availability/backend/availability/policies/[id]/page.tsx +0 -182
  101. package/src/modules/availability/backend/availability/policies/create/page.meta.ts +0 -8
  102. package/src/modules/availability/backend/availability/policies/create/page.tsx +0 -105
  103. package/src/modules/availability/backend/availability/policies/formGroups.ts +0 -77
  104. package/src/modules/availability/backend/availability/policies/page.meta.ts +0 -12
  105. package/src/modules/availability/backend/availability/policies/page.tsx +0 -196
  106. package/src/modules/availability/commands/policies.ts +0 -358
  107. package/src/modules/availability/commands/scope.ts +0 -26
  108. package/src/modules/availability/data/entities.ts +0 -92
  109. package/src/modules/availability/data/validators.ts +0 -70
  110. package/src/modules/availability/di.ts +0 -54
  111. package/src/modules/availability/events.ts +0 -17
  112. package/src/modules/availability/i18n/de.json +0 -81
  113. package/src/modules/availability/i18n/en.json +0 -81
  114. package/src/modules/availability/i18n/es.json +0 -81
  115. package/src/modules/availability/i18n/ko.json +0 -81
  116. package/src/modules/availability/i18n/pl.json +0 -81
  117. package/src/modules/availability/index.ts +0 -13
  118. package/src/modules/availability/lib/policyResolution.ts +0 -264
  119. package/src/modules/availability/lib/tryResolve.ts +0 -8
  120. package/src/modules/availability/migrations/.snapshot-open-mercato.json +0 -375
  121. package/src/modules/availability/migrations/Migration20260922095844_availability.ts +0 -13
  122. package/src/modules/availability/setup.ts +0 -10
  123. package/src/modules/wms/lib/availabilityCache.ts +0 -136
  124. package/src/modules/wms/lib/availabilityCalculation.ts +0 -289
  125. package/src/modules/wms/lib/availabilityProvider.ts +0 -29
  126. package/src/modules/wms/lib/sqlInClause.ts +0 -21
  127. package/src/modules/wms/lib/tryResolve.ts +0 -8
  128. package/src/modules/wms/subscribers/invalidate-availability-cache.ts +0 -30
@@ -10,12 +10,15 @@ import { E } from "../../../../../../generated/entities.ids.generated.js";
10
10
  import { flash } from "@open-mercato/ui/backend/FlashMessages";
11
11
  import { useT } from "@open-mercato/shared/lib/i18n/context";
12
12
  import { useOrganizationScopeDetail } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
13
+ import { crudFormExtensionSpotId } from "@open-mercato/shared/modules/widgets/extension-points";
14
+ import { extensionPoints } from "@open-mercato/core/modules/customers/extension-points";
13
15
  import {
14
16
  buildCompanyPayload,
15
17
  createCompanyFormFields,
16
18
  createCompanyFormGroups,
17
19
  createCompanyFormSchema
18
20
  } from "../../../../components/formConfig.js";
21
+ const COMPANY_CREATE_LEGACY_INJECTION_SPOT_ID = crudFormExtensionSpotId("customers.customer_entity");
19
22
  function CreateCompanyPage() {
20
23
  const t = useT();
21
24
  const router = useRouter();
@@ -34,6 +37,8 @@ function CreateCompanyPage() {
34
37
  fields,
35
38
  groups,
36
39
  initialValues: { addresses: [] },
40
+ injectionSpotId: extensionPoints.hosts.companyForm.spotId,
41
+ legacyInjectionSpotId: COMPANY_CREATE_LEGACY_INJECTION_SPOT_ID,
37
42
  entityIds: [E.customers.customer_entity, E.customers.customer_company_profile],
38
43
  submitLabel: t("customers.companies.form.submit"),
39
44
  cancelHref: returnTo ?? "/backend/customers/companies",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/customers/backend/customers/companies/create/page.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { createCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { E } from '#generated/entities.ids.generated'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport {\n buildCompanyPayload,\n createCompanyFormFields,\n createCompanyFormGroups,\n createCompanyFormSchema,\n type CompanyFormValues,\n} from '../../../../components/formConfig'\n\nexport default function CreateCompanyPage() {\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const { organizationId } = useOrganizationScopeDetail()\n\n const formSchema = React.useMemo(() => createCompanyFormSchema(), [])\n const fields = React.useMemo(() => createCompanyFormFields(t), [t])\n const groups = React.useMemo(() => createCompanyFormGroups(t), [t])\n const returnTo = searchParams.get('returnTo')\n\n return (\n <Page>\n <PageBody>\n <CrudForm<CompanyFormValues>\n title={t('customers.companies.create.title')}\n titleHeadingLevel={1}\n backHref={returnTo ?? '/backend/customers/companies'}\n fields={fields}\n groups={groups}\n initialValues={{ addresses: [] as CompanyFormValues['addresses'] }}\n entityIds={[E.customers.customer_entity, E.customers.customer_company_profile]}\n submitLabel={t('customers.companies.form.submit')}\n cancelHref={returnTo ?? '/backend/customers/companies'}\n schema={formSchema}\n onSubmit={async (values) => {\n const addresses = Array.isArray(values.addresses) ? values.addresses : []\n let payload: Record<string, unknown>\n try {\n payload = buildCompanyPayload(values, organizationId)\n } catch (err) {\n if (err instanceof Error) {\n if (err.message === 'DISPLAY_NAME_REQUIRED') {\n const message = t('customers.companies.form.displayName.error')\n throw createCrudFormError(message, { displayName: message })\n }\n if (err.message === 'ANNUAL_REVENUE_INVALID') {\n const message = t('customers.companies.form.annualRevenue.error')\n throw createCrudFormError(message, { annualRevenue: message })\n }\n }\n throw err\n }\n\n const { result: created } = await createCrud<{ id?: string; entityId?: string }>(\n 'customers/companies',\n payload,\n )\n const newId =\n created && typeof created.id === 'string'\n ? created.id\n : (typeof created?.entityId === 'string' ? created.entityId : null)\n\n if (newId && addresses.length) {\n const normalize = (value?: string | null) => {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n return trimmed.length ? trimmed : undefined\n }\n for (const entry of addresses) {\n const normalizedLine1 = normalize(entry.addressLine1)\n if (!normalizedLine1) continue\n const body: Record<string, unknown> = {\n entityId: newId,\n ...(organizationId ? { organizationId } : {}),\n addressLine1: normalizedLine1,\n isPrimary: entry.isPrimary ?? false,\n }\n const name = normalize(entry.name)\n if (name !== undefined) body.name = name\n const purpose = normalize(entry.purpose)\n if (purpose !== undefined) body.purpose = purpose\n const line2 = normalize(entry.addressLine2)\n if (line2 !== undefined) body.addressLine2 = line2\n const buildingNumber = normalize(entry.buildingNumber)\n if (buildingNumber !== undefined) body.buildingNumber = buildingNumber\n const flatNumber = normalize(entry.flatNumber)\n if (flatNumber !== undefined) body.flatNumber = flatNumber\n const city = normalize(entry.city)\n if (city !== undefined) body.city = city\n const region = normalize(entry.region)\n if (region !== undefined) body.region = region\n const postalCode = normalize(entry.postalCode)\n if (postalCode !== undefined) body.postalCode = postalCode\n const country = normalize(entry.country)\n if (country !== undefined) body.country = country.toUpperCase()\n if (typeof entry.latitude === 'number') body.latitude = entry.latitude\n if (typeof entry.longitude === 'number') body.longitude = entry.longitude\n try {\n await createCrud('customers/addresses', body)\n } catch (addressErr) {\n const message =\n addressErr instanceof Error && addressErr.message\n ? addressErr.message\n : t('customers.companies.detail.addresses.error')\n flash(message, 'error')\n }\n }\n }\n\n flash(t('customers.companies.form.success'), 'success')\n if (returnTo) router.push(returnTo)\n else if (newId) router.push(`/backend/customers/companies-v2/${newId}`)\n else router.push('/backend/customers/companies')\n }}\n />\n </PageBody>\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { createCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { E } from '#generated/entities.ids.generated'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { crudFormExtensionSpotId } from '@open-mercato/shared/modules/widgets/extension-points'\nimport { extensionPoints } from '@open-mercato/core/modules/customers/extension-points'\nimport {\n buildCompanyPayload,\n createCompanyFormFields,\n createCompanyFormGroups,\n createCompanyFormSchema,\n type CompanyFormValues,\n} from '../../../../components/formConfig'\n\nconst COMPANY_CREATE_LEGACY_INJECTION_SPOT_ID = crudFormExtensionSpotId('customers.customer_entity')\n\nexport default function CreateCompanyPage() {\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const { organizationId } = useOrganizationScopeDetail()\n\n const formSchema = React.useMemo(() => createCompanyFormSchema(), [])\n const fields = React.useMemo(() => createCompanyFormFields(t), [t])\n const groups = React.useMemo(() => createCompanyFormGroups(t), [t])\n const returnTo = searchParams.get('returnTo')\n\n return (\n <Page>\n <PageBody>\n <CrudForm<CompanyFormValues>\n title={t('customers.companies.create.title')}\n titleHeadingLevel={1}\n backHref={returnTo ?? '/backend/customers/companies'}\n fields={fields}\n groups={groups}\n initialValues={{ addresses: [] as CompanyFormValues['addresses'] }}\n injectionSpotId={extensionPoints.hosts.companyForm.spotId}\n legacyInjectionSpotId={COMPANY_CREATE_LEGACY_INJECTION_SPOT_ID}\n entityIds={[E.customers.customer_entity, E.customers.customer_company_profile]}\n submitLabel={t('customers.companies.form.submit')}\n cancelHref={returnTo ?? '/backend/customers/companies'}\n schema={formSchema}\n onSubmit={async (values) => {\n const addresses = Array.isArray(values.addresses) ? values.addresses : []\n let payload: Record<string, unknown>\n try {\n payload = buildCompanyPayload(values, organizationId)\n } catch (err) {\n if (err instanceof Error) {\n if (err.message === 'DISPLAY_NAME_REQUIRED') {\n const message = t('customers.companies.form.displayName.error')\n throw createCrudFormError(message, { displayName: message })\n }\n if (err.message === 'ANNUAL_REVENUE_INVALID') {\n const message = t('customers.companies.form.annualRevenue.error')\n throw createCrudFormError(message, { annualRevenue: message })\n }\n }\n throw err\n }\n\n const { result: created } = await createCrud<{ id?: string; entityId?: string }>(\n 'customers/companies',\n payload,\n )\n const newId =\n created && typeof created.id === 'string'\n ? created.id\n : (typeof created?.entityId === 'string' ? created.entityId : null)\n\n if (newId && addresses.length) {\n const normalize = (value?: string | null) => {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n return trimmed.length ? trimmed : undefined\n }\n for (const entry of addresses) {\n const normalizedLine1 = normalize(entry.addressLine1)\n if (!normalizedLine1) continue\n const body: Record<string, unknown> = {\n entityId: newId,\n ...(organizationId ? { organizationId } : {}),\n addressLine1: normalizedLine1,\n isPrimary: entry.isPrimary ?? false,\n }\n const name = normalize(entry.name)\n if (name !== undefined) body.name = name\n const purpose = normalize(entry.purpose)\n if (purpose !== undefined) body.purpose = purpose\n const line2 = normalize(entry.addressLine2)\n if (line2 !== undefined) body.addressLine2 = line2\n const buildingNumber = normalize(entry.buildingNumber)\n if (buildingNumber !== undefined) body.buildingNumber = buildingNumber\n const flatNumber = normalize(entry.flatNumber)\n if (flatNumber !== undefined) body.flatNumber = flatNumber\n const city = normalize(entry.city)\n if (city !== undefined) body.city = city\n const region = normalize(entry.region)\n if (region !== undefined) body.region = region\n const postalCode = normalize(entry.postalCode)\n if (postalCode !== undefined) body.postalCode = postalCode\n const country = normalize(entry.country)\n if (country !== undefined) body.country = country.toUpperCase()\n if (typeof entry.latitude === 'number') body.latitude = entry.latitude\n if (typeof entry.longitude === 'number') body.longitude = entry.longitude\n try {\n await createCrud('customers/addresses', body)\n } catch (addressErr) {\n const message =\n addressErr instanceof Error && addressErr.message\n ? addressErr.message\n : t('customers.companies.detail.addresses.error')\n flash(message, 'error')\n }\n }\n }\n\n flash(t('customers.companies.form.success'), 'success')\n if (returnTo) router.push(returnTo)\n else if (newId) router.push(`/backend/customers/companies-v2/${newId}`)\n else router.push('/backend/customers/companies')\n }}\n />\n </PageBody>\n </Page>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,4 @@
1
1
  import { asValue } from "awilix";
2
- import { availabilityProviderRegistry } from "@open-mercato/shared/lib/availability";
3
2
  import {
4
3
  InventoryBalance,
5
4
  InventoryLot,
@@ -10,7 +9,6 @@ import {
10
9
  WarehouseLocation,
11
10
  WarehouseZone
12
11
  } from "./data/entities.js";
13
- import { createWmsAvailabilityProvider } from "./lib/availabilityProvider.js";
14
12
  function register(container) {
15
13
  container.register({
16
14
  Warehouse: asValue(Warehouse),
@@ -22,7 +20,6 @@ function register(container) {
22
20
  InventoryReservation: asValue(InventoryReservation),
23
21
  InventoryMovement: asValue(InventoryMovement)
24
22
  });
25
- availabilityProviderRegistry.register(createWmsAvailabilityProvider(container));
26
23
  }
27
24
  export {
28
25
  register
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/wms/di.ts"],
4
- "sourcesContent": ["import { asValue } from 'awilix'\nimport type { AppContainer } from '@open-mercato/shared/lib/di/container'\nimport { availabilityProviderRegistry } from '@open-mercato/shared/lib/availability'\nimport {\n InventoryBalance,\n InventoryLot,\n InventoryMovement,\n InventoryReservation,\n ProductInventoryProfile,\n Warehouse,\n WarehouseLocation,\n WarehouseZone,\n} from './data/entities'\nimport { createWmsAvailabilityProvider } from './lib/availabilityProvider'\n\nexport function register(container: AppContainer) {\n container.register({\n Warehouse: asValue(Warehouse),\n WarehouseZone: asValue(WarehouseZone),\n WarehouseLocation: asValue(WarehouseLocation),\n ProductInventoryProfile: asValue(ProductInventoryProfile),\n InventoryLot: asValue(InventoryLot),\n InventoryBalance: asValue(InventoryBalance),\n InventoryReservation: asValue(InventoryReservation),\n InventoryMovement: asValue(InventoryMovement),\n })\n\n // Explicit, idempotent (replace-by-id) registration into the shared,\n // dependency-free registry \u2014 never \"same DI key, load order wins\" (\u00A73.1).\n availabilityProviderRegistry.register(createWmsAvailabilityProvider(container))\n}\n"],
5
- "mappings": "AAAA,SAAS,eAAe;AAExB,SAAS,oCAAoC;AAC7C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,qCAAqC;AAEvC,SAAS,SAAS,WAAyB;AAChD,YAAU,SAAS;AAAA,IACjB,WAAW,QAAQ,SAAS;AAAA,IAC5B,eAAe,QAAQ,aAAa;AAAA,IACpC,mBAAmB,QAAQ,iBAAiB;AAAA,IAC5C,yBAAyB,QAAQ,uBAAuB;AAAA,IACxD,cAAc,QAAQ,YAAY;AAAA,IAClC,kBAAkB,QAAQ,gBAAgB;AAAA,IAC1C,sBAAsB,QAAQ,oBAAoB;AAAA,IAClD,mBAAmB,QAAQ,iBAAiB;AAAA,EAC9C,CAAC;AAID,+BAA6B,SAAS,8BAA8B,SAAS,CAAC;AAChF;",
4
+ "sourcesContent": ["import { asValue } from 'awilix'\nimport type { AppContainer } from '@open-mercato/shared/lib/di/container'\nimport {\n InventoryBalance,\n InventoryLot,\n InventoryMovement,\n InventoryReservation,\n ProductInventoryProfile,\n Warehouse,\n WarehouseLocation,\n WarehouseZone,\n} from './data/entities'\n\nexport function register(container: AppContainer) {\n container.register({\n Warehouse: asValue(Warehouse),\n WarehouseZone: asValue(WarehouseZone),\n WarehouseLocation: asValue(WarehouseLocation),\n ProductInventoryProfile: asValue(ProductInventoryProfile),\n InventoryLot: asValue(InventoryLot),\n InventoryBalance: asValue(InventoryBalance),\n InventoryReservation: asValue(InventoryReservation),\n InventoryMovement: asValue(InventoryMovement),\n })\n}\n"],
5
+ "mappings": "AAAA,SAAS,eAAe;AAExB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,SAAS,SAAS,WAAyB;AAChD,YAAU,SAAS;AAAA,IACjB,WAAW,QAAQ,SAAS;AAAA,IAC5B,eAAe,QAAQ,aAAa;AAAA,IACpC,mBAAmB,QAAQ,iBAAiB;AAAA,IAC5C,yBAAyB,QAAQ,uBAAuB;AAAA,IACxD,cAAc,QAAQ,YAAY;AAAA,IAClC,kBAAkB,QAAQ,gBAAgB;AAAA,IAC1C,sBAAsB,QAAQ,oBAAoB;AAAA,IAClD,mBAAmB,QAAQ,iBAAiB;AAAA,EAC9C,CAAC;AACH;",
6
6
  "names": []
7
7
  }
@@ -14,7 +14,6 @@ export const M = {
14
14
  "sales": "sales",
15
15
  "warranty_claims": "warranty_claims",
16
16
  "wms": "wms",
17
- "availability": "availability",
18
17
  "api_keys": "api_keys",
19
18
  "devices": "devices",
20
19
  "dictionaries": "dictionaries",
@@ -192,9 +191,6 @@ export const M = {
192
191
  "sales_order_warehouse_assignment": "wms:sales_order_warehouse_assignment",
193
192
  "inventory_movement": "wms:inventory_movement"
194
193
  },
195
- "availability": {
196
- "availability_policy": "availability:availability_policy"
197
- },
198
194
  "api_keys": {
199
195
  "api_key": "api_keys:api_key"
200
196
  },
@@ -112,27 +112,6 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
112
112
  "created_at": "created_at",
113
113
  "updated_at": "updated_at"
114
114
  },
115
- "availability_policy": {
116
- "id": "id",
117
- "organization_id": "organization_id",
118
- "tenant_id": "tenant_id",
119
- "store_id": "store_id",
120
- "product_id": "product_id",
121
- "variant_id": "variant_id",
122
- "is_stock_managed": "is_stock_managed",
123
- "allow_backorder": "allow_backorder",
124
- "backorder_lead_time_days": "backorder_lead_time_days",
125
- "preorder_release_at": "preorder_release_at",
126
- "low_stock_threshold": "low_stock_threshold",
127
- "min_order_quantity": "min_order_quantity",
128
- "max_order_quantity": "max_order_quantity",
129
- "quantity_increment": "quantity_increment",
130
- "hide_when_out_of_stock": "hide_when_out_of_stock",
131
- "is_active": "is_active",
132
- "created_at": "created_at",
133
- "updated_at": "updated_at",
134
- "deleted_at": "deleted_at"
135
- },
136
115
  "business_rule": {
137
116
  "id": "id",
138
117
  "rule_id": "rule_id",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.8.1-develop.7266.1.8e520bbe03",
3
+ "version": "0.8.1-develop.7268.1.033c0546d5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -253,16 +253,16 @@
253
253
  "zod": "^4.4.3"
254
254
  },
255
255
  "peerDependencies": {
256
- "@open-mercato/ai-assistant": "0.8.1-develop.7266.1.8e520bbe03",
257
- "@open-mercato/shared": "0.8.1-develop.7266.1.8e520bbe03",
258
- "@open-mercato/ui": "0.8.1-develop.7266.1.8e520bbe03",
256
+ "@open-mercato/ai-assistant": "0.8.1-develop.7268.1.033c0546d5",
257
+ "@open-mercato/shared": "0.8.1-develop.7268.1.033c0546d5",
258
+ "@open-mercato/ui": "0.8.1-develop.7268.1.033c0546d5",
259
259
  "react": "^19.0.0",
260
260
  "react-dom": "^19.0.0"
261
261
  },
262
262
  "devDependencies": {
263
- "@open-mercato/ai-assistant": "0.8.1-develop.7266.1.8e520bbe03",
264
- "@open-mercato/shared": "0.8.1-develop.7266.1.8e520bbe03",
265
- "@open-mercato/ui": "0.8.1-develop.7266.1.8e520bbe03",
263
+ "@open-mercato/ai-assistant": "0.8.1-develop.7268.1.033c0546d5",
264
+ "@open-mercato/shared": "0.8.1-develop.7268.1.033c0546d5",
265
+ "@open-mercato/ui": "0.8.1-develop.7268.1.033c0546d5",
266
266
  "@testing-library/dom": "^10.4.1",
267
267
  "@testing-library/jest-dom": "^7.0.1",
268
268
  "@testing-library/react": "^16.3.3",
@@ -62,9 +62,6 @@
62
62
  "auth.acl.features.auth.users.delete": "Delete users",
63
63
  "auth.acl.features.auth.users.edit": "Edit users",
64
64
  "auth.acl.features.auth.users.list": "List users",
65
- "auth.acl.features.availability.check": "Run availability checks",
66
- "auth.acl.features.availability.policies.manage": "Manage availability policies",
67
- "auth.acl.features.availability.policies.view": "View availability policies",
68
65
  "auth.acl.features.business_rules.execute": "Execute business rules manually",
69
66
  "auth.acl.features.business_rules.manage": "Create, edit, and delete business rules",
70
67
  "auth.acl.features.business_rules.manage_sets": "Manage rule sets",
@@ -62,9 +62,6 @@
62
62
  "auth.acl.features.auth.users.delete": "Delete users",
63
63
  "auth.acl.features.auth.users.edit": "Edit users",
64
64
  "auth.acl.features.auth.users.list": "List users",
65
- "auth.acl.features.availability.check": "Run availability checks",
66
- "auth.acl.features.availability.policies.manage": "Manage availability policies",
67
- "auth.acl.features.availability.policies.view": "View availability policies",
68
65
  "auth.acl.features.business_rules.execute": "Execute business rules manually",
69
66
  "auth.acl.features.business_rules.manage": "Create, edit, and delete business rules",
70
67
  "auth.acl.features.business_rules.manage_sets": "Manage rule sets",
@@ -62,9 +62,6 @@
62
62
  "auth.acl.features.auth.users.delete": "Delete users",
63
63
  "auth.acl.features.auth.users.edit": "Edit users",
64
64
  "auth.acl.features.auth.users.list": "List users",
65
- "auth.acl.features.availability.check": "Run availability checks",
66
- "auth.acl.features.availability.policies.manage": "Manage availability policies",
67
- "auth.acl.features.availability.policies.view": "View availability policies",
68
65
  "auth.acl.features.business_rules.execute": "Execute business rules manually",
69
66
  "auth.acl.features.business_rules.manage": "Create, edit, and delete business rules",
70
67
  "auth.acl.features.business_rules.manage_sets": "Manage rule sets",
@@ -62,9 +62,6 @@
62
62
  "auth.acl.features.auth.users.delete": "Delete users",
63
63
  "auth.acl.features.auth.users.edit": "Edit users",
64
64
  "auth.acl.features.auth.users.list": "List users",
65
- "auth.acl.features.availability.check": "Run availability checks",
66
- "auth.acl.features.availability.policies.manage": "Manage availability policies",
67
- "auth.acl.features.availability.policies.view": "View availability policies",
68
65
  "auth.acl.features.business_rules.execute": "Execute business rules manually",
69
66
  "auth.acl.features.business_rules.manage": "Create, edit, and delete business rules",
70
67
  "auth.acl.features.business_rules.manage_sets": "Manage rule sets",
@@ -62,9 +62,6 @@
62
62
  "auth.acl.features.auth.users.delete": "Usuwaj użytkowników",
63
63
  "auth.acl.features.auth.users.edit": "Edytuj użytkowników",
64
64
  "auth.acl.features.auth.users.list": "Wyświetl listę użytkowników",
65
- "auth.acl.features.availability.check": "Uruchamiaj sprawdzenia dostępności",
66
- "auth.acl.features.availability.policies.manage": "Zarządzaj politykami dostępności",
67
- "auth.acl.features.availability.policies.view": "Wyświetl polityki dostępności",
68
65
  "auth.acl.features.business_rules.execute": "Uruchamiaj reguły biznesowe ręcznie",
69
66
  "auth.acl.features.business_rules.manage": "Twórz, edytuj i usuwaj reguły biznesowe",
70
67
  "auth.acl.features.business_rules.manage_sets": "Zarządzaj zestawami reguł",
@@ -320,7 +320,7 @@ Both link to `/backend/customer_accounts/{sourceEntityId}` for staff review.
320
320
  | `customers.person` | `account-status` | Alias for hosts requesting the bare `customers.person` entity spot |
321
321
  | `crud-form:customers.person` | `account-status` | Shows portal account status on the person v2 detail page (`people-v2/[id]`) |
322
322
  | `customers.company` | `company-users` | Alias for hosts requesting the bare `customers.company` entity spot |
323
- | `crud-form:customers.company` | `company-users` | Shows portal users on the company v2 detail page (`companies-v2/[id]`) |
323
+ | `crud-form:customers.company` | `company-users` | Shows portal users on every company surface that publishes the host — the company v2 detail page (`companies-v2/[id]`), the company create page (`companies/create`), and the sales document "Create company" quick dialog — where it has no `recordId` and renders its empty state |
324
324
 
325
325
  Both inject as column 2 groups with priority 200, gated by `customer_accounts.view` feature.
326
326
 
@@ -10,6 +10,8 @@ import { E } from '#generated/entities.ids.generated'
10
10
  import { flash } from '@open-mercato/ui/backend/FlashMessages'
11
11
  import { useT } from '@open-mercato/shared/lib/i18n/context'
12
12
  import { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'
13
+ import { crudFormExtensionSpotId } from '@open-mercato/shared/modules/widgets/extension-points'
14
+ import { extensionPoints } from '@open-mercato/core/modules/customers/extension-points'
13
15
  import {
14
16
  buildCompanyPayload,
15
17
  createCompanyFormFields,
@@ -18,6 +20,8 @@ import {
18
20
  type CompanyFormValues,
19
21
  } from '../../../../components/formConfig'
20
22
 
23
+ const COMPANY_CREATE_LEGACY_INJECTION_SPOT_ID = crudFormExtensionSpotId('customers.customer_entity')
24
+
21
25
  export default function CreateCompanyPage() {
22
26
  const t = useT()
23
27
  const router = useRouter()
@@ -39,6 +43,8 @@ export default function CreateCompanyPage() {
39
43
  fields={fields}
40
44
  groups={groups}
41
45
  initialValues={{ addresses: [] as CompanyFormValues['addresses'] }}
46
+ injectionSpotId={extensionPoints.hosts.companyForm.spotId}
47
+ legacyInjectionSpotId={COMPANY_CREATE_LEGACY_INJECTION_SPOT_ID}
42
48
  entityIds={[E.customers.customer_entity, E.customers.customer_company_profile]}
43
49
  submitLabel={t('customers.companies.form.submit')}
44
50
  cancelHref={returnTo ?? '/backend/customers/companies'}
@@ -1,6 +1,5 @@
1
1
  import { asValue } from 'awilix'
2
2
  import type { AppContainer } from '@open-mercato/shared/lib/di/container'
3
- import { availabilityProviderRegistry } from '@open-mercato/shared/lib/availability'
4
3
  import {
5
4
  InventoryBalance,
6
5
  InventoryLot,
@@ -11,7 +10,6 @@ import {
11
10
  WarehouseLocation,
12
11
  WarehouseZone,
13
12
  } from './data/entities'
14
- import { createWmsAvailabilityProvider } from './lib/availabilityProvider'
15
13
 
16
14
  export function register(container: AppContainer) {
17
15
  container.register({
@@ -24,8 +22,4 @@ export function register(container: AppContainer) {
24
22
  InventoryReservation: asValue(InventoryReservation),
25
23
  InventoryMovement: asValue(InventoryMovement),
26
24
  })
27
-
28
- // Explicit, idempotent (replace-by-id) registration into the shared,
29
- // dependency-free registry — never "same DI key, load order wins" (§3.1).
30
- availabilityProviderRegistry.register(createWmsAvailabilityProvider(container))
31
25
  }
@@ -1,41 +0,0 @@
1
- const id = "id";
2
- const organization_id = "organization_id";
3
- const tenant_id = "tenant_id";
4
- const store_id = "store_id";
5
- const product_id = "product_id";
6
- const variant_id = "variant_id";
7
- const is_stock_managed = "is_stock_managed";
8
- const allow_backorder = "allow_backorder";
9
- const backorder_lead_time_days = "backorder_lead_time_days";
10
- const preorder_release_at = "preorder_release_at";
11
- const low_stock_threshold = "low_stock_threshold";
12
- const min_order_quantity = "min_order_quantity";
13
- const max_order_quantity = "max_order_quantity";
14
- const quantity_increment = "quantity_increment";
15
- const hide_when_out_of_stock = "hide_when_out_of_stock";
16
- const is_active = "is_active";
17
- const created_at = "created_at";
18
- const updated_at = "updated_at";
19
- const deleted_at = "deleted_at";
20
- export {
21
- allow_backorder,
22
- backorder_lead_time_days,
23
- created_at,
24
- deleted_at,
25
- hide_when_out_of_stock,
26
- id,
27
- is_active,
28
- is_stock_managed,
29
- low_stock_threshold,
30
- max_order_quantity,
31
- min_order_quantity,
32
- organization_id,
33
- preorder_release_at,
34
- product_id,
35
- quantity_increment,
36
- store_id,
37
- tenant_id,
38
- updated_at,
39
- variant_id
40
- };
41
- //# sourceMappingURL=index.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../generated/entities/availability_policy/index.ts"],
4
- "sourcesContent": ["export const id = \"id\";\nexport const organization_id = \"organization_id\";\nexport const tenant_id = \"tenant_id\";\nexport const store_id = \"store_id\";\nexport const product_id = \"product_id\";\nexport const variant_id = \"variant_id\";\nexport const is_stock_managed = \"is_stock_managed\";\nexport const allow_backorder = \"allow_backorder\";\nexport const backorder_lead_time_days = \"backorder_lead_time_days\";\nexport const preorder_release_at = \"preorder_release_at\";\nexport const low_stock_threshold = \"low_stock_threshold\";\nexport const min_order_quantity = \"min_order_quantity\";\nexport const max_order_quantity = \"max_order_quantity\";\nexport const quantity_increment = \"quantity_increment\";\nexport const hide_when_out_of_stock = \"hide_when_out_of_stock\";\nexport const is_active = \"is_active\";\nexport const created_at = \"created_at\";\nexport const updated_at = \"updated_at\";\nexport const deleted_at = \"deleted_at\";\n"],
5
- "mappings": "AAAO,MAAM,KAAK;AACX,MAAM,kBAAkB;AACxB,MAAM,YAAY;AAClB,MAAM,WAAW;AACjB,MAAM,aAAa;AACnB,MAAM,aAAa;AACnB,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,2BAA2B;AACjC,MAAM,sBAAsB;AAC5B,MAAM,sBAAsB;AAC5B,MAAM,qBAAqB;AAC3B,MAAM,qBAAqB;AAC3B,MAAM,qBAAqB;AAC3B,MAAM,yBAAyB;AAC/B,MAAM,YAAY;AAClB,MAAM,aAAa;AACnB,MAAM,aAAa;AACnB,MAAM,aAAa;",
6
- "names": []
7
- }
@@ -1,16 +0,0 @@
1
- const features = [
2
- { id: "availability.policies.view", title: "View availability policies", module: "availability" },
3
- {
4
- id: "availability.policies.manage",
5
- title: "Manage availability policies",
6
- module: "availability",
7
- dependsOn: ["availability.policies.view"]
8
- },
9
- { id: "availability.check", title: "Run availability checks", module: "availability" }
10
- ];
11
- var acl_default = features;
12
- export {
13
- acl_default as default,
14
- features
15
- };
16
- //# sourceMappingURL=acl.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/modules/availability/acl.ts"],
4
- "sourcesContent": ["export const features = [\n { id: 'availability.policies.view', title: 'View availability policies', module: 'availability' },\n {\n id: 'availability.policies.manage',\n title: 'Manage availability policies',\n module: 'availability',\n dependsOn: ['availability.policies.view'],\n },\n { id: 'availability.check', title: 'Run availability checks', module: 'availability' },\n]\n\nexport default features\n"],
5
- "mappings": "AAAO,MAAM,WAAW;AAAA,EACtB,EAAE,IAAI,8BAA8B,OAAO,8BAA8B,QAAQ,eAAe;AAAA,EAChG;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW,CAAC,4BAA4B;AAAA,EAC1C;AAAA,EACA,EAAE,IAAI,sBAAsB,OAAO,2BAA2B,QAAQ,eAAe;AACvF;AAEA,IAAO,cAAQ;",
6
- "names": []
7
- }
@@ -1,95 +0,0 @@
1
- import { NextResponse } from "next/server";
2
- import { z } from "zod";
3
- import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
4
- import { resolveActiveOrganizationId, organizationScopeRequiredResponse } from "@open-mercato/shared/lib/auth/organizationScope";
5
- import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
6
- import { resolveAvailability, availabilityItemKey } from "@open-mercato/shared/lib/availability";
7
- import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
8
- import { tryResolve } from "../../lib/tryResolve.js";
9
- const routeMetadata = {
10
- POST: { requireAuth: true, requireFeatures: ["availability.check"] }
11
- };
12
- const metadata = routeMetadata;
13
- const openApi = {
14
- tags: ["Availability"],
15
- summary: "Reproduce the availability state and policy trace a buyer would see for one item.",
16
- description: "Admin/debug tool. Mirrors resolveAvailability() and includes the per-field policySourceId trace."
17
- };
18
- const checkSchema = z.object({
19
- productId: z.uuid(),
20
- variantId: z.uuid().nullable().optional(),
21
- quantity: z.coerce.number().int().min(1).default(1),
22
- storeId: z.uuid().nullable().optional()
23
- });
24
- async function POST(req) {
25
- const { translate } = await resolveTranslations();
26
- const auth = await getAuthFromRequest(req);
27
- if (!auth || !auth.tenantId) {
28
- return NextResponse.json({ error: translate("availability.errors.unauthorized", "Unauthorized") }, { status: 401 });
29
- }
30
- const organizationId = resolveActiveOrganizationId(auth);
31
- if (!organizationId) return organizationScopeRequiredResponse();
32
- const body = await req.json().catch(() => ({}));
33
- const parsed = checkSchema.safeParse(body);
34
- if (!parsed.success) {
35
- return NextResponse.json(
36
- { error: translate("availability.errors.invalidCheckRequest", "Invalid request") },
37
- { status: 400 }
38
- );
39
- }
40
- const { productId, variantId, quantity, storeId } = parsed.data;
41
- const tenantId = auth.tenantId;
42
- const container = await createRequestContainer();
43
- const em = container.resolve("em");
44
- const CatalogProduct = tryResolve(container, "CatalogProduct");
45
- if (CatalogProduct) {
46
- const product = await em.findOne(CatalogProduct, { id: productId, organizationId, tenantId, deletedAt: null });
47
- if (!product) {
48
- return NextResponse.json(
49
- { error: translate("availability.errors.productNotFound", "No such product") },
50
- { status: 404 }
51
- );
52
- }
53
- if (variantId) {
54
- const CatalogProductVariant = tryResolve(container, "CatalogProductVariant");
55
- if (CatalogProductVariant) {
56
- const variant = await em.findOne(CatalogProductVariant, {
57
- id: variantId,
58
- organizationId,
59
- tenantId,
60
- deletedAt: null
61
- });
62
- if (!variant) {
63
- return NextResponse.json(
64
- { error: translate("availability.errors.variantNotFound", "No such variant") },
65
- { status: 404 }
66
- );
67
- }
68
- }
69
- }
70
- }
71
- const query = {
72
- tenantId,
73
- organizationId,
74
- storeId: storeId ?? null,
75
- items: [{ catalogProductId: productId, catalogVariantId: variantId ?? null, quantity }]
76
- };
77
- const moduleConfig = tryResolve(container, "moduleConfigService");
78
- const result = await resolveAvailability(query, moduleConfig ? { moduleConfig } : void 0);
79
- const item = result.byItem[availabilityItemKey({ catalogProductId: productId, catalogVariantId: variantId ?? null })] ?? null;
80
- const policyResolutionService = tryResolve(container, "policyResolutionService");
81
- const policyTrace = policyResolutionService ? await policyResolutionService.resolve(em, {
82
- tenantId,
83
- organizationId,
84
- storeId: storeId ?? null,
85
- productId,
86
- variantId: variantId ?? null
87
- }) : null;
88
- return NextResponse.json({ availability: item, policyTrace });
89
- }
90
- export {
91
- POST,
92
- metadata,
93
- openApi
94
- };
95
- //# sourceMappingURL=route.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../src/modules/availability/api/check/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveActiveOrganizationId, organizationScopeRequiredResponse } from '@open-mercato/shared/lib/auth/organizationScope'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { resolveAvailability, availabilityItemKey } from '@open-mercato/shared/lib/availability'\nimport type { AvailabilityModuleConfigReader, AvailabilityQuery } from '@open-mercato/shared/lib/availability'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { tryResolve } from '../../lib/tryResolve'\nimport type { PolicyResolutionService } from '../../lib/policyResolution'\n\n/**\n * `POST /api/availability/check` \u2014 admin/debug reproduction of what a buyer saw,\n * including the per-field `policySourceId` trace. No public storefront endpoints\n * ship in this module (\u00A78).\n */\nconst routeMetadata = {\n POST: { requireAuth: true, requireFeatures: ['availability.check'] },\n}\n\nexport const metadata = routeMetadata\n\nexport const openApi = {\n tags: ['Availability'],\n summary: 'Reproduce the availability state and policy trace a buyer would see for one item.',\n description: 'Admin/debug tool. Mirrors resolveAvailability() and includes the per-field policySourceId trace.',\n}\n\nconst checkSchema = z.object({\n productId: z.uuid(),\n variantId: z.uuid().nullable().optional(),\n quantity: z.coerce.number().int().min(1).default(1),\n storeId: z.uuid().nullable().optional(),\n})\n\nexport async function POST(req: Request) {\n const { translate } = await resolveTranslations()\n const auth = await getAuthFromRequest(req)\n if (!auth || !auth.tenantId) {\n return NextResponse.json({ error: translate('availability.errors.unauthorized', 'Unauthorized') }, { status: 401 })\n }\n\n const organizationId = resolveActiveOrganizationId(auth)\n if (!organizationId) return organizationScopeRequiredResponse()\n\n const body = await req.json().catch(() => ({}))\n const parsed = checkSchema.safeParse(body)\n if (!parsed.success) {\n return NextResponse.json(\n { error: translate('availability.errors.invalidCheckRequest', 'Invalid request') },\n { status: 400 },\n )\n }\n const { productId, variantId, quantity, storeId } = parsed.data\n const tenantId = auth.tenantId\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n\n // Soft-resolved product/variant existence check \u2014 degrades gracefully when\n // `catalog` is ejected (Phase 1 gate: coherent behaviour without it).\n const CatalogProduct = tryResolve<new () => unknown>(container, 'CatalogProduct')\n if (CatalogProduct) {\n const product = await em.findOne(CatalogProduct as any, { id: productId, organizationId, tenantId, deletedAt: null })\n if (!product) {\n return NextResponse.json(\n { error: translate('availability.errors.productNotFound', 'No such product') },\n { status: 404 },\n )\n }\n if (variantId) {\n const CatalogProductVariant = tryResolve<new () => unknown>(container, 'CatalogProductVariant')\n if (CatalogProductVariant) {\n const variant = await em.findOne(CatalogProductVariant as any, {\n id: variantId,\n organizationId,\n tenantId,\n deletedAt: null,\n })\n if (!variant) {\n return NextResponse.json(\n { error: translate('availability.errors.variantNotFound', 'No such variant') },\n { status: 404 },\n )\n }\n }\n }\n }\n\n const query: AvailabilityQuery = {\n tenantId,\n organizationId,\n storeId: storeId ?? null,\n items: [{ catalogProductId: productId, catalogVariantId: variantId ?? null, quantity }],\n }\n\n const moduleConfig = tryResolve<AvailabilityModuleConfigReader>(container, 'moduleConfigService')\n const result = await resolveAvailability(query, moduleConfig ? { moduleConfig } : undefined)\n const item = result.byItem[availabilityItemKey({ catalogProductId: productId, catalogVariantId: variantId ?? null })] ?? null\n\n const policyResolutionService = tryResolve<PolicyResolutionService>(container, 'policyResolutionService')\n const policyTrace = policyResolutionService\n ? await policyResolutionService.resolve(em, {\n tenantId,\n organizationId,\n storeId: storeId ?? null,\n productId,\n variantId: variantId ?? null,\n })\n : null\n\n return NextResponse.json({ availability: item, policyTrace })\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,27 +0,0 @@
1
- import {
2
- createCrudOpenApiFactory,
3
- createPagedListResponseSchema as createSharedPagedListResponseSchema,
4
- defaultCreateResponseSchema as sharedDefaultCreateResponseSchema,
5
- defaultOkResponseSchema as sharedDefaultOkResponseSchema
6
- } from "@open-mercato/shared/lib/openapi/crud";
7
- const defaultCreateResponseSchema = sharedDefaultCreateResponseSchema;
8
- const defaultOkResponseSchema = sharedDefaultOkResponseSchema;
9
- function createPagedListResponseSchema(itemSchema) {
10
- return createSharedPagedListResponseSchema(itemSchema, { paginationMetaOptional: true });
11
- }
12
- const buildAvailabilityCrudOpenApi = createCrudOpenApiFactory({
13
- defaultTag: "Availability",
14
- defaultCreateResponseSchema,
15
- defaultOkResponseSchema,
16
- makeListDescription: ({ pluralLower }) => `Returns a paginated collection of ${pluralLower} scoped to the authenticated organization.`
17
- });
18
- function createAvailabilityCrudOpenApi(options) {
19
- return buildAvailabilityCrudOpenApi(options);
20
- }
21
- export {
22
- createAvailabilityCrudOpenApi,
23
- createPagedListResponseSchema,
24
- defaultCreateResponseSchema,
25
- defaultOkResponseSchema
26
- };
27
- //# sourceMappingURL=openapi.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/modules/availability/api/openapi.ts"],
4
- "sourcesContent": ["import { type ZodTypeAny } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport {\n createCrudOpenApiFactory,\n createPagedListResponseSchema as createSharedPagedListResponseSchema,\n defaultCreateResponseSchema as sharedDefaultCreateResponseSchema,\n defaultOkResponseSchema as sharedDefaultOkResponseSchema,\n type CrudOpenApiOptions,\n} from '@open-mercato/shared/lib/openapi/crud'\n\nexport const defaultCreateResponseSchema = sharedDefaultCreateResponseSchema\nexport const defaultOkResponseSchema = sharedDefaultOkResponseSchema\n\nexport function createPagedListResponseSchema(itemSchema: ZodTypeAny) {\n return createSharedPagedListResponseSchema(itemSchema, { paginationMetaOptional: true })\n}\n\nconst buildAvailabilityCrudOpenApi = createCrudOpenApiFactory({\n defaultTag: 'Availability',\n defaultCreateResponseSchema,\n defaultOkResponseSchema,\n makeListDescription: ({ pluralLower }) =>\n `Returns a paginated collection of ${pluralLower} scoped to the authenticated organization.`,\n})\n\nexport function createAvailabilityCrudOpenApi(options: CrudOpenApiOptions): OpenApiRouteDoc {\n return buildAvailabilityCrudOpenApi(options)\n}\n"],
5
- "mappings": "AAEA;AAAA,EACE;AAAA,EACA,iCAAiC;AAAA,EACjC,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,OAEtB;AAEA,MAAM,8BAA8B;AACpC,MAAM,0BAA0B;AAEhC,SAAS,8BAA8B,YAAwB;AACpE,SAAO,oCAAoC,YAAY,EAAE,wBAAwB,KAAK,CAAC;AACzF;AAEA,MAAM,+BAA+B,yBAAyB;AAAA,EAC5D,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,qBAAqB,CAAC,EAAE,YAAY,MAClC,qCAAqC,WAAW;AACpD,CAAC;AAEM,SAAS,8BAA8B,SAA8C;AAC1F,SAAO,6BAA6B,OAAO;AAC7C;",
6
- "names": []
7
- }
@@ -1,58 +0,0 @@
1
- import { NextResponse } from "next/server";
2
- import { z } from "zod";
3
- import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
4
- import { resolveActiveOrganizationId, organizationScopeRequiredResponse } from "@open-mercato/shared/lib/auth/organizationScope";
5
- import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
6
- import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
7
- import { createPolicyResolutionService } from "../../../lib/policyResolution.js";
8
- const routeMetadata = {
9
- GET: { requireAuth: true, requireFeatures: ["availability.policies.view"] }
10
- };
11
- const metadata = routeMetadata;
12
- const openApi = {
13
- tags: ["Availability"],
14
- summary: "Preview the currently persisted policy resolution chain for a product/variant/store target."
15
- };
16
- const querySchema = z.object({
17
- productId: z.uuid(),
18
- variantId: z.uuid().nullable().optional(),
19
- storeId: z.uuid().nullable().optional()
20
- });
21
- async function GET(req) {
22
- const { translate } = await resolveTranslations();
23
- const auth = await getAuthFromRequest(req);
24
- if (!auth || !auth.tenantId) {
25
- return NextResponse.json({ error: translate("availability.errors.unauthorized", "Unauthorized") }, { status: 401 });
26
- }
27
- const organizationId = resolveActiveOrganizationId(auth);
28
- if (!organizationId) return organizationScopeRequiredResponse();
29
- const url = new URL(req.url);
30
- const parsed = querySchema.safeParse({
31
- productId: url.searchParams.get("productId") ?? void 0,
32
- variantId: url.searchParams.get("variantId") ?? void 0,
33
- storeId: url.searchParams.get("storeId") ?? void 0
34
- });
35
- if (!parsed.success) {
36
- return NextResponse.json(
37
- { error: translate("availability.errors.invalidPreviewRequest", "Invalid request") },
38
- { status: 400 }
39
- );
40
- }
41
- const container = await createRequestContainer();
42
- const em = container.resolve("em");
43
- const service = createPolicyResolutionService(container);
44
- const trace = await service.resolve(em, {
45
- tenantId: auth.tenantId,
46
- organizationId,
47
- storeId: parsed.data.storeId ?? null,
48
- productId: parsed.data.productId,
49
- variantId: parsed.data.variantId ?? null
50
- });
51
- return NextResponse.json({ policyTrace: trace });
52
- }
53
- export {
54
- GET,
55
- metadata,
56
- openApi
57
- };
58
- //# sourceMappingURL=route.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../src/modules/availability/api/policies/resolve-preview/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveActiveOrganizationId, organizationScopeRequiredResponse } from '@open-mercato/shared/lib/auth/organizationScope'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { createPolicyResolutionService } from '../../../lib/policyResolution'\n\n/**\n * `GET /api/availability/policies/resolve-preview` \u2014 the currently PERSISTED\n * resolution chain for a (product, variant, store) target, used by the policy\n * edit/create form to show \"which level currently decides each field\" (US-A2)\n * before the admin saves an override.\n */\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['availability.policies.view'] },\n}\n\nexport const metadata = routeMetadata\n\nexport const openApi = {\n tags: ['Availability'],\n summary: 'Preview the currently persisted policy resolution chain for a product/variant/store target.',\n}\n\nconst querySchema = z.object({\n productId: z.uuid(),\n variantId: z.uuid().nullable().optional(),\n storeId: z.uuid().nullable().optional(),\n})\n\nexport async function GET(req: Request) {\n const { translate } = await resolveTranslations()\n const auth = await getAuthFromRequest(req)\n if (!auth || !auth.tenantId) {\n return NextResponse.json({ error: translate('availability.errors.unauthorized', 'Unauthorized') }, { status: 401 })\n }\n const organizationId = resolveActiveOrganizationId(auth)\n if (!organizationId) return organizationScopeRequiredResponse()\n\n const url = new URL(req.url)\n const parsed = querySchema.safeParse({\n productId: url.searchParams.get('productId') ?? undefined,\n variantId: url.searchParams.get('variantId') ?? undefined,\n storeId: url.searchParams.get('storeId') ?? undefined,\n })\n if (!parsed.success) {\n return NextResponse.json(\n { error: translate('availability.errors.invalidPreviewRequest', 'Invalid request') },\n { status: 400 },\n )\n }\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n const service = createPolicyResolutionService(container)\n const trace = await service.resolve(em, {\n tenantId: auth.tenantId,\n organizationId,\n storeId: parsed.data.storeId ?? null,\n productId: parsed.data.productId,\n variantId: parsed.data.variantId ?? null,\n })\n\n return NextResponse.json({ policyTrace: trace })\n}\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,0BAA0B;AACnC,SAAS,6BAA6B,yCAAyC;AAC/E,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,qCAAqC;AAQ9C,MAAM,gBAAgB;AAAA,EACpB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,4BAA4B,EAAE;AAC5E;AAEO,MAAM,WAAW;AAEjB,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,cAAc;AAAA,EACrB,SAAS;AACX;AAEA,MAAM,cAAc,EAAE,OAAO;AAAA,EAC3B,WAAW,EAAE,KAAK;AAAA,EAClB,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EACxC,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS;AACxC,CAAC;AAED,eAAsB,IAAI,KAAc;AACtC,QAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,QAAQ,CAAC,KAAK,UAAU;AAC3B,WAAO,aAAa,KAAK,EAAE,OAAO,UAAU,oCAAoC,cAAc,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACpH;AACA,QAAM,iBAAiB,4BAA4B,IAAI;AACvD,MAAI,CAAC,eAAgB,QAAO,kCAAkC;AAE9D,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,QAAM,SAAS,YAAY,UAAU;AAAA,IACnC,WAAW,IAAI,aAAa,IAAI,WAAW,KAAK;AAAA,IAChD,WAAW,IAAI,aAAa,IAAI,WAAW,KAAK;AAAA,IAChD,SAAS,IAAI,aAAa,IAAI,SAAS,KAAK;AAAA,EAC9C,CAAC;AACD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa;AAAA,MAClB,EAAE,OAAO,UAAU,6CAA6C,iBAAiB,EAAE;AAAA,MACnF,EAAE,QAAQ,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,KAAK,UAAU,QAAQ,IAAI;AACjC,QAAM,UAAU,8BAA8B,SAAS;AACvD,QAAM,QAAQ,MAAM,QAAQ,QAAQ,IAAI;AAAA,IACtC,UAAU,KAAK;AAAA,IACf;AAAA,IACA,SAAS,OAAO,KAAK,WAAW;AAAA,IAChC,WAAW,OAAO,KAAK;AAAA,IACvB,WAAW,OAAO,KAAK,aAAa;AAAA,EACtC,CAAC;AAED,SAAO,aAAa,KAAK,EAAE,aAAa,MAAM,CAAC;AACjD;",
6
- "names": []
7
- }