sla show
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -137,4 +137,4 @@ dist
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
.storage
|
||||
storage/organizations/
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"audit": "payload-parity",
|
||||
"overallStatus": "PASS",
|
||||
"quotationCode": "CRA2606-1121",
|
||||
"previewHash": "f50ad995d51a33c5ae169f788591f9efe6e70b7a4f96d6861b549b0c6f71cd2e",
|
||||
"generationHash": "f50ad995d51a33c5ae169f788591f9efe6e70b7a4f96d6861b549b0c6f71cd2e",
|
||||
"snapshotHash": "f50ad995d51a33c5ae169f788591f9efe6e70b7a4f96d6861b549b0c6f71cd2e",
|
||||
"quotationCode": "CRA2606-1108",
|
||||
"previewHash": "8f93479501b66dfd397c742447b010eaf427697429bfcfd523cd127d06106f26",
|
||||
"generationHash": "8f93479501b66dfd397c742447b010eaf427697429bfcfd523cd127d06106f26",
|
||||
"snapshotHash": "8f93479501b66dfd397c742447b010eaf427697429bfcfd523cd127d06106f26",
|
||||
"mismatches": [],
|
||||
"comparableFieldCount": 25,
|
||||
"topicInputKeyCount": 0,
|
||||
"comparableFieldCount": 31,
|
||||
"topicInputKeyCount": 6,
|
||||
"signatureParity": true,
|
||||
"priceTableParity": true,
|
||||
"priceTableRowCount": 1,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"overallStatus": "PASS",
|
||||
"results": [
|
||||
{
|
||||
"templateName": "ALLA Demo Organization Quotation Standard",
|
||||
"templateName": "ALLA Demo Quotation Standard",
|
||||
"organizationId": "daf796fc-4588-5240-a27e-9bfef0739658",
|
||||
"version": "1.0",
|
||||
"duplicateFieldNames": [],
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"audit": "approved-snapshot-parity",
|
||||
"overallStatus": "PASS",
|
||||
"quotationCode": "CRA2606-1121",
|
||||
"quotationCode": "CRA2606-1108",
|
||||
"approvedSnapshotAvailable": true,
|
||||
"approvedTemplateVersionId": "adf930b4-3d63-4ee1-bec9-3e82854ca406",
|
||||
"computedTemplateVersionId": "adf930b4-3d63-4ee1-bec9-3e82854ca406",
|
||||
"approvedTemplateVersionId": "e7e89bf2-f107-4f90-b03d-4a7533883d84",
|
||||
"computedTemplateVersionId": "e7e89bf2-f107-4f90-b03d-4a7533883d84",
|
||||
"inconsistentTemplateKeys": [],
|
||||
"computedSignatureHash": "ef7a8fc3429f1c5b5a74ac0452d3de809558842f5431d0d5b02122980a286117",
|
||||
"storedSignatureHash": "ef7a8fc3429f1c5b5a74ac0452d3de809558842f5431d0d5b02122980a286117",
|
||||
"computedSignatureHash": "922ab2a823f98b032b17da281c86c3a2780d27cca73a60a7b983d14ad039b229",
|
||||
"storedSignatureHash": "922ab2a823f98b032b17da281c86c3a2780d27cca73a60a7b983d14ad039b229",
|
||||
"approvedArtifactReference": null,
|
||||
"refreshedFixtureSnapshot": true,
|
||||
"usedAuditFixture": false
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"generatedAt": "2026-06-30T13:14:19.935Z",
|
||||
"overallStatus": "FAIL",
|
||||
"quotationCode": "CRA2606-1121",
|
||||
"generatedAt": "2026-06-30T16:18:58.393Z",
|
||||
"overallStatus": "PASS",
|
||||
"quotationCode": "CRA2606-1108",
|
||||
"artifacts": {
|
||||
"templateVersionReport": "template-version-report.json",
|
||||
"placeholderIntegrityReport": "placeholder-integrity-report.json",
|
||||
@@ -11,11 +11,11 @@
|
||||
"signatureAuditReport": "signature-audit-report.json"
|
||||
},
|
||||
"statuses": {
|
||||
"templateVersion": "FAIL",
|
||||
"templateVersion": "PASS",
|
||||
"placeholderIntegrity": "PASS",
|
||||
"runtimePayload": "PASS",
|
||||
"payloadParity": "PASS",
|
||||
"topicRuntime": "FAIL",
|
||||
"topicRuntime": "PASS",
|
||||
"approvedSnapshotParity": "PASS",
|
||||
"staticLabels": "PASS"
|
||||
},
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# PDF Integrity Summary
|
||||
|
||||
- Generated At: 2026-06-30T13:14:19.935Z
|
||||
- Overall Status: FAIL
|
||||
- Quotation Code: CRA2606-1121
|
||||
- Generated At: 2026-06-30T16:18:58.393Z
|
||||
- Overall Status: PASS
|
||||
- Quotation Code: CRA2606-1108
|
||||
|
||||
## Statuses
|
||||
|
||||
- Template Version Integrity: FAIL
|
||||
- Template Version Integrity: PASS
|
||||
- Placeholder Integrity: PASS
|
||||
- Runtime Payload: PASS
|
||||
- Payload Parity: PASS
|
||||
- Topic Runtime: FAIL
|
||||
- Topic Runtime: PASS
|
||||
- Approved Snapshot Parity: PASS
|
||||
- Static Labels: PASS
|
||||
- Price Table Present: Yes
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
{
|
||||
"audit": "template-version-integrity",
|
||||
"overallStatus": "FAIL",
|
||||
"overallStatus": "PASS",
|
||||
"activeTemplateCount": 1,
|
||||
"quotationCode": "CRA2606-1121",
|
||||
"quotationCode": "CRA2606-1108",
|
||||
"approvedTemplateVersionId": null,
|
||||
"approvedTemplateVersionIsActive": false,
|
||||
"issues": [
|
||||
{
|
||||
"kind": "ACTIVE_VERSION_SCHEMA_DRIFT",
|
||||
"message": "Active template version does not match source JSON for ALLA Demo Organization Quotation Standard.",
|
||||
"context": {
|
||||
"templateId": "83928eee-0b3b-4dcb-9756-726dc2337e6c",
|
||||
"organizationName": "ALLA Demo Organization",
|
||||
"activeVersionId": "adf930b4-3d63-4ee1-bec9-3e82854ca406",
|
||||
"activeVersion": "1.0",
|
||||
"sourceFile": "src/pdfme_template/ALLA_template_pdfme_fainal3.json"
|
||||
}
|
||||
}
|
||||
]
|
||||
"issues": []
|
||||
}
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
{
|
||||
"audit": "topic-runtime",
|
||||
"overallStatus": "FAIL",
|
||||
"quotationCode": "CRA2606-1121",
|
||||
"topicCount": 0,
|
||||
"topicInputKeys": [],
|
||||
"itemTopicInputKeys": [],
|
||||
"overallStatus": "PASS",
|
||||
"quotationCode": "CRA2606-1108",
|
||||
"topicCount": 3,
|
||||
"topicInputKeys": [
|
||||
"topic_1_0",
|
||||
"topic_1_1",
|
||||
"topic_1_2"
|
||||
],
|
||||
"itemTopicInputKeys": [
|
||||
"item_topic_1_0",
|
||||
"item_topic_1_1",
|
||||
"item_topic_1_2"
|
||||
],
|
||||
"duplicateKeys": [],
|
||||
"emptySections": []
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"generatedAt": "2026-06-30T13:14:09.584Z",
|
||||
"generatedAt": "2026-06-30T16:18:57.428Z",
|
||||
"overallStatus": "PASS",
|
||||
"quotationCode": "CRA2606-1121",
|
||||
"quotationCode": "CRA2606-1108",
|
||||
"expectedFixtureCode": "QT-H5-AUDIT",
|
||||
"template": {
|
||||
"templateName": "ALLA Demo Organization Quotation Standard",
|
||||
"templateName": "ALLA Demo Quotation Standard",
|
||||
"version": "1.0",
|
||||
"versionId": "adf930b4-3d63-4ee1-bec9-3e82854ca406",
|
||||
"versionId": "e7e89bf2-f107-4f90-b03d-4a7533883d84",
|
||||
"fieldCount": 44,
|
||||
"previousVersion": null,
|
||||
"deletedFields": [],
|
||||
@@ -238,11 +238,11 @@
|
||||
]
|
||||
},
|
||||
"metrics": {
|
||||
"topicCount": 0,
|
||||
"itemCount": 0,
|
||||
"partyCount": 2,
|
||||
"dynamicTopicFieldCount": 0,
|
||||
"dynamicTopicItemFieldCount": 0,
|
||||
"topicCount": 3,
|
||||
"itemCount": 4,
|
||||
"partyCount": 1,
|
||||
"dynamicTopicFieldCount": 3,
|
||||
"dynamicTopicItemFieldCount": 3,
|
||||
"mappingCount": 23
|
||||
},
|
||||
"mappingCoverage": {
|
||||
@@ -256,8 +256,8 @@
|
||||
"itemTableColumns": []
|
||||
},
|
||||
"runtimePayload": {
|
||||
"templateInputKeys": 25,
|
||||
"topicInputKeys": 0,
|
||||
"templateInputKeys": 31,
|
||||
"topicInputKeys": 6,
|
||||
"priceTableRows": 1
|
||||
},
|
||||
"consistency": {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# PDF Audit Report
|
||||
|
||||
- Generated At: 2026-06-30T13:14:09.584Z
|
||||
- Generated At: 2026-06-30T16:18:57.428Z
|
||||
- Overall Status: PASS
|
||||
- Quotation Code: CRA2606-1121
|
||||
- Template: ALLA Demo Organization Quotation Standard v1.0
|
||||
- Quotation Code: CRA2606-1108
|
||||
- Template: ALLA Demo Quotation Standard v1.0
|
||||
- Previous Version: None
|
||||
|
||||
## Metrics
|
||||
|
||||
- Topic Count: 0
|
||||
- Item Count: 0
|
||||
- Project Party Count: 2
|
||||
- Topic Count: 3
|
||||
- Item Count: 4
|
||||
- Project Party Count: 1
|
||||
- Mapping Count: 23
|
||||
|
||||
## Mapping Coverage
|
||||
|
||||
@@ -1,3 +1,106 @@
|
||||
CREATE TABLE "app_notification_deliveries" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"notification_id" text NOT NULL,
|
||||
"channel" text NOT NULL,
|
||||
"recipient_address" text,
|
||||
"status" text DEFAULT 'pending' NOT NULL,
|
||||
"attempt_count" integer DEFAULT 0 NOT NULL,
|
||||
"last_error" text,
|
||||
"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 "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 "app_notification_events" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"event_type" text NOT NULL,
|
||||
"entity_type" text NOT NULL,
|
||||
"entity_id" text NOT NULL,
|
||||
"actor_user_id" text,
|
||||
"payload" jsonb,
|
||||
"dedupe_key" text,
|
||||
"status" text DEFAULT 'pending' NOT NULL,
|
||||
"last_error" text,
|
||||
"published_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"processed_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 "app_notification_templates" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"event_type" text NOT NULL,
|
||||
"code" text DEFAULT '' NOT NULL,
|
||||
"name" text DEFAULT '' NOT NULL,
|
||||
"channel" text NOT NULL,
|
||||
"subject_template" text,
|
||||
"title_template" text NOT NULL,
|
||||
"body_template" text NOT NULL,
|
||||
"body_format" text DEFAULT 'plain' NOT NULL,
|
||||
"link_template" text,
|
||||
"language" text DEFAULT 'th' NOT NULL,
|
||||
"variables" jsonb,
|
||||
"version" integer DEFAULT 1 NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"metadata" jsonb,
|
||||
"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 "app_notifications" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"recipient_user_id" text NOT NULL,
|
||||
"event_id" text NOT NULL,
|
||||
"title" text NOT NULL,
|
||||
"body" text NOT NULL,
|
||||
"link_url" text,
|
||||
"severity" text DEFAULT 'info' NOT NULL,
|
||||
"status" text DEFAULT 'unread' NOT NULL,
|
||||
"read_at" timestamp with time zone,
|
||||
"archived_at" timestamp with time zone,
|
||||
"metadata" jsonb,
|
||||
"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_approval_actions" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
@@ -12,6 +115,60 @@ CREATE TABLE "crm_approval_actions" (
|
||||
"deleted_at" timestamp with time zone
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "crm_approval_escalation_policies" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"workflow_id" text NOT NULL,
|
||||
"step_number" integer NOT NULL,
|
||||
"trigger_after_hours" integer NOT NULL,
|
||||
"target_type" text NOT NULL,
|
||||
"target_value" text,
|
||||
"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_approval_matrices" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"entity_type" text NOT NULL,
|
||||
"workflow_id" text NOT NULL,
|
||||
"branch_id" text,
|
||||
"product_type" text,
|
||||
"min_amount" double precision,
|
||||
"max_amount" double precision,
|
||||
"currency" text,
|
||||
"priority" integer DEFAULT 100 NOT NULL,
|
||||
"is_default" boolean DEFAULT false NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"description" 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,
|
||||
"updated_by" text NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "crm_approval_reminder_policies" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"workflow_id" text NOT NULL,
|
||||
"step_number" integer NOT NULL,
|
||||
"sla_hours" integer DEFAULT 24 NOT NULL,
|
||||
"reminder_offsets_hours" integer[] DEFAULT '{}' NOT NULL,
|
||||
"calendar_mode" text DEFAULT 'calendar_days' NOT NULL,
|
||||
"timeout_action" text DEFAULT 'none' 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_approval_requests" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
@@ -19,6 +176,7 @@ CREATE TABLE "crm_approval_requests" (
|
||||
"entity_type" text NOT NULL,
|
||||
"entity_id" text NOT NULL,
|
||||
"current_step" integer DEFAULT 1 NOT NULL,
|
||||
"current_step_started_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"status" text NOT NULL,
|
||||
"requested_by" text NOT NULL,
|
||||
"requested_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
@@ -35,7 +193,11 @@ CREATE TABLE "crm_approval_steps" (
|
||||
"step_number" integer NOT NULL,
|
||||
"role_code" text NOT NULL,
|
||||
"role_name" text NOT NULL,
|
||||
"approval_mode" text DEFAULT 'sequential' NOT NULL,
|
||||
"is_required" boolean DEFAULT true NOT NULL,
|
||||
"sla_hours" integer DEFAULT 24 NOT NULL,
|
||||
"calendar_mode" text DEFAULT 'calendar_days' NOT NULL,
|
||||
"timeout_action" text DEFAULT 'none' 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
|
||||
@@ -47,7 +209,11 @@ CREATE TABLE "crm_approval_workflows" (
|
||||
"code" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"entity_type" text NOT NULL,
|
||||
"description" text,
|
||||
"is_system" boolean DEFAULT false NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"created_by" text NOT NULL,
|
||||
"updated_by" text 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
|
||||
@@ -164,6 +330,49 @@ CREATE TABLE "crm_document_artifacts" (
|
||||
"deleted_at" timestamp with time zone
|
||||
);
|
||||
--> 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
|
||||
CREATE TABLE "crm_document_template_mappings" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
@@ -201,6 +410,7 @@ CREATE TABLE "crm_document_template_versions" (
|
||||
"version" text NOT NULL,
|
||||
"file_path" text,
|
||||
"schema_json" jsonb NOT NULL,
|
||||
"metadata_json" jsonb,
|
||||
"preview_image_url" text,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
@@ -270,6 +480,7 @@ CREATE TABLE "crm_opportunities" (
|
||||
"project_location" text,
|
||||
"product_type" text NOT NULL,
|
||||
"status" text NOT NULL,
|
||||
"outcome_status" text DEFAULT 'open' NOT NULL,
|
||||
"priority" text NOT NULL,
|
||||
"lead_channel" text,
|
||||
"estimated_value" double precision,
|
||||
@@ -281,6 +492,7 @@ CREATE TABLE "crm_opportunities" (
|
||||
"is_hot_project" boolean DEFAULT false NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"pipeline_stage" text DEFAULT 'lead' NOT NULL,
|
||||
"closed_at" timestamp with time zone,
|
||||
"closed_won_at" timestamp with time zone,
|
||||
"closed_lost_at" timestamp with time zone,
|
||||
"closed_by_user_id" text,
|
||||
@@ -289,8 +501,11 @@ CREATE TABLE "crm_opportunities" (
|
||||
"po_amount" double precision,
|
||||
"po_currency" text,
|
||||
"lost_reason" text,
|
||||
"lost_detail" text,
|
||||
"lost_competitor" text,
|
||||
"lost_remark" text,
|
||||
"cancel_reason" text,
|
||||
"no_quotation_reason" text,
|
||||
"assigned_to_user_id" text,
|
||||
"assigned_at" timestamp with time zone,
|
||||
"assigned_by" text,
|
||||
@@ -549,11 +764,14 @@ CREATE TABLE "document_sequences" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"branch_id" text DEFAULT '' NOT NULL,
|
||||
"product_type" text DEFAULT 'all' NOT NULL,
|
||||
"document_type" text NOT NULL,
|
||||
"prefix" text NOT NULL,
|
||||
"period" text NOT NULL,
|
||||
"current_number" integer DEFAULT 0 NOT NULL,
|
||||
"padding_length" integer DEFAULT 3 NOT NULL,
|
||||
"format" text DEFAULT '{prefix}{period}-{running}' NOT NULL,
|
||||
"reset_policy" text DEFAULT 'period' 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
|
||||
@@ -637,10 +855,17 @@ CREATE TABLE "users" (
|
||||
"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");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "app_notification_events_org_dedupe_idx" ON "app_notification_events" USING btree ("organization_id","dedupe_key");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "app_notification_templates_org_event_channel_idx" ON "app_notification_templates" USING btree ("organization_id","event_type","channel");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "app_notifications_recipient_event_idx" ON "app_notifications" USING btree ("recipient_user_id","event_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_approval_reminder_policies_workflow_step_idx" ON "crm_approval_reminder_policies" USING btree ("workflow_id","step_number");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_approval_steps_workflow_step_idx" ON "crm_approval_steps" USING btree ("workflow_id","step_number");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_approval_workflows_org_code_idx" ON "crm_approval_workflows" USING btree ("organization_id","code");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_contact_shares_org_contact_shared_user_idx" ON "crm_contact_shares" USING btree ("organization_id","contact_id","shared_to_user_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_customers_org_code_idx" ON "crm_customers" USING btree ("organization_id","code");--> 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 "crm_document_template_mappings_version_placeholder_idx" ON "crm_document_template_mappings" USING btree ("template_version_id","placeholder_key");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_document_template_table_columns_mapping_name_idx" ON "crm_document_template_table_columns" USING btree ("mapping_id","column_name");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_document_template_versions_template_version_idx" ON "crm_document_template_versions" USING btree ("template_id","version");--> statement-breakpoint
|
||||
@@ -651,7 +876,7 @@ CREATE UNIQUE INDEX "crm_quotations_org_code_idx" ON "crm_quotations" USING btre
|
||||
CREATE UNIQUE INDEX "crm_report_definitions_org_code_idx" ON "crm_report_definitions" USING btree ("organization_id","code");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_role_profiles_org_code_idx" ON "crm_role_profiles" USING btree ("organization_id","code");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_user_role_assignments_org_user_role_idx" ON "crm_user_role_assignments" USING btree ("organization_id","user_id","role_profile_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "document_sequences_org_doc_period_branch_idx" ON "document_sequences" USING btree ("organization_id","document_type","period","branch_id");--> 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");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "ms_options_org_category_code_idx" ON "ms_options" USING btree ("organization_id","category","code");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "organizations_slug_idx" ON "organizations" USING btree ("slug");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "users_email_idx" ON "users" USING btree ("email");
|
||||
@@ -1,5 +0,0 @@
|
||||
ALTER TABLE "crm_opportunities" ADD COLUMN "outcome_status" text DEFAULT 'open' NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "crm_opportunities" ADD COLUMN "closed_at" timestamp with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "crm_opportunities" ADD COLUMN "lost_detail" text;--> statement-breakpoint
|
||||
ALTER TABLE "crm_opportunities" ADD COLUMN "cancel_reason" text;--> statement-breakpoint
|
||||
ALTER TABLE "crm_opportunities" ADD COLUMN "no_quotation_reason" text;
|
||||
@@ -1,20 +0,0 @@
|
||||
CREATE TABLE "crm_approval_matrices" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"entity_type" text NOT NULL,
|
||||
"workflow_id" text NOT NULL,
|
||||
"branch_id" text,
|
||||
"product_type" text,
|
||||
"min_amount" double precision,
|
||||
"max_amount" double precision,
|
||||
"currency" text,
|
||||
"priority" integer DEFAULT 100 NOT NULL,
|
||||
"is_default" boolean DEFAULT false NOT NULL,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"description" 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,
|
||||
"updated_by" text NOT NULL
|
||||
);
|
||||
@@ -1,14 +0,0 @@
|
||||
ALTER TABLE "crm_approval_workflows"
|
||||
ADD COLUMN "description" text;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "crm_approval_workflows"
|
||||
ADD COLUMN "is_system" boolean DEFAULT false NOT NULL;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "crm_approval_workflows"
|
||||
ADD COLUMN "created_by" text NOT NULL DEFAULT '';
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "crm_approval_workflows"
|
||||
ADD COLUMN "updated_by" text NOT NULL DEFAULT '';
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "crm_approval_steps"
|
||||
ADD COLUMN "approval_mode" text DEFAULT 'sequential' NOT NULL;
|
||||
@@ -1,73 +0,0 @@
|
||||
CREATE TABLE "app_notification_deliveries" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"notification_id" text NOT NULL,
|
||||
"channel" text NOT NULL,
|
||||
"recipient_address" text,
|
||||
"status" text DEFAULT 'pending' NOT NULL,
|
||||
"attempt_count" integer DEFAULT 0 NOT NULL,
|
||||
"last_error" text,
|
||||
"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 "app_notification_events" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"event_type" text NOT NULL,
|
||||
"entity_type" text NOT NULL,
|
||||
"entity_id" text NOT NULL,
|
||||
"actor_user_id" text,
|
||||
"payload" jsonb,
|
||||
"dedupe_key" text,
|
||||
"status" text DEFAULT 'pending' NOT NULL,
|
||||
"last_error" text,
|
||||
"published_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"processed_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 "app_notification_templates" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"event_type" text NOT NULL,
|
||||
"channel" text NOT NULL,
|
||||
"title_template" text NOT NULL,
|
||||
"body_template" text NOT NULL,
|
||||
"link_template" text,
|
||||
"is_active" boolean DEFAULT true NOT NULL,
|
||||
"metadata" jsonb,
|
||||
"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 "app_notifications" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"recipient_user_id" text NOT NULL,
|
||||
"event_id" text NOT NULL,
|
||||
"title" text NOT NULL,
|
||||
"body" text NOT NULL,
|
||||
"link_url" text,
|
||||
"severity" text DEFAULT 'info' NOT NULL,
|
||||
"status" text DEFAULT 'unread' NOT NULL,
|
||||
"read_at" timestamp with time zone,
|
||||
"archived_at" timestamp with time zone,
|
||||
"metadata" jsonb,
|
||||
"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_events_org_dedupe_idx"
|
||||
ON "app_notification_events" USING btree ("organization_id", "dedupe_key");
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "app_notification_templates_org_event_channel_idx"
|
||||
ON "app_notification_templates" USING btree ("organization_id", "event_type", "channel");
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "app_notifications_recipient_event_idx"
|
||||
ON "app_notifications" USING btree ("recipient_user_id", "event_id");
|
||||
@@ -1,38 +0,0 @@
|
||||
CREATE TABLE "crm_approval_escalation_policies" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"workflow_id" text NOT NULL,
|
||||
"step_number" integer NOT NULL,
|
||||
"trigger_after_hours" integer NOT NULL,
|
||||
"target_type" text NOT NULL,
|
||||
"target_value" text,
|
||||
"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_approval_reminder_policies" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"organization_id" text NOT NULL,
|
||||
"workflow_id" text NOT NULL,
|
||||
"step_number" integer NOT NULL,
|
||||
"sla_hours" integer DEFAULT 24 NOT NULL,
|
||||
"reminder_offsets_hours" integer[] DEFAULT '{}' NOT NULL,
|
||||
"calendar_mode" text DEFAULT 'calendar_days' NOT NULL,
|
||||
"timeout_action" text DEFAULT 'none' 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
|
||||
ALTER TABLE "crm_approval_requests" ADD COLUMN "current_step_started_at" timestamp with time zone DEFAULT now() NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "crm_approval_steps" ADD COLUMN "sla_hours" integer DEFAULT 24 NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "crm_approval_steps" ADD COLUMN "calendar_mode" text DEFAULT 'calendar_days' NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "crm_approval_steps" ADD COLUMN "timeout_action" text DEFAULT 'none' NOT NULL;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "crm_approval_reminder_policies_workflow_step_idx" ON "crm_approval_reminder_policies" USING btree ("workflow_id","step_number");
|
||||
@@ -1,11 +0,0 @@
|
||||
ALTER TABLE "crm_document_template_versions" ADD COLUMN "metadata_json" jsonb;
|
||||
--> statement-breakpoint
|
||||
UPDATE "crm_document_template_versions"
|
||||
SET
|
||||
"metadata_json" = COALESCE("metadata_json", "schema_json" -> '__templateManagement'),
|
||||
"schema_json" = CASE
|
||||
WHEN "schema_json" ? '__templateManagement'
|
||||
THEN "schema_json" - '__templateManagement'
|
||||
ELSE "schema_json"
|
||||
END
|
||||
WHERE "schema_json" ? '__templateManagement';
|
||||
@@ -1,50 +0,0 @@
|
||||
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 UNIQUE INDEX "crm_document_libraries_org_code_idx" ON "crm_document_libraries" USING btree ("organization_id","code");
|
||||
--> 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
|
||||
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 "crm_document_library_versions_active_library_idx"
|
||||
ON "crm_document_library_versions" USING btree ("library_id")
|
||||
WHERE "is_active" = true AND "deleted_at" IS NULL;
|
||||
@@ -1,28 +0,0 @@
|
||||
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
|
||||
UPDATE "document_sequences"
|
||||
SET
|
||||
"product_type" = CASE
|
||||
WHEN "document_type" = 'quotation' THEN 'legacy'
|
||||
ELSE 'all'
|
||||
END,
|
||||
"format" = '{prefix}{period}-{running}',
|
||||
"reset_policy" = 'period';
|
||||
--> statement-breakpoint
|
||||
DROP INDEX "document_sequences_org_doc_period_branch_idx";
|
||||
--> 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"
|
||||
);
|
||||
@@ -1,60 +0,0 @@
|
||||
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"
|
||||
);
|
||||
@@ -1,89 +0,0 @@
|
||||
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");
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5,71 +5,8 @@
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1782359607850,
|
||||
"tag": "0000_hard_butterfly",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "7",
|
||||
"when": 1782381033930,
|
||||
"tag": "0001_lazy_otto_octavius",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1782604800000,
|
||||
"tag": "0002_calm_approval_matrix",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1782691200000,
|
||||
"tag": "0003_workflow_builder_foundation",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1782455991734,
|
||||
"tag": "0004_unusual_hairball",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1782464526434,
|
||||
"tag": "0005_furry_maelstrom",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1782749787685,
|
||||
"tag": "0006_lazy_shiver_man",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "7",
|
||||
"when": 1782910000000,
|
||||
"tag": "0007_document_library_foundation",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"version": "7",
|
||||
"when": 1782913600000,
|
||||
"tag": "0008_document_sequence_scope_refactor",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1782815675836,
|
||||
"tag": "0009_stale_next_avengers",
|
||||
"when": 1782833951256,
|
||||
"tag": "0000_short_the_executioner",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
|
||||
2
next-env.d.ts
vendored
2
next-env.d.ts
vendored
@@ -1,6 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import "./.next/types/routes.d.ts";
|
||||
import "./.next/dev/types/routes.d.ts";
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
|
||||
327
plans/task-p.7.2.1.md
Normal file
327
plans/task-p.7.2.1.md
Normal file
@@ -0,0 +1,327 @@
|
||||
# Amendment to Task P.7.1.2 – Working Documents & Official Documents UX
|
||||
|
||||
## Design Revision
|
||||
|
||||
Following the UX review, the document experience will be refined to better reflect the actual CRM business process.
|
||||
|
||||
The terminology **Draft PDF** is too technical for end users and should not be the primary wording exposed in the UI.
|
||||
|
||||
The new UX separates documents into three business levels.
|
||||
|
||||
---
|
||||
|
||||
# Level 1 — Working Documents
|
||||
|
||||
Purpose:
|
||||
|
||||
Internal working documents used during quotation preparation.
|
||||
|
||||
Source:
|
||||
|
||||
Live quotation data.
|
||||
|
||||
Characteristics:
|
||||
|
||||
* Generated from current database values.
|
||||
* Changes whenever quotation data changes.
|
||||
* Used internally only.
|
||||
* Not legally or commercially binding.
|
||||
* Not intended for customer delivery.
|
||||
* Not part of audit history.
|
||||
|
||||
UI terminology:
|
||||
|
||||
```text
|
||||
Working Documents
|
||||
```
|
||||
|
||||
Primary document:
|
||||
|
||||
```text
|
||||
Preview PDF
|
||||
```
|
||||
|
||||
The UI should avoid exposing the technical term **Draft PDF**.
|
||||
|
||||
Instead:
|
||||
|
||||
```text
|
||||
Preview PDF
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```text
|
||||
Working Copy
|
||||
```
|
||||
|
||||
may be displayed.
|
||||
|
||||
Available actions:
|
||||
|
||||
```text
|
||||
Generate
|
||||
Preview
|
||||
```
|
||||
|
||||
No Download button is required unless business rules explicitly allow downloading internal working copies.
|
||||
|
||||
---
|
||||
|
||||
# Level 2 — Official Documents
|
||||
|
||||
Purpose:
|
||||
|
||||
Business-approved immutable documents.
|
||||
|
||||
Source:
|
||||
|
||||
Approved Snapshot.
|
||||
|
||||
Characteristics:
|
||||
|
||||
* Generated only after approval.
|
||||
* Immutable.
|
||||
* Stored as document artifact.
|
||||
* Used for audit.
|
||||
* Used for revision history.
|
||||
* Used as official company record.
|
||||
|
||||
UI terminology:
|
||||
|
||||
```text
|
||||
Official Documents
|
||||
```
|
||||
|
||||
Primary document:
|
||||
|
||||
```text
|
||||
Approved PDF
|
||||
```
|
||||
|
||||
Available actions:
|
||||
|
||||
```text
|
||||
Preview
|
||||
Download
|
||||
```
|
||||
|
||||
No Generate button should appear here because approval already created the official document.
|
||||
|
||||
---
|
||||
|
||||
# Level 3 — Customer Package
|
||||
|
||||
Purpose:
|
||||
|
||||
Deliverable package sent to customers.
|
||||
|
||||
Source:
|
||||
|
||||
Approved PDF
|
||||
|
||||
plus
|
||||
|
||||
Document Library appendices.
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
Approved PDF
|
||||
|
||||
+
|
||||
|
||||
SLA
|
||||
|
||||
+
|
||||
|
||||
Warranty
|
||||
|
||||
+
|
||||
|
||||
Datasheet
|
||||
|
||||
+
|
||||
|
||||
Drawing
|
||||
```
|
||||
|
||||
Characteristics:
|
||||
|
||||
* Generated after document assembly.
|
||||
* Built from official documents.
|
||||
* Represents exactly what customers receive.
|
||||
* May be regenerated if append documents change.
|
||||
|
||||
Available actions:
|
||||
|
||||
```text
|
||||
Generate Package
|
||||
|
||||
Preview Package
|
||||
|
||||
Download Package
|
||||
|
||||
Send Package (future)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Relationship Between Document Types
|
||||
|
||||
Business flow becomes:
|
||||
|
||||
```text
|
||||
Quotation
|
||||
|
||||
↓
|
||||
|
||||
Working Documents
|
||||
|
||||
↓
|
||||
|
||||
Approval
|
||||
|
||||
↓
|
||||
|
||||
Official Documents
|
||||
|
||||
↓
|
||||
|
||||
Customer Package
|
||||
|
||||
↓
|
||||
|
||||
Email Customer
|
||||
```
|
||||
|
||||
This hierarchy should be reflected visually.
|
||||
|
||||
---
|
||||
|
||||
# Documents Tab Layout
|
||||
|
||||
Replace the previous layout with:
|
||||
|
||||
```text
|
||||
Documents
|
||||
|
||||
────────────────────────
|
||||
|
||||
Working Documents
|
||||
|
||||
Preview PDF
|
||||
|
||||
[Generate]
|
||||
|
||||
[Preview]
|
||||
|
||||
────────────────────────
|
||||
|
||||
Official Documents
|
||||
|
||||
Approved PDF
|
||||
|
||||
[Preview]
|
||||
|
||||
[Download]
|
||||
|
||||
────────────────────────
|
||||
|
||||
Customer Package
|
||||
|
||||
Status
|
||||
|
||||
Included Documents
|
||||
|
||||
Warnings
|
||||
|
||||
[Generate Package]
|
||||
|
||||
[Preview Package]
|
||||
|
||||
[Download Package]
|
||||
|
||||
[Send Package]
|
||||
```
|
||||
|
||||
The **Send Package** action remains disabled until P.7.2.
|
||||
|
||||
---
|
||||
|
||||
# Customer Package Tab
|
||||
|
||||
The dedicated Customer Package tab remains.
|
||||
|
||||
It focuses on operational details:
|
||||
|
||||
* Package status
|
||||
* Included documents
|
||||
* Assembly warnings
|
||||
* Generated time
|
||||
* Generated by
|
||||
* Page count
|
||||
* Checksum
|
||||
* Generate / Regenerate
|
||||
* Preview
|
||||
* Download
|
||||
|
||||
This tab is not responsible for previewing individual PDFs.
|
||||
|
||||
---
|
||||
|
||||
# UX Rules
|
||||
|
||||
Working Documents
|
||||
|
||||
* Can always regenerate.
|
||||
* Uses live quotation data.
|
||||
* Intended for internal review.
|
||||
|
||||
Official Documents
|
||||
|
||||
* Never regenerate from this screen.
|
||||
* Always read-only.
|
||||
* Represents approved business record.
|
||||
|
||||
Customer Package
|
||||
|
||||
* Always assembled from Official Documents.
|
||||
* Must never assemble from Working Documents.
|
||||
* If no Approved PDF exists, package generation must fail with a business-readable message.
|
||||
|
||||
---
|
||||
|
||||
# Business Rules
|
||||
|
||||
Customer Package must always use:
|
||||
|
||||
```text
|
||||
Approved PDF
|
||||
|
||||
+
|
||||
|
||||
Active Document Library files
|
||||
```
|
||||
|
||||
Customer Package must never use:
|
||||
|
||||
```text
|
||||
Working Documents
|
||||
|
||||
Preview PDF
|
||||
|
||||
Draft runtime output
|
||||
```
|
||||
|
||||
This guarantees that every package delivered to a customer is assembled from approved, auditable content.
|
||||
|
||||
---
|
||||
|
||||
# Acceptance Criteria (Additional)
|
||||
|
||||
* "Draft PDF" is no longer the primary UI terminology.
|
||||
* Documents are clearly separated into Working Documents, Official Documents, and Customer Package.
|
||||
* Customer Package assembly is based exclusively on Approved PDF.
|
||||
* UI hierarchy reflects the CRM document lifecycle.
|
||||
* The new terminology is reusable across future modules such as Purchase Order, Service Report, Inspection Report, and Work Order.
|
||||
@@ -1,7 +1,7 @@
|
||||
import { runNodeScript } from './lib/seed-utils.ts';
|
||||
import { runNodeScript } from "./lib/seed-utils.ts";
|
||||
|
||||
function main() {
|
||||
runNodeScript('seed:uat:core', 'src/db/seeds/uat.seed.ts');
|
||||
runNodeScript("seed:uat:core", "src/db/seeds/uat.seed.ts");
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
@@ -1576,7 +1576,7 @@ async function upsertDocumentSequencesForOrganizationV2(
|
||||
|
||||
async function upsertApprovalWorkflowsForOrganization(
|
||||
sql: SqlClient,
|
||||
organizationId: string,
|
||||
organization: { id: string; createdBy: string },
|
||||
) {
|
||||
for (const workflow of APPROVAL_WORKFLOWS) {
|
||||
const [workflowRow] = await sql`
|
||||
@@ -1587,14 +1587,18 @@ async function upsertApprovalWorkflowsForOrganization(
|
||||
name,
|
||||
entity_type,
|
||||
is_active,
|
||||
created_by,
|
||||
updated_by,
|
||||
deleted_at
|
||||
) values (
|
||||
${crypto.randomUUID()},
|
||||
${organizationId},
|
||||
${organization.id},
|
||||
${workflow.code},
|
||||
${workflow.name},
|
||||
${workflow.entityType},
|
||||
${true},
|
||||
${organization.createdBy},
|
||||
${organization.createdBy},
|
||||
${null}
|
||||
)
|
||||
on conflict (organization_id, code) do update
|
||||
@@ -1602,6 +1606,7 @@ async function upsertApprovalWorkflowsForOrganization(
|
||||
name = excluded.name,
|
||||
entity_type = excluded.entity_type,
|
||||
is_active = excluded.is_active,
|
||||
updated_by = excluded.updated_by,
|
||||
deleted_at = excluded.deleted_at,
|
||||
updated_at = now()
|
||||
returning id
|
||||
@@ -1620,7 +1625,7 @@ async function upsertApprovalWorkflowsForOrganization(
|
||||
deleted_at
|
||||
) values (
|
||||
${crypto.randomUUID()},
|
||||
${organizationId},
|
||||
${organization.id},
|
||||
${workflowRow.id},
|
||||
${step.stepNumber},
|
||||
${step.roleCode},
|
||||
@@ -2338,7 +2343,7 @@ async function main() {
|
||||
organization,
|
||||
branchRows,
|
||||
);
|
||||
await upsertApprovalWorkflowsForOrganization(sql, organization.id);
|
||||
await upsertApprovalWorkflowsForOrganization(sql, organization);
|
||||
await upsertApprovalMatricesForOrganization(sql, organization);
|
||||
await upsertDocumentTemplatesForOrganization(sql, organization);
|
||||
await upsertDocumentLibraryForOrganization(sql, organization);
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { getDefaultPermissions } from '../../lib/auth/rbac.ts';
|
||||
import { createSqlClient, deterministicId, type SqlClient } from '../../../scripts/lib/seed-utils.ts';
|
||||
import { getDefaultPermissions } from "../../lib/auth/rbac.ts";
|
||||
import {
|
||||
createSqlClient,
|
||||
deterministicId,
|
||||
type SqlClient,
|
||||
} from "../../../scripts/lib/seed-utils.ts";
|
||||
|
||||
type UserRow = {
|
||||
id: string;
|
||||
@@ -7,17 +11,19 @@ type UserRow = {
|
||||
};
|
||||
|
||||
const DEFAULT_ORGANIZATION = {
|
||||
id: deterministicId('organization:alla-demo'),
|
||||
name: 'ALLA Demo Organization',
|
||||
slug: 'alla-demo',
|
||||
membershipId: deterministicId('membership:alla-demo:super-admin')
|
||||
id: deterministicId("organization:alla-demo"),
|
||||
name: "ALLA Demo",
|
||||
slug: "alla-demo",
|
||||
membershipId: deterministicId("membership:alla-demo:super-admin"),
|
||||
};
|
||||
|
||||
async function resolveSuperAdmin(sql: SqlClient): Promise<UserRow> {
|
||||
const email = process.env.SUPER_ADMIN_EMAIL?.trim().toLowerCase();
|
||||
|
||||
if (!email) {
|
||||
throw new Error('SUPER_ADMIN_EMAIL is required before running system organization seed.');
|
||||
throw new Error(
|
||||
"SUPER_ADMIN_EMAIL is required before running system organization seed.",
|
||||
);
|
||||
}
|
||||
|
||||
const [user] = await sql<UserRow[]>`
|
||||
@@ -28,7 +34,7 @@ async function resolveSuperAdmin(sql: SqlClient): Promise<UserRow> {
|
||||
`;
|
||||
|
||||
if (!user) {
|
||||
throw new Error('Super admin user not found. Run seed-super-admin first.');
|
||||
throw new Error("Super admin user not found. Run seed-super-admin first.");
|
||||
}
|
||||
|
||||
return user;
|
||||
@@ -46,7 +52,7 @@ async function ensureOrganization(sql: SqlClient, superAdmin: UserRow) {
|
||||
${DEFAULT_ORGANIZATION.id},
|
||||
${DEFAULT_ORGANIZATION.name},
|
||||
${DEFAULT_ORGANIZATION.slug},
|
||||
${'enterprise'},
|
||||
${"enterprise"},
|
||||
${superAdmin.id}
|
||||
)
|
||||
on conflict (slug) do update
|
||||
@@ -56,7 +62,7 @@ async function ensureOrganization(sql: SqlClient, superAdmin: UserRow) {
|
||||
updated_at = now()
|
||||
`;
|
||||
|
||||
const membershipPermissions = getDefaultPermissions('admin', 'crm_admin');
|
||||
const membershipPermissions = getDefaultPermissions("admin", "crm_admin");
|
||||
const [existingMembership] = await sql<{ id: string }[]>`
|
||||
select id
|
||||
from memberships
|
||||
@@ -69,8 +75,8 @@ async function ensureOrganization(sql: SqlClient, superAdmin: UserRow) {
|
||||
await sql`
|
||||
update memberships
|
||||
set
|
||||
role = ${'admin'},
|
||||
business_role = ${'crm_admin'},
|
||||
role = ${"admin"},
|
||||
business_role = ${"crm_admin"},
|
||||
permissions = ${sql.array(membershipPermissions)},
|
||||
updated_at = now()
|
||||
where id = ${existingMembership.id}
|
||||
@@ -90,8 +96,8 @@ async function ensureOrganization(sql: SqlClient, superAdmin: UserRow) {
|
||||
${DEFAULT_ORGANIZATION.membershipId},
|
||||
${superAdmin.id},
|
||||
${DEFAULT_ORGANIZATION.id},
|
||||
${'admin'},
|
||||
${'crm_admin'},
|
||||
${"admin"},
|
||||
${"crm_admin"},
|
||||
${sql.array(membershipPermissions)},
|
||||
${sql.array([])},
|
||||
${sql.array([])}
|
||||
@@ -122,8 +128,8 @@ async function main() {
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(
|
||||
'[seed:system-org] Failed:',
|
||||
error instanceof Error ? error.message : String(error)
|
||||
"[seed:system-org] Failed:",
|
||||
error instanceof Error ? error.message : String(error),
|
||||
);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
|
||||
@@ -1,36 +1,38 @@
|
||||
export const DOCUMENT_LIBRARY_TYPES = [
|
||||
'sla',
|
||||
'warranty',
|
||||
'terms_conditions',
|
||||
'company_profile',
|
||||
'datasheet',
|
||||
'drawing',
|
||||
'certificate',
|
||||
'appendix',
|
||||
'safety_document',
|
||||
'installation_manual'
|
||||
"sla",
|
||||
"warranty",
|
||||
"terms_conditions",
|
||||
"company_profile",
|
||||
"datasheet",
|
||||
"drawing",
|
||||
"certificate",
|
||||
"appendix",
|
||||
"safety_document",
|
||||
"installation_manual",
|
||||
] as const;
|
||||
|
||||
export const DOCUMENT_LIBRARY_BRANDS = ['alla', 'onvalla', 'generic'] as const;
|
||||
export const DOCUMENT_LIBRARY_LANGUAGES = ['th', 'en'] as const;
|
||||
export const DOCUMENT_LIBRARY_BRANDS = ["alla", "onvalla", "generic"] as const;
|
||||
export const DOCUMENT_LIBRARY_LANGUAGES = ["th", "en"] as const;
|
||||
export const DOCUMENT_LIBRARY_PRODUCT_TYPES = [
|
||||
'all',
|
||||
'crane',
|
||||
'dock_door',
|
||||
'solar',
|
||||
'service'
|
||||
"all",
|
||||
"crane",
|
||||
"dock_door",
|
||||
"solar",
|
||||
"service",
|
||||
] as const;
|
||||
export const DOCUMENT_LIBRARY_VERSION_STATUSES = [
|
||||
'draft',
|
||||
'published',
|
||||
'active',
|
||||
'archived'
|
||||
"draft",
|
||||
"published",
|
||||
"active",
|
||||
"archived",
|
||||
] as const;
|
||||
|
||||
export type DocumentLibraryType = (typeof DOCUMENT_LIBRARY_TYPES)[number];
|
||||
export type DocumentLibraryBrand = (typeof DOCUMENT_LIBRARY_BRANDS)[number];
|
||||
export type DocumentLibraryLanguage = (typeof DOCUMENT_LIBRARY_LANGUAGES)[number];
|
||||
export type DocumentLibraryProductType = (typeof DOCUMENT_LIBRARY_PRODUCT_TYPES)[number];
|
||||
export type DocumentLibraryLanguage =
|
||||
(typeof DOCUMENT_LIBRARY_LANGUAGES)[number];
|
||||
export type DocumentLibraryProductType =
|
||||
(typeof DOCUMENT_LIBRARY_PRODUCT_TYPES)[number];
|
||||
export type DocumentLibraryVersionStatus =
|
||||
(typeof DOCUMENT_LIBRARY_VERSION_STATUSES)[number];
|
||||
|
||||
@@ -44,7 +46,7 @@ export interface DocumentLibraryRecord {
|
||||
brand: DocumentLibraryBrand;
|
||||
language: DocumentLibraryLanguage;
|
||||
productType: DocumentLibraryProductType;
|
||||
status: 'active' | 'inactive';
|
||||
status: "active" | "inactive";
|
||||
isActive: boolean;
|
||||
createdBy: string;
|
||||
updatedBy: string;
|
||||
@@ -91,7 +93,7 @@ export interface DocumentLibraryFilters {
|
||||
brand?: DocumentLibraryBrand;
|
||||
language?: DocumentLibraryLanguage;
|
||||
productType?: DocumentLibraryProductType;
|
||||
isActive?: 'true' | 'false';
|
||||
isActive?: "true" | "false";
|
||||
}
|
||||
|
||||
export interface DocumentLibraryMutationPayload {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user