@open-mercato/core 0.6.1-develop.3276.1.1fcd145078 → 0.6.1-develop.3278.1.a4d26475e4
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/.turbo/turbo-build.log +2 -2
- package/dist/generated/entities/domain_mapping/index.js +31 -0
- package/dist/generated/entities/domain_mapping/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +2 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +16 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/salesUi.js +18 -17
- package/dist/helpers/integration/salesUi.js.map +2 -2
- package/dist/modules/customer_accounts/acl.js +2 -1
- package/dist/modules/customer_accounts/acl.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js +110 -0
- package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js.map +7 -0
- package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js +114 -0
- package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js.map +7 -0
- package/dist/modules/customer_accounts/api/admin/domain-mappings.js +271 -0
- package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +7 -0
- package/dist/modules/customer_accounts/api/domain-check.js +70 -0
- package/dist/modules/customer_accounts/api/domain-check.js.map +7 -0
- package/dist/modules/customer_accounts/api/domain-resolve/all.js +128 -0
- package/dist/modules/customer_accounts/api/domain-resolve/all.js.map +7 -0
- package/dist/modules/customer_accounts/api/domain-resolve.js +84 -0
- package/dist/modules/customer_accounts/api/domain-resolve.js.map +7 -0
- package/dist/modules/customer_accounts/api/login.js +14 -3
- package/dist/modules/customer_accounts/api/login.js.map +2 -2
- package/dist/modules/customer_accounts/api/magic-link/request.js +14 -3
- package/dist/modules/customer_accounts/api/magic-link/request.js.map +2 -2
- package/dist/modules/customer_accounts/api/password/reset-request.js +14 -3
- package/dist/modules/customer_accounts/api/password/reset-request.js.map +2 -2
- package/dist/modules/customer_accounts/api/signup.js +32 -5
- package/dist/modules/customer_accounts/api/signup.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js +48 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +43 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js +53 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js +69 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js +31 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js +147 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js +39 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js +60 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js +11 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js +1 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +361 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +7 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js +28 -0
- package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js.map +7 -0
- package/dist/modules/customer_accounts/data/enrichers.js +78 -12
- package/dist/modules/customer_accounts/data/enrichers.js.map +2 -2
- package/dist/modules/customer_accounts/data/entities.js +85 -2
- package/dist/modules/customer_accounts/data/entities.js.map +2 -2
- package/dist/modules/customer_accounts/data/guards.js +130 -0
- package/dist/modules/customer_accounts/data/guards.js.map +7 -0
- package/dist/modules/customer_accounts/data/validators.js +19 -0
- package/dist/modules/customer_accounts/data/validators.js.map +2 -2
- package/dist/modules/customer_accounts/di.js +23 -1
- package/dist/modules/customer_accounts/di.js.map +2 -2
- package/dist/modules/customer_accounts/events.js +9 -2
- package/dist/modules/customer_accounts/events.js.map +2 -2
- package/dist/modules/customer_accounts/lib/customerAuthServer.js +27 -7
- package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +2 -2
- package/dist/modules/customer_accounts/lib/customerUrl.js +48 -0
- package/dist/modules/customer_accounts/lib/customerUrl.js.map +7 -0
- package/dist/modules/customer_accounts/lib/hostname.js +55 -0
- package/dist/modules/customer_accounts/lib/hostname.js.map +7 -0
- package/dist/modules/customer_accounts/lib/platformDomains.js +7 -0
- package/dist/modules/customer_accounts/lib/platformDomains.js.map +7 -0
- package/dist/modules/customer_accounts/lib/proxyRanges.js +71 -0
- package/dist/modules/customer_accounts/lib/proxyRanges.js.map +7 -0
- package/dist/modules/customer_accounts/lib/rateLimiter.js +7 -0
- package/dist/modules/customer_accounts/lib/rateLimiter.js.map +2 -2
- package/dist/modules/customer_accounts/lib/resolveTenantContext.js +63 -0
- package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +7 -0
- package/dist/modules/customer_accounts/lib/secretCompare.js +13 -0
- package/dist/modules/customer_accounts/lib/secretCompare.js.map +7 -0
- package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js +37 -0
- package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js.map +7 -0
- package/dist/modules/customer_accounts/notifications.client.js +76 -0
- package/dist/modules/customer_accounts/notifications.client.js.map +2 -2
- package/dist/modules/customer_accounts/notifications.js +76 -0
- package/dist/modules/customer_accounts/notifications.js.map +2 -2
- package/dist/modules/customer_accounts/services/domainMappingService.js +497 -0
- package/dist/modules/customer_accounts/services/domainMappingService.js.map +7 -0
- package/dist/modules/customer_accounts/setup.js +48 -1
- package/dist/modules/customer_accounts/setup.js.map +2 -2
- package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js +29 -0
- package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js.map +7 -0
- package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js +29 -0
- package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js.map +7 -0
- package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js +30 -0
- package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js.map +7 -0
- package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js +31 -0
- package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js.map +7 -0
- package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js +29 -0
- package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js.map +7 -0
- package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js +67 -0
- package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js.map +7 -0
- package/dist/modules/customer_accounts/workers/domainVerificationWorker.js +34 -0
- package/dist/modules/customer_accounts/workers/domainVerificationWorker.js.map +7 -0
- package/dist/modules/customers/api/companies/route.js +4 -9
- package/dist/modules/customers/api/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +4 -9
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/people/route.js +4 -9
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/api/utils.js +0 -12
- package/dist/modules/customers/api/utils.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +361 -284
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +378 -473
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +368 -286
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/components/detail/assignableStaff.js +15 -1
- package/dist/modules/customers/components/detail/assignableStaff.js.map +2 -2
- package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js +188 -36
- package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js +2 -2
- package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js.map +2 -2
- package/dist/modules/customers/widgets/injection-table.js +6 -0
- package/dist/modules/customers/widgets/injection-table.js.map +2 -2
- package/dist/modules/perspectives/services/perspectiveService.js +16 -2
- package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +1 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +31 -8
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/generated/entities/domain_mapping/index.ts +14 -0
- package/generated/entities.ids.generated.ts +2 -1
- package/generated/entity-fields-registry.ts +16 -0
- package/package.json +5 -5
- package/src/helpers/integration/salesUi.ts +27 -23
- package/src/modules/customer_accounts/acl.ts +1 -0
- package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.ts +119 -0
- package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.ts +123 -0
- package/src/modules/customer_accounts/api/admin/domain-mappings.ts +303 -0
- package/src/modules/customer_accounts/api/domain-check.ts +83 -0
- package/src/modules/customer_accounts/api/domain-resolve/all.ts +139 -0
- package/src/modules/customer_accounts/api/domain-resolve.ts +91 -0
- package/src/modules/customer_accounts/api/login.ts +14 -3
- package/src/modules/customer_accounts/api/magic-link/request.ts +14 -3
- package/src/modules/customer_accounts/api/password/reset-request.ts +15 -3
- package/src/modules/customer_accounts/api/signup.ts +36 -5
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.tsx +70 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +66 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.tsx +78 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.tsx +90 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.tsx +43 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.tsx +178 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.tsx +56 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.tsx +69 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.ts +10 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.ts +31 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.ts +26 -0
- package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +411 -0
- package/src/modules/customer_accounts/data/enrichers.ts +95 -12
- package/src/modules/customer_accounts/data/entities.ts +80 -1
- package/src/modules/customer_accounts/data/guards.ts +155 -0
- package/src/modules/customer_accounts/data/validators.ts +26 -0
- package/src/modules/customer_accounts/di.ts +35 -1
- package/src/modules/customer_accounts/events.ts +8 -1
- package/src/modules/customer_accounts/i18n/de.json +78 -0
- package/src/modules/customer_accounts/i18n/en.json +78 -0
- package/src/modules/customer_accounts/i18n/es.json +78 -0
- package/src/modules/customer_accounts/i18n/pl.json +78 -0
- package/src/modules/customer_accounts/lib/customerAuthServer.ts +44 -8
- package/src/modules/customer_accounts/lib/customerUrl.ts +72 -0
- package/src/modules/customer_accounts/lib/hostname.ts +76 -0
- package/src/modules/customer_accounts/lib/platformDomains.ts +14 -0
- package/src/modules/customer_accounts/lib/proxyRanges.ts +85 -0
- package/src/modules/customer_accounts/lib/rateLimiter.ts +10 -0
- package/src/modules/customer_accounts/lib/resolveTenantContext.ts +96 -0
- package/src/modules/customer_accounts/lib/secretCompare.ts +20 -0
- package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +341 -0
- package/src/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.ts +38 -0
- package/src/modules/customer_accounts/notifications.client.ts +76 -0
- package/src/modules/customer_accounts/notifications.ts +76 -0
- package/src/modules/customer_accounts/services/domainMappingService.ts +632 -0
- package/src/modules/customer_accounts/setup.ts +81 -1
- package/src/modules/customer_accounts/subscribers/invalidateDomainCache.ts +35 -0
- package/src/modules/customer_accounts/subscribers/notifyDomainActivated.ts +32 -0
- package/src/modules/customer_accounts/subscribers/notifyDomainDnsFailed.ts +33 -0
- package/src/modules/customer_accounts/subscribers/notifyDomainTlsFailed.ts +34 -0
- package/src/modules/customer_accounts/subscribers/notifyDomainVerified.ts +32 -0
- package/src/modules/customer_accounts/workers/domainTlsRetryWorker.ts +84 -0
- package/src/modules/customer_accounts/workers/domainVerificationWorker.ts +45 -0
- package/src/modules/customers/api/companies/route.ts +4 -9
- package/src/modules/customers/api/deals/route.ts +4 -9
- package/src/modules/customers/api/people/route.ts +4 -9
- package/src/modules/customers/api/utils.ts +0 -14
- package/src/modules/customers/backend/customers/companies/page.tsx +321 -237
- package/src/modules/customers/backend/customers/deals/page.tsx +321 -455
- package/src/modules/customers/backend/customers/people/page.tsx +331 -240
- package/src/modules/customers/components/detail/assignableStaff.ts +21 -0
- package/src/modules/customers/i18n/de.json +31 -0
- package/src/modules/customers/i18n/en.json +31 -0
- package/src/modules/customers/i18n/es.json +31 -0
- package/src/modules/customers/i18n/pl.json +31 -0
- package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.tsx +197 -40
- package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.ts +13 -7
- package/src/modules/customers/widgets/injection-table.ts +6 -0
- package/src/modules/perspectives/services/perspectiveService.ts +30 -2
- package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +1 -0
- package/src/modules/query_index/lib/engine.ts +46 -8
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const id = "id";
|
|
2
|
+
export const hostname = "hostname";
|
|
3
|
+
export const tenant_id = "tenant_id";
|
|
4
|
+
export const organization_id = "organization_id";
|
|
5
|
+
export const replaces_domain = "replaces_domain";
|
|
6
|
+
export const provider = "provider";
|
|
7
|
+
export const status = "status";
|
|
8
|
+
export const verified_at = "verified_at";
|
|
9
|
+
export const last_dns_check_at = "last_dns_check_at";
|
|
10
|
+
export const dns_failure_reason = "dns_failure_reason";
|
|
11
|
+
export const tls_failure_reason = "tls_failure_reason";
|
|
12
|
+
export const tls_retry_count = "tls_retry_count";
|
|
13
|
+
export const created_at = "created_at";
|
|
14
|
+
export const updated_at = "updated_at";
|
|
@@ -262,7 +262,8 @@ export const M = {
|
|
|
262
262
|
"customer_user_session": "customer_accounts:customer_user_session",
|
|
263
263
|
"customer_user_email_verification": "customer_accounts:customer_user_email_verification",
|
|
264
264
|
"customer_user_password_reset": "customer_accounts:customer_user_password_reset",
|
|
265
|
-
"customer_user_invitation": "customer_accounts:customer_user_invitation"
|
|
265
|
+
"customer_user_invitation": "customer_accounts:customer_user_invitation",
|
|
266
|
+
"domain_mapping": "customer_accounts:domain_mapping"
|
|
266
267
|
}
|
|
267
268
|
} as const;
|
|
268
269
|
|
|
@@ -985,6 +985,22 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
|
|
|
985
985
|
"created_at": "created_at",
|
|
986
986
|
"updated_at": "updated_at"
|
|
987
987
|
},
|
|
988
|
+
"domain_mapping": {
|
|
989
|
+
"id": "id",
|
|
990
|
+
"hostname": "hostname",
|
|
991
|
+
"tenant_id": "tenant_id",
|
|
992
|
+
"organization_id": "organization_id",
|
|
993
|
+
"replaces_domain": "replaces_domain",
|
|
994
|
+
"provider": "provider",
|
|
995
|
+
"status": "status",
|
|
996
|
+
"verified_at": "verified_at",
|
|
997
|
+
"last_dns_check_at": "last_dns_check_at",
|
|
998
|
+
"dns_failure_reason": "dns_failure_reason",
|
|
999
|
+
"tls_failure_reason": "tls_failure_reason",
|
|
1000
|
+
"tls_retry_count": "tls_retry_count",
|
|
1001
|
+
"created_at": "created_at",
|
|
1002
|
+
"updated_at": "updated_at"
|
|
1003
|
+
},
|
|
988
1004
|
"encryption_map": {
|
|
989
1005
|
"id": "id",
|
|
990
1006
|
"entity_id": "entity_id",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.6.1-develop.
|
|
3
|
+
"version": "0.6.1-develop.3278.1.a4d26475e4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -237,12 +237,12 @@
|
|
|
237
237
|
"ts-pattern": "^5.0.0"
|
|
238
238
|
},
|
|
239
239
|
"peerDependencies": {
|
|
240
|
-
"@open-mercato/ai-assistant": "0.6.1-develop.
|
|
241
|
-
"@open-mercato/shared": "0.6.1-develop.
|
|
240
|
+
"@open-mercato/ai-assistant": "0.6.1-develop.3278.1.a4d26475e4",
|
|
241
|
+
"@open-mercato/shared": "0.6.1-develop.3278.1.a4d26475e4"
|
|
242
242
|
},
|
|
243
243
|
"devDependencies": {
|
|
244
|
-
"@open-mercato/ai-assistant": "0.6.1-develop.
|
|
245
|
-
"@open-mercato/shared": "0.6.1-develop.
|
|
244
|
+
"@open-mercato/ai-assistant": "0.6.1-develop.3278.1.a4d26475e4",
|
|
245
|
+
"@open-mercato/shared": "0.6.1-develop.3278.1.a4d26475e4",
|
|
246
246
|
"@testing-library/dom": "^10.4.1",
|
|
247
247
|
"@testing-library/jest-dom": "^6.9.1",
|
|
248
248
|
"@testing-library/react": "^16.3.1",
|
|
@@ -94,10 +94,6 @@ function parseCurrencyAmount(value: string): number {
|
|
|
94
94
|
return Number.parseFloat(lastMatch.replace('$', ''));
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
function normalizeAdjustmentKindValue(kindLabel: string): string {
|
|
98
|
-
return kindLabel.trim().toLowerCase().replace(/\s+/g, '_');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
97
|
function readId(payload: unknown, keys: string[]): string | null {
|
|
102
98
|
if (!payload || typeof payload !== 'object') return null;
|
|
103
99
|
const map = payload as Record<string, unknown>;
|
|
@@ -1099,32 +1095,40 @@ export async function addAdjustment(page: Page, options: AddAdjustmentOptions):
|
|
|
1099
1095
|
// Radix Select trigger — target by CrudForm field id (kind picker)
|
|
1100
1096
|
const kindTrigger = dialog.locator('[data-crud-field-id="kind"] [role="combobox"]').first();
|
|
1101
1097
|
await expect(kindTrigger).toBeVisible({ timeout: TEST_WAIT_TIMEOUT_MS });
|
|
1102
|
-
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
if ((await kindTrigger.count()) > 0) {
|
|
1111
|
-
const expectedKindValue = normalizeAdjustmentKindValue(options.kindLabel ?? 'Surcharge');
|
|
1112
|
-
const kindLabel = options.kindLabel ?? 'Surcharge';
|
|
1113
|
-
await kindTrigger.click();
|
|
1114
|
-
const option = page.getByRole('option', { name: new RegExp(`^${escapeRegExp(kindLabel)}$`, 'i') }).first();
|
|
1115
|
-
const optionVisible = await option.waitFor({ state: 'visible', timeout: 2_000 }).then(
|
|
1116
|
-
() => true,
|
|
1117
|
-
() => false,
|
|
1098
|
+
const kindLabel = options.kindLabel ?? 'Surcharge';
|
|
1099
|
+
const selectKindOption = async (): Promise<void> => {
|
|
1100
|
+
if ((await kindTrigger.count()) === 0) return;
|
|
1101
|
+
await waitForOptionalTextToDisappear(
|
|
1102
|
+
dialog,
|
|
1103
|
+
/Loading adjustment kinds…|Loading adjustment kinds\.\.\./i,
|
|
1104
|
+
TEST_WAIT_TIMEOUT_MS,
|
|
1118
1105
|
);
|
|
1106
|
+
await expect(kindTrigger).toBeEnabled({ timeout: TEST_WAIT_TIMEOUT_MS });
|
|
1107
|
+
await kindTrigger.click();
|
|
1108
|
+
const kindOption = page.getByRole('option', { name: new RegExp(`^${escapeRegExp(kindLabel)}$`, 'i') }).first();
|
|
1109
|
+
const optionVisible = await kindOption
|
|
1110
|
+
.waitFor({ state: 'visible', timeout: TEST_WAIT_TIMEOUT_MS })
|
|
1111
|
+
.then(() => true, () => false);
|
|
1119
1112
|
if (optionVisible) {
|
|
1120
|
-
await
|
|
1113
|
+
await kindOption.click({ force: true });
|
|
1121
1114
|
} else {
|
|
1115
|
+
// Fallback: drive selection via keyboard when modal-backdrop click interception
|
|
1116
|
+
// hides the rendered option. Brought forward from develop.
|
|
1122
1117
|
await page.keyboard.type(kindLabel.charAt(0));
|
|
1123
1118
|
await page.waitForTimeout(150);
|
|
1124
1119
|
await page.keyboard.press('Enter');
|
|
1125
1120
|
}
|
|
1126
|
-
|
|
1127
|
-
}
|
|
1121
|
+
await expect(kindTrigger).toContainText(kindLabel, { timeout: 2_000 });
|
|
1122
|
+
};
|
|
1123
|
+
|
|
1124
|
+
// Select kind first — the Radix Select interaction can trigger CrudForm re-renders that
|
|
1125
|
+
// clear inputs filled before it, so we run the dropdown sequence up front and then fill
|
|
1126
|
+
// the remaining fields once.
|
|
1127
|
+
await selectKindOption();
|
|
1128
|
+
|
|
1129
|
+
const labelInput = dialog.getByPlaceholder(/e\.g\. Shipping fee/i).first();
|
|
1130
|
+
await expect(labelInput).toBeVisible({ timeout: TEST_WAIT_TIMEOUT_MS });
|
|
1131
|
+
await fillControlledInput(labelInput, options.label);
|
|
1128
1132
|
|
|
1129
1133
|
const fixedAmountButton = dialog.getByRole('button', { name: /^Fixed amount$/i }).first();
|
|
1130
1134
|
if ((await fixedAmountButton.count()) > 0) {
|
|
@@ -3,6 +3,7 @@ export const features = [
|
|
|
3
3
|
{ id: 'customer_accounts.manage', title: 'Manage customer accounts', module: 'customer_accounts' },
|
|
4
4
|
{ id: 'customer_accounts.roles.manage', title: 'Manage customer roles', module: 'customer_accounts' },
|
|
5
5
|
{ id: 'customer_accounts.invite', title: 'Invite customer users', module: 'customer_accounts' },
|
|
6
|
+
{ id: 'customer_accounts.domain.manage', title: 'Manage custom portal domains', module: 'customer_accounts' },
|
|
6
7
|
]
|
|
7
8
|
|
|
8
9
|
export default features
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
|
|
4
|
+
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
5
|
+
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
6
|
+
import { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'
|
|
7
|
+
import {
|
|
8
|
+
validateCrudMutationGuard,
|
|
9
|
+
runCrudMutationGuardAfterSuccess,
|
|
10
|
+
} from '@open-mercato/shared/lib/crud/mutation-guard'
|
|
11
|
+
import { DomainMappingService } from '@open-mercato/core/modules/customer_accounts/services/domainMappingService'
|
|
12
|
+
|
|
13
|
+
const FEATURE = 'customer_accounts.domain.manage'
|
|
14
|
+
|
|
15
|
+
export const metadata = {
|
|
16
|
+
POST: { requireAuth: true, requireFeatures: [FEATURE] },
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function POST(req: Request, ctx: { params: Promise<{ id: string }> }) {
|
|
20
|
+
const auth = await getAuthFromRequest(req)
|
|
21
|
+
if (!auth || !auth.tenantId) return NextResponse.json({ ok: false, error: 'Unauthorized' }, { status: 401 })
|
|
22
|
+
|
|
23
|
+
const container = await createRequestContainer()
|
|
24
|
+
const rbac = container.resolve('rbacService') as RbacService
|
|
25
|
+
const allowed = await rbac.userHasAllFeatures(auth.sub, [FEATURE], {
|
|
26
|
+
tenantId: auth.tenantId,
|
|
27
|
+
organizationId: auth.orgId,
|
|
28
|
+
})
|
|
29
|
+
if (!allowed) return NextResponse.json({ ok: false, error: 'Forbidden' }, { status: 403 })
|
|
30
|
+
|
|
31
|
+
const { id } = await ctx.params
|
|
32
|
+
const service = container.resolve('domainMappingService') as DomainMappingService
|
|
33
|
+
const record = await service.findById(id, { tenantId: auth.tenantId })
|
|
34
|
+
if (!record) return NextResponse.json({ ok: false, error: 'Not found' }, { status: 404 })
|
|
35
|
+
|
|
36
|
+
const guardResult = await validateCrudMutationGuard(container, {
|
|
37
|
+
tenantId: auth.tenantId,
|
|
38
|
+
organizationId: record.organizationId,
|
|
39
|
+
userId: auth.sub,
|
|
40
|
+
resourceKind: 'customer_accounts.domain_mapping',
|
|
41
|
+
resourceId: id,
|
|
42
|
+
operation: 'update',
|
|
43
|
+
requestMethod: req.method,
|
|
44
|
+
requestHeaders: req.headers,
|
|
45
|
+
})
|
|
46
|
+
if (guardResult && !guardResult.ok) {
|
|
47
|
+
return NextResponse.json(guardResult.body, { status: guardResult.status })
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let updated
|
|
51
|
+
try {
|
|
52
|
+
updated = await service.healthCheck(id)
|
|
53
|
+
} catch (err) {
|
|
54
|
+
return NextResponse.json(
|
|
55
|
+
{ ok: false, error: err instanceof Error ? err.message : 'Health check failed' },
|
|
56
|
+
{ status: 500 },
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {
|
|
61
|
+
await runCrudMutationGuardAfterSuccess(container, {
|
|
62
|
+
tenantId: auth.tenantId,
|
|
63
|
+
organizationId: record.organizationId,
|
|
64
|
+
userId: auth.sub,
|
|
65
|
+
resourceKind: 'customer_accounts.domain_mapping',
|
|
66
|
+
resourceId: id,
|
|
67
|
+
operation: 'update',
|
|
68
|
+
requestMethod: req.method,
|
|
69
|
+
requestHeaders: req.headers,
|
|
70
|
+
metadata: guardResult.metadata ?? null,
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return NextResponse.json({
|
|
75
|
+
ok: true,
|
|
76
|
+
domainMapping: {
|
|
77
|
+
id: updated.id,
|
|
78
|
+
hostname: updated.hostname,
|
|
79
|
+
status: updated.status,
|
|
80
|
+
tlsRetryCount: updated.tlsRetryCount,
|
|
81
|
+
tlsFailureReason: updated.tlsFailureReason ?? null,
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const errorSchema = z.object({ ok: z.literal(false), error: z.string() })
|
|
87
|
+
|
|
88
|
+
export const openApi: OpenApiRouteDoc = {
|
|
89
|
+
tag: 'CustomerAccounts',
|
|
90
|
+
summary: 'TLS health check for a custom domain mapping',
|
|
91
|
+
methods: {
|
|
92
|
+
POST: {
|
|
93
|
+
summary: 'Trigger TLS health check',
|
|
94
|
+
description:
|
|
95
|
+
'Runs an HTTPS probe to verify Traefik has provisioned a certificate. On success: transitions the mapping to active.',
|
|
96
|
+
responses: [
|
|
97
|
+
{
|
|
98
|
+
status: 200,
|
|
99
|
+
description: 'OK',
|
|
100
|
+
schema: z.object({
|
|
101
|
+
ok: z.literal(true),
|
|
102
|
+
domainMapping: z.object({
|
|
103
|
+
id: z.string().uuid(),
|
|
104
|
+
hostname: z.string(),
|
|
105
|
+
status: z.string(),
|
|
106
|
+
tlsRetryCount: z.number().int().nonnegative(),
|
|
107
|
+
tlsFailureReason: z.string().nullable(),
|
|
108
|
+
}),
|
|
109
|
+
}),
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
errors: [
|
|
113
|
+
{ status: 401, description: 'Unauthorized', schema: errorSchema },
|
|
114
|
+
{ status: 403, description: 'Forbidden', schema: errorSchema },
|
|
115
|
+
{ status: 404, description: 'Not found', schema: errorSchema },
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
|
|
4
|
+
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
5
|
+
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
6
|
+
import { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'
|
|
7
|
+
import {
|
|
8
|
+
validateCrudMutationGuard,
|
|
9
|
+
runCrudMutationGuardAfterSuccess,
|
|
10
|
+
} from '@open-mercato/shared/lib/crud/mutation-guard'
|
|
11
|
+
import { DomainMappingService } from '@open-mercato/core/modules/customer_accounts/services/domainMappingService'
|
|
12
|
+
|
|
13
|
+
const FEATURE = 'customer_accounts.domain.manage'
|
|
14
|
+
|
|
15
|
+
export const metadata = {
|
|
16
|
+
POST: { requireAuth: true, requireFeatures: [FEATURE] },
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function POST(req: Request, ctx: { params: Promise<{ id: string }> }) {
|
|
20
|
+
const auth = await getAuthFromRequest(req)
|
|
21
|
+
if (!auth || !auth.tenantId) return NextResponse.json({ ok: false, error: 'Unauthorized' }, { status: 401 })
|
|
22
|
+
|
|
23
|
+
const container = await createRequestContainer()
|
|
24
|
+
const rbac = container.resolve('rbacService') as RbacService
|
|
25
|
+
const allowed = await rbac.userHasAllFeatures(auth.sub, [FEATURE], {
|
|
26
|
+
tenantId: auth.tenantId,
|
|
27
|
+
organizationId: auth.orgId,
|
|
28
|
+
})
|
|
29
|
+
if (!allowed) return NextResponse.json({ ok: false, error: 'Forbidden' }, { status: 403 })
|
|
30
|
+
|
|
31
|
+
const { id } = await ctx.params
|
|
32
|
+
const service = container.resolve('domainMappingService') as DomainMappingService
|
|
33
|
+
const record = await service.findById(id, { tenantId: auth.tenantId })
|
|
34
|
+
if (!record) return NextResponse.json({ ok: false, error: 'Not found' }, { status: 404 })
|
|
35
|
+
|
|
36
|
+
const guardResult = await validateCrudMutationGuard(container, {
|
|
37
|
+
tenantId: auth.tenantId,
|
|
38
|
+
organizationId: record.organizationId,
|
|
39
|
+
userId: auth.sub,
|
|
40
|
+
resourceKind: 'customer_accounts.domain_mapping',
|
|
41
|
+
resourceId: id,
|
|
42
|
+
operation: 'update',
|
|
43
|
+
requestMethod: req.method,
|
|
44
|
+
requestHeaders: req.headers,
|
|
45
|
+
})
|
|
46
|
+
if (guardResult && !guardResult.ok) {
|
|
47
|
+
return NextResponse.json(guardResult.body, { status: guardResult.status })
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let result
|
|
51
|
+
try {
|
|
52
|
+
result = await service.verify(id)
|
|
53
|
+
} catch (err) {
|
|
54
|
+
return NextResponse.json(
|
|
55
|
+
{ ok: false, error: err instanceof Error ? err.message : 'DNS verification failed' },
|
|
56
|
+
{ status: 500 },
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {
|
|
61
|
+
await runCrudMutationGuardAfterSuccess(container, {
|
|
62
|
+
tenantId: auth.tenantId,
|
|
63
|
+
organizationId: record.organizationId,
|
|
64
|
+
userId: auth.sub,
|
|
65
|
+
resourceKind: 'customer_accounts.domain_mapping',
|
|
66
|
+
resourceId: id,
|
|
67
|
+
operation: 'update',
|
|
68
|
+
requestMethod: req.method,
|
|
69
|
+
requestHeaders: req.headers,
|
|
70
|
+
metadata: guardResult.metadata ?? null,
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return NextResponse.json({
|
|
75
|
+
ok: true,
|
|
76
|
+
domainMapping: {
|
|
77
|
+
id: result.domainMapping.id,
|
|
78
|
+
hostname: result.domainMapping.hostname,
|
|
79
|
+
status: result.domainMapping.status,
|
|
80
|
+
verifiedAt: result.domainMapping.verifiedAt?.toISOString() ?? null,
|
|
81
|
+
lastDnsCheckAt: result.domainMapping.lastDnsCheckAt?.toISOString() ?? null,
|
|
82
|
+
dnsFailureReason: result.domainMapping.dnsFailureReason ?? null,
|
|
83
|
+
},
|
|
84
|
+
diagnostics: result.diagnostics ?? null,
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const errorSchema = z.object({ ok: z.literal(false), error: z.string() })
|
|
89
|
+
|
|
90
|
+
export const openApi: OpenApiRouteDoc = {
|
|
91
|
+
tag: 'CustomerAccounts',
|
|
92
|
+
summary: 'Verify a custom domain mapping (DNS check)',
|
|
93
|
+
methods: {
|
|
94
|
+
POST: {
|
|
95
|
+
summary: 'Trigger DNS verification',
|
|
96
|
+
description:
|
|
97
|
+
'Runs DNS verification (CNAME → A → reverse-resolve fallback) for the domain mapping. Returns diagnostics on failure.',
|
|
98
|
+
responses: [
|
|
99
|
+
{
|
|
100
|
+
status: 200,
|
|
101
|
+
description: 'OK — see status',
|
|
102
|
+
schema: z.object({
|
|
103
|
+
ok: z.literal(true),
|
|
104
|
+
domainMapping: z.object({
|
|
105
|
+
id: z.string().uuid(),
|
|
106
|
+
hostname: z.string(),
|
|
107
|
+
status: z.string(),
|
|
108
|
+
verifiedAt: z.string().nullable(),
|
|
109
|
+
lastDnsCheckAt: z.string().nullable(),
|
|
110
|
+
dnsFailureReason: z.string().nullable(),
|
|
111
|
+
}),
|
|
112
|
+
diagnostics: z.unknown().nullable(),
|
|
113
|
+
}),
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
errors: [
|
|
117
|
+
{ status: 401, description: 'Unauthorized', schema: errorSchema },
|
|
118
|
+
{ status: 403, description: 'Forbidden', schema: errorSchema },
|
|
119
|
+
{ status: 404, description: 'Not found', schema: errorSchema },
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
}
|