@open-mercato/core 0.6.8-develop.7068.1.c55b52e1a1 → 0.6.8-develop.7072.1.19c2a8bbe0

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 (51) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +5 -1
  3. package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
  4. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +5 -1
  5. package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
  6. package/dist/modules/auth/components/AclEditor.js +39 -30
  7. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  8. package/dist/modules/customers/api/companies/[id]/people/route.js +1 -1
  9. package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
  10. package/dist/modules/customers/api/companies/[id]/route.js +8 -9
  11. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  12. package/dist/modules/customers/api/deals/[id]/companies/route.js +1 -1
  13. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
  14. package/dist/modules/customers/api/deals/[id]/people/route.js +1 -1
  15. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  16. package/dist/modules/customers/api/deals/[id]/route.js +8 -25
  17. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  18. package/dist/modules/customers/api/deals/[id]/stats/route.js +3 -22
  19. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
  20. package/dist/modules/customers/api/entity-roles-factory.js +4 -4
  21. package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
  22. package/dist/modules/customers/api/people/[id]/companies/context.js +1 -1
  23. package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
  24. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +1 -1
  25. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  26. package/dist/modules/customers/api/people/[id]/route.js +11 -10
  27. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  28. package/dist/modules/customers/lib/detailReadAccess.js +12 -0
  29. package/dist/modules/customers/lib/detailReadAccess.js.map +7 -0
  30. package/package.json +7 -7
  31. package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +5 -2
  32. package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +5 -2
  33. package/src/modules/auth/components/AclEditor.tsx +63 -33
  34. package/src/modules/auth/i18n/de.json +380 -0
  35. package/src/modules/auth/i18n/en.json +380 -0
  36. package/src/modules/auth/i18n/es.json +380 -0
  37. package/src/modules/auth/i18n/ko.json +380 -0
  38. package/src/modules/auth/i18n/pl.json +382 -2
  39. package/src/modules/customers/api/companies/[id]/people/route.ts +4 -1
  40. package/src/modules/customers/api/companies/[id]/route.ts +13 -10
  41. package/src/modules/customers/api/deals/[id]/companies/route.ts +4 -1
  42. package/src/modules/customers/api/deals/[id]/people/route.ts +4 -1
  43. package/src/modules/customers/api/deals/[id]/route.ts +17 -28
  44. package/src/modules/customers/api/deals/[id]/stats/route.ts +10 -25
  45. package/src/modules/customers/api/entity-roles-factory.ts +8 -4
  46. package/src/modules/customers/api/people/[id]/companies/context.ts +4 -1
  47. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +4 -1
  48. package/src/modules/customers/api/people/[id]/route.ts +16 -11
  49. package/src/modules/customers/lib/detailReadAccess.ts +35 -0
  50. package/src/modules/dashboards/i18n/es.json +4 -4
  51. package/src/modules/dashboards/i18n/pl.json +7 -7
@@ -4,14 +4,10 @@ import { Button } from '@open-mercato/ui/primitives/button'
4
4
  import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
5
5
  import Link from 'next/link'
6
6
  import { hasFeature, matchFeature } from '@open-mercato/shared/security/features'
