@fast-white-cat/integration-ksef-direct 0.1.0

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 (140) hide show
  1. package/README.md +36 -0
  2. package/dist/index.js +2 -0
  3. package/dist/index.js.map +7 -0
  4. package/dist/modules/integration_ksef_direct/acl.js +13 -0
  5. package/dist/modules/integration_ksef_direct/acl.js.map +7 -0
  6. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents/[id].js +92 -0
  7. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents/[id].js.map +7 -0
  8. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents.js +105 -0
  9. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents.js.map +7 -0
  10. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/health.js +158 -0
  11. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/health.js.map +7 -0
  12. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents/[id].js +86 -0
  13. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents/[id].js.map +7 -0
  14. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents.js +112 -0
  15. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents.js.map +7 -0
  16. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/seller-info.js +54 -0
  17. package/dist/modules/integration_ksef_direct/api/get/integration-ksef-direct/seller-info.js.map +7 -0
  18. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents/[id]/send.js +64 -0
  19. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents/[id]/send.js.map +7 -0
  20. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents.js +104 -0
  21. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents.js.map +7 -0
  22. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/invoice-numbers.js +41 -0
  23. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/invoice-numbers.js.map +7 -0
  24. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/fetch.js +172 -0
  25. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/fetch.js.map +7 -0
  26. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/sync.js +80 -0
  27. package/dist/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/sync.js.map +7 -0
  28. package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.js +441 -0
  29. package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.js.map +7 -0
  30. package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.meta.js +8 -0
  31. package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.meta.js.map +7 -0
  32. package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/page.js +193 -0
  33. package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/page.js.map +7 -0
  34. package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/received-documents/page.js +314 -0
  35. package/dist/modules/integration_ksef_direct/backend/integration-ksef-direct/received-documents/page.js.map +7 -0
  36. package/dist/modules/integration_ksef_direct/backend/page.js +154 -0
  37. package/dist/modules/integration_ksef_direct/backend/page.js.map +7 -0
  38. package/dist/modules/integration_ksef_direct/commands/create-ksef-direct-document.js +80 -0
  39. package/dist/modules/integration_ksef_direct/commands/create-ksef-direct-document.js.map +7 -0
  40. package/dist/modules/integration_ksef_direct/commands/enqueue-ksef-direct-document.js +43 -0
  41. package/dist/modules/integration_ksef_direct/commands/enqueue-ksef-direct-document.js.map +7 -0
  42. package/dist/modules/integration_ksef_direct/data/entities.js +224 -0
  43. package/dist/modules/integration_ksef_direct/data/entities.js.map +7 -0
  44. package/dist/modules/integration_ksef_direct/data/validators.js +103 -0
  45. package/dist/modules/integration_ksef_direct/data/validators.js.map +7 -0
  46. package/dist/modules/integration_ksef_direct/di.js +11 -0
  47. package/dist/modules/integration_ksef_direct/di.js.map +7 -0
  48. package/dist/modules/integration_ksef_direct/events.js +21 -0
  49. package/dist/modules/integration_ksef_direct/events.js.map +7 -0
  50. package/dist/modules/integration_ksef_direct/index.js +10 -0
  51. package/dist/modules/integration_ksef_direct/index.js.map +7 -0
  52. package/dist/modules/integration_ksef_direct/integration.js +56 -0
  53. package/dist/modules/integration_ksef_direct/integration.js.map +7 -0
  54. package/dist/modules/integration_ksef_direct/lib/health.js +32 -0
  55. package/dist/modules/integration_ksef_direct/lib/health.js.map +7 -0
  56. package/dist/modules/integration_ksef_direct/lib/invoiceNumberFormat.js +23 -0
  57. package/dist/modules/integration_ksef_direct/lib/invoiceNumberFormat.js.map +7 -0
  58. package/dist/modules/integration_ksef_direct/lib/ksefClient.js +523 -0
  59. package/dist/modules/integration_ksef_direct/lib/ksefClient.js.map +7 -0
  60. package/dist/modules/integration_ksef_direct/lib/ksefCrypto.js +103 -0
  61. package/dist/modules/integration_ksef_direct/lib/ksefCrypto.js.map +7 -0
  62. package/dist/modules/integration_ksef_direct/lib/ksefFa2Xml.js +123 -0
  63. package/dist/modules/integration_ksef_direct/lib/ksefFa2Xml.js.map +7 -0
  64. package/dist/modules/integration_ksef_direct/lib/ksefXmlParser.js +76 -0
  65. package/dist/modules/integration_ksef_direct/lib/ksefXmlParser.js.map +7 -0
  66. package/dist/modules/integration_ksef_direct/migrations/Migration20260519210000_integration_ksef_direct.js +15 -0
  67. package/dist/modules/integration_ksef_direct/migrations/Migration20260519210000_integration_ksef_direct.js.map +7 -0
  68. package/dist/modules/integration_ksef_direct/migrations/Migration20260520120000_ksef_direct_documents.js +17 -0
  69. package/dist/modules/integration_ksef_direct/migrations/Migration20260520120000_ksef_direct_documents.js.map +7 -0
  70. package/dist/modules/integration_ksef_direct/migrations/Migration20260520220000_ksef_direct_send_queue.js +15 -0
  71. package/dist/modules/integration_ksef_direct/migrations/Migration20260520220000_ksef_direct_send_queue.js.map +7 -0
  72. package/dist/modules/integration_ksef_direct/migrations/Migration20260520230000_ksef_direct_seller_per_document.js +17 -0
  73. package/dist/modules/integration_ksef_direct/migrations/Migration20260520230000_ksef_direct_seller_per_document.js.map +7 -0
  74. package/dist/modules/integration_ksef_direct/migrations/Migration20260521120000_ksef_direct_received_documents.js +16 -0
  75. package/dist/modules/integration_ksef_direct/migrations/Migration20260521120000_ksef_direct_received_documents.js.map +7 -0
  76. package/dist/modules/integration_ksef_direct/migrations/Migration20260521130000_ksef_received_download_urls.js +15 -0
  77. package/dist/modules/integration_ksef_direct/migrations/Migration20260521130000_ksef_received_download_urls.js.map +7 -0
  78. package/dist/modules/integration_ksef_direct/setup.js +11 -0
  79. package/dist/modules/integration_ksef_direct/setup.js.map +7 -0
  80. package/dist/modules/integration_ksef_direct/subscribers/auto-enqueue-ksef-document.js +19 -0
  81. package/dist/modules/integration_ksef_direct/subscribers/auto-enqueue-ksef-document.js.map +7 -0
  82. package/dist/modules/integration_ksef_direct/workers/check-ksef-document-status.js +103 -0
  83. package/dist/modules/integration_ksef_direct/workers/check-ksef-document-status.js.map +7 -0
  84. package/dist/modules/integration_ksef_direct/workers/send-ksef-document.js +104 -0
  85. package/dist/modules/integration_ksef_direct/workers/send-ksef-document.js.map +7 -0
  86. package/dist/modules/integration_ksef_direct/workers/sync-received-documents.js +137 -0
  87. package/dist/modules/integration_ksef_direct/workers/sync-received-documents.js.map +7 -0
  88. package/dist/types/declarations.d.js +1 -0
  89. package/dist/types/declarations.d.js.map +7 -0
  90. package/package.json +98 -0
  91. package/src/index.ts +1 -0
  92. package/src/modules/integration_ksef_direct/__tests__/invoiceNumberFormat.test.ts +42 -0
  93. package/src/modules/integration_ksef_direct/__tests__/ksefFa2Xml.test.ts +407 -0
  94. package/src/modules/integration_ksef_direct/__tests__/ksefXmlParser.test.ts +230 -0
  95. package/src/modules/integration_ksef_direct/acl.ts +9 -0
  96. package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents/[id].ts +94 -0
  97. package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents.ts +111 -0
  98. package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/health.ts +194 -0
  99. package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents/[id].ts +88 -0
  100. package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents.ts +119 -0
  101. package/src/modules/integration_ksef_direct/api/get/integration-ksef-direct/seller-info.ts +62 -0
  102. package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents/[id]/send.ts +64 -0
  103. package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/documents.ts +109 -0
  104. package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/invoice-numbers.ts +40 -0
  105. package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/fetch.ts +185 -0
  106. package/src/modules/integration_ksef_direct/api/post/integration-ksef-direct/received-documents/sync.ts +86 -0
  107. package/src/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.meta.ts +4 -0
  108. package/src/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/new/page.tsx +470 -0
  109. package/src/modules/integration_ksef_direct/backend/integration-ksef-direct/documents/page.tsx +233 -0
  110. package/src/modules/integration_ksef_direct/backend/integration-ksef-direct/received-documents/page.tsx +415 -0
  111. package/src/modules/integration_ksef_direct/backend/page.tsx +183 -0
  112. package/src/modules/integration_ksef_direct/commands/create-ksef-direct-document.ts +93 -0
  113. package/src/modules/integration_ksef_direct/commands/enqueue-ksef-direct-document.ts +57 -0
  114. package/src/modules/integration_ksef_direct/data/entities.ts +195 -0
  115. package/src/modules/integration_ksef_direct/data/validators.ts +115 -0
  116. package/src/modules/integration_ksef_direct/di.ts +9 -0
  117. package/src/modules/integration_ksef_direct/events.ts +18 -0
  118. package/src/modules/integration_ksef_direct/i18n/en.json +115 -0
  119. package/src/modules/integration_ksef_direct/i18n/pl.json +115 -0
  120. package/src/modules/integration_ksef_direct/index.ts +6 -0
  121. package/src/modules/integration_ksef_direct/integration.ts +54 -0
  122. package/src/modules/integration_ksef_direct/lib/health.ts +43 -0
  123. package/src/modules/integration_ksef_direct/lib/invoiceNumberFormat.ts +23 -0
  124. package/src/modules/integration_ksef_direct/lib/ksefClient.ts +668 -0
  125. package/src/modules/integration_ksef_direct/lib/ksefCrypto.ts +138 -0
  126. package/src/modules/integration_ksef_direct/lib/ksefFa2Xml.ts +147 -0
  127. package/src/modules/integration_ksef_direct/lib/ksefXmlParser.ts +97 -0
  128. package/src/modules/integration_ksef_direct/migrations/.snapshot-open-mercato.json +1028 -0
  129. package/src/modules/integration_ksef_direct/migrations/Migration20260519210000_integration_ksef_direct.ts +15 -0
  130. package/src/modules/integration_ksef_direct/migrations/Migration20260520120000_ksef_direct_documents.ts +17 -0
  131. package/src/modules/integration_ksef_direct/migrations/Migration20260520220000_ksef_direct_send_queue.ts +15 -0
  132. package/src/modules/integration_ksef_direct/migrations/Migration20260520230000_ksef_direct_seller_per_document.ts +17 -0
  133. package/src/modules/integration_ksef_direct/migrations/Migration20260521120000_ksef_direct_received_documents.ts +16 -0
  134. package/src/modules/integration_ksef_direct/migrations/Migration20260521130000_ksef_received_download_urls.ts +15 -0
  135. package/src/modules/integration_ksef_direct/setup.ts +9 -0
  136. package/src/modules/integration_ksef_direct/subscribers/auto-enqueue-ksef-document.ts +21 -0
  137. package/src/modules/integration_ksef_direct/workers/check-ksef-document-status.ts +129 -0
  138. package/src/modules/integration_ksef_direct/workers/send-ksef-document.ts +137 -0
  139. package/src/modules/integration_ksef_direct/workers/sync-received-documents.ts +171 -0
  140. package/src/types/declarations.d.ts +1 -0
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # @fast-white-cat/integration-ksef-direct
2
+
3
+ OpenMercato module for direct integration with the Polish National e-Invoice System ([KSeF](https://ksef.mf.gov.pl)) via the official Ministry of Finance REST API v2 — no third-party middleware required.
4
+
5
+ ## Features
6
+
7
+ - Send invoices to KSeF (FA(2) format)
8
+ - Poll submission status and retrieve KSeF reference numbers
9
+ - Fetch and sync received invoices
10
+ - Health check for connection status and rate limits
11
+ - Supports both test (`api-test.ksef.mf.gov.pl`) and production (`api.ksef.mf.gov.pl`) environments
12
+
13
+ ## Requirements
14
+
15
+ - OpenMercato `>=0.6.2 <0.7.0`
16
+ - KSeF token and NIP (Tax Identification Number)
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npx mercato add @fast-white-cat/integration-ksef-direct
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ After installation, go to **Settings → Integrations → KSeF Direct** and provide:
27
+
28
+ | Field | Description |
29
+ |-------|-------------|
30
+ | KSeF Token | Authorization token issued by KSeF |
31
+ | NIP | Your company's tax identification number |
32
+ | Environment | `test` or `production` |
33
+
34
+ ## License
35
+
36
+ Proprietary — © FastWhiteCat
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./modules/integration_ksef_direct/index.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["export * from './modules/integration_ksef_direct/index'\n"],
5
+ "mappings": "AAAA,cAAc;",
6
+ "names": []
7
+ }
@@ -0,0 +1,13 @@
1
+ const features = [
2
+ { id: "integration_ksef_direct.view", title: "View KSeF Direct connection status", module: "integration_ksef_direct" },
3
+ { id: "integration_ksef_direct.manage", title: "Manage KSeF Direct integration", module: "integration_ksef_direct" },
4
+ { id: "integration_ksef_direct.documents.view", title: "View KSeF Direct documents", module: "integration_ksef_direct" },
5
+ { id: "integration_ksef_direct.documents.create", title: "Create KSeF Direct documents manually", module: "integration_ksef_direct" },
6
+ { id: "integration_ksef_direct.documents.send", title: "Send KSeF Direct documents to KSeF", module: "integration_ksef_direct" },
7
+ { id: "integration_ksef_direct.received_documents.view", title: "View KSeF Direct received documents", module: "integration_ksef_direct" },
8
+ { id: "integration_ksef_direct.received_documents.sync", title: "Sync KSeF Direct received documents", module: "integration_ksef_direct" }
9
+ ];
10
+ export {
11
+ features
12
+ };
13
+ //# sourceMappingURL=acl.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/modules/integration_ksef_direct/acl.ts"],
4
+ "sourcesContent": ["export const features = [\n { id: 'integration_ksef_direct.view', title: 'View KSeF Direct connection status', module: 'integration_ksef_direct' },\n { id: 'integration_ksef_direct.manage', title: 'Manage KSeF Direct integration', module: 'integration_ksef_direct' },\n { id: 'integration_ksef_direct.documents.view', title: 'View KSeF Direct documents', module: 'integration_ksef_direct' },\n { id: 'integration_ksef_direct.documents.create', title: 'Create KSeF Direct documents manually', module: 'integration_ksef_direct' },\n { id: 'integration_ksef_direct.documents.send', title: 'Send KSeF Direct documents to KSeF', module: 'integration_ksef_direct' },\n { id: 'integration_ksef_direct.received_documents.view', title: 'View KSeF Direct received documents', module: 'integration_ksef_direct' },\n { id: 'integration_ksef_direct.received_documents.sync', title: 'Sync KSeF Direct received documents', module: 'integration_ksef_direct' },\n]\n"],
5
+ "mappings": "AAAO,MAAM,WAAW;AAAA,EACtB,EAAE,IAAI,gCAAgC,OAAO,sCAAsC,QAAQ,0BAA0B;AAAA,EACrH,EAAE,IAAI,kCAAkC,OAAO,kCAAkC,QAAQ,0BAA0B;AAAA,EACnH,EAAE,IAAI,0CAA0C,OAAO,8BAA8B,QAAQ,0BAA0B;AAAA,EACvH,EAAE,IAAI,4CAA4C,OAAO,yCAAyC,QAAQ,0BAA0B;AAAA,EACpI,EAAE,IAAI,0CAA0C,OAAO,sCAAsC,QAAQ,0BAA0B;AAAA,EAC/H,EAAE,IAAI,mDAAmD,OAAO,uCAAuC,QAAQ,0BAA0B;AAAA,EACzI,EAAE,IAAI,mDAAmD,OAAO,uCAAuC,QAAQ,0BAA0B;AAC3I;",
6
+ "names": []
7
+ }
@@ -0,0 +1,92 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { KsefDirectDocument } from "../../../../data/entities.js";
6
+ const metadata = {
7
+ path: "/integration-ksef-direct/documents/[id]",
8
+ GET: { requireAuth: true, requireFeatures: ["integration_ksef_direct.documents.view"] }
9
+ };
10
+ async function GET(req, { params }) {
11
+ const auth = await getAuthFromRequest(req);
12
+ if (!auth?.tenantId || !auth.orgId) {
13
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
14
+ }
15
+ const container = await createRequestContainer();
16
+ const em = container.resolve("em");
17
+ const doc = await em.findOne(KsefDirectDocument, {
18
+ id: params.id,
19
+ organizationId: auth.orgId,
20
+ tenantId: auth.tenantId
21
+ });
22
+ if (!doc) {
23
+ return NextResponse.json({ error: "Not found" }, { status: 404 });
24
+ }
25
+ return NextResponse.json({
26
+ id: doc.id,
27
+ source: doc.source,
28
+ status: doc.status,
29
+ invoiceNumber: doc.invoiceNumber,
30
+ sellerNip: doc.sellerNip,
31
+ buyerNip: doc.buyerNip,
32
+ buyerName: doc.buyerName ?? null,
33
+ issueDate: doc.issueDate.toISOString().split("T")[0],
34
+ saleDate: doc.saleDate ? doc.saleDate.toISOString().split("T")[0] : null,
35
+ netAmount: doc.netAmount,
36
+ vatAmount: doc.vatAmount,
37
+ grossAmount: doc.grossAmount,
38
+ currency: doc.currency,
39
+ lineItems: doc.lineItems,
40
+ notes: doc.notes ?? null,
41
+ ksefReferenceNumber: doc.ksefReferenceNumber ?? null,
42
+ errorMessage: doc.errorMessage ?? null,
43
+ createdAt: doc.createdAt.toISOString(),
44
+ updatedAt: doc.updatedAt.toISOString()
45
+ });
46
+ }
47
+ const openApi = {
48
+ tag: "KSeF Direct",
49
+ summary: "Get KSeF Direct document",
50
+ methods: {
51
+ GET: {
52
+ summary: "Get a single KSeF Direct document",
53
+ description: "Returns the full document record including line items.",
54
+ responses: [
55
+ {
56
+ status: 200,
57
+ description: "Document record",
58
+ schema: z.object({
59
+ id: z.string().uuid(),
60
+ source: z.string(),
61
+ status: z.string(),
62
+ invoiceNumber: z.string(),
63
+ sellerNip: z.string(),
64
+ buyerNip: z.string(),
65
+ buyerName: z.string().nullable(),
66
+ issueDate: z.string(),
67
+ saleDate: z.string().nullable(),
68
+ netAmount: z.string(),
69
+ vatAmount: z.string(),
70
+ grossAmount: z.string(),
71
+ currency: z.string(),
72
+ lineItems: z.array(z.record(z.unknown())),
73
+ notes: z.string().nullable(),
74
+ ksefReferenceNumber: z.string().nullable(),
75
+ errorMessage: z.string().nullable(),
76
+ createdAt: z.string(),
77
+ updatedAt: z.string()
78
+ })
79
+ }
80
+ ],
81
+ errors: [
82
+ { status: 404, description: "Document not found", schema: z.object({ error: z.string() }) }
83
+ ]
84
+ }
85
+ }
86
+ };
87
+ export {
88
+ GET,
89
+ metadata,
90
+ openApi
91
+ };
92
+ //# sourceMappingURL=%5Bid%5D.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents/%5Bid%5D.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { KsefDirectDocument } from '../../../../data/entities'\n\nexport const metadata = {\n path: '/integration-ksef-direct/documents/[id]',\n GET: { requireAuth: true, requireFeatures: ['integration_ksef_direct.documents.view'] },\n}\n\nexport async function GET(req: Request, { params }: { params: { id: string } }) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as any\n\n const doc = await em.findOne(KsefDirectDocument, {\n id: params.id,\n organizationId: auth.orgId,\n tenantId: auth.tenantId,\n })\n\n if (!doc) {\n return NextResponse.json({ error: 'Not found' }, { status: 404 })\n }\n\n return NextResponse.json({\n id: doc.id,\n source: doc.source,\n status: doc.status,\n invoiceNumber: doc.invoiceNumber,\n sellerNip: doc.sellerNip,\n buyerNip: doc.buyerNip,\n buyerName: doc.buyerName ?? null,\n issueDate: doc.issueDate.toISOString().split('T')[0],\n saleDate: doc.saleDate ? doc.saleDate.toISOString().split('T')[0] : null,\n netAmount: doc.netAmount,\n vatAmount: doc.vatAmount,\n grossAmount: doc.grossAmount,\n currency: doc.currency,\n lineItems: doc.lineItems,\n notes: doc.notes ?? null,\n ksefReferenceNumber: doc.ksefReferenceNumber ?? null,\n errorMessage: doc.errorMessage ?? null,\n createdAt: doc.createdAt.toISOString(),\n updatedAt: doc.updatedAt.toISOString(),\n })\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'KSeF Direct',\n summary: 'Get KSeF Direct document',\n methods: {\n GET: {\n summary: 'Get a single KSeF Direct document',\n description: 'Returns the full document record including line items.',\n responses: [\n {\n status: 200,\n description: 'Document record',\n schema: z.object({\n id: z.string().uuid(),\n source: z.string(),\n status: z.string(),\n invoiceNumber: z.string(),\n sellerNip: z.string(),\n buyerNip: z.string(),\n buyerName: z.string().nullable(),\n issueDate: z.string(),\n saleDate: z.string().nullable(),\n netAmount: z.string(),\n vatAmount: z.string(),\n grossAmount: z.string(),\n currency: z.string(),\n lineItems: z.array(z.record(z.unknown())),\n notes: z.string().nullable(),\n ksefReferenceNumber: z.string().nullable(),\n errorMessage: z.string().nullable(),\n createdAt: z.string(),\n updatedAt: z.string(),\n }),\n },\n ],\n errors: [\n { status: 404, description: 'Document not found', schema: z.object({ error: z.string() }) },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,105 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { KsefDirectDocument } from "../../../data/entities.js";
6
+ const metadata = {
7
+ path: "/integration-ksef-direct/documents",
8
+ GET: { requireAuth: true, requireFeatures: ["integration_ksef_direct.documents.view"] }
9
+ };
10
+ const querySchema = z.object({
11
+ page: z.coerce.number().min(1).default(1),
12
+ pageSize: z.coerce.number().min(1).max(100).default(50),
13
+ status: z.string().optional(),
14
+ source: z.string().optional(),
15
+ search: z.string().optional()
16
+ });
17
+ async function GET(req) {
18
+ const auth = await getAuthFromRequest(req);
19
+ if (!auth?.tenantId || !auth.orgId) {
20
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
21
+ }
22
+ const url = new URL(req.url);
23
+ const parsed = querySchema.safeParse(Object.fromEntries(url.searchParams.entries()));
24
+ if (!parsed.success) {
25
+ return NextResponse.json({ error: "Invalid query" }, { status: 400 });
26
+ }
27
+ const query = parsed.data;
28
+ const container = await createRequestContainer();
29
+ const em = container.resolve("em");
30
+ const where = {
31
+ organizationId: auth.orgId,
32
+ tenantId: auth.tenantId
33
+ };
34
+ if (query.status) where.status = query.status;
35
+ if (query.source) where.source = query.source;
36
+ const [docs, total] = await em.findAndCount(
37
+ KsefDirectDocument,
38
+ where,
39
+ {
40
+ orderBy: { createdAt: "DESC" },
41
+ limit: query.pageSize,
42
+ offset: (query.page - 1) * query.pageSize
43
+ }
44
+ );
45
+ const items = docs.map((doc) => ({
46
+ id: doc.id,
47
+ source: doc.source,
48
+ status: doc.status,
49
+ invoiceNumber: doc.invoiceNumber,
50
+ buyerNip: doc.buyerNip,
51
+ buyerName: doc.buyerName ?? null,
52
+ issueDate: doc.issueDate.toISOString().split("T")[0],
53
+ sellerNip: doc.sellerNip,
54
+ netAmount: doc.netAmount,
55
+ vatAmount: doc.vatAmount,
56
+ grossAmount: doc.grossAmount,
57
+ currency: doc.currency,
58
+ ksefReferenceNumber: doc.ksefReferenceNumber ?? null,
59
+ createdAt: doc.createdAt.toISOString()
60
+ }));
61
+ return NextResponse.json({ items, total, page: query.page, pageSize: query.pageSize });
62
+ }
63
+ const openApi = {
64
+ tag: "KSeF Direct",
65
+ summary: "List KSeF Direct documents",
66
+ methods: {
67
+ GET: {
68
+ summary: "List KSeF Direct documents",
69
+ description: "Returns a paginated list of KSeF Direct document records for the current organization.",
70
+ responses: [
71
+ {
72
+ status: 200,
73
+ description: "Paginated list",
74
+ schema: z.object({
75
+ items: z.array(z.object({
76
+ id: z.string().uuid(),
77
+ source: z.string(),
78
+ status: z.string(),
79
+ invoiceNumber: z.string(),
80
+ buyerNip: z.string(),
81
+ buyerName: z.string().nullable(),
82
+ issueDate: z.string(),
83
+ sellerNip: z.string(),
84
+ netAmount: z.string(),
85
+ vatAmount: z.string(),
86
+ grossAmount: z.string(),
87
+ currency: z.string(),
88
+ ksefReferenceNumber: z.string().nullable(),
89
+ createdAt: z.string()
90
+ })),
91
+ total: z.number(),
92
+ page: z.number(),
93
+ pageSize: z.number()
94
+ })
95
+ }
96
+ ]
97
+ }
98
+ }
99
+ };
100
+ export {
101
+ GET,
102
+ metadata,
103
+ openApi
104
+ };
105
+ //# sourceMappingURL=documents.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/modules/integration_ksef_direct/api/get/integration-ksef-direct/documents.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { KsefDirectDocument } from '../../../data/entities'\n\nexport const metadata = {\n path: '/integration-ksef-direct/documents',\n GET: { requireAuth: true, requireFeatures: ['integration_ksef_direct.documents.view'] },\n}\n\nconst querySchema = z.object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n status: z.string().optional(),\n source: z.string().optional(),\n search: z.string().optional(),\n})\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const url = new URL(req.url)\n const parsed = querySchema.safeParse(Object.fromEntries(url.searchParams.entries()))\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid query' }, { status: 400 })\n }\n const query = parsed.data\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as any\n\n const where: Record<string, unknown> = {\n organizationId: auth.orgId,\n tenantId: auth.tenantId,\n }\n\n if (query.status) where.status = query.status\n if (query.source) where.source = query.source\n\n const [docs, total] = await em.findAndCount(\n KsefDirectDocument,\n where,\n {\n orderBy: { createdAt: 'DESC' },\n limit: query.pageSize,\n offset: (query.page - 1) * query.pageSize,\n },\n )\n\n const items = docs.map((doc: KsefDirectDocument) => ({\n id: doc.id,\n source: doc.source,\n status: doc.status,\n invoiceNumber: doc.invoiceNumber,\n buyerNip: doc.buyerNip,\n buyerName: doc.buyerName ?? null,\n issueDate: doc.issueDate.toISOString().split('T')[0],\n sellerNip: doc.sellerNip,\n netAmount: doc.netAmount,\n vatAmount: doc.vatAmount,\n grossAmount: doc.grossAmount,\n currency: doc.currency,\n ksefReferenceNumber: doc.ksefReferenceNumber ?? null,\n createdAt: doc.createdAt.toISOString(),\n }))\n\n return NextResponse.json({ items, total, page: query.page, pageSize: query.pageSize })\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'KSeF Direct',\n summary: 'List KSeF Direct documents',\n methods: {\n GET: {\n summary: 'List KSeF Direct documents',\n description: 'Returns a paginated list of KSeF Direct document records for the current organization.',\n responses: [\n {\n status: 200,\n description: 'Paginated list',\n schema: z.object({\n items: z.array(z.object({\n id: z.string().uuid(),\n source: z.string(),\n status: z.string(),\n invoiceNumber: z.string(),\n buyerNip: z.string(),\n buyerName: z.string().nullable(),\n issueDate: z.string(),\n sellerNip: z.string(),\n netAmount: z.string(),\n vatAmount: z.string(),\n grossAmount: z.string(),\n currency: z.string(),\n ksefReferenceNumber: z.string().nullable(),\n createdAt: z.string(),\n })),\n total: z.number(),\n page: z.number(),\n pageSize: z.number(),\n }),\n },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,158 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { verifyAccess, KsefAuthError, KsefNetworkError } from "../../../lib/ksefClient.js";
6
+ import { KsefDirectCredentialsSchema } from "../../../data/validators.js";
7
+ const metadata = {
8
+ path: "/integration-ksef-direct/health",
9
+ GET: { requireAuth: true, requireFeatures: ["integration_ksef_direct.manage"] }
10
+ };
11
+ async function GET(req) {
12
+ const auth = await getAuthFromRequest(req);
13
+ if (!auth?.tenantId || !auth.orgId) {
14
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
15
+ }
16
+ const container = await createRequestContainer();
17
+ const credentialsService = container.resolve("integrationCredentialsService");
18
+ const em = container.resolve("em");
19
+ const { KsefDirectConnection } = await import("../../../data/entities.js");
20
+ const { emitKsefDirectEvent } = await import("../../../events.js");
21
+ const rawCredentials = credentialsService ? await credentialsService.resolve("integration_ksef_direct", {
22
+ tenantId: auth.tenantId,
23
+ organizationId: auth.orgId
24
+ }) : null;
25
+ const credentialsParsed = rawCredentials ? KsefDirectCredentialsSchema.safeParse(rawCredentials) : null;
26
+ if (!credentialsParsed?.success) {
27
+ await upsertConnection(em, KsefDirectConnection, auth.orgId, auth.tenantId, {
28
+ status: "unconfigured",
29
+ lastCheckedAt: null,
30
+ errorMessage: null,
31
+ errorCode: null
32
+ });
33
+ return NextResponse.json({ status: "unconfigured", lastCheckedAt: null });
34
+ }
35
+ const credentials = {
36
+ ksefToken: credentialsParsed.data.ksef_token,
37
+ nip: credentialsParsed.data.nip,
38
+ environment: credentialsParsed.data.environment
39
+ };
40
+ await upsertConnection(em, KsefDirectConnection, auth.orgId, auth.tenantId, {
41
+ status: "checking",
42
+ lastCheckedAt: null,
43
+ errorMessage: null,
44
+ errorCode: null
45
+ });
46
+ try {
47
+ const rateLimits = await verifyAccess(credentials);
48
+ const now = /* @__PURE__ */ new Date();
49
+ await upsertConnection(em, KsefDirectConnection, auth.orgId, auth.tenantId, {
50
+ status: "connected",
51
+ lastCheckedAt: now,
52
+ errorMessage: null,
53
+ errorCode: null
54
+ });
55
+ await emitKsefDirectEvent("ksef_direct.connection.checked", {
56
+ organizationId: auth.orgId,
57
+ tenantId: auth.tenantId
58
+ });
59
+ await emitKsefDirectEvent("ksef_direct.connection.connected", {
60
+ organizationId: auth.orgId,
61
+ tenantId: auth.tenantId
62
+ });
63
+ return NextResponse.json({
64
+ status: "connected",
65
+ lastCheckedAt: now.toISOString(),
66
+ environment: credentials.environment,
67
+ rateLimits
68
+ });
69
+ } catch (err) {
70
+ const now = /* @__PURE__ */ new Date();
71
+ const errorMessage = err instanceof Error ? err.message : "Unknown error";
72
+ const errorCode = err instanceof KsefAuthError ? err.errorCode : err instanceof KsefNetworkError ? err.errorCode : "UNKNOWN_ERROR";
73
+ await upsertConnection(em, KsefDirectConnection, auth.orgId, auth.tenantId, {
74
+ status: "error",
75
+ lastCheckedAt: now,
76
+ errorMessage,
77
+ errorCode
78
+ });
79
+ await emitKsefDirectEvent("ksef_direct.connection.checked", {
80
+ organizationId: auth.orgId,
81
+ tenantId: auth.tenantId
82
+ });
83
+ await emitKsefDirectEvent("ksef_direct.connection.failed", {
84
+ organizationId: auth.orgId,
85
+ tenantId: auth.tenantId
86
+ });
87
+ return NextResponse.json({
88
+ status: "error",
89
+ lastCheckedAt: now.toISOString(),
90
+ error: errorMessage,
91
+ errorCode
92
+ });
93
+ }
94
+ }
95
+ async function upsertConnection(em, KsefDirectConnection, organizationId, tenantId, payload) {
96
+ const existing = await em.findOne(KsefDirectConnection, { organizationId, tenantId });
97
+ if (existing) {
98
+ existing.status = payload.status;
99
+ existing.lastCheckedAt = payload.lastCheckedAt;
100
+ existing.errorMessage = payload.errorMessage;
101
+ existing.errorCode = payload.errorCode;
102
+ existing.updatedAt = /* @__PURE__ */ new Date();
103
+ await em.flush();
104
+ } else {
105
+ const connection = em.create(KsefDirectConnection, {
106
+ organizationId,
107
+ tenantId,
108
+ status: payload.status,
109
+ lastCheckedAt: payload.lastCheckedAt,
110
+ errorMessage: payload.errorMessage,
111
+ errorCode: payload.errorCode
112
+ });
113
+ await em.persist(connection).flush();
114
+ }
115
+ }
116
+ const openApi = {
117
+ tag: "KSeF Direct",
118
+ summary: "KSeF Direct health check",
119
+ methods: {
120
+ GET: {
121
+ summary: "Check KSeF Direct connection health",
122
+ description: "Performs a full authentication flow against the KSeF MF API v2 and returns connection status.",
123
+ responses: [
124
+ {
125
+ status: 200,
126
+ description: "Health check result",
127
+ schema: z.union([
128
+ z.object({
129
+ status: z.literal("connected"),
130
+ lastCheckedAt: z.string(),
131
+ environment: z.enum(["test", "production"]),
132
+ rateLimits: z.object({
133
+ otherPerSecond: z.number().optional(),
134
+ otherPerMinute: z.number().optional()
135
+ }).optional()
136
+ }),
137
+ z.object({
138
+ status: z.literal("error"),
139
+ lastCheckedAt: z.string(),
140
+ error: z.string(),
141
+ errorCode: z.string()
142
+ }),
143
+ z.object({
144
+ status: z.literal("unconfigured"),
145
+ lastCheckedAt: z.null()
146
+ })
147
+ ])
148
+ }
149
+ ]
150
+ }
151
+ }
152
+ };
153
+ export {
154
+ GET,
155
+ metadata,
156
+ openApi
157
+ };
158
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/modules/integration_ksef_direct/api/get/integration-ksef-direct/health.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { verifyAccess, KsefAuthError, KsefNetworkError } from '../../../lib/ksefClient'\nimport type { KsefCredentials } from '../../../lib/ksefClient'\nimport { KsefDirectCredentialsSchema } from '../../../data/validators'\n\nexport const metadata = {\n path: '/integration-ksef-direct/health',\n GET: { requireAuth: true, requireFeatures: ['integration_ksef_direct.manage'] },\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const container = await createRequestContainer()\n const credentialsService = container.resolve('integrationCredentialsService') as any\n const em = container.resolve('em') as any\n\n const { KsefDirectConnection } = await import('../../../data/entities')\n const { emitKsefDirectEvent } = await import('../../../events')\n\n const rawCredentials = credentialsService\n ? await credentialsService.resolve('integration_ksef_direct', {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n })\n : null\n\n const credentialsParsed = rawCredentials\n ? KsefDirectCredentialsSchema.safeParse(rawCredentials)\n : null\n\n if (!credentialsParsed?.success) {\n await upsertConnection(em, KsefDirectConnection, auth.orgId, auth.tenantId, {\n status: 'unconfigured',\n lastCheckedAt: null,\n errorMessage: null,\n errorCode: null,\n })\n return NextResponse.json({ status: 'unconfigured', lastCheckedAt: null })\n }\n\n const credentials: KsefCredentials = {\n ksefToken: credentialsParsed.data.ksef_token,\n nip: credentialsParsed.data.nip,\n environment: credentialsParsed.data.environment,\n }\n\n await upsertConnection(em, KsefDirectConnection, auth.orgId, auth.tenantId, {\n status: 'checking',\n lastCheckedAt: null,\n errorMessage: null,\n errorCode: null,\n })\n\n try {\n const rateLimits = await verifyAccess(credentials)\n const now = new Date()\n\n await upsertConnection(em, KsefDirectConnection, auth.orgId, auth.tenantId, {\n status: 'connected',\n lastCheckedAt: now,\n errorMessage: null,\n errorCode: null,\n })\n\n await emitKsefDirectEvent('ksef_direct.connection.checked', {\n organizationId: auth.orgId,\n tenantId: auth.tenantId,\n })\n await emitKsefDirectEvent('ksef_direct.connection.connected', {\n organizationId: auth.orgId,\n tenantId: auth.tenantId,\n })\n\n return NextResponse.json({\n status: 'connected',\n lastCheckedAt: now.toISOString(),\n environment: credentials.environment,\n rateLimits,\n })\n } catch (err) {\n const now = new Date()\n const errorMessage = err instanceof Error ? err.message : 'Unknown error'\n const errorCode =\n err instanceof KsefAuthError\n ? err.errorCode\n : err instanceof KsefNetworkError\n ? err.errorCode\n : 'UNKNOWN_ERROR'\n\n await upsertConnection(em, KsefDirectConnection, auth.orgId, auth.tenantId, {\n status: 'error',\n lastCheckedAt: now,\n errorMessage,\n errorCode,\n })\n\n await emitKsefDirectEvent('ksef_direct.connection.checked', {\n organizationId: auth.orgId,\n tenantId: auth.tenantId,\n })\n await emitKsefDirectEvent('ksef_direct.connection.failed', {\n organizationId: auth.orgId,\n tenantId: auth.tenantId,\n })\n\n return NextResponse.json({\n status: 'error',\n lastCheckedAt: now.toISOString(),\n error: errorMessage,\n errorCode,\n })\n }\n}\n\ninterface UpsertPayload {\n status: 'unconfigured' | 'checking' | 'connected' | 'error'\n lastCheckedAt: Date | null\n errorMessage: string | null\n errorCode: string | null\n}\n\nasync function upsertConnection(\n em: any,\n KsefDirectConnection: any,\n organizationId: string,\n tenantId: string,\n payload: UpsertPayload,\n): Promise<void> {\n const existing = await em.findOne(KsefDirectConnection, { organizationId, tenantId })\n if (existing) {\n existing.status = payload.status\n existing.lastCheckedAt = payload.lastCheckedAt\n existing.errorMessage = payload.errorMessage\n existing.errorCode = payload.errorCode\n existing.updatedAt = new Date()\n await em.flush()\n } else {\n const connection = em.create(KsefDirectConnection, {\n organizationId,\n tenantId,\n status: payload.status,\n lastCheckedAt: payload.lastCheckedAt,\n errorMessage: payload.errorMessage,\n errorCode: payload.errorCode,\n })\n await em.persist(connection).flush()\n }\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'KSeF Direct',\n summary: 'KSeF Direct health check',\n methods: {\n GET: {\n summary: 'Check KSeF Direct connection health',\n description: 'Performs a full authentication flow against the KSeF MF API v2 and returns connection status.',\n responses: [\n {\n status: 200,\n description: 'Health check result',\n schema: z.union([\n z.object({\n status: z.literal('connected'),\n lastCheckedAt: z.string(),\n environment: z.enum(['test', 'production']),\n rateLimits: z.object({\n otherPerSecond: z.number().optional(),\n otherPerMinute: z.number().optional(),\n }).optional(),\n }),\n z.object({\n status: z.literal('error'),\n lastCheckedAt: z.string(),\n error: z.string(),\n errorCode: z.string(),\n }),\n z.object({\n status: z.literal('unconfigured'),\n lastCheckedAt: z.null(),\n }),\n ]),\n },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,86 @@
1
+ import { NextResponse } from "next/server";
2
+ import { z } from "zod";
3
+ import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
4
+ import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
5
+ import { KsefDirectReceivedDocument } from "../../../../data/entities.js";
6
+ const metadata = {
7
+ path: "/integration-ksef-direct/received-documents/[id]",
8
+ GET: { requireAuth: true, requireFeatures: ["integration_ksef_direct.received_documents.view"] }
9
+ };
10
+ async function GET(req, { params }) {
11
+ const auth = await getAuthFromRequest(req);
12
+ if (!auth?.tenantId || !auth.orgId) {
13
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
14
+ }
15
+ const container = await createRequestContainer();
16
+ const em = container.resolve("em");
17
+ const doc = await em.findOne(KsefDirectReceivedDocument, {
18
+ id: params.id,
19
+ organizationId: auth.orgId,
20
+ tenantId: auth.tenantId
21
+ });
22
+ if (!doc) {
23
+ return NextResponse.json({ error: "Not found" }, { status: 404 });
24
+ }
25
+ return NextResponse.json({
26
+ id: doc.id,
27
+ ksefReferenceNumber: doc.ksefReferenceNumber,
28
+ invoiceNumber: doc.invoiceNumber ?? null,
29
+ sellerNip: doc.sellerNip ?? null,
30
+ sellerName: doc.sellerName ?? null,
31
+ issueDate: doc.issueDate ?? null,
32
+ currency: doc.currency ?? null,
33
+ netAmount: doc.netAmount ?? null,
34
+ vatAmount: doc.vatAmount ?? null,
35
+ grossAmount: doc.grossAmount ?? null,
36
+ rawXml: doc.rawXml ?? null,
37
+ status: doc.status,
38
+ errorMessage: doc.errorMessage ?? null,
39
+ syncedAt: doc.syncedAt?.toISOString() ?? null,
40
+ createdAt: doc.createdAt.toISOString(),
41
+ updatedAt: doc.updatedAt.toISOString()
42
+ });
43
+ }
44
+ const openApi = {
45
+ tag: "KSeF Direct",
46
+ summary: "Get received KSeF document",
47
+ methods: {
48
+ GET: {
49
+ summary: "Get a single received KSeF document",
50
+ description: "Returns the full received document record including raw FA(2) XML.",
51
+ responses: [
52
+ {
53
+ status: 200,
54
+ description: "Document record",
55
+ schema: z.object({
56
+ id: z.string().uuid(),
57
+ ksefReferenceNumber: z.string(),
58
+ invoiceNumber: z.string().nullable(),
59
+ sellerNip: z.string().nullable(),
60
+ sellerName: z.string().nullable(),
61
+ issueDate: z.string().nullable(),
62
+ currency: z.string().nullable(),
63
+ netAmount: z.string().nullable(),
64
+ vatAmount: z.string().nullable(),
65
+ grossAmount: z.string().nullable(),
66
+ rawXml: z.string().nullable(),
67
+ status: z.string(),
68
+ errorMessage: z.string().nullable(),
69
+ syncedAt: z.string().nullable(),
70
+ createdAt: z.string(),
71
+ updatedAt: z.string()
72
+ })
73
+ }
74
+ ],
75
+ errors: [
76
+ { status: 404, description: "Not found", schema: z.object({ error: z.string() }) }
77
+ ]
78
+ }
79
+ }
80
+ };
81
+ export {
82
+ GET,
83
+ metadata,
84
+ openApi
85
+ };
86
+ //# sourceMappingURL=%5Bid%5D.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/integration_ksef_direct/api/get/integration-ksef-direct/received-documents/%5Bid%5D.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { KsefDirectReceivedDocument } from '../../../../data/entities'\n\nexport const metadata = {\n path: '/integration-ksef-direct/received-documents/[id]',\n GET: { requireAuth: true, requireFeatures: ['integration_ksef_direct.received_documents.view'] },\n}\n\nexport async function GET(req: Request, { params }: { params: { id: string } }) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n const container = await createRequestContainer()\n const em = container.resolve('em') as any\n\n const doc = await em.findOne(KsefDirectReceivedDocument, {\n id: params.id,\n organizationId: auth.orgId,\n tenantId: auth.tenantId,\n })\n\n if (!doc) {\n return NextResponse.json({ error: 'Not found' }, { status: 404 })\n }\n\n return NextResponse.json({\n id: doc.id,\n ksefReferenceNumber: doc.ksefReferenceNumber,\n invoiceNumber: doc.invoiceNumber ?? null,\n sellerNip: doc.sellerNip ?? null,\n sellerName: doc.sellerName ?? null,\n issueDate: doc.issueDate ?? null,\n currency: doc.currency ?? null,\n netAmount: doc.netAmount ?? null,\n vatAmount: doc.vatAmount ?? null,\n grossAmount: doc.grossAmount ?? null,\n rawXml: doc.rawXml ?? null,\n status: doc.status,\n errorMessage: doc.errorMessage ?? null,\n syncedAt: doc.syncedAt?.toISOString() ?? null,\n createdAt: doc.createdAt.toISOString(),\n updatedAt: doc.updatedAt.toISOString(),\n })\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'KSeF Direct',\n summary: 'Get received KSeF document',\n methods: {\n GET: {\n summary: 'Get a single received KSeF document',\n description: 'Returns the full received document record including raw FA(2) XML.',\n responses: [\n {\n status: 200,\n description: 'Document record',\n schema: z.object({\n id: z.string().uuid(),\n ksefReferenceNumber: z.string(),\n invoiceNumber: z.string().nullable(),\n sellerNip: z.string().nullable(),\n sellerName: z.string().nullable(),\n issueDate: z.string().nullable(),\n currency: z.string().nullable(),\n netAmount: z.string().nullable(),\n vatAmount: z.string().nullable(),\n grossAmount: z.string().nullable(),\n rawXml: z.string().nullable(),\n status: z.string(),\n errorMessage: z.string().nullable(),\n syncedAt: z.string().nullable(),\n createdAt: z.string(),\n updatedAt: z.string(),\n }),\n },\n ],\n errors: [\n { status: 404, description: 'Not found', schema: z.object({ error: z.string() }) },\n ],\n },\n },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,SAAS;AAElB,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,kCAAkC;AAEpC,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,iDAAiD,EAAE;AACjG;AAEA,eAAsB,IAAI,KAAc,EAAE,OAAO,GAA+B;AAC9E,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AAEA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,KAAK,UAAU,QAAQ,IAAI;AAEjC,QAAM,MAAM,MAAM,GAAG,QAAQ,4BAA4B;AAAA,IACvD,IAAI,OAAO;AAAA,IACX,gBAAgB,KAAK;AAAA,IACrB,UAAU,KAAK;AAAA,EACjB,CAAC;AAED,MAAI,CAAC,KAAK;AACR,WAAO,aAAa,KAAK,EAAE,OAAO,YAAY,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAClE;AAEA,SAAO,aAAa,KAAK;AAAA,IACvB,IAAI,IAAI;AAAA,IACR,qBAAqB,IAAI;AAAA,IACzB,eAAe,IAAI,iBAAiB;AAAA,IACpC,WAAW,IAAI,aAAa;AAAA,IAC5B,YAAY,IAAI,cAAc;AAAA,IAC9B,WAAW,IAAI,aAAa;AAAA,IAC5B,UAAU,IAAI,YAAY;AAAA,IAC1B,WAAW,IAAI,aAAa;AAAA,IAC5B,WAAW,IAAI,aAAa;AAAA,IAC5B,aAAa,IAAI,eAAe;AAAA,IAChC,QAAQ,IAAI,UAAU;AAAA,IACtB,QAAQ,IAAI;AAAA,IACZ,cAAc,IAAI,gBAAgB;AAAA,IAClC,UAAU,IAAI,UAAU,YAAY,KAAK;AAAA,IACzC,WAAW,IAAI,UAAU,YAAY;AAAA,IACrC,WAAW,IAAI,UAAU,YAAY;AAAA,EACvC,CAAC;AACH;AAEO,MAAM,UAA2B;AAAA,EACtC,KAAK;AAAA,EACL,SAAS;AAAA,EACT,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,QACT;AAAA,UACE,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,QAAQ,EAAE,OAAO;AAAA,YACf,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,YACpB,qBAAqB,EAAE,OAAO;AAAA,YAC9B,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,YACnC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,YAC/B,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,YAChC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,YAC/B,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,YAC9B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,YAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,YAC/B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,YACjC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,YAC5B,QAAQ,EAAE,OAAO;AAAA,YACjB,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,YAClC,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,YAC9B,WAAW,EAAE,OAAO;AAAA,YACpB,WAAW,EAAE,OAAO;AAAA,UACtB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MACA,QAAQ;AAAA,QACN,EAAE,QAAQ,KAAK,aAAa,aAAa,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }