@open-mercato/core 0.10.1-develop.7749.1.ea3edf75e3 → 0.10.1-develop.7752.1.fd7c06569b

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 (40) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/api_keys/services/principalService.js +3 -2
  3. package/dist/modules/api_keys/services/principalService.js.map +2 -2
  4. package/dist/modules/api_keys/services/sessionKeyRoles.js +29 -0
  5. package/dist/modules/api_keys/services/sessionKeyRoles.js.map +7 -0
  6. package/dist/modules/auth/cli.js +13 -2
  7. package/dist/modules/auth/cli.js.map +2 -2
  8. package/dist/modules/auth/services/rbacService.js +18 -10
  9. package/dist/modules/auth/services/rbacService.js.map +2 -2
  10. package/dist/modules/business_rules/lib/action-executor.js +2 -1
  11. package/dist/modules/business_rules/lib/action-executor.js.map +2 -2
  12. package/dist/modules/directory/utils/organizationScope.js +11 -4
  13. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  14. package/dist/modules/entities/subscribers/seed-tenant-encryption-maps-retry.js +14 -0
  15. package/dist/modules/entities/subscribers/seed-tenant-encryption-maps-retry.js.map +7 -0
  16. package/dist/modules/entities/subscribers/seed-tenant-encryption-maps.js +37 -0
  17. package/dist/modules/entities/subscribers/seed-tenant-encryption-maps.js.map +7 -0
  18. package/dist/modules/warranty_claims/commands/claim-lines.js +25 -1
  19. package/dist/modules/warranty_claims/commands/claim-lines.js.map +3 -3
  20. package/dist/modules/warranty_claims/commands/claims.js +19 -1
  21. package/dist/modules/warranty_claims/commands/claims.js.map +2 -2
  22. package/dist/modules/warranty_claims/commands/shared.js +30 -0
  23. package/dist/modules/warranty_claims/commands/shared.js.map +2 -2
  24. package/package.json +7 -7
  25. package/src/modules/api_keys/services/principalService.ts +3 -2
  26. package/src/modules/api_keys/services/sessionKeyRoles.ts +35 -0
  27. package/src/modules/auth/cli.ts +11 -4
  28. package/src/modules/auth/services/rbacService.ts +22 -9
  29. package/src/modules/business_rules/lib/action-executor.ts +2 -3
  30. package/src/modules/directory/utils/organizationScope.ts +11 -4
  31. package/src/modules/entities/subscribers/seed-tenant-encryption-maps-retry.ts +12 -0
  32. package/src/modules/entities/subscribers/seed-tenant-encryption-maps.ts +38 -0
  33. package/src/modules/warranty_claims/commands/claim-lines.ts +26 -1
  34. package/src/modules/warranty_claims/commands/claims.ts +19 -1
  35. package/src/modules/warranty_claims/commands/shared.ts +36 -1
  36. package/src/modules/warranty_claims/i18n/de.json +1 -0
  37. package/src/modules/warranty_claims/i18n/en.json +1 -0
  38. package/src/modules/warranty_claims/i18n/es.json +1 -0
  39. package/src/modules/warranty_claims/i18n/ko.json +1 -0
  40. package/src/modules/warranty_claims/i18n/pl.json +1 -0
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from 'crypto'
2
- import type { FindOneOptions } from '@mikro-orm/core'
2
+ import { LockMode, type FindOneOptions } from '@mikro-orm/core'
3
3
  import type { EntityManager } from '@mikro-orm/postgresql'
4
4
  import type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
5
5
  import { CrudHttpError, assertFound } from '@open-mercato/shared/lib/crud/errors'
@@ -102,6 +102,41 @@ export async function requireScopedClaim(
102
102
  return assertFound(claim, notFoundMessage)
103
103
  }
104
104
 