7
- import { useT } from '@open-mercato/shared/lib/i18n/context'
7
+ import { useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'
8
8
  import type { FeatureDescriptor } from '@open-mercato/shared/security/aclDependencies'
9
9
  import { AclDependencyDiagnosticsPanel } from './AclDependencyDiagnosticsPanel'
10
10
 
11
- function toTitleCase(value: string): string {
12
- return value.replace(/[-_.]/g, ' ').replace(/\b\w/g, (char) => char.toUpperCase())
13
- }
14
-
15
11
  function normalizeFeatureArray(input: unknown): string[] {
16
12
  if (!Array.isArray(input)) return []
17
13
  const dedup = new Set<string>()
@@ -30,12 +26,16 @@ function isTenantRestrictedFeature(feature: string): boolean {
30
26
  return false
31
27
  }
32
28
 
33
- function formatWildcardLabel(moduleId: string, wildcard: string): string {
29
+ function formatWildcardLabel(t: TranslateFn, moduleId: string, wildcard: string): string {
34
30
  if (!wildcard.endsWith('.*')) return wildcard
35
31
  const prefix = `${moduleId}.`
36
32
  const suffix = wildcard.startsWith(prefix) ? wildcard.slice(prefix.length, -2) : wildcard.slice(0, -2)
37
- if (!suffix) return 'All features'
38
- return `All ${suffix.split('.').map(toTitleCase).join(' / ')}`
33
+ if (!suffix) return t('auth.acl.wildcards.allFeatures', 'All features')
34
+ const group = suffix
35
+ .split('.')
36
+ .map((segment) => segment.replace(/[-_]/g, ' ').replace(/\b\w/g, (char) => char.toUpperCase()))
37
+ .join(' / ')
38
+ return t('auth.acl.wildcards.allGroup', 'All permissions in {group}', { group })
39
39
  }
40
40
 
41
41
  type Feature = { id: string; title: string; module: string; dependsOn?: string[] }
@@ -257,19 +257,28 @@ export function AclEditor({
257
257
  const grouped = React.useMemo(() => {
258
258
  const moduleMap = new Map<string, string>()
259
259
  for (const m of modules) {
260
- moduleMap.set(m.id, m.title)
260
+ moduleMap.set(m.id, t(`auth.acl.modules.${m.id}`, m.title))
261
261
  }
262
262
  const map = new Map<string, { moduleId: string; moduleTitle: string; features: Feature[] }>()
263
263
  for (const f of features) {
264
264
  const moduleId = f.module
265
265
  const moduleTitle = moduleMap.get(moduleId) || moduleId
266
+ const localizedFeature = {
267
+ ...f,
268
+ title: t(`auth.acl.features.${f.id}`, f.title),
269
+ }
266
270
  if (!map.has(moduleId)) {
267
271
  map.set(moduleId, { moduleId, moduleTitle, features: [] })
268
272
  }
269
- map.get(moduleId)!.features.push(f)
273
+ map.get(moduleId)!.features.push(localizedFeature)
270
274
  }
271
275
  return Array.from(map.values()).sort((a, b) => a.moduleTitle.localeCompare(b.moduleTitle))
272
- }, [features, modules])
276
+ }, [features, modules, t])
277
+
278
+ const localizedFeatures = React.useMemo(
279
+ () => grouped.flatMap((group) => group.features),
280
+ [grouped],
281
+ )
273
282
 
274
283
  const hasGlobalWildcard = granted.includes('*')
275
284
  const hasOrganizationRestriction = Array.isArray(organizations) && organizations.length > 0
@@ -305,22 +314,28 @@ export function AclEditor({
305
314
 
306
315
  const isFeatureChecked = (featureId: string) => hasFeature(granted, featureId)
307
316
 
308
- if (loading) return <div className="text-sm text-muted-foreground">Loading ACL…</div>
317
+ if (loading) {
318
+ return (
319
+ <div className="text-sm text-muted-foreground">
320
+ {t('auth.acl.loading', 'Loading access control…')}
321
+ </div>
322
+ )
323
+ }
309
324
 
310
325
  const showRoleBanner = kind === 'user' && !hasCustomAcl && !overrideEnabled
311
326
 
312
327
  return (
313
328
  <div className="space-y-4">
314
329
  {showRoleBanner && (
315
- <div className="rounded-lg border border-blue-200 bg-blue-50 p-4">
316
- <div className="text-sm font-medium text-blue-900 mb-2">
317
- Permissions inherited from roles
330
+ <div className="rounded-lg border border-status-info-border bg-status-info-bg p-4">
331
+ <div className="text-sm font-medium text-status-info-text mb-2">
332
+ {t('auth.acl.inherited.title', 'Permissions inherited from roles')}
318
333
  </div>
319
- <div className="text-sm text-blue-700 mb-3">
320
- This user currently inherits permissions from their assigned roles.
334
+ <div className="text-sm text-status-info-text mb-3">
335
+ {t('auth.acl.inherited.description', 'This user currently inherits permissions from their assigned roles.')}
321
336
  {roleDetails.length > 0 && (
322
337
  <span>
323
- {' '}Assigned roles:{' '}
338
+ {' '}{t('auth.acl.inherited.assignedRoles', 'Assigned roles:')}{' '}
324
339
  {roleDetails.map((role, idx) => {
325
340
  const roleId = typeof role?.id === 'string' && role.id.length > 0 ? role.id : `role-${idx}`
326
341
  const roleName = typeof role?.name === 'string' && role.name.length > 0 ? role.name : roleId
@@ -329,7 +344,7 @@ export function AclEditor({
329
344
  {idx > 0 && ', '}
330
345
  <Link
331
346
  href={`/backend/roles/${roleId}/edit`}
332
- className="font-semibold text-blue-900 underline hover:text-blue-950 transition-colors"
347
+ className="font-semibold text-status-info-text underline"
333
348
  >
334
349
  {roleName}
335
350
  </Link>
@@ -347,8 +362,8 @@ export function AclEditor({
347
362
  checked={overrideEnabled}
348
363
  onChange={(e) => setOverrideEnabled(e.target.checked)}
349
364
  />
350
- <label htmlFor="overrideAcl" className="text-sm text-blue-900 font-medium">
351
- Override permissions for this user only
365
+ <label htmlFor="overrideAcl" className="text-sm text-status-info-text font-medium">
366
+ {t('auth.acl.inherited.override', 'Override permissions for this user only')}
352
367
  </label>
353
368
  </div>
354
369
  </div>
@@ -364,31 +379,39 @@ export function AclEditor({
364
379
  disabled={!actorIsSuperAdmin}
365
380
  onChange={(e) => setIsSuperAdmin(!!e.target.checked)}
366
381
  />
367
- <label htmlFor="isSuperAdmin" className="text-sm">Super Admin (all features)</label>
382
+ <label htmlFor="isSuperAdmin" className="text-sm">
383
+ {t('auth.acl.superAdmin.label', 'Super Admin (all features)')}
384
+ </label>
368
385
  </div>
369
386
  {!actorIsSuperAdmin && (
370
- <p className="text-xs text-muted-foreground">Only super administrators can change this option.</p>
387
+ <p className="text-xs text-muted-foreground">
388
+ {t('auth.acl.superAdmin.hint', 'Only super administrators can change this option.')}
389
+ </p>
371
390
  )}
372
391
  {!isSuperAdmin && (
373
392
  <>
374
393
  {hasGlobalWildcard && (
375
- <div className="rounded border border-blue-200 bg-blue-50 p-3">
376
- <div className="text-sm font-medium text-blue-900">Global wildcard (*) enabled</div>
377
- <div className="text-xs text-blue-700 mt-1">This grants access to all features in the system.</div>
394
+ <div className="rounded border border-status-info-border bg-status-info-bg p-3">
395
+ <div className="text-sm font-medium text-status-info-text">
396
+ {t('auth.acl.globalWildcard.title', 'Global wildcard (*) enabled')}
397
+ </div>
398
+ <div className="text-xs text-status-info-text mt-1">
399
+ {t('auth.acl.globalWildcard.description', 'This grants access to all features in the system.')}
400
+ </div>
378
401
  <Button
379
402
  variant="outline"
380
403
  size="sm"
381
404
  className="mt-2"
382
405
  onClick={() => updateGranted((prev) => prev.filter((x) => x !== '*'))}
383
406
  >
384
- Remove global wildcard
407
+ {t('auth.acl.globalWildcard.remove', 'Remove global wildcard')}
385
408
  </Button>
386
409
  </div>
387
410
  )}
388
411
  {!hasGlobalWildcard && (
389
412
  <AclDependencyDiagnosticsPanel
390
413
  granted={granted}
391
- catalog={features as readonly FeatureDescriptor[]}
414
+ catalog={localizedFeatures as readonly FeatureDescriptor[]}
392
415
  onGrantedChange={updateGranted}
393
416
  hideUnknownReferences={process.env.NODE_ENV === 'production'}
394
417
  />
@@ -433,8 +456,13 @@ export function AclEditor({
433
456
  onChange={(e) => toggleModuleWildcard(group.moduleId, e.target.checked)}
434
457
  />
435
458
  <label htmlFor={`module-${group.moduleId}`} className="text-sm text-muted-foreground">
436
- All {moduleWildcard && !hasGlobalWildcard ? <span className="font-medium text-blue-600">({group.moduleId}.*)</span> : ''}
437
- {moduleRestricted ? <span className="ml-2 text-xs font-medium text-muted-foreground">(manage via super admin)</span> : null}
459
+ {t('auth.acl.allModuleFeatures', 'All')}{' '}
460
+ {moduleWildcard && !hasGlobalWildcard ? <span className="font-medium text-status-info-text">({group.moduleId}.*)</span> : ''}
461
+ {moduleRestricted ? (
462
+ <span className="ml-2 text-xs font-medium text-muted-foreground">
463
+ {t('auth.acl.manageViaSuperAdmin', '(manage via super admin)')}
464
+ </span>
465
+ ) : null}
438
466
  </label>
439
467
  </div>
440
468
  </div>
@@ -459,7 +487,7 @@ export function AclEditor({
459
487
  htmlFor={`wildcard-${wildcard}`}
460
488
  className={`text-sm ${disabled ? 'text-muted-foreground' : ''}`}
461
489
  >
462
- {formatWildcardLabel(group.moduleId, wildcard)}{' '}
490
+ {formatWildcardLabel(t, group.moduleId, wildcard)}{' '}
463
491
  <span className="text-muted-foreground text-xs font-mono">({wildcard})</span>
464
492
  {wildcardRestricted ? (
465
493
  <span className="ml-2 text-xs font-medium text-muted-foreground">
@@ -535,7 +563,9 @@ export function AclEditor({
535
563
  <div className="text-sm font-medium mb-2">
536
564
  {t('auth.acl.organizationsScope', 'Organizations scope')}
537
565
  </div>
538
- <div className="text-xs text-muted-foreground mb-2">Empty = all organizations. Select one or more to restrict.</div>
566
+ <div className="text-xs text-muted-foreground mb-2">
567
+ {t('auth.acl.organizationsScopeHint', 'Empty means all organizations. Select one or more to restrict access.')}
568
+ </div>
539
569
  <div className="grid grid-cols-1 md:grid-cols-2 gap-2">
540
570
  {orgOptions.map((o) => {
541
571
  const checked = organizations == null ? false : (organizations || []).includes(o.id)
@@ -557,7 +587,7 @@ export function AclEditor({
557
587
  <Button variant="outline" onClick={() => setOrganizations(null)}>{t('auth.acl.allowAllOrganizations', 'Allow all organizations')}</Button>
558
588
  </div>
559
589
  {showOrganizationWarning && (
560
- <div className="mt-3 rounded border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900">
590
+ <div className="mt-3 rounded border border-status-warning-border bg-status-warning-bg px-3 py-2 text-sm text-status-warning-text">
561
591
  {t('auth.acl.organizationWarning', 'Organization restrictions are saved only when at least one feature override is selected. Add a feature or enable a module wildcard before saving.')}
562
592
  </div>
563
593
  )}
@@ -3,6 +3,7 @@
3
3
  "auth.accessDenied.home": "Zur Startseite",
4
4
  "auth.accessDenied.message": "Du hast keine Berechtigung, diese Seite anzuzeigen. Bitte wende dich an deinen Administrator.",
5
5
  "auth.accessDenied.title": "Zugriff verweigert",
6
+ "auth.acl.allModuleFeatures": "All",
6
7
  "auth.acl.allowAllOrganizations": "Alle Organisationen zulassen",
7
8
  "auth.acl.deps.missing.add": "\"{dep}\" hinzufügen",
8
9
  "auth.acl.deps.missing.item": "\"{feature}\" benötigt:",
@@ -12,9 +13,388 @@
12
13
  "auth.acl.deps.orphaned.restore": "\"{dependency}\" wiederherstellen",
13
14
  "auth.acl.deps.orphaned.title": "Entfernung einer Berechtigung, die andere gewährte Berechtigungen benötigen:",
14
15
  "auth.acl.deps.unknown.title": "Einige deklarierte Abhängigkeiten passen zu keiner bekannten Berechtigung:",
16
+ "auth.acl.features.ai_assistant.conversations.manage": "Manage AI Assistant Conversations",
17
+ "auth.acl.features.ai_assistant.conversations.share": "Share AI Assistant Conversations",
18
+ "auth.acl.features.ai_assistant.mcp.serve": "Start MCP Server",
19
+ "auth.acl.features.ai_assistant.mcp_servers.manage": "Manage MCP Server Configurations",
20
+ "auth.acl.features.ai_assistant.mcp_servers.view": "View MCP Server Configurations",
21
+ "auth.acl.features.ai_assistant.settings.manage": "Manage AI Assistant Settings",
22
+ "auth.acl.features.ai_assistant.tools.list": "List MCP Tools",
23
+ "auth.acl.features.ai_assistant.view": "View AI Assistant Settings",
24
+ "auth.acl.features.analytics.view": "View analytics widgets",
25
+ "auth.acl.features.api_keys.create": "Create API keys",
26
+ "auth.acl.features.api_keys.delete": "Delete API keys",
27
+ "auth.acl.features.api_keys.view": "View API keys",
28
+ "auth.acl.features.attachments.manage": "Manage attachments",
29
+ "auth.acl.features.attachments.view": "View attachments",
30
+ "auth.acl.features.audit_logs.redo_self": "Redo own actions",
31
+ "auth.acl.features.audit_logs.redo_tenant": "Redo tenant actions",
32
+ "auth.acl.features.audit_logs.undo_self": "Undo own actions",
33
+ "auth.acl.features.audit_logs.undo_tenant": "Undo tenant actions",
34
+ "auth.acl.features.audit_logs.view_self": "View own audit logs",
35
+ "auth.acl.features.audit_logs.view_tenant": "View tenant audit logs",
36
+ "auth.acl.features.auth.acl.manage": "Manage ACLs",
37
+ "auth.acl.features.auth.roles.list": "List roles",
38
+ "auth.acl.features.auth.roles.manage": "Manage roles",
39
+ "auth.acl.features.auth.sidebar.manage": "Manage sidebar presets",
40
+ "auth.acl.features.auth.users.create": "Create users",
41
+ "auth.acl.features.auth.users.delete": "Delete users",
42
+ "auth.acl.features.auth.users.edit": "Edit users",
43
+ "auth.acl.features.auth.users.list": "List users",
44
+ "auth.acl.features.business_rules.execute": "Execute business rules manually",
45
+ "auth.acl.features.business_rules.manage": "Create, edit, and delete business rules",
46
+ "auth.acl.features.business_rules.manage_sets": "Manage rule sets",
47
+ "auth.acl.features.business_rules.view": "View business rules",
48
+ "auth.acl.features.business_rules.view_logs": "View rule execution logs",
49
+ "auth.acl.features.catalog.categories.manage": "Manage catalog categories",
50
+ "auth.acl.features.catalog.categories.view": "View catalog categories",
51
+ "auth.acl.features.catalog.pricing.manage": "Manage catalog pricing",
52
+ "auth.acl.features.catalog.products.manage": "Manage catalog products",
53
+ "auth.acl.features.catalog.products.view": "View catalog products",
54
+ "auth.acl.features.catalog.settings.manage": "Manage catalog settings",
55
+ "auth.acl.features.catalog.variants.manage": "Manage catalog variants",
56
+ "auth.acl.features.channel_apns.configure": "Configure APNs credentials",
57
+ "auth.acl.features.channel_apns.view": "View APNs channel configuration",
58
+ "auth.acl.features.channel_expo.configure": "Configure Expo push credentials",
59
+ "auth.acl.features.channel_expo.view": "View Expo push channel configuration",
60
+ "auth.acl.features.channel_fcm.configure": "Configure FCM credentials",
61
+ "auth.acl.features.channel_fcm.view": "View FCM channel configuration",
62
+ "auth.acl.features.channel_gmail.configure": "Configure Gmail OAuth defaults",
63
+ "auth.acl.features.channel_gmail.view": "View Gmail channel configuration",
64
+ "auth.acl.features.channel_imap.configure": "Configure IMAP channel defaults",
65
+ "auth.acl.features.channel_imap.view": "View IMAP channel configuration",
66
+ "auth.acl.features.checkout.create": "Create checkout links and templates",
67
+ "auth.acl.features.checkout.delete": "Delete checkout links and templates",
68
+ "auth.acl.features.checkout.edit": "Edit checkout links and templates",
69
+ "auth.acl.features.checkout.export": "Export checkout transactions",
70
+ "auth.acl.features.checkout.view": "View checkout links and transactions",
71
+ "auth.acl.features.checkout.viewPii": "View checkout customer PII",
72
+ "auth.acl.features.communication_channels.admin": "Administer all communication channels (tenant-wide)",
73
+ "auth.acl.features.communication_channels.assign": "Assign channel conversations",
74
+ "auth.acl.features.communication_channels.channel.import_history": "Import channel history",
75
+ "auth.acl.features.communication_channels.channel.push.manage": "Manage push delivery",
76
+ "auth.acl.features.communication_channels.connect_tenant_channel": "Connect tenant-wide communication channel",
77
+ "auth.acl.features.communication_channels.connect_user_channel": "Connect own communication channel",
78
+ "auth.acl.features.communication_channels.manage": "Manage communication channels",
79
+ "auth.acl.features.communication_channels.react": "React to channel messages",
80
+ "auth.acl.features.communication_channels.view": "View communication channels",
81
+ "auth.acl.features.configs.cache.manage": "Manage cache",
82
+ "auth.acl.features.configs.cache.view": "View cache overview",
83
+ "auth.acl.features.configs.manage": "Manage configuration",
84
+ "auth.acl.features.configs.system_status.view": "View system status",
85
+ "auth.acl.features.currencies.fetch.manage": "Manage currency fetch configuration",
86
+ "auth.acl.features.currencies.fetch.view": "View currency fetch configuration",
87
+ "auth.acl.features.currencies.manage": "Manage currencies",
88
+ "auth.acl.features.currencies.rates.manage": "Manage exchange rates",
89
+ "auth.acl.features.currencies.rates.view": "View exchange rates",
90
+ "auth.acl.features.currencies.view": "View currencies",
91
+ "auth.acl.features.customer_accounts.domain.manage": "Manage custom portal domains",
92
+ "auth.acl.features.customer_accounts.invite": "Invite customer users",
93
+ "auth.acl.features.customer_accounts.manage": "Manage customer accounts",
94
+ "auth.acl.features.customer_accounts.roles.manage": "Manage customer roles",
95
+ "auth.acl.features.customer_accounts.view": "View customer accounts",
96
+ "auth.acl.features.customers.activities.manage": "Manage activities",
97
+ "auth.acl.features.customers.activities.view": "View activities",
98
+ "auth.acl.features.customers.companies.manage": "Manage companies",
99
+ "auth.acl.features.customers.companies.view": "View companies",
100
+ "auth.acl.features.customers.deals.manage": "Manage deals",
101
+ "auth.acl.features.customers.deals.view": "View deals",
102
+ "auth.acl.features.customers.email.compose": "Compose / send emails from CRM",
103
+ "auth.acl.features.customers.email.view_private": "View other users' private emails (reserved — inert in v1)",
104
+ "auth.acl.features.customers.interactions.manage": "Manage interactions",
105
+ "auth.acl.features.customers.interactions.view": "View interactions",
106
+ "auth.acl.features.customers.people.manage": "Manage people",
107
+ "auth.acl.features.customers.people.view": "View people",
108
+ "auth.acl.features.customers.pipelines.manage": "Manage pipelines",
109
+ "auth.acl.features.customers.pipelines.view": "View pipelines",
110
+ "auth.acl.features.customers.roles.manage": "Manage entity roles",
111
+ "auth.acl.features.customers.roles.view": "View entity roles",
112
+ "auth.acl.features.customers.settings.manage": "Manage customer settings",
113
+ "auth.acl.features.customers.widgets.new-customers": "Use customer new customers widget",
114
+ "auth.acl.features.customers.widgets.new-deals": "Use customer new deals widget",
115
+ "auth.acl.features.customers.widgets.next-interactions": "Use customer next interactions widget",
116
+ "auth.acl.features.customers.widgets.todos": "Use customer todos widget",
117
+ "auth.acl.features.dashboards.admin.assign-widgets": "Manage dashboard widget availability",
118
+ "auth.acl.features.dashboards.configure": "Customize dashboard layout",
119
+ "auth.acl.features.dashboards.view": "View dashboard",
120
+ "auth.acl.features.data_sync.configure": "Configure sync mappings and schedules",
121
+ "auth.acl.features.data_sync.run": "Run sync operations",
122
+ "auth.acl.features.data_sync.view": "View sync runs",
123
+ "auth.acl.features.design_system.view": "View the design system gallery",
124
+ "auth.acl.features.devices.admin": "Manage devices across users",
125
+ "auth.acl.features.devices.manage": "Manage own devices",
126
+ "auth.acl.features.devices.view": "View own devices",
127
+ "auth.acl.features.dictionaries.manage": "Manage shared dictionaries",
128
+ "auth.acl.features.dictionaries.view": "View shared dictionaries",
129
+ "auth.acl.features.directory.organizations.manage": "Manage organizations",
130
+ "auth.acl.features.directory.organizations.view": "View organizations",
131
+ "auth.acl.features.directory.tenants.manage": "Manage tenants",
132
+ "auth.acl.features.directory.tenants.view": "View tenants",
133
+ "auth.acl.features.documents.create": "Create documents",
134
+ "auth.acl.features.documents.delete": "Delete documents",
135
+ "auth.acl.features.documents.edit": "Edit documents",
136
+ "auth.acl.features.documents.manage": "Manage all documents",
137
+ "auth.acl.features.documents.share": "Share documents",
138
+ "auth.acl.features.documents.templates.manage": "Manage document templates",
139
+ "auth.acl.features.documents.view": "View documents",
140
+ "auth.acl.features.entities.definitions.manage": "Manage custom field definitions",
141
+ "auth.acl.features.entities.definitions.view": "View custom field definitions",
142
+ "auth.acl.features.entities.records.manage": "Manage records",
143
+ "auth.acl.features.entities.records.view": "View records",
144
+ "auth.acl.features.eudr.mappings.manage": "Manage EUDR mappings",
145
+ "auth.acl.features.eudr.mappings.view": "View EUDR mappings",
146
+ "auth.acl.features.eudr.plots.manage": "Manage EUDR plots",
147
+ "auth.acl.features.eudr.plots.view": "View EUDR plots",
148
+ "auth.acl.features.eudr.risk.manage": "Manage EUDR risk assessments",
149
+ "auth.acl.features.eudr.risk.view": "View EUDR risk assessments",
150
+ "auth.acl.features.eudr.statements.manage": "Manage EUDR statements",
151
+ "auth.acl.features.eudr.statements.view": "View EUDR statements",
152
+ "auth.acl.features.eudr.submissions.manage": "Manage EUDR submissions",
153
+ "auth.acl.features.eudr.submissions.view": "View EUDR submissions",
154
+ "auth.acl.features.example.backend": "Access example backend",
155
+ "auth.acl.features.example.manage": "Manage example (override probe)",
156
+ "auth.acl.features.example.todos.manage": "Manage todos",
157
+ "auth.acl.features.example.todos.view": "View todos",
158
+ "auth.acl.features.example.view": "View example enrichments",
159
+ "auth.acl.features.example.widgets.injection": "Use injection widgets",
160
+ "auth.acl.features.example.widgets.notes": "Use dashboard notes widget",
161
+ "auth.acl.features.example.widgets.todo": "Use dashboard todo widget",
162
+ "auth.acl.features.example.widgets.welcome": "Use dashboard welcome widget",
163
+ "auth.acl.features.example_customers_sync.manage": "Manage Example customer sync",
164
+ "auth.acl.features.example_customers_sync.view": "View Example customer sync diagnostics",
165
+ "auth.acl.features.feature_toggles.global.manage": "Manage system-wide global feature toggles",
166
+ "auth.acl.features.feature_toggles.manage": "Manage per-tenant feature toggle overrides",
167
+ "auth.acl.features.feature_toggles.view": "View feature toggles",
168
+ "auth.acl.features.gateway_stripe.configure": "Configure Stripe gateway settings",
169
+ "auth.acl.features.gateway_stripe.view": "View Stripe gateway configuration",
170
+ "auth.acl.features.inbox_ops.log.view": "View processing log",
171
+ "auth.acl.features.inbox_ops.proposals.manage": "Manage proposals",
172
+ "auth.acl.features.inbox_ops.proposals.view": "View proposals",
173
+ "auth.acl.features.inbox_ops.replies.send": "Send draft replies",
174
+ "auth.acl.features.inbox_ops.settings.manage": "Manage inbox settings",
175
+ "auth.acl.features.integrations.credentials.manage": "Manage integration credentials",
176
+ "auth.acl.features.integrations.manage": "Manage integration configurations",
177
+ "auth.acl.features.integrations.view": "View integrations and external ID mappings",
178
+ "auth.acl.features.messages.actions": "Execute message actions",
179
+ "auth.acl.features.messages.attach": "Attach records to messages",
180
+ "auth.acl.features.messages.attach_files": "Attach files to messages",
181
+ "auth.acl.features.messages.compose": "Compose messages",
182
+ "auth.acl.features.messages.email": "Send messages via email",
183
+ "auth.acl.features.messages.manage": "Manage all messages",
184
+ "auth.acl.features.messages.view": "View messages",
185
+ "auth.acl.features.notifications.create": "Create notifications for others",
186
+ "auth.acl.features.notifications.manage": "Manage all notifications",
187
+ "auth.acl.features.notifications.manage_preferences": "Manage own notification preferences",
188
+ "auth.acl.features.notifications.manage_user_preferences": "Manage other users' notification preferences",
189
+ "auth.acl.features.notifications.view": "View own notifications",
190
+ "auth.acl.features.onboarding.access": "Access onboarding flow",
191
+ "auth.acl.features.onboarding.submit": "Submit onboarding request",
192
+ "auth.acl.features.onboarding.verify": "Verify onboarding request",
193
+ "auth.acl.features.payment_gateways.capture": "Capture authorized payments",
194
+ "auth.acl.features.payment_gateways.manage": "Create and manage payment sessions",
195
+ "auth.acl.features.payment_gateways.refund": "Refund captured payments",
196
+ "auth.acl.features.payment_gateways.view": "View payment gateway transactions",
197
+ "auth.acl.features.perspectives.role_defaults": "Manage role default perspectives",
198
+ "auth.acl.features.perspectives.use": "Use table perspectives",
199
+ "auth.acl.features.planner.manage_availability": "Manage availability",
200
+ "auth.acl.features.planner.view": "View schedules",
201
+ "auth.acl.features.progress.cancel": "Cancel progress jobs",
202
+ "auth.acl.features.progress.create": "Create progress jobs",
203
+ "auth.acl.features.progress.manage": "Manage all progress jobs",
204
+ "auth.acl.features.progress.update": "Update progress jobs",
205
+ "auth.acl.features.progress.view": "View progress jobs",
206
+ "auth.acl.features.push_notifications.send_custom": "Send custom push notifications",
207
+ "auth.acl.features.push_notifications.view_deliveries": "View push delivery log",
208
+ "auth.acl.features.query_index.purge": "Purge index",
209
+ "auth.acl.features.query_index.reindex": "Trigger reindex",
210
+ "auth.acl.features.query_index.status.view": "View index status",
211
+ "auth.acl.features.record_locks.force_release": "Force release locks owned by other users",
212
+ "auth.acl.features.record_locks.manage": "Manage record locking settings",
213
+ "auth.acl.features.record_locks.override_incoming": "Override incoming conflict changes",
214
+ "auth.acl.features.record_locks.view": "View and use record locking",
215
+ "auth.acl.features.resources.manage_resources": "Manage resources",
216
+ "auth.acl.features.resources.view": "View resources",
217
+ "auth.acl.features.sales.channels.manage": "Manage sales channels",
218
+ "auth.acl.features.sales.channels.view": "View sales channels",
219
+ "auth.acl.features.sales.credit_memos.manage": "Manage credit memos",
220
+ "auth.acl.features.sales.documents.number.edit": "Edit sales document numbers",
221
+ "auth.acl.features.sales.invoices.manage": "Manage sales invoices",
222
+ "auth.acl.features.sales.orders.approve": "Approve sales orders",
223
+ "auth.acl.features.sales.orders.manage": "Manage sales orders",
224
+ "auth.acl.features.sales.orders.view": "View sales orders",
225
+ "auth.acl.features.sales.payments.manage": "Manage order payments",
226
+ "auth.acl.features.sales.quotes.manage": "Manage sales quotes",
227
+ "auth.acl.features.sales.quotes.view": "View sales quotes",
228
+ "auth.acl.features.sales.returns.create": "Create order returns",
229
+ "auth.acl.features.sales.returns.manage": "Edit and delete order returns",
230
+ "auth.acl.features.sales.returns.view": "View order returns",
231
+ "auth.acl.features.sales.settings.manage": "Manage sales configuration",
232
+ "auth.acl.features.sales.settings.view": "View sales configuration",
233
+ "auth.acl.features.sales.shipments.manage": "Manage order shipments",
234
+ "auth.acl.features.sales.widgets.new-orders": "View new orders widget",
235
+ "auth.acl.features.sales.widgets.new-quotes": "View new quotes widget",
236
+ "auth.acl.features.scheduler.jobs.manage": "Manage schedules",
237
+ "auth.acl.features.scheduler.jobs.trigger": "Trigger schedules",
238
+ "auth.acl.features.scheduler.jobs.view": "View schedules",
239
+ "auth.acl.features.search.embeddings.manage": "Manage embedding settings",
240
+ "auth.acl.features.search.embeddings.view": "View embedding settings",
241
+ "auth.acl.features.search.global": "Use global search (Cmd+K)",
242
+ "auth.acl.features.search.manage": "Manage search settings",
243
+ "auth.acl.features.search.reindex": "Reindex search data",
244
+ "auth.acl.features.search.view": "View search settings",
245
+ "auth.acl.features.security.admin.manage": "Manage security policies",
246
+ "auth.acl.features.security.mfa.manage": "Manage MFA settings",
247
+ "auth.acl.features.security.profile.manage": "Manage security profile",
248
+ "auth.acl.features.security.profile.password": "Change own password",
249
+ "auth.acl.features.security.profile.view": "View security profile",
250
+ "auth.acl.features.security.sudo.manage": "Manage sudo protection",
251
+ "auth.acl.features.security.sudo.view": "View sudo protection",
252
+ "auth.acl.features.shipping_carriers.manage": "Manage shipping carrier operations",
253
+ "auth.acl.features.shipping_carriers.view": "View shipping carrier shipments",
254
+ "auth.acl.features.sso.config.manage": "Manage SSO configuration",
255
+ "auth.acl.features.sso.config.view": "View SSO configuration",
256
+ "auth.acl.features.sso.scim.manage": "Manage SCIM provisioning tokens",
257
+ "auth.acl.features.staff.leave_requests.manage": "Manage leave requests",
258
+ "auth.acl.features.staff.leave_requests.send": "Send leave requests",
259
+ "auth.acl.features.staff.manage_team": "Manage employees",
260
+ "auth.acl.features.staff.my_availability.manage": "Manage my availability",
261
+ "auth.acl.features.staff.my_availability.unavailability": "Manage my unavailability",
262
+ "auth.acl.features.staff.my_availability.view": "View my availability",
263
+ "auth.acl.features.staff.my_leave_requests.send": "Send my leave requests",
264
+ "auth.acl.features.staff.my_leave_requests.view": "View my leave requests",
265
+ "auth.acl.features.staff.timesheets.approve": "Approve reportee time",
266
+ "auth.acl.features.staff.timesheets.lock": "Lock time periods",
267
+ "auth.acl.features.staff.timesheets.manage_all": "Manage all employees entries",
268
+ "auth.acl.features.staff.timesheets.manage_own": "Create/edit/delete own entries",
269
+ "auth.acl.features.staff.timesheets.projects.manage": "Manage time projects",
270
+ "auth.acl.features.staff.timesheets.projects.view": "View time projects",
271
+ "auth.acl.features.staff.timesheets.view": "View own time entries",
272
+ "auth.acl.features.staff.view": "View employees",
273
+ "auth.acl.features.storage_providers.manage": "Manage storage providers",
274
+ "auth.acl.features.sync_excel.run": "Upload CSV files and prepare imports",
275
+ "auth.acl.features.sync_excel.view": "View sync_excel uploads and previews",
276
+ "auth.acl.features.translations.manage": "Manage entity translations",
277
+ "auth.acl.features.translations.manage_locales": "Configure supported locales",
278
+ "auth.acl.features.translations.view": "View translations",
279
+ "auth.acl.features.warranty_claims.claim.create": "Create warranty claims",
280
+ "auth.acl.features.warranty_claims.claim.delete": "Delete warranty claims",
281
+ "auth.acl.features.warranty_claims.claim.manage": "Manage warranty claims",
282
+ "auth.acl.features.warranty_claims.claim.view": "View warranty claims",
283
+ "auth.acl.features.warranty_claims.external.submit": "Submit external warranty claims",
284
+ "auth.acl.features.warranty_claims.external.view": "View external warranty claims",
285
+ "auth.acl.features.warranty_claims.receiving.manage": "Manage warranty receiving and grading",
286
+ "auth.acl.features.warranty_claims.registration.manage": "Manage warranty registrations",
287
+ "auth.acl.features.warranty_claims.registration.view": "View warranty registrations",
288
+ "auth.acl.features.warranty_claims.settings.manage": "Manage warranty claim settings",
289
+ "auth.acl.features.warranty_claims.troubleshooting.manage": "Manage warranty troubleshooting guides",
290
+ "auth.acl.features.warranty_claims.vendor_policy.manage": "Manage warranty vendor policies",
291
+ "auth.acl.features.webhooks.manage": "Manage webhooks",
292
+ "auth.acl.features.webhooks.secrets": "View and rotate webhook secrets",
293
+ "auth.acl.features.webhooks.test": "Test webhooks",
294
+ "auth.acl.features.webhooks.view": "View webhooks",
295
+ "auth.acl.features.wms.adjust_inventory": "Adjust and move inventory",
296
+ "auth.acl.features.wms.cycle_count": "Run cycle counts",
297
+ "auth.acl.features.wms.import": "Import inventory from CSV",
298
+ "auth.acl.features.wms.manage_inventory": "Manage inventory profiles and stock state",
299
+ "auth.acl.features.wms.manage_locations": "Manage warehouse locations",
300
+ "auth.acl.features.wms.manage_reservations": "Manage inventory reservations",
301
+ "auth.acl.features.wms.manage_warehouses": "Manage warehouses",
302
+ "auth.acl.features.wms.manage_zones": "Manage warehouse zones",
303
+ "auth.acl.features.wms.receive_inventory": "Receive inbound inventory",
304
+ "auth.acl.features.wms.view": "View WMS data",
305
+ "auth.acl.features.workflows.definitions.create": "Create workflow definitions",
306
+ "auth.acl.features.workflows.definitions.delete": "Delete workflow definitions",
307
+ "auth.acl.features.workflows.definitions.edit": "Edit workflow definitions",
308
+ "auth.acl.features.workflows.definitions.view": "View workflow definitions",
309
+ "auth.acl.features.workflows.events.view": "View workflow events",
310
+ "auth.acl.features.workflows.instances.cancel": "Cancel workflow instances",
311
+ "auth.acl.features.workflows.instances.create": "Start workflow instances",
312
+ "auth.acl.features.workflows.instances.retry": "Retry workflow instances",
313
+ "auth.acl.features.workflows.instances.signal": "Signal workflow instances",
314
+ "auth.acl.features.workflows.instances.view": "View workflow instances",
315
+ "auth.acl.features.workflows.manage": "Manage workflows",
316
+ "auth.acl.features.workflows.signals.send": "Send workflow signals",
317
+ "auth.acl.features.workflows.tasks.claim": "Claim workflow tasks",
318
+ "auth.acl.features.workflows.tasks.complete": "Complete workflow tasks",
319
+ "auth.acl.features.workflows.tasks.view": "View user tasks",
320
+ "auth.acl.features.workflows.view": "View workflows",
321
+ "auth.acl.features.workflows.view_logs": "View workflow logs",
322
+ "auth.acl.features.workflows.view_tasks": "View workflow tasks",
323
+ "auth.acl.globalWildcard.description": "This grants access to all features in the system.",
324
+ "auth.acl.globalWildcard.remove": "Remove global wildcard",
325
+ "auth.acl.globalWildcard.title": "Global wildcard (*) enabled",
326
+ "auth.acl.inherited.assignedRoles": "Assigned roles:",
327
+ "auth.acl.inherited.description": "This user currently inherits permissions from their assigned roles.",
328
+ "auth.acl.inherited.override": "Override permissions for this user only",
329
+ "auth.acl.inherited.title": "Permissions inherited from roles",
330
+ "auth.acl.loading": "Loading access control…",
331
+ "auth.acl.manageViaSuperAdmin": "(manage via super admin)",
332
+ "auth.acl.modules.ai_assistant": "AI Assistant",
333
+ "auth.acl.modules.api_keys": "API Keys",
334
+ "auth.acl.modules.attachments": "Attachments",
335
+ "auth.acl.modules.audit_logs": "Audit & Action Logs",
336
+ "auth.acl.modules.auth": "Authentication & Accounts",
337
+ "auth.acl.modules.business_rules": "Business Rules",
338
+ "auth.acl.modules.catalog": "Product Catalog",
339
+ "auth.acl.modules.channel_apns": "Apple Push Notification Channel",
340
+ "auth.acl.modules.channel_expo": "Expo Push Channel",
341
+ "auth.acl.modules.channel_fcm": "Firebase Cloud Messaging Channel",
342
+ "auth.acl.modules.channel_gmail": "Gmail Email Channel",
343
+ "auth.acl.modules.channel_imap": "IMAP + SMTP Email Channel",
344
+ "auth.acl.modules.checkout": "Checkout",
345
+ "auth.acl.modules.communication_channels": "Communication Channels",
346
+ "auth.acl.modules.configs": "Configuration",
347
+ "auth.acl.modules.currencies": "Currencies",
348
+ "auth.acl.modules.customer_accounts": "Customer Identity & Portal Authentication",
349
+ "auth.acl.modules.customers": "Customer Relationship Management",
350
+ "auth.acl.modules.dashboards": "Admin Dashboards",
351
+ "auth.acl.modules.data_sync": "Data Sync",
352
+ "auth.acl.modules.design_system": "Design system gallery",
353
+ "auth.acl.modules.devices": "Devices",
354
+ "auth.acl.modules.dictionaries": "Shared Dictionaries",
355
+ "auth.acl.modules.directory": "Directory (Tenants & Organizations)",
356
+ "auth.acl.modules.documents": "Documents",
357
+ "auth.acl.modules.entities": "Custom Entities & Fields",
358
+ "auth.acl.modules.eudr": "EUDR Compliance",
359
+ "auth.acl.modules.example": "Example Module",
360
+ "auth.acl.modules.example_customers_sync": "Example Customers Sync",
361
+ "auth.acl.modules.feature_toggles": "Feature Toggles",
362
+ "auth.acl.modules.gateway_stripe": "Stripe Payment Gateway",
363
+ "auth.acl.modules.inbox_ops": "InboxOps — Email-to-ERP Agent",
364
+ "auth.acl.modules.integrations": "Integrations",
365
+ "auth.acl.modules.messages": "Messages",
366
+ "auth.acl.modules.notifications": "Notifications",
367
+ "auth.acl.modules.onboarding": "Onboarding",
368
+ "auth.acl.modules.payment_gateways": "Payment Gateways",
369
+ "auth.acl.modules.perspectives": "Table perspectives",
370
+ "auth.acl.modules.planner": "Worktime / Availabilities",
371
+ "auth.acl.modules.progress": "Progress",
372
+ "auth.acl.modules.push_notifications": "Push Notifications",
373
+ "auth.acl.modules.query_index": "Query Indexes",
374
+ "auth.acl.modules.record_locks": "Record Locking",
375
+ "auth.acl.modules.resources": "Resource planning",
376
+ "auth.acl.modules.sales": "Sales Management",
377
+ "auth.acl.modules.scheduler": "Scheduler",
378
+ "auth.acl.modules.search": "Search",
379
+ "auth.acl.modules.security": "Security",
380
+ "auth.acl.modules.shipping_carriers": "Shipping Carriers",
381
+ "auth.acl.modules.sso": "sso",
382
+ "auth.acl.modules.staff": "Employees",
383
+ "auth.acl.modules.storage_s3": "S3-Compatible Storage",
384
+ "auth.acl.modules.sync_excel": "Excel / CSV Import",
385
+ "auth.acl.modules.translations": "Entity Translations",
386
+ "auth.acl.modules.warranty_claims": "Warranty & RMA",
387
+ "auth.acl.modules.webhooks": "Webhooks",
388
+ "auth.acl.modules.wms": "Warehouse Management System",
389
+ "auth.acl.modules.workflows": "Workflow Engine",
15
390
  "auth.acl.organizationWarning": "Organisationseinschränkungen werden nur gespeichert, wenn mindestens eine Berechtigungsüberschreibung ausgewählt ist. Füge eine Berechtigung hinzu oder aktiviere einen Modul-Wildcard vor dem Speichern.",
16
391
  "auth.acl.organizationsScope": "Organisationsbereich",
392
+ "auth.acl.organizationsScopeHint": "Empty means all organizations. Select one or more to restrict access.",
17
393
  "auth.acl.restricted": "Eingeschränkt",
394
+ "auth.acl.superAdmin.hint": "Only super administrators can change this option.",
395
+ "auth.acl.superAdmin.label": "Super Admin (all features)",
396
+ "auth.acl.wildcards.allFeatures": "All features",
397
+ "auth.acl.wildcards.allGroup": "All permissions in {group}",
18
398
  "auth.actions.contactSupport": "Support kontaktieren",
19
399
  "auth.actions.viewPermissions": "Berechtigungen anzeigen",
20
400
  "auth.actions.viewSessions": "Sitzungen anzeigen",