diff --git a/.gitignore b/.gitignore
index 54ebf32..f71a9f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -137,3 +137,4 @@ dist
.yarn/install-state.gz
.pnp.*
+.storage
diff --git a/artifacts/pdf-audit/payload-parity-report.json b/artifacts/pdf-audit/payload-parity-report.json
index 02db715..944007a 100644
--- a/artifacts/pdf-audit/payload-parity-report.json
+++ b/artifacts/pdf-audit/payload-parity-report.json
@@ -1,10 +1,10 @@
{
"audit": "payload-parity",
"overallStatus": "PASS",
- "quotationCode": "CRA2606-1108",
- "previewHash": "8f93479501b66dfd397c742447b010eaf427697429bfcfd523cd127d06106f26",
- "generationHash": "8f93479501b66dfd397c742447b010eaf427697429bfcfd523cd127d06106f26",
- "snapshotHash": "8f93479501b66dfd397c742447b010eaf427697429bfcfd523cd127d06106f26",
+ "quotationCode": "CRA2606-1107",
+ "previewHash": "dd0c565a00c6161d66e3286380ca41eec17a2eee1f183236644733141cd6c1e6",
+ "generationHash": "dd0c565a00c6161d66e3286380ca41eec17a2eee1f183236644733141cd6c1e6",
+ "snapshotHash": "dd0c565a00c6161d66e3286380ca41eec17a2eee1f183236644733141cd6c1e6",
"mismatches": [],
"comparableFieldCount": 31,
"topicInputKeyCount": 6,
diff --git a/artifacts/pdf-audit/runtime-payload-report.json b/artifacts/pdf-audit/runtime-payload-report.json
index 46001f2..c8bab22 100644
--- a/artifacts/pdf-audit/runtime-payload-report.json
+++ b/artifacts/pdf-audit/runtime-payload-report.json
@@ -2,7 +2,7 @@
"audit": "runtime-payload",
"overallStatus": "PASS",
"staticLabelsStatus": "PASS",
- "quotationCode": "CRA2606-1108",
+ "quotationCode": "CRA2606-1107",
"templateName": "ALLA Demo Organization Quotation Standard",
"templateVersion": "1.0",
"findingCount": 168,
@@ -25,28 +25,28 @@
"field": "documentData.customer.id",
"source": "documentData",
"status": "PASS",
- "value": "85928568-22f2-424c-8896-a8e107ce3738",
+ "value": "11bf503b-9ae7-4f67-b800-2772fee2131c",
"message": "String is populated"
},
{
"field": "documentData.customer.name",
"source": "documentData",
"status": "PASS",
- "value": "มหาวิทยาลัยเทคโนโลยีพระจอมเกล้าพระนครเหนือ",
+ "value": "บริษัท นอร์ธเทิร์น แมชชีนเนอรี่ ดีลเลอร์ จำกัด",
"message": "String is populated"
},
{
"field": "documentData.customer.address",
"source": "documentData",
"status": "PASS",
- "value": "Bang Sue, Bangkok",
+ "value": "Mueang Chiang Mai, Chiang Mai",
"message": "String is populated"
},
{
"field": "documentData.customer.phone",
"source": "documentData",
"status": "PASS",
- "value": "02-400827",
+ "value": "02-400824",
"message": "String is populated"
},
{
@@ -60,14 +60,14 @@
"field": "documentData.contact.id",
"source": "documentData",
"status": "PASS",
- "value": "307bcf2f-46df-4ab7-b090-872b99338bf1",
+ "value": "a2cec2b0-23cc-4c49-8063-1d1fc9777cd0",
"message": "String is populated"
},
{
"field": "documentData.contact.name",
"source": "documentData",
"status": "PASS",
- "value": "คุณวราภรณ์ เกษมศรี",
+ "value": "คุณกิตติพงศ์ สุวรรณ",
"message": "String is populated"
},
{
@@ -81,56 +81,56 @@
"field": "documentData.contact.mobile",
"source": "documentData",
"status": "PASS",
- "value": "0810000250",
+ "value": "0810000220",
"message": "String is populated"
},
{
"field": "documentData.contact.position",
"source": "documentData",
"status": "PASS",
- "value": "Procurement Manager",
+ "value": "Plant Manager",
"message": "String is populated"
},
{
"field": "documentData.quotation.id",
"source": "documentData",
"status": "PASS",
- "value": "f9290e40-0836-431d-9d9f-0ff25fa2bcc3",
+ "value": "02d6b4b3-b11c-4a6e-9518-1258c8fcf4a1",
"message": "String is populated"
},
{
"field": "documentData.quotation.code",
"source": "documentData",
"status": "PASS",
- "value": "CRA2606-1108",
+ "value": "CRA2606-1107",
"message": "String is populated"
},
{
"field": "documentData.quotation.projectName",
"source": "documentData",
"status": "PASS",
- "value": "Material Handling Lab Crane",
+ "value": "Dealer Stock Crane Package",
"message": "String is populated"
},
{
"field": "documentData.quotation.projectLocation",
"source": "documentData",
"status": "PASS",
- "value": "Bang Sue Engineering Faculty",
+ "value": "Chiang Mai Service Warehouse",
"message": "String is populated"
},
{
"field": "documentData.quotation.attention",
"source": "documentData",
"status": "PASS",
- "value": "คุณวราภรณ์ เกษมศรี",
+ "value": "คุณกิตติพงศ์ สุวรรณ",
"message": "String is populated"
},
{
"field": "documentData.quotation.reference",
"source": "documentData",
"status": "PASS",
- "value": "crm-uat-seed-v1:university-lab-crane-approved",
+ "value": "crm-uat-seed-v1:dealer-channel-approved",
"message": "String is populated"
},
{
@@ -151,14 +151,14 @@
"field": "documentData.quotation.subtotal",
"source": "documentData",
"status": "PASS",
- "value": 3008000,
+ "value": 4418000,
"message": "Scalar value is populated"
},
{
"field": "documentData.quotation.totalAmount",
"source": "documentData",
"status": "PASS",
- "value": 3122003,
+ "value": 4585442,
"message": "Scalar value is populated"
},
{
@@ -172,7 +172,7 @@
"field": "documentData.items[0].id",
"source": "documentData",
"status": "PASS",
- "value": "2822652d-cab6-4b00-8b21-93a8b0c3d33f",
+ "value": "e150f933-729b-4ec1-bd3e-8514c1e05766",
"message": "String is populated"
},
{
@@ -186,7 +186,7 @@
"field": "documentData.items[0].description",
"source": "documentData",
"status": "PASS",
- "value": "Main equipment supply for Material Handling Lab Crane",
+ "value": "Main equipment supply for Dealer Stock Crane Package",
"message": "String is populated"
},
{
@@ -207,7 +207,7 @@
"field": "documentData.items[0].unitPrice",
"source": "documentData",
"status": "PASS",
- "value": 1717102,
+ "value": 2521993,
"message": "Scalar value is populated"
},
{
@@ -221,14 +221,14 @@
"field": "documentData.items[0].totalPrice",
"source": "documentData",
"status": "PASS",
- "value": 1717102,
+ "value": 2521993,
"message": "Scalar value is populated"
},
{
"field": "documentData.items[1].id",
"source": "documentData",
"status": "PASS",
- "value": "d080c242-c39b-4192-adab-f28fc0171389",
+ "value": "efcbc2e2-c561-478f-bfad-98dcbbd30ea6",
"message": "String is populated"
},
{
@@ -242,7 +242,7 @@
"field": "documentData.items[1].description",
"source": "documentData",
"status": "PASS",
- "value": "Installation and commissioning for Material Handling Lab Crane",
+ "value": "Installation and commissioning for Dealer Stock Crane Package",
"message": "String is populated"
},
{
@@ -263,7 +263,7 @@
"field": "documentData.items[1].unitPrice",
"source": "documentData",
"status": "PASS",
- "value": 874161,
+ "value": 1283924,
"message": "Scalar value is populated"
},
{
@@ -277,14 +277,14 @@
"field": "documentData.items[1].totalPrice",
"source": "documentData",
"status": "PASS",
- "value": 874161,
+ "value": 1283924,
"message": "Scalar value is populated"
},
{
"field": "documentData.items[2].id",
"source": "documentData",
"status": "PASS",
- "value": "de54b922-db69-42e3-a93c-940330852362",
+ "value": "d574bc39-ddd2-4f29-96fa-0091439c8abf",
"message": "String is populated"
},
{
@@ -298,7 +298,7 @@
"field": "documentData.items[2].description",
"source": "documentData",
"status": "PASS",
- "value": "Operator training and documentation for Material Handling Lab Crane",
+ "value": "Operator training and documentation for Dealer Stock Crane Package",
"message": "String is populated"
},
{
@@ -319,7 +319,7 @@
"field": "documentData.items[2].unitPrice",
"source": "documentData",
"status": "PASS",
- "value": 312200,
+ "value": 458544,
"message": "Scalar value is populated"
},
{
@@ -333,14 +333,14 @@
"field": "documentData.items[2].totalPrice",
"source": "documentData",
"status": "PASS",
- "value": 312200,
+ "value": 458544,
"message": "Scalar value is populated"
},
{
"field": "documentData.items[3].id",
"source": "documentData",
"status": "PASS",
- "value": "c903ac48-45c5-43b1-8948-1a196ec0d576",
+ "value": "0baeeec0-f2b0-4ea0-82d6-f80aa9de5aef",
"message": "String is populated"
},
{
@@ -354,7 +354,7 @@
"field": "documentData.items[3].description",
"source": "documentData",
"status": "PASS",
- "value": "Project management and testing for Material Handling Lab Crane",
+ "value": "Project management and testing for Dealer Stock Crane Package",
"message": "String is populated"
},
{
@@ -375,7 +375,7 @@
"field": "documentData.items[3].unitPrice",
"source": "documentData",
"status": "PASS",
- "value": 218540,
+ "value": 320981,
"message": "Scalar value is populated"
},
{
@@ -389,7 +389,7 @@
"field": "documentData.items[3].totalPrice",
"source": "documentData",
"status": "PASS",
- "value": 218540,
+ "value": 320981,
"message": "Scalar value is populated"
},
{
@@ -403,14 +403,14 @@
"field": "documentData.quotationCustomers[0].id",
"source": "documentData",
"status": "PASS",
- "value": "c15f26c7-2f23-44fc-84e2-0a435901f887",
+ "value": "81752ed4-508c-4946-9bd0-1450df258ffa",
"message": "String is populated"
},
{
"field": "documentData.quotationCustomers[0].customerId",
"source": "documentData",
"status": "PASS",
- "value": "85928568-22f2-424c-8896-a8e107ce3738",
+ "value": "11bf503b-9ae7-4f67-b800-2772fee2131c",
"message": "String is populated"
},
{
@@ -438,7 +438,7 @@
"field": "documentData.topics.all[0].id",
"source": "documentData",
"status": "PASS",
- "value": "396189b7-ca6c-4fc4-80dd-04f3f903f77b",
+ "value": "2f5b2486-9527-4a34-b5bc-319a76f26a97",
"message": "String is populated"
},
{
@@ -473,7 +473,7 @@
"field": "documentData.topics.all[0].items[0].content",
"source": "documentData",
"status": "PASS",
- "value": "Supply and execute material handling lab crane according to approved drawing.",
+ "value": "Supply and execute dealer stock crane package according to approved drawing.",
"message": "String is populated"
},
{
@@ -501,7 +501,7 @@
"field": "documentData.topics.all[1].id",
"source": "documentData",
"status": "PASS",
- "value": "41b30c9e-2adb-4407-b5f6-f803cc08bdb4",
+ "value": "6ea81a68-390f-4015-bd80-19f792eb57b6",
"message": "String is populated"
},
{
@@ -564,7 +564,7 @@
"field": "documentData.topics.all[2].id",
"source": "documentData",
"status": "PASS",
- "value": "1ef3d0b6-b722-42e1-b8c1-e328fbb1bb57",
+ "value": "2b9042e6-150f-4701-91c7-f490ff48de55",
"message": "String is populated"
},
{
@@ -634,7 +634,7 @@
"field": "documentData.topics.exclusion[0].id",
"source": "documentData",
"status": "PASS",
- "value": "41b30c9e-2adb-4407-b5f6-f803cc08bdb4",
+ "value": "6ea81a68-390f-4015-bd80-19f792eb57b6",
"message": "String is populated"
},
{
@@ -732,14 +732,14 @@
"field": "documentData.pdfme.quotation_date",
"source": "documentData",
"status": "PASS",
- "value": "Jun 15, 2026",
+ "value": "Jun 3, 2026",
"message": "String is populated"
},
{
"field": "documentData.pdfme.quotation_price",
"source": "documentData",
"status": "PASS",
- "value": "THB 3,008,000.00",
+ "value": "THB 4,418,000.00",
"message": "String is populated"
},
{
@@ -816,70 +816,70 @@
"field": "documentData.signatures.preparedBy.actedAt",
"source": "documentData",
"status": "PASS",
- "value": "2026-06-15T09:00:00.000Z",
+ "value": "2026-06-03T09:00:00.000Z",
"message": "String is populated"
},
{
"field": "documentData.signatures.approvedBy.name",
"source": "documentData",
"status": "PASS",
- "value": "-",
+ "value": "Sales Manager UAT",
"message": "String is populated"
},
{
"field": "documentData.signatures.approvedBy.position",
"source": "documentData",
"status": "PASS",
- "value": "-",
+ "value": "Sales Manager",
"message": "String is populated"
},
{
"field": "documentData.signatures.approvedBy.actedAt",
"source": "documentData",
- "status": "WARNING",
- "value": null,
- "message": "Value is null"
+ "status": "PASS",
+ "value": "2026-06-06T10:00:00.000Z",
+ "message": "String is populated"
},
{
"field": "documentData.signatures.authorizedBy.name",
"source": "documentData",
"status": "PASS",
- "value": "Sales Manager UAT",
+ "value": "CEO UAT",
"message": "String is populated"
},
{
"field": "documentData.signatures.authorizedBy.position",
"source": "documentData",
"status": "PASS",
- "value": "Sales Manager",
+ "value": "General Manager",
"message": "String is populated"
},
{
"field": "documentData.signatures.authorizedBy.actedAt",
"source": "documentData",
"status": "PASS",
- "value": "2026-06-17T11:00:00.000Z",
+ "value": "2026-06-07T09:00:00.000Z",
"message": "String is populated"
},
{
"field": "templateInput.customer_name",
"source": "templateInput",
"status": "PASS",
- "value": "มหาวิทยาลัยเทคโนโลยีพระจอมเกล้าพระนครเหนือ",
+ "value": "บริษัท นอร์ธเทิร์น แมชชีนเนอรี่ ดีลเลอร์ จำกัด",
"message": "String is populated"
},
{
"field": "templateInput.customer_addr",
"source": "templateInput",
"status": "PASS",
- "value": "Bang Sue, Bangkok",
+ "value": "Mueang Chiang Mai, Chiang Mai",
"message": "String is populated"
},
{
"field": "templateInput.customer_tel",
"source": "templateInput",
"status": "PASS",
- "value": "02-400827",
+ "value": "02-400824",
"message": "String is populated"
},
{
@@ -893,35 +893,35 @@
"field": "templateInput.customer_att",
"source": "templateInput",
"status": "PASS",
- "value": "คุณวราภรณ์ เกษมศรี",
+ "value": "คุณกิตติพงศ์ สุวรรณ",
"message": "String is populated"
},
{
"field": "templateInput.project_name",
"source": "templateInput",
"status": "PASS",
- "value": "Material Handling Lab Crane",
+ "value": "Dealer Stock Crane Package",
"message": "String is populated"
},
{
"field": "templateInput.site_location",
"source": "templateInput",
"status": "PASS",
- "value": "Bang Sue Engineering Faculty",
+ "value": "Chiang Mai Service Warehouse",
"message": "String is populated"
},
{
"field": "templateInput.quotation_date_data",
"source": "templateInput",
"status": "PASS",
- "value": "Jun 15, 2026",
+ "value": "Jun 3, 2026",
"message": "String is populated"
},
{
"field": "templateInput.quotation_code_data",
"source": "templateInput",
"status": "PASS",
- "value": "CRA2606-1108",
+ "value": "CRA2606-1107",
"message": "String is populated"
},
{
@@ -935,7 +935,7 @@
"field": "templateInput.quotation_price",
"source": "templateInput",
"status": "PASS",
- "value": "THB 3,008,000.00",
+ "value": "THB 4,418,000.00",
"message": "String is populated"
},
{
@@ -998,35 +998,35 @@
"field": "templateInput.app2",
"source": "templateInput",
"status": "PASS",
- "value": "-",
+ "value": "Sales Manager UAT",
"message": "String is populated"
},
{
"field": "templateInput.app2_position",
"source": "templateInput",
"status": "PASS",
- "value": "-",
+ "value": "Sales Manager",
"message": "String is populated"
},
{
"field": "templateInput.app3",
"source": "templateInput",
"status": "PASS",
- "value": "Sales Manager UAT",
+ "value": "CEO UAT",
"message": "String is populated"
},
{
"field": "templateInput.app3_position",
"source": "templateInput",
"status": "PASS",
- "value": "Sales Manager",
+ "value": "General Manager",
"message": "String is populated"
},
{
"field": "templateInput.quotation_date",
"source": "templateInput",
"status": "PASS",
- "value": "Jun 15, 2026",
+ "value": "Jun 3, 2026",
"message": "String is populated"
},
{
@@ -1075,7 +1075,7 @@
"field": "templateInput.quotation_code",
"source": "templateInput",
"status": "PASS",
- "value": "CRA2606-1108",
+ "value": "CRA2606-1107",
"message": "String is populated"
},
{
@@ -1138,7 +1138,7 @@
"field": "templateInput.quotation_price_data[0][1]",
"source": "templateInput",
"status": "PASS",
- "value": "฿3,008,000.00",
+ "value": "฿4,418,000.00",
"message": "Price table amount cell is formatted"
},
{
diff --git a/artifacts/pdf-audit/signature-audit-report.json b/artifacts/pdf-audit/signature-audit-report.json
index 5843580..c99056b 100644
--- a/artifacts/pdf-audit/signature-audit-report.json
+++ b/artifacts/pdf-audit/signature-audit-report.json
@@ -1,14 +1,14 @@
{
"audit": "approved-snapshot-parity",
"overallStatus": "PASS",
- "quotationCode": "CRA2606-1108",
+ "quotationCode": "CRA2606-1107",
"approvedSnapshotAvailable": true,
"approvedTemplateVersionId": "adf930b4-3d63-4ee1-bec9-3e82854ca406",
"computedTemplateVersionId": "adf930b4-3d63-4ee1-bec9-3e82854ca406",
"inconsistentTemplateKeys": [],
- "computedSignatureHash": "922ab2a823f98b032b17da281c86c3a2780d27cca73a60a7b983d14ad039b229",
- "storedSignatureHash": "922ab2a823f98b032b17da281c86c3a2780d27cca73a60a7b983d14ad039b229",
- "approvedArtifactReference": null,
+ "computedSignatureHash": "4106a8d9883d207231103e13f29aff692e6ad1d81a0e61cb26cea7ceea73e3b8",
+ "storedSignatureHash": "4106a8d9883d207231103e13f29aff692e6ad1d81a0e61cb26cea7ceea73e3b8",
+ "approvedArtifactReference": "artifact:6dfd7a74-8e9a-48ad-a4fe-dbb520edf581",
"refreshedFixtureSnapshot": true,
"usedAuditFixture": false
}
diff --git a/artifacts/pdf-audit/summary.json b/artifacts/pdf-audit/summary.json
index 97b502d..ea1fdf1 100644
--- a/artifacts/pdf-audit/summary.json
+++ b/artifacts/pdf-audit/summary.json
@@ -1,7 +1,7 @@
{
- "generatedAt": "2026-06-30T08:23:40.205Z",
+ "generatedAt": "2026-06-30T09:16:22.613Z",
"overallStatus": "PASS",
- "quotationCode": "CRA2606-1108",
+ "quotationCode": "CRA2606-1107",
"artifacts": {
"templateVersionReport": "template-version-report.json",
"placeholderIntegrityReport": "placeholder-integrity-report.json",
diff --git a/artifacts/pdf-audit/summary.md b/artifacts/pdf-audit/summary.md
index 4b279ee..5352f0c 100644
--- a/artifacts/pdf-audit/summary.md
+++ b/artifacts/pdf-audit/summary.md
@@ -1,8 +1,8 @@
# PDF Integrity Summary
-- Generated At: 2026-06-30T08:23:40.205Z
+- Generated At: 2026-06-30T09:16:22.613Z
- Overall Status: PASS
-- Quotation Code: CRA2606-1108
+- Quotation Code: CRA2606-1107
## Statuses
diff --git a/artifacts/pdf-audit/template-version-report.json b/artifacts/pdf-audit/template-version-report.json
index e460b67..0be0b51 100644
--- a/artifacts/pdf-audit/template-version-report.json
+++ b/artifacts/pdf-audit/template-version-report.json
@@ -2,7 +2,7 @@
"audit": "template-version-integrity",
"overallStatus": "PASS",
"activeTemplateCount": 1,
- "quotationCode": "CRA2606-1108",
+ "quotationCode": "CRA2606-1107",
"approvedTemplateVersionId": null,
"approvedTemplateVersionIsActive": false,
"issues": []
diff --git a/artifacts/pdf-audit/topic-runtime-report.json b/artifacts/pdf-audit/topic-runtime-report.json
index fd65a3d..ca4af66 100644
--- a/artifacts/pdf-audit/topic-runtime-report.json
+++ b/artifacts/pdf-audit/topic-runtime-report.json
@@ -1,7 +1,7 @@
{
"audit": "topic-runtime",
"overallStatus": "PASS",
- "quotationCode": "CRA2606-1108",
+ "quotationCode": "CRA2606-1107",
"topicCount": 3,
"topicInputKeys": [
"topic_1_0",
diff --git a/docs/implementation/pdf-audit-report.json b/docs/implementation/pdf-audit-report.json
index 6879a8e..bda7c06 100644
--- a/docs/implementation/pdf-audit-report.json
+++ b/docs/implementation/pdf-audit-report.json
@@ -1,7 +1,7 @@
{
- "generatedAt": "2026-06-30T08:23:36.291Z",
+ "generatedAt": "2026-06-30T09:16:20.352Z",
"overallStatus": "PASS",
- "quotationCode": "CRA2606-1108",
+ "quotationCode": "CRA2606-1107",
"expectedFixtureCode": "QT-H5-AUDIT",
"template": {
"templateName": "ALLA Demo Organization Quotation Standard",
@@ -263,7 +263,7 @@
"consistency": {
"status": "PASS",
"approvedSnapshotAvailable": true,
- "approvedArtifactReference": null,
+ "approvedArtifactReference": "artifact:6dfd7a74-8e9a-48ad-a4fe-dbb520edf581",
"inconsistentKeys": []
},
"integritySummary": {
diff --git a/docs/implementation/pdf-audit-report.md b/docs/implementation/pdf-audit-report.md
index d67b5c3..5125518 100644
--- a/docs/implementation/pdf-audit-report.md
+++ b/docs/implementation/pdf-audit-report.md
@@ -1,8 +1,8 @@
# PDF Audit Report
-- Generated At: 2026-06-30T08:23:36.291Z
+- Generated At: 2026-06-30T09:16:20.352Z
- Overall Status: PASS
-- Quotation Code: CRA2606-1108
+- Quotation Code: CRA2606-1107
- Template: ALLA Demo Organization Quotation Standard v1.0
- Previous Version: None
diff --git a/docs/implementation/task-p.7.1-implementation.md b/docs/implementation/task-p.7.1-implementation.md
new file mode 100644
index 0000000..e4b39a8
--- /dev/null
+++ b/docs/implementation/task-p.7.1-implementation.md
@@ -0,0 +1,66 @@
+# Task P.7.1 Implementation Report
+
+## Scope
+This round starts Task P.7.1 by extending the existing notification foundation into a reusable delivery layer for channel-based notifications, with email as the first implemented provider.
+
+## Review Summary
+Reviewed before implementation:
+- [AGENTS.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/AGENTS.md)
+- [docs/standards/project-foundations.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/standards/project-foundations.md)
+- [docs/standards/architecture-rules.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/standards/architecture-rules.md)
+- [docs/standards/ui-ux-rules.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/standards/ui-ux-rules.md)
+- [docs/standards/task-review-checklist.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/standards/task-review-checklist.md)
+- [docs/adr/0008-attachment-storage-strategy.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/adr/0008-attachment-storage-strategy.md)
+- [docs/adr/0009-approved-document-storage-lifecycle.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/adr/0009-approved-document-storage-lifecycle.md)
+- [docs/implementation/task-f4-notification-framework-foundation.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/implementation/task-f4-notification-framework-foundation.md)
+- [docs/implementation/task-f5-approval-automation-foundation.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/implementation/task-f5-approval-automation-foundation.md)
+- [docs/implementation/task-i-storage-artifact-lifecycle.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/implementation/task-i-storage-artifact-lifecycle.md)
+- [docs/implementation/task-p.7-implementation.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/implementation/task-p.7-implementation.md)
+
+## Discovery Findings
+- The repo already had an in-app notification foundation from Task F4 using `app_notification_events`, `app_notifications`, `app_notification_templates`, and `app_notification_deliveries`.
+- Approval automation from Task F5 already publishes reminder/escalation events and proves scheduler-oriented notification orchestration exists, but only for in-app delivery.
+- Storage and immutable document delivery foundations already exist and are reusable through:
+ - [src/features/foundation/document-artifact/server/service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-artifact/server/service.ts)
+ - [src/features/foundation/document-library/server/service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-library/server/service.ts)
+ - [src/features/foundation/storage/service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/storage/service.ts)
+- There was no usable SMTP provider implementation in the workspace yet; `nodemailer` had to be added.
+- There was no generic external-delivery history/queue log yet; the old `app_notification_deliveries` rows were still shaped around inbox notifications.
+
+## Delivered In This Round
+- Expanded notification contracts in [src/features/foundation/notifications/types.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/types.ts) to cover channels, dispatch status, external recipients, template metadata, attachments, and provider interfaces.
+- Extended notification template schema and added a new dispatch/history table in:
+ - [src/db/schema.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/db/schema.ts)
+ - [drizzle/0009_notification_delivery_foundation.sql](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/drizzle/0009_notification_delivery_foundation.sql)
+- Added reusable rendering, queue execution, attachment resolution, and provider plumbing:
+ - [src/features/foundation/notifications/server/template-renderer.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/template-renderer.ts)
+ - [src/features/foundation/notifications/server/delivery-engine.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/delivery-engine.ts)
+ - [src/features/foundation/notifications/server/attachment-service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/attachment-service.ts)
+ - [src/features/foundation/notifications/server/email-provider.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/email-provider.ts)
+ - [src/features/foundation/notifications/server/provider-factory.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/provider-factory.ts)
+ - [src/features/foundation/notifications/server/service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/service.ts)
+- Added API entry points for the first reusable send/preview/history/detail/resend flow:
+ - [src/app/api/notifications/preview/route.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/notifications/preview/route.ts)
+ - [src/app/api/notifications/send/route.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/notifications/send/route.ts)
+ - [src/app/api/notifications/history/route.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/notifications/history/route.ts)
+ - [src/app/api/notifications/history/[id]/route.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/notifications/history/%5Bid%5D/route.ts)
+ - [src/app/api/notifications/history/[id]/resend/route.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/notifications/history/%5Bid%5D/resend/route.ts)
+- Added new permissions in [src/lib/auth/rbac.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/lib/auth/rbac.ts):
+ - `notification.send`
+ - `notification.resend`
+ - `notification.manage_template`
+ - `notification.view_history`
+- Kept the original approval bell/inbox flow intact by updating [src/features/foundation/notifications/server/event-service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/event-service.ts) only where the richer template contract needed compatibility.
+
+## Design Notes
+- The old in-app notification foundation remains the source of truth for header bell / inbox UX.
+- The new delivery foundation uses a separate `app_notification_dispatches` log so external-channel delivery history does not depend on internal inbox rows.
+- Attachment resolution is storage-backed only. It reads existing artifact/document-library files and does not regenerate PDFs during send.
+- If a channel-specific template is missing, the new service falls back to the event's active in-app template so the API remains usable during migration.
+
+## Known Gaps After This Round
+- No template management UI yet.
+- No automated CRM event publication into email dispatch yet; CRM modules still need to call the new service/API explicitly.
+- No seed update was added yet for dedicated email templates, so best experience currently comes from template override or the in-app fallback path.
+- No Teams / LINE / Slack / SMS / web push provider implementations yet.
+- No background worker process yet; queue behavior is modeled in persisted dispatch status plus retry semantics, but still executed synchronously in this round.
diff --git a/docs/implementation/task-p.7.1-verification-report.md b/docs/implementation/task-p.7.1-verification-report.md
new file mode 100644
index 0000000..cbbb992
--- /dev/null
+++ b/docs/implementation/task-p.7.1-verification-report.md
@@ -0,0 +1,41 @@
+# Task P.7.1 Verification Report
+
+## Scope
+Verification for the first implementation round of Task P.7.1 notification foundation.
+
+## Verified Files
+- [src/features/foundation/notifications/types.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/types.ts)
+- [src/features/foundation/notifications/server/service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/service.ts)
+- [src/features/foundation/notifications/server/email-provider.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/email-provider.ts)
+- [src/features/foundation/notifications/server/attachment-service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/attachment-service.ts)
+- [src/features/foundation/notifications/server/template-renderer.test.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/template-renderer.test.ts)
+- [src/features/foundation/notifications/server/delivery-engine.test.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/notifications/server/delivery-engine.test.ts)
+- [src/app/api/notifications/send/route.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/notifications/send/route.ts)
+- [src/app/api/notifications/preview/route.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/notifications/preview/route.ts)
+- [src/app/api/notifications/history/route.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/notifications/history/route.ts)
+
+## Commands Run
+```bash
+npm install nodemailer@^7.0.7
+npm install -D @types/nodemailer
+npm run typecheck
+npm exec tsx --test src/features/foundation/notifications/server/template-renderer.test.ts src/features/foundation/notifications/server/delivery-engine.test.ts
+npm run build
+npm run audit:pdf
+```
+
+## Results On 2026-06-30
+- `npm run typecheck` = PASS
+- `npm exec tsx --test ...` = PASS
+- `npm run build` = PASS
+- `npm run audit:pdf` = PASS
+
+## Notes
+- `npm run build` completed successfully, but Next.js still emitted the pre-existing Turbopack root warning and existing NFT tracing warning unrelated to this notification task.
+- `npm run audit:pdf` refreshed existing audit artifacts and reports under `artifacts/pdf-audit/**` and `docs/implementation/pdf-audit-report.*`.
+- End-to-end SMTP send against a real server was not exercised in this round because provider credentials are environment-specific and out of task scope.
+
+## Residual Risk
+- Real email delivery still depends on valid `SMTP_*` environment configuration.
+- Channel-specific email templates should be seeded or managed explicitly in a follow-up round for the best operator experience.
+- History/detail/resend APIs were compile- and test-verified, but not manually exercised against live dispatch rows in this round.
diff --git a/drizzle/0009_notification_delivery_foundation.sql b/drizzle/0009_notification_delivery_foundation.sql
new file mode 100644
index 0000000..8131377
--- /dev/null
+++ b/drizzle/0009_notification_delivery_foundation.sql
@@ -0,0 +1,60 @@
+ALTER TABLE "app_notification_templates"
+ ADD COLUMN "code" text DEFAULT '' NOT NULL,
+ ADD COLUMN "name" text DEFAULT '' NOT NULL,
+ ADD COLUMN "subject_template" text,
+ ADD COLUMN "body_format" text DEFAULT 'plain' NOT NULL,
+ ADD COLUMN "language" text DEFAULT 'th' NOT NULL,
+ ADD COLUMN "variables" jsonb,
+ ADD COLUMN "version" integer DEFAULT 1 NOT NULL;
+--> statement-breakpoint
+UPDATE "app_notification_templates"
+SET
+ "code" = CASE
+ WHEN "code" = '' THEN replace("event_type", '.', '_') || '_' || "channel"
+ ELSE "code"
+ END,
+ "name" = CASE
+ WHEN "name" = '' THEN "event_type" || ' (' || "channel" || ')'
+ ELSE "name"
+ END,
+ "subject_template" = COALESCE("subject_template", "title_template"),
+ "variables" = COALESCE("variables", '[]'::jsonb);
+--> statement-breakpoint
+CREATE TABLE "app_notification_dispatches" (
+ "id" text PRIMARY KEY NOT NULL,
+ "organization_id" text NOT NULL,
+ "event_id" text NOT NULL,
+ "template_id" text,
+ "entity_type" text NOT NULL,
+ "entity_id" text NOT NULL,
+ "channel" text NOT NULL,
+ "provider_key" text NOT NULL,
+ "status" text DEFAULT 'pending' NOT NULL,
+ "recipient_to" jsonb NOT NULL,
+ "recipient_cc" jsonb,
+ "recipient_bcc" jsonb,
+ "reply_to" text,
+ "subject" text NOT NULL,
+ "body_text" text NOT NULL,
+ "body_html" text,
+ "attachments" jsonb,
+ "recipient_user_id" text,
+ "recipient_address" text,
+ "requested_by" text NOT NULL,
+ "metadata" jsonb,
+ "last_error" text,
+ "retry_count" integer DEFAULT 0 NOT NULL,
+ "max_retry_count" integer DEFAULT 3 NOT NULL,
+ "last_attempt_at" timestamp with time zone,
+ "sent_at" timestamp with time zone,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
+);
+--> statement-breakpoint
+CREATE UNIQUE INDEX "app_notification_dispatches_org_event_channel_recipient_idx"
+ ON "app_notification_dispatches" USING btree (
+ "organization_id",
+ "event_id",
+ "channel",
+ "recipient_address"
+ );
diff --git a/drizzle/0009_stale_next_avengers.sql b/drizzle/0009_stale_next_avengers.sql
new file mode 100644
index 0000000..18822d1
--- /dev/null
+++ b/drizzle/0009_stale_next_avengers.sql
@@ -0,0 +1,89 @@
+CREATE TABLE "app_notification_dispatches" (
+ "id" text PRIMARY KEY NOT NULL,
+ "organization_id" text NOT NULL,
+ "event_id" text NOT NULL,
+ "template_id" text,
+ "entity_type" text NOT NULL,
+ "entity_id" text NOT NULL,
+ "channel" text NOT NULL,
+ "provider_key" text NOT NULL,
+ "status" text DEFAULT 'pending' NOT NULL,
+ "recipient_to" jsonb NOT NULL,
+ "recipient_cc" jsonb,
+ "recipient_bcc" jsonb,
+ "reply_to" text,
+ "subject" text NOT NULL,
+ "body_text" text NOT NULL,
+ "body_html" text,
+ "attachments" jsonb,
+ "recipient_user_id" text,
+ "recipient_address" text,
+ "requested_by" text NOT NULL,
+ "metadata" jsonb,
+ "last_error" text,
+ "retry_count" integer DEFAULT 0 NOT NULL,
+ "max_retry_count" integer DEFAULT 3 NOT NULL,
+ "last_attempt_at" timestamp with time zone,
+ "sent_at" timestamp with time zone,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
+);
+--> statement-breakpoint
+CREATE TABLE "crm_document_libraries" (
+ "id" text PRIMARY KEY NOT NULL,
+ "organization_id" text NOT NULL,
+ "code" text NOT NULL,
+ "name" text NOT NULL,
+ "document_type" text NOT NULL,
+ "description" text,
+ "brand" text NOT NULL,
+ "language" text NOT NULL,
+ "product_type" text NOT NULL,
+ "status" text DEFAULT 'active' NOT NULL,
+ "is_active" boolean DEFAULT true NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "deleted_at" timestamp with time zone,
+ "created_by" text NOT NULL,
+ "updated_by" text NOT NULL
+);
+--> statement-breakpoint
+CREATE TABLE "crm_document_library_versions" (
+ "id" text PRIMARY KEY NOT NULL,
+ "organization_id" text NOT NULL,
+ "library_id" text NOT NULL,
+ "version" text NOT NULL,
+ "file_name" text NOT NULL,
+ "storage_provider" text NOT NULL,
+ "storage_key" text NOT NULL,
+ "mime_type" text NOT NULL,
+ "file_size" integer NOT NULL,
+ "checksum" text NOT NULL,
+ "page_count" integer NOT NULL,
+ "status" text DEFAULT 'draft' NOT NULL,
+ "is_active" boolean DEFAULT false NOT NULL,
+ "published_at" timestamp with time zone,
+ "published_by" text,
+ "archived_at" timestamp with time zone,
+ "archived_by" text,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "deleted_at" timestamp with time zone,
+ "created_by" text NOT NULL
+);
+--> statement-breakpoint
+DROP INDEX "document_sequences_org_doc_period_branch_idx";--> statement-breakpoint
+ALTER TABLE "app_notification_templates" ADD COLUMN "code" text DEFAULT '' NOT NULL;--> statement-breakpoint
+ALTER TABLE "app_notification_templates" ADD COLUMN "name" text DEFAULT '' NOT NULL;--> statement-breakpoint
+ALTER TABLE "app_notification_templates" ADD COLUMN "subject_template" text;--> statement-breakpoint
+ALTER TABLE "app_notification_templates" ADD COLUMN "body_format" text DEFAULT 'plain' NOT NULL;--> statement-breakpoint
+ALTER TABLE "app_notification_templates" ADD COLUMN "language" text DEFAULT 'th' NOT NULL;--> statement-breakpoint
+ALTER TABLE "app_notification_templates" ADD COLUMN "variables" jsonb;--> statement-breakpoint
+ALTER TABLE "app_notification_templates" ADD COLUMN "version" integer DEFAULT 1 NOT NULL;--> statement-breakpoint
+ALTER TABLE "document_sequences" ADD COLUMN "product_type" text DEFAULT 'all' NOT NULL;--> statement-breakpoint
+ALTER TABLE "document_sequences" ADD COLUMN "format" text DEFAULT '{prefix}{period}-{running}' NOT NULL;--> statement-breakpoint
+ALTER TABLE "document_sequences" ADD COLUMN "reset_policy" text DEFAULT 'period' NOT NULL;--> statement-breakpoint
+CREATE UNIQUE INDEX "app_notification_dispatches_org_event_channel_recipient_idx" ON "app_notification_dispatches" USING btree ("organization_id","event_id","channel","recipient_address");--> statement-breakpoint
+CREATE UNIQUE INDEX "crm_document_libraries_org_code_idx" ON "crm_document_libraries" USING btree ("organization_id","code");--> statement-breakpoint
+CREATE UNIQUE INDEX "crm_document_library_versions_library_version_idx" ON "crm_document_library_versions" USING btree ("library_id","version");--> statement-breakpoint
+CREATE UNIQUE INDEX "document_sequences_org_branch_product_doc_period_idx" ON "document_sequences" USING btree ("organization_id","branch_id","product_type","document_type","period");
\ No newline at end of file
diff --git a/drizzle/meta/0009_snapshot.json b/drizzle/meta/0009_snapshot.json
new file mode 100644
index 0000000..83839c9
--- /dev/null
+++ b/drizzle/meta/0009_snapshot.json
@@ -0,0 +1,5757 @@
+{
+ "id": "feac04da-e5b6-4e63-926a-15526b1de66f",
+ "prevId": "61cab7a1-31a8-47e2-b563-e6c9dc313f32",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.app_notification_deliveries": {
+ "name": "app_notification_deliveries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "notification_id": {
+ "name": "notification_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "channel": {
+ "name": "channel",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "recipient_address": {
+ "name": "recipient_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sent_at": {
+ "name": "sent_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.app_notification_dispatches": {
+ "name": "app_notification_dispatches",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_id": {
+ "name": "event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "template_id": {
+ "name": "template_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "channel": {
+ "name": "channel",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_key": {
+ "name": "provider_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "recipient_to": {
+ "name": "recipient_to",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "recipient_cc": {
+ "name": "recipient_cc",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "recipient_bcc": {
+ "name": "recipient_bcc",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reply_to": {
+ "name": "reply_to",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subject": {
+ "name": "subject",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body_text": {
+ "name": "body_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body_html": {
+ "name": "body_html",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attachments": {
+ "name": "attachments",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "recipient_user_id": {
+ "name": "recipient_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "recipient_address": {
+ "name": "recipient_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_by": {
+ "name": "requested_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "retry_count": {
+ "name": "retry_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "max_retry_count": {
+ "name": "max_retry_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 3
+ },
+ "last_attempt_at": {
+ "name": "last_attempt_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sent_at": {
+ "name": "sent_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "app_notification_dispatches_org_event_channel_recipient_idx": {
+ "name": "app_notification_dispatches_org_event_channel_recipient_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "recipient_address",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.app_notification_events": {
+ "name": "app_notification_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_user_id": {
+ "name": "actor_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dedupe_key": {
+ "name": "dedupe_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "processed_at": {
+ "name": "processed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "app_notification_events_org_dedupe_idx": {
+ "name": "app_notification_events_org_dedupe_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "dedupe_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.app_notification_templates": {
+ "name": "app_notification_templates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "channel": {
+ "name": "channel",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_template": {
+ "name": "subject_template",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title_template": {
+ "name": "title_template",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body_template": {
+ "name": "body_template",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body_format": {
+ "name": "body_format",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'plain'"
+ },
+ "link_template": {
+ "name": "link_template",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'th'"
+ },
+ "variables": {
+ "name": "variables",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "app_notification_templates_org_event_channel_idx": {
+ "name": "app_notification_templates_org_event_channel_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "event_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.app_notifications": {
+ "name": "app_notifications",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "recipient_user_id": {
+ "name": "recipient_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_id": {
+ "name": "event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body": {
+ "name": "body",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "link_url": {
+ "name": "link_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "severity": {
+ "name": "severity",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'info'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unread'"
+ },
+ "read_at": {
+ "name": "read_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "app_notifications_recipient_event_idx": {
+ "name": "app_notifications_recipient_event_idx",
+ "columns": [
+ {
+ "expression": "recipient_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_approval_actions": {
+ "name": "crm_approval_actions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "approval_request_id": {
+ "name": "approval_request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "step_number": {
+ "name": "step_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "remark": {
+ "name": "remark",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "acted_by": {
+ "name": "acted_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "acted_at": {
+ "name": "acted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_approval_escalation_policies": {
+ "name": "crm_approval_escalation_policies",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "step_number": {
+ "name": "step_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trigger_after_hours": {
+ "name": "trigger_after_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_type": {
+ "name": "target_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_value": {
+ "name": "target_value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_approval_matrices": {
+ "name": "crm_approval_matrices",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "branch_id": {
+ "name": "branch_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "product_type": {
+ "name": "product_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_amount": {
+ "name": "min_amount",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_amount": {
+ "name": "max_amount",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "priority": {
+ "name": "priority",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_approval_reminder_policies": {
+ "name": "crm_approval_reminder_policies",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "step_number": {
+ "name": "step_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sla_hours": {
+ "name": "sla_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 24
+ },
+ "reminder_offsets_hours": {
+ "name": "reminder_offsets_hours",
+ "type": "integer[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "calendar_mode": {
+ "name": "calendar_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'calendar_days'"
+ },
+ "timeout_action": {
+ "name": "timeout_action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "crm_approval_reminder_policies_workflow_step_idx": {
+ "name": "crm_approval_reminder_policies_workflow_step_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "step_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_approval_requests": {
+ "name": "crm_approval_requests",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_step": {
+ "name": "current_step",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "current_step_started_at": {
+ "name": "current_step_started_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requested_by": {
+ "name": "requested_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requested_at": {
+ "name": "requested_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_approval_steps": {
+ "name": "crm_approval_steps",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "step_number": {
+ "name": "step_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role_code": {
+ "name": "role_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role_name": {
+ "name": "role_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "approval_mode": {
+ "name": "approval_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'sequential'"
+ },
+ "is_required": {
+ "name": "is_required",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "sla_hours": {
+ "name": "sla_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 24
+ },
+ "calendar_mode": {
+ "name": "calendar_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'calendar_days'"
+ },
+ "timeout_action": {
+ "name": "timeout_action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "crm_approval_steps_workflow_step_idx": {
+ "name": "crm_approval_steps_workflow_step_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "step_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_approval_workflows": {
+ "name": "crm_approval_workflows",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "crm_approval_workflows_org_code_idx": {
+ "name": "crm_approval_workflows_org_code_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_contact_shares": {
+ "name": "crm_contact_shares",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contact_id": {
+ "name": "contact_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "shared_to_user_id": {
+ "name": "shared_to_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "shared_by_user_id": {
+ "name": "shared_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "shared_at": {
+ "name": "shared_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "remark": {
+ "name": "remark",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "crm_contact_shares_org_contact_shared_user_idx": {
+ "name": "crm_contact_shares_org_contact_shared_user_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "contact_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "shared_to_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_customer_contacts": {
+ "name": "crm_customer_contacts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "customer_id": {
+ "name": "customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "position": {
+ "name": "position",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "department": {
+ "name": "department",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "phone": {
+ "name": "phone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mobile": {
+ "name": "mobile",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_primary": {
+ "name": "is_primary",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_customer_owner_history": {
+ "name": "crm_customer_owner_history",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "customer_id": {
+ "name": "customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "old_owner_user_id": {
+ "name": "old_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "new_owner_user_id": {
+ "name": "new_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "changed_by": {
+ "name": "changed_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "changed_at": {
+ "name": "changed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "remark": {
+ "name": "remark",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_customers": {
+ "name": "crm_customers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "branch_id": {
+ "name": "branch_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "abbr": {
+ "name": "abbr",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tax_id": {
+ "name": "tax_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customer_type": {
+ "name": "customer_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "customer_status": {
+ "name": "customer_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "address": {
+ "name": "address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "province": {
+ "name": "province",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "district": {
+ "name": "district",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sub_district": {
+ "name": "sub_district",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "postal_code": {
+ "name": "postal_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "country": {
+ "name": "country",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "phone": {
+ "name": "phone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "fax": {
+ "name": "fax",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "website": {
+ "name": "website",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lead_channel": {
+ "name": "lead_channel",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customer_group": {
+ "name": "customer_group",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customer_sub_group": {
+ "name": "customer_sub_group",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_user_id": {
+ "name": "owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_assigned_at": {
+ "name": "owner_assigned_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_assigned_by": {
+ "name": "owner_assigned_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "crm_customers_org_code_idx": {
+ "name": "crm_customers_org_code_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_document_artifacts": {
+ "name": "crm_document_artifacts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_type": {
+ "name": "document_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "artifact_type": {
+ "name": "artifact_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "template_version_id": {
+ "name": "template_version_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "storage_provider": {
+ "name": "storage_provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_key": {
+ "name": "storage_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_name": {
+ "name": "file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "checksum": {
+ "name": "checksum",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "generated_by": {
+ "name": "generated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "generated_at": {
+ "name": "generated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "locked_at": {
+ "name": "locked_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "locked_by": {
+ "name": "locked_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "voided_at": {
+ "name": "voided_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "voided_by": {
+ "name": "voided_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "void_reason": {
+ "name": "void_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_document_libraries": {
+ "name": "crm_document_libraries",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_type": {
+ "name": "document_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "brand": {
+ "name": "brand",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "product_type": {
+ "name": "product_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "crm_document_libraries_org_code_idx": {
+ "name": "crm_document_libraries_org_code_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_document_library_versions": {
+ "name": "crm_document_library_versions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "library_id": {
+ "name": "library_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_name": {
+ "name": "file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_provider": {
+ "name": "storage_provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_key": {
+ "name": "storage_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mime_type": {
+ "name": "mime_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "checksum": {
+ "name": "checksum",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "page_count": {
+ "name": "page_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "published_by": {
+ "name": "published_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_by": {
+ "name": "archived_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "crm_document_library_versions_library_version_idx": {
+ "name": "crm_document_library_versions_library_version_idx",
+ "columns": [
+ {
+ "expression": "library_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "version",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_document_template_mappings": {
+ "name": "crm_document_template_mappings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "template_version_id": {
+ "name": "template_version_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "placeholder_key": {
+ "name": "placeholder_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_path": {
+ "name": "source_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "data_type": {
+ "name": "data_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sheet_name": {
+ "name": "sheet_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "default_value": {
+ "name": "default_value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "format_mask": {
+ "name": "format_mask",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "crm_document_template_mappings_version_placeholder_idx": {
+ "name": "crm_document_template_mappings_version_placeholder_idx",
+ "columns": [
+ {
+ "expression": "template_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "placeholder_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_document_template_table_columns": {
+ "name": "crm_document_template_table_columns",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mapping_id": {
+ "name": "mapping_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "column_name": {
+ "name": "column_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_field": {
+ "name": "source_field",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "column_letter": {
+ "name": "column_letter",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "format_mask": {
+ "name": "format_mask",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "crm_document_template_table_columns_mapping_name_idx": {
+ "name": "crm_document_template_table_columns_mapping_name_idx",
+ "columns": [
+ {
+ "expression": "mapping_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "column_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_document_template_versions": {
+ "name": "crm_document_template_versions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "template_id": {
+ "name": "template_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_path": {
+ "name": "file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "schema_json": {
+ "name": "schema_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata_json": {
+ "name": "metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "preview_image_url": {
+ "name": "preview_image_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "crm_document_template_versions_template_version_idx": {
+ "name": "crm_document_template_versions_template_version_idx",
+ "columns": [
+ {
+ "expression": "template_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "version",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_document_templates": {
+ "name": "crm_document_templates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_type": {
+ "name": "document_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "product_type": {
+ "name": "product_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_type": {
+ "name": "file_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "template_name": {
+ "name": "template_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "crm_document_templates_org_doc_product_file_name_idx": {
+ "name": "crm_document_templates_org_doc_product_file_name_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "product_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "file_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "template_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_leads": {
+ "name": "crm_leads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "branch_id": {
+ "name": "branch_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "customer_id": {
+ "name": "customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contact_id": {
+ "name": "contact_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_name": {
+ "name": "project_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_location": {
+ "name": "project_location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "product_type": {
+ "name": "product_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "priority": {
+ "name": "priority",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "estimated_value": {
+ "name": "estimated_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "awareness_id": {
+ "name": "awareness_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'new_job'"
+ },
+ "followup_status": {
+ "name": "followup_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lost_reason": {
+ "name": "lost_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "owner_marketing_user_id": {
+ "name": "owner_marketing_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assigned_sales_owner_id": {
+ "name": "assigned_sales_owner_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assigned_at": {
+ "name": "assigned_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assigned_by": {
+ "name": "assigned_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assignment_remark": {
+ "name": "assignment_remark",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "crm_leads_org_code_idx": {
+ "name": "crm_leads_org_code_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_opportunities": {
+ "name": "crm_opportunities",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "branch_id": {
+ "name": "branch_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lead_id": {
+ "name": "lead_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "customer_id": {
+ "name": "customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contact_id": {
+ "name": "contact_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requirement": {
+ "name": "requirement",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_name": {
+ "name": "project_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_location": {
+ "name": "project_location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "product_type": {
+ "name": "product_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "outcome_status": {
+ "name": "outcome_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'open'"
+ },
+ "priority": {
+ "name": "priority",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lead_channel": {
+ "name": "lead_channel",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "estimated_value": {
+ "name": "estimated_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "chance_percent": {
+ "name": "chance_percent",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expected_close_date": {
+ "name": "expected_close_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "competitor": {
+ "name": "competitor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_hot_project": {
+ "name": "is_hot_project",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "pipeline_stage": {
+ "name": "pipeline_stage",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'lead'"
+ },
+ "closed_at": {
+ "name": "closed_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "closed_won_at": {
+ "name": "closed_won_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "closed_lost_at": {
+ "name": "closed_lost_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "closed_by_user_id": {
+ "name": "closed_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "po_number": {
+ "name": "po_number",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "po_date": {
+ "name": "po_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "po_amount": {
+ "name": "po_amount",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "po_currency": {
+ "name": "po_currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lost_reason": {
+ "name": "lost_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lost_detail": {
+ "name": "lost_detail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lost_competitor": {
+ "name": "lost_competitor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lost_remark": {
+ "name": "lost_remark",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cancel_reason": {
+ "name": "cancel_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "no_quotation_reason": {
+ "name": "no_quotation_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assigned_to_user_id": {
+ "name": "assigned_to_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assigned_at": {
+ "name": "assigned_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assigned_by": {
+ "name": "assigned_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assignment_remark": {
+ "name": "assignment_remark",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "crm_opportunities_org_code_idx": {
+ "name": "crm_opportunities_org_code_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_opportunity_attachments": {
+ "name": "crm_opportunity_attachments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "opportunity_id": {
+ "name": "opportunity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_name": {
+ "name": "file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_file_name": {
+ "name": "original_file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_provider": {
+ "name": "storage_provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_key": {
+ "name": "storage_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_type": {
+ "name": "file_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uploaded_at": {
+ "name": "uploaded_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "uploaded_by": {
+ "name": "uploaded_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_opportunity_customers": {
+ "name": "crm_opportunity_customers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "opportunity_id": {
+ "name": "opportunity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "customer_id": {
+ "name": "customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "remark": {
+ "name": "remark",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_opportunity_followups": {
+ "name": "crm_opportunity_followups",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "opportunity_id": {
+ "name": "opportunity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "followup_date": {
+ "name": "followup_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "followup_type": {
+ "name": "followup_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contact_id": {
+ "name": "contact_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_followup_date": {
+ "name": "next_followup_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_action": {
+ "name": "next_action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_quotation_attachments": {
+ "name": "crm_quotation_attachments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "quotation_id": {
+ "name": "quotation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_name": {
+ "name": "file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_file_name": {
+ "name": "original_file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_path": {
+ "name": "file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_type": {
+ "name": "file_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uploaded_at": {
+ "name": "uploaded_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "uploaded_by": {
+ "name": "uploaded_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_quotation_customers": {
+ "name": "crm_quotation_customers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "quotation_id": {
+ "name": "quotation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "customer_id": {
+ "name": "customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_primary": {
+ "name": "is_primary",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "remark": {
+ "name": "remark",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_quotation_followups": {
+ "name": "crm_quotation_followups",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "quotation_id": {
+ "name": "quotation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "followup_date": {
+ "name": "followup_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "followup_type": {
+ "name": "followup_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contact_id": {
+ "name": "contact_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_followup_date": {
+ "name": "next_followup_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_action": {
+ "name": "next_action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_quotation_items": {
+ "name": "crm_quotation_items",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "quotation_id": {
+ "name": "quotation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "item_number": {
+ "name": "item_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "product_type": {
+ "name": "product_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "quantity": {
+ "name": "quantity",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "unit": {
+ "name": "unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "unit_price": {
+ "name": "unit_price",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "discount": {
+ "name": "discount",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "discount_type": {
+ "name": "discount_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tax_rate": {
+ "name": "tax_rate",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "total_price": {
+ "name": "total_price",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_quotation_topic_items": {
+ "name": "crm_quotation_topic_items",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "topic_id": {
+ "name": "topic_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_quotation_topics": {
+ "name": "crm_quotation_topics",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "quotation_id": {
+ "name": "quotation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "topic_type": {
+ "name": "topic_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_quotations": {
+ "name": "crm_quotations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "branch_id": {
+ "name": "branch_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "opportunity_id": {
+ "name": "opportunity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "customer_id": {
+ "name": "customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contact_id": {
+ "name": "contact_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quotation_date": {
+ "name": "quotation_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "valid_until": {
+ "name": "valid_until",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quotation_type": {
+ "name": "quotation_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_name": {
+ "name": "project_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "project_location": {
+ "name": "project_location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attention": {
+ "name": "attention",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reference": {
+ "name": "reference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "parent_quotation_id": {
+ "name": "parent_quotation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revision_remark": {
+ "name": "revision_remark",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "currency": {
+ "name": "currency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "exchange_rate": {
+ "name": "exchange_rate",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "subtotal": {
+ "name": "subtotal",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "discount": {
+ "name": "discount",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "discount_type": {
+ "name": "discount_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tax_rate": {
+ "name": "tax_rate",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tax_amount": {
+ "name": "tax_amount",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "total_amount": {
+ "name": "total_amount",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "chance_percent": {
+ "name": "chance_percent",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_hot_project": {
+ "name": "is_hot_project",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "competitor": {
+ "name": "competitor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "salesman_id": {
+ "name": "salesman_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_sent": {
+ "name": "is_sent",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "sent_at": {
+ "name": "sent_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sent_via": {
+ "name": "sent_via",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approved_at": {
+ "name": "approved_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approved_artifact_id": {
+ "name": "approved_artifact_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approved_pdf_url": {
+ "name": "approved_pdf_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approved_snapshot": {
+ "name": "approved_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "approved_template_version_id": {
+ "name": "approved_template_version_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accepted_at": {
+ "name": "accepted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rejected_at": {
+ "name": "rejected_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rejection_reason": {
+ "name": "rejection_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "crm_quotations_org_code_idx": {
+ "name": "crm_quotations_org_code_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_report_definitions": {
+ "name": "crm_report_definitions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "crm_report_definitions_org_code_idx": {
+ "name": "crm_report_definitions_org_code_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_role_profiles": {
+ "name": "crm_role_profiles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "permissions": {
+ "name": "permissions",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "branch_scope_mode": {
+ "name": "branch_scope_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'assigned'"
+ },
+ "product_scope_mode": {
+ "name": "product_scope_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'assigned'"
+ },
+ "ownership_scope": {
+ "name": "ownership_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'own'"
+ },
+ "approval_authority": {
+ "name": "approval_authority",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "crm_role_profiles_org_code_idx": {
+ "name": "crm_role_profiles_org_code_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.crm_user_role_assignments": {
+ "name": "crm_user_role_assignments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role_profile_id": {
+ "name": "role_profile_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "branch_scope_mode": {
+ "name": "branch_scope_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'inherit'"
+ },
+ "branch_scope_ids": {
+ "name": "branch_scope_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "product_type_scope_mode": {
+ "name": "product_type_scope_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'inherit'"
+ },
+ "product_type_scope_ids": {
+ "name": "product_type_scope_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "is_primary": {
+ "name": "is_primary",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "assigned_by": {
+ "name": "assigned_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "assigned_at": {
+ "name": "assigned_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "crm_user_role_assignments_org_user_role_idx": {
+ "name": "crm_user_role_assignments_org_user_role_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role_profile_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.document_sequences": {
+ "name": "document_sequences",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "branch_id": {
+ "name": "branch_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "product_type": {
+ "name": "product_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'all'"
+ },
+ "document_type": {
+ "name": "document_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prefix": {
+ "name": "prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "period": {
+ "name": "period",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_number": {
+ "name": "current_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "padding_length": {
+ "name": "padding_length",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 3
+ },
+ "format": {
+ "name": "format",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{prefix}{period}-{running}'"
+ },
+ "reset_policy": {
+ "name": "reset_policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'period'"
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "document_sequences_org_branch_product_doc_period_idx": {
+ "name": "document_sequences_org_branch_product_doc_period_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "branch_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "product_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "period",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.memberships": {
+ "name": "memberships",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'user'"
+ },
+ "business_role": {
+ "name": "business_role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'sales_support'"
+ },
+ "permissions": {
+ "name": "permissions",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "branch_scope_ids": {
+ "name": "branch_scope_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "product_type_scope_ids": {
+ "name": "product_type_scope_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.ms_options": {
+ "name": "ms_options",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "parent_id": {
+ "name": "parent_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "ms_options_org_category_code_idx": {
+ "name": "ms_options_org_category_code_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "category",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "code",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.organizations": {
+ "name": "organizations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "image_url": {
+ "name": "image_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "plan": {
+ "name": "plan",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'free'"
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "organizations_slug_idx": {
+ "name": "organizations_slug_idx",
+ "columns": [
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.products": {
+ "name": "products",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "identity": {
+ "type": "always",
+ "name": "products_id_seq",
+ "schema": "public",
+ "increment": "1",
+ "startWith": "1",
+ "minValue": "1",
+ "maxValue": "2147483647",
+ "cache": "1",
+ "cycle": false
+ }
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category": {
+ "name": "category",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "photo_url": {
+ "name": "photo_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "price": {
+ "name": "price",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tr_audit_logs": {
+ "name": "tr_audit_logs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "branch_id": {
+ "name": "branch_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "before_data": {
+ "name": "before_data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "after_data": {
+ "name": "after_data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.users": {
+ "name": "users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password_hash": {
+ "name": "password_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "system_role": {
+ "name": "system_role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'user'"
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "active_organization_id": {
+ "name": "active_organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "users_email_idx": {
+ "name": "users_email_idx",
+ "columns": [
+ {
+ "expression": "email",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "views": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json
index bdd14c8..81902e4 100644
--- a/drizzle/meta/_journal.json
+++ b/drizzle/meta/_journal.json
@@ -64,6 +64,13 @@
"when": 1782913600000,
"tag": "0008_document_sequence_scope_refactor",
"breakpoints": true
+ },
+ {
+ "idx": 9,
+ "version": "7",
+ "when": 1782815675836,
+ "tag": "0009_stale_next_avengers",
+ "breakpoints": true
}
]
-}
+}
\ No newline at end of file
diff --git a/next-env.d.ts b/next-env.d.ts
index 9edff1c..c4b7818 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,6 +1,6 @@
/// Hello {{customerName}}
Ready
Hello ACME