105
+ export async function assertUniqueClaimLineNumbers(lineNumbers: Iterable<number>): Promise<void> {
106
+ const usedNumbers = new Set<number>()
107
+ for (const lineNo of lineNumbers) {
108
+ if (usedNumbers.has(lineNo)) {
109
+ const { translate } = await resolveTranslations()
110
+ const code = 'warranty_claims.errors.duplicateLineNo'
111
+ throw new CrudHttpError(409, {
112
+ error: translate(code, 'Another line on this claim already uses that line number. Remove the line that uses this number, then retry.'),
113
+ code,
114
+ })
115
+ }
116
+ usedNumbers.add(lineNo)
117
+ }
118
+ }
119
+
120
+ export async function assertClaimLineNumberAvailable(
121
+ em: EntityManager,
122
+ claim: WarrantyClaim,
123
+ lineNo: number,
124
+ excludedLineId?: string,
125
+ allowCurrentNumber = false,
126
+ ): Promise<void> {
127
+ const scope = { tenantId: claim.tenantId, organizationId: claim.organizationId }
128
+ await requireScopedClaim(em, claim.id, scope, { lockMode: LockMode.PESSIMISTIC_WRITE })
129
+ const siblings = await findWithDecryption(
130
+ em,
131
+ WarrantyClaimLine,
132
+ { claim: claim.id, lineNo, deletedAt: null, tenantId: scope.tenantId, organizationId: scope.organizationId },
133
+ {},
134
+ scope,
135
+ )
136
+ if (allowCurrentNumber && siblings.some((line) => line.id === excludedLineId)) return
137
+ await assertUniqueClaimLineNumbers([lineNo, ...siblings.filter((line) => line.id !== excludedLineId).map((line) => line.lineNo)])
138
+ }
139
+
105
140
  export function appendClaimEvent(
106
141
  em: EntityManager,
107
142
  claim: WarrantyClaim,
@@ -287,6 +287,7 @@
287
287
  "warranty_claims.errors.deleteNotAllowed": "Nur Claims mit Status Entwurf oder Storniert können gelöscht werden.",
288
288
  "warranty_claims.errors.dispositionGradeConflict": "Wiedereinlagerung ist nur für Artikel mit Bewertung A oder B erlaubt.",
289
289
  "warranty_claims.errors.dispositionTypeConflict": "Diese Disposition ist für diesen Reklamationstyp nicht verfügbar.",
290
+ "warranty_claims.errors.duplicateLineNo": "Eine andere Position dieses Anspruchs verwendet bereits diese Positionsnummer. Entfernen Sie die Position mit dieser Nummer und versuchen Sie es erneut.",
290
291
  "warranty_claims.errors.duplicateSerial": "Eine Registrierung mit dieser Seriennummer existiert bereits.",
291
292
  "warranty_claims.errors.fieldLocked": "Dieses Feld kann im aktuellen Claim-Status nicht bearbeitet werden.",
292
293
  "warranty_claims.errors.invalidAssignee": "Die ausgewählte zuständige Person wurde nicht gefunden.",
@@ -287,6 +287,7 @@
287
287
  "warranty_claims.errors.deleteNotAllowed": "Only draft or cancelled claims can be deleted.",
288
288
  "warranty_claims.errors.dispositionGradeConflict": "Restock is only allowed for grade A or B items.",
289
289
  "warranty_claims.errors.dispositionTypeConflict": "This disposition is not available for this claim type.",
290
+ "warranty_claims.errors.duplicateLineNo": "Another line on this claim already uses that line number. Remove the line that uses this number, then retry.",
290
291
  "warranty_claims.errors.duplicateSerial": "A registration with this serial number already exists.",
291
292
  "warranty_claims.errors.fieldLocked": "This field can't be edited in the current claim status.",
292
293
  "warranty_claims.errors.invalidAssignee": "The selected assignee could not be found.",
@@ -287,6 +287,7 @@
287
287
  "warranty_claims.errors.deleteNotAllowed": "Solo se pueden eliminar reclamos en estado borrador o cancelado.",
288
288
  "warranty_claims.errors.dispositionGradeConflict": "La reposición de inventario solo está permitida para artículos con grado A o B.",
289
289
  "warranty_claims.errors.dispositionTypeConflict": "Esta disposición no está disponible para este tipo de reclamación.",
290
+ "warranty_claims.errors.duplicateLineNo": "Otra línea de esta reclamación ya utiliza ese número de línea. Elimina la línea que usa ese número y vuelve a intentarlo.",
290
291
  "warranty_claims.errors.duplicateSerial": "Ya existe un registro con este número de serie.",
291
292
  "warranty_claims.errors.fieldLocked": "Este campo no se puede editar en el estado actual del reclamo.",
292
293
  "warranty_claims.errors.invalidAssignee": "No se pudo encontrar el responsable seleccionado.",
@@ -287,6 +287,7 @@
287
287
  "warranty_claims.errors.deleteNotAllowed": "초안 또는 취소된 클레임만 삭제할 수 있습니다.",
288
288
  "warranty_claims.errors.dispositionGradeConflict": "재입고는 등급 A 또는 B 품목에만 허용됩니다.",
289
289
  "warranty_claims.errors.dispositionTypeConflict": "이 처리 방식은 해당 클레임 유형에서 사용할 수 없습니다.",
290
+ "warranty_claims.errors.duplicateLineNo": "이 청구의 다른 항목에서 이미 이 항목 번호를 사용하고 있습니다. 해당 번호를 사용하는 항목을 삭제한 다음 다시 시도하세요.",
290
291
  "warranty_claims.errors.duplicateSerial": "이 일련번호로 등록된 항목이 이미 있습니다.",
291
292
  "warranty_claims.errors.fieldLocked": "현재 클레임 상태에서는 이 항목을 수정할 수 없습니다.",
292
293
  "warranty_claims.errors.invalidAssignee": "선택한 담당자를 찾을 수 없습니다.",
@@ -287,6 +287,7 @@
287
287
  "warranty_claims.errors.deleteNotAllowed": "Można usuwać tylko reklamacje w statusie roboczym lub anulowane.",
288
288
  "warranty_claims.errors.dispositionGradeConflict": "Przyjęcie na stan jest dozwolone tylko dla pozycji z oceną A lub B.",
289
289
  "warranty_claims.errors.dispositionTypeConflict": "Ta dyspozycja nie jest dostępna dla tego typu reklamacji.",
290
+ "warranty_claims.errors.duplicateLineNo": "Inna pozycja tej reklamacji używa już tego numeru. Usuń pozycję z tym numerem, a następnie spróbuj ponownie.",
290
291
  "warranty_claims.errors.duplicateSerial": "Rejestracja z tym numerem seryjnym już istnieje.",
291
292
  "warranty_claims.errors.fieldLocked": "Tego pola nie można edytować w bieżącym statusie reklamacji.",
292
293
  "warranty_claims.errors.invalidAssignee": "Nie znaleziono wybranej osoby przypisanej.",