@open-mercato/core 0.10.1-develop.7847.1.7d83dc5794 → 0.10.1-develop.7862.1.ee520f7662

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 (81) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/attachments/api/file/[id]/route.js +6 -1
  3. package/dist/modules/attachments/api/file/[id]/route.js.map +2 -2
  4. package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js +6 -1
  5. package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js.map +2 -2
  6. package/dist/modules/attachments/api/library/[id]/route.js +16 -1
  7. package/dist/modules/attachments/api/library/[id]/route.js.map +2 -2
  8. package/dist/modules/attachments/api/route.js +11 -3
  9. package/dist/modules/attachments/api/route.js.map +2 -2
  10. package/dist/modules/attachments/cli.js +2 -0
  11. package/dist/modules/attachments/cli.js.map +2 -2
  12. package/dist/modules/attachments/data/validators.js +11 -0
  13. package/dist/modules/attachments/data/validators.js.map +2 -2
  14. package/dist/modules/attachments/index.js +10 -0
  15. package/dist/modules/attachments/index.js.map +2 -2
  16. package/dist/modules/attachments/lib/access-query.js +5 -1
  17. package/dist/modules/attachments/lib/access-query.js.map +2 -2
  18. package/dist/modules/attachments/lib/createFromBuffer.js +2 -0
  19. package/dist/modules/attachments/lib/createFromBuffer.js.map +2 -2
  20. package/dist/modules/attachments/lib/drivers/driverFactory.js +54 -33
  21. package/dist/modules/attachments/lib/drivers/driverFactory.js.map +2 -2
  22. package/dist/modules/attachments/lib/drivers/index.js +11 -1
  23. package/dist/modules/attachments/lib/drivers/index.js.map +2 -2
  24. package/dist/modules/attachments/lib/drivers/storageValidation.js +85 -0
  25. package/dist/modules/attachments/lib/drivers/storageValidation.js.map +7 -0
  26. package/dist/modules/attachments/lib/scoped-upload-service.js +3 -1
  27. package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
  28. package/dist/modules/attachments/lib/storageErrors.js +22 -0
  29. package/dist/modules/attachments/lib/storageErrors.js.map +7 -0
  30. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +5 -4
  31. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +3 -3
  32. package/dist/modules/customers/api/companies/[id]/route.js +4 -9
  33. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  34. package/dist/modules/customers/api/people/[id]/route.js +4 -9
  35. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  36. package/dist/modules/customers/components/detail/TaskDialog.js +2 -0
  37. package/dist/modules/customers/components/detail/TaskDialog.js.map +2 -2
  38. package/dist/modules/customers/lib/todoCompatibility.js +23 -0
  39. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  40. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js +1 -4
  41. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js.map +2 -2
  42. package/dist/modules/warranty_claims/backend/components/WarrantyWorkspace.js +8 -1
  43. package/dist/modules/warranty_claims/backend/components/WarrantyWorkspace.js.map +2 -2
  44. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/[id]/page.js +18 -3
  45. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/[id]/page.js.map +2 -2
  46. package/jest.config.cjs +1 -1
  47. package/package.json +8 -8
  48. package/src/modules/attachments/api/file/[id]/route.ts +7 -1
  49. package/src/modules/attachments/api/image/[id]/[[...slug]]/route.ts +7 -1
  50. package/src/modules/attachments/api/library/[id]/route.ts +14 -1
  51. package/src/modules/attachments/api/route.ts +11 -3
  52. package/src/modules/attachments/cli.ts +2 -0
  53. package/src/modules/attachments/data/validators.ts +11 -0
  54. package/src/modules/attachments/i18n/de.json +1 -0
  55. package/src/modules/attachments/i18n/en.json +1 -0
  56. package/src/modules/attachments/i18n/es.json +1 -0
  57. package/src/modules/attachments/i18n/ko.json +1 -0
  58. package/src/modules/attachments/i18n/pl.json +1 -0
  59. package/src/modules/attachments/index.ts +12 -0
  60. package/src/modules/attachments/lib/access-query.ts +5 -1
  61. package/src/modules/attachments/lib/createFromBuffer.ts +2 -0
  62. package/src/modules/attachments/lib/drivers/driverFactory.ts +79 -55
  63. package/src/modules/attachments/lib/drivers/index.ts +13 -0
  64. package/src/modules/attachments/lib/drivers/storageValidation.ts +114 -0
  65. package/src/modules/attachments/lib/scoped-upload-service.ts +3 -1
  66. package/src/modules/attachments/lib/storageErrors.ts +21 -0
  67. package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +3 -1
  68. package/src/modules/audit_logs/i18n/de.json +1 -0
  69. package/src/modules/audit_logs/i18n/en.json +1 -0
  70. package/src/modules/audit_logs/i18n/es.json +1 -0
  71. package/src/modules/audit_logs/i18n/ko.json +1 -0
  72. package/src/modules/audit_logs/i18n/pl.json +1 -0
  73. package/src/modules/customer_accounts/AGENTS.md +1 -1
  74. package/src/modules/customers/api/companies/[id]/route.ts +6 -13
  75. package/src/modules/customers/api/people/[id]/route.ts +6 -13
  76. package/src/modules/customers/components/detail/TaskDialog.tsx +2 -0
  77. package/src/modules/customers/lib/todoCompatibility.ts +28 -0
  78. package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +0 -3
  79. package/src/modules/sales/AGENTS.md +3 -3
  80. package/src/modules/warranty_claims/backend/components/WarrantyWorkspace.tsx +8 -1
  81. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/[id]/page.tsx +22 -3
@@ -181,9 +181,6 @@ const CustomerTodosWidget: React.FC<DashboardWidgetComponentProps<CustomerTodoWi
181
181
  <p className="text-sm font-medium text-foreground">
182
182
  {item.todoTitle ?? t('customers.widgets.todos.untitled')}
183
183
  </p>
184
- {item.todoSource ? (
185
- <p className="text-xs text-muted-foreground">{item.todoSource}</p>
186
- ) : null}
187
184
  </div>
188
185
  <div className="mt-2 flex flex-wrap gap-3 text-xs">
189
186
  {href ? (
@@ -5,7 +5,7 @@ Use the sales module for orders, quotes, invoices, shipments, and payments. This
5
5
  ## Always
6
6
 
7
7
  1. **MUST use `salesCalculationService` from DI** for document math.
8
- 2. **MUST follow document flow**: Quote → Order → Invoice — no skipping steps
8
+ 2. **MUST follow document flow**: Quote → Order → Invoice (quote optional)
9
9
  3. **MUST scope all documents to a channel** — channel selection affects pricing, numbering, and visibility
10
10
 
11
11
  ## Ask First
@@ -36,7 +36,7 @@ Quote → Order → Invoice
36
36
  Shipments + Payments
37
37
  ```
38
38
 
39
- - Quotes convert to orders — MUST NOT create orders without a source quote (unless configured)
39
+ - Quotes convert via `sales.quotes.convert_to_order`; orders MAY also be created without a quote
40
40
  - Orders track shipments and payments independently
41
41
  - Each entity has its own status workflow — MUST NOT skip workflow states
42
42
 
@@ -56,7 +56,7 @@ const calcService = container.resolve('salesCalculationService')
56
56
 
57
57
  ### Core Entities
58
58
  - **Sales Orders** — confirmed customer orders. MUST have a channel and at least one line
59
- - **Sales Quotes** — proposed orders. MUST track conversion status
59
+ - **Sales Quotes** — proposed orders; deleted on conversion
60
60
  - **Order/Quote Lines** — individual items. MUST reference valid products
61
61
  - **Adjustments** — discounts/surcharges. MUST use registered `AdjustmentKind`
62
62
 
@@ -1,6 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import * as React from 'react'
4
+ import { cn } from '@open-mercato/shared/lib/utils'
4
5
  import { Tabs, TabsList, TabsTrigger } from '@open-mercato/ui/primitives/tabs'
5
6
 
6
7
  export type WarrantyWorkspaceTab = {
@@ -60,7 +61,13 @@ export function WarrantyWorkspace({
60
61
  </TabsList>
61
62
  </Tabs>
62
63
  ) : null}
63
- <div className={`min-w-0 [&>[data-component-handle]>div:first-child_[data-slot=button]]:h-8 [&>[data-component-handle]>div:first-child_[data-slot=search-input-wrapper]]:h-8 [&_[data-slot=table-header]_[data-slot=table-row]]:h-9 [&_[data-slot=table-body]_[data-slot=table-row]]:h-16 ${contentClassName ?? ''}`}>{children}</div>
64
+ <div className={cn(
65
+ 'min-w-0 [&>[data-component-handle]>div:first-child_[data-slot=button]]:h-8 [&>[data-component-handle]>div:first-child_[data-slot=search-input-wrapper]]:h-8 [&_[data-slot=table-header]_[data-slot=table-row]]:h-9 [&_[data-slot=table-body]_[data-slot=table-row]]:h-16',
66
+ 'md:[&_[data-slot=table-head][class*=sticky]]:bg-card md:[&_[data-slot=table-cell][class*=sticky]]:bg-card',
67
+ 'md:[&_[data-slot=table-head][class*=sticky]]:bg-linear-to-r md:[&_[data-slot=table-head][class*=sticky]]:from-muted/40 md:[&_[data-slot=table-head][class*=sticky]]:to-muted/40',
68
+ 'md:[&_[data-slot=table-row]:hover_[data-slot=table-cell][class*=sticky]]:bg-linear-to-r md:[&_[data-slot=table-row]:hover_[data-slot=table-cell][class*=sticky]]:from-muted/30 md:[&_[data-slot=table-row]:hover_[data-slot=table-cell][class*=sticky]]:to-muted/30',
69
+ contentClassName,
70
+ )}>{children}</div>
64
71
  </section>
65
72
  )
66
73
  }
@@ -93,6 +93,8 @@ type AttachmentResponse = { items: PortalAttachment[] }
93
93
  type MutationOkResponse = { ok: boolean; error?: string }
94
94
  type UploadResponse = MutationOkResponse & { item?: PortalAttachment }
95
95
  type ClaimActionResponse = MutationOkResponse & { claimId?: string; status?: string }
96
+ type PortalOption = { value: string; label: string }
97
+ type PortalOptionsResponse = { ok: boolean; result?: { reasons: PortalOption[] } }
96
98
 
97
99
  type PortalClaimAction = 'submit' | 'withdraw'
98
100
 
@@ -248,10 +250,12 @@ function buildTrackerSteps(claim: PortalClaim, t: TranslateFn, locale: string):
248
250
  })
249
251
  }
250
252
 
251
- function buildClaimTitle(claim: PortalClaim, t: TranslateFn): string {
253
+ function buildClaimTitle(claim: PortalClaim, reasonOptions: PortalOption[], t: TranslateFn): string {
252
254
  const typeLabel = t(`warranty_claims.claimType.${claim.claimType}`)
253
255
  if (claim.reasonCode) {
254
- const reasonLabel = localizeDictionaryLabel(t, 'reason', claim.reasonCode, claim.reasonCode)
256
+ const reasonCode = claim.reasonCode
257
+ const dictionaryLabel = reasonOptions.find((option) => option.value === reasonCode)?.label ?? reasonCode
258
+ const reasonLabel = localizeDictionaryLabel(t, 'reason', reasonCode, dictionaryLabel)
255
259
  return t('warranty_claims.portal.tracker.titleWithReason', { reason: reasonLabel, type: typeLabel })
256
260
  }
257
261
  return t('warranty_claims.portal.tracker.titleFallback', { type: typeLabel })
@@ -340,6 +344,7 @@ export default function WarrantyClaimPortalDetailPage({ params }: Props) {
340
344
  const [claim, setClaim] = React.useState<PortalClaim | null>(null)
341
345
  const [events, setEvents] = React.useState<PortalClaimEvent[]>([])
342
346
  const [attachments, setAttachments] = React.useState<PortalAttachment[]>([])
347
+ const [reasonOptions, setReasonOptions] = React.useState<PortalOption[]>([])
343
348
  const [isLoading, setIsLoading] = React.useState(true)
344
349
  const [error, setError] = React.useState<string | null>(null)
345
350
  const [notFound, setNotFound] = React.useState(false)
@@ -402,6 +407,20 @@ export default function WarrantyClaimPortalDetailPage({ params }: Props) {
402
407
  if (user) void loadClaim()
403
408
  }, [loadClaim, user])
404
409
 
410
+ React.useEffect(() => {
411
+ if (!user) return
412
+ let cancelled = false
413
+ apiCall<PortalOptionsResponse>('/api/warranty_claims/portal/options')
414
+ .then((result) => {
415
+ if (cancelled) return
416
+ setReasonOptions(result.result?.ok ? result.result.result?.reasons ?? [] : [])
417
+ })
418
+ .catch(() => {})
419
+ return () => {
420
+ cancelled = true
421
+ }
422
+ }, [user])
423
+
405
424
  const submitComment = React.useCallback(async () => {
406
425
  if (!claim || commentSubmitting) return
407
426
  const body = comment.trim()
@@ -741,7 +760,7 @@ export default function WarrantyClaimPortalDetailPage({ params }: Props) {
741
760
  ) : null}
742
761
  </div>
743
762
  <h1 className="text-xl font-bold text-foreground">
744
- {buildClaimTitle(claim, t)}
763
+ {buildClaimTitle(claim, reasonOptions, t)}
745
764
  </h1>
746
765
  <p className="text-sm text-muted-foreground">
747
766
  {buildClaimSubtitle(claim, t, locale)}