-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmigration_to_postgres.sql
More file actions
1323 lines (1233 loc) · 40.8 KB
/
migration_to_postgres.sql
File metadata and controls
1323 lines (1233 loc) · 40.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
-- SQLite to PostgreSQL Migration Script
-- Generated automatically
-- Review and test before running on production!
-- Enable UUID extension (common in Supabase)
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Table: admins
DROP TABLE IF EXISTS admins CASCADE;
CREATE TABLE admins (
id INTEGER NOT NULL,
username VARCHAR NOT NULL,
email VARCHAR NOT NULL,
name VARCHAR NOT NULL,
hashed_password VARCHAR NOT NULL,
is_active BOOLEAN,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
-- Indexes for admins
CREATE UNIQUE INDEX ix_admins_email ON admins (email);
CREATE INDEX ix_admins_id ON admins (id);
CREATE UNIQUE INDEX ix_admins_username ON admins (username);
-- Table: agent_permission_overrides
DROP TABLE IF EXISTS agent_permission_overrides CASCADE;
CREATE TABLE agent_permission_overrides (
id INTEGER NOT NULL,
agent_id INTEGER NOT NULL,
permission VARCHAR NOT NULL,
granted BOOLEAN,
granted_by INTEGER,
granted_at TIMESTAMP,
reason TEXT,
PRIMARY KEY (id),
CONSTRAINT unique_agent_permission UNIQUE (agent_id, permission),
FOREIGN KEY(agent_id) REFERENCES agents (id),
FOREIGN KEY(granted_by) REFERENCES agents (id)
);
-- Indexes for agent_permission_overrides
CREATE INDEX ix_agent_permission_overrides_id ON agent_permission_overrides (id);
-- Table: agent_role_history
DROP TABLE IF EXISTS agent_role_history CASCADE;
CREATE TABLE agent_role_history (
id INTEGER NOT NULL,
agent_id INTEGER NOT NULL,
old_role VARCHAR,
new_role VARCHAR NOT NULL,
changed_by INTEGER,
changed_at TIMESTAMP,
reason TEXT,
PRIMARY KEY (id),
FOREIGN KEY(agent_id) REFERENCES agents (id),
FOREIGN KEY(changed_by) REFERENCES agents (id)
);
-- Indexes for agent_role_history
CREATE INDEX ix_agent_role_history_id ON agent_role_history (id);
-- Table: agent_sessions
DROP TABLE IF EXISTS agent_sessions CASCADE;
CREATE TABLE agent_sessions (
id INTEGER NOT NULL,
agent_id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
session_id VARCHAR NOT NULL,
status VARCHAR,
login_at TIMESTAMP,
logout_at TIMESTAMP,
last_activity TIMESTAMP,
active_conversations INTEGER,
max_concurrent_chats INTEGER,
is_accepting_chats BOOLEAN,
messages_sent INTEGER,
conversations_handled INTEGER,
average_response_time FLOAT,
total_online_time INTEGER,
ip_address VARCHAR,
user_agent VARCHAR,
websocket_id VARCHAR,
device_type VARCHAR,
browser VARCHAR,
status_message VARCHAR,
away_message VARCHAR,
PRIMARY KEY (id),
FOREIGN KEY(agent_id) REFERENCES agents (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
UNIQUE (websocket_id)
);
-- Indexes for agent_sessions
CREATE INDEX ix_agent_sessions_id ON agent_sessions (id);
CREATE UNIQUE INDEX ix_agent_sessions_session_id ON agent_sessions (session_id);
-- Table: agent_tag_performance
DROP TABLE IF EXISTS agent_tag_performance CASCADE;
CREATE TABLE agent_tag_performance (
id INTEGER NOT NULL,
agent_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
total_conversations INTEGER,
successful_resolutions INTEGER,
average_resolution_time FLOAT,
customer_satisfaction_avg FLOAT,
conversations_last_30_days INTEGER,
satisfaction_last_30_days FLOAT,
proficiency_level INTEGER,
improvement_trend FLOAT,
certified BOOLEAN,
certification_date TIMESTAMP,
last_training_date TIMESTAMP,
is_available_for_tag BOOLEAN,
max_concurrent_for_tag INTEGER,
current_active_conversations INTEGER,
last_updated TIMESTAMP,
last_conversation_date TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(agent_id) REFERENCES agents (id),
FOREIGN KEY(tag_id) REFERENCES agent_tags (id)
);
-- Indexes for agent_tag_performance
CREATE INDEX ix_agent_tag_performance_id ON agent_tag_performance (id);
-- Table: agent_tags
DROP TABLE IF EXISTS agent_tags CASCADE;
CREATE TABLE agent_tags (
id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
name VARCHAR(50) NOT NULL,
display_name VARCHAR(100) NOT NULL,
category VARCHAR(50) NOT NULL,
description TEXT,
color VARCHAR(7),
icon VARCHAR(50),
priority_weight FLOAT,
is_active BOOLEAN,
keywords JSON,
routing_rules JSON,
total_conversations INTEGER,
success_rate FLOAT,
average_satisfaction FLOAT,
created_by INTEGER,
created_at TIMESTAMP,
updated_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
FOREIGN KEY(created_by) REFERENCES agents (id)
);
-- Indexes for agent_tags
CREATE INDEX ix_agent_tags_category ON agent_tags (category);
CREATE INDEX ix_agent_tags_id ON agent_tags (id);
CREATE INDEX ix_agent_tags_name ON agent_tags (name);
-- Table: agent_tags_association
DROP TABLE IF EXISTS agent_tags_association CASCADE;
CREATE TABLE agent_tags_association (
agent_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
proficiency_level INTEGER,
assigned_at TIMESTAMP,
assigned_by INTEGER,
PRIMARY KEY (agent_id, tag_id),
FOREIGN KEY(agent_id) REFERENCES agents (id),
FOREIGN KEY(tag_id) REFERENCES agent_tags (id),
FOREIGN KEY(assigned_by) REFERENCES agents (id)
);
-- Table: agents
DROP TABLE IF EXISTS agents CASCADE;
CREATE TABLE agents (
id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
email VARCHAR NOT NULL,
full_name VARCHAR NOT NULL,
display_name VARCHAR,
avatar_url VARCHAR,
password_hash VARCHAR,
invite_token VARCHAR,
invited_by INTEGER NOT NULL,
invited_at TIMESTAMP,
password_set_at TIMESTAMP,
status VARCHAR,
is_active BOOLEAN,
last_login TIMESTAMP,
last_seen TIMESTAMP,
is_online BOOLEAN,
total_conversations INTEGER,
total_messages_sent INTEGER,
average_response_time FLOAT,
customer_satisfaction_avg FLOAT,
conversations_today INTEGER,
notification_settings TEXT,
timezone VARCHAR,
max_concurrent_chats INTEGER,
auto_assign BOOLEAN,
work_hours_start VARCHAR,
work_hours_end VARCHAR,
work_days VARCHAR,
created_at TIMESTAMP,
updated_at TIMESTAMP,
role VARCHAR,
promoted_at TIMESTAMP,
promoted_by INTEGER,
can_assign_conversations BOOLEAN,
can_manage_team BOOLEAN,
can_access_analytics BOOLEAN,
primary_specialization VARCHAR(50),
secondary_specializations JSON,
skill_level INTEGER,
accepts_overflow BOOLEAN,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
FOREIGN KEY(invited_by) REFERENCES tenants (id),
FOREIGN KEY(promoted_by) REFERENCES agents (id)
);
-- Indexes for agents
CREATE INDEX ix_agents_email ON agents (email);
CREATE INDEX ix_agents_id ON agents (id);
CREATE UNIQUE INDEX ix_agents_invite_token ON agents (invite_token);
-- Table: billing_history
DROP TABLE IF EXISTS billing_history CASCADE;
CREATE TABLE billing_history (
id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
subscription_id INTEGER NOT NULL,
amount NUMERIC(10, 2) NOT NULL,
currency VARCHAR,
billing_period_start TIMESTAMP NOT NULL,
billing_period_end TIMESTAMP NOT NULL,
plan_name VARCHAR,
conversations_included INTEGER,
conversations_used INTEGER,
addons_included TEXT,
stripe_invoice_id VARCHAR,
stripe_charge_id VARCHAR,
payment_status VARCHAR,
payment_date TIMESTAMP,
payment_method VARCHAR,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
FOREIGN KEY(subscription_id) REFERENCES tenant_subscriptions (id)
);
-- Indexes for billing_history
CREATE INDEX ix_billing_history_id ON billing_history (id);
-- Table: booking_requests
DROP TABLE IF EXISTS booking_requests CASCADE;
CREATE TABLE booking_requests (
id INTEGER NOT NULL,
tenant_id INTEGER,
session_id VARCHAR,
user_identifier VARCHAR,
user_email VARCHAR,
user_name VARCHAR,
calendly_event_uri VARCHAR,
calendly_event_uuid VARCHAR,
booking_url VARCHAR,
status VARCHAR,
booking_message TEXT,
created_at TIMESTAMP,
booked_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
FOREIGN KEY(session_id) REFERENCES chat_sessions (session_id)
);
-- Indexes for booking_requests
CREATE INDEX ix_booking_requests_id ON booking_requests (id);
-- Table: chat_messages
DROP TABLE IF EXISTS chat_messages CASCADE;
CREATE TABLE chat_messages (
id INTEGER NOT NULL,
session_id INTEGER,
content TEXT,
translated_content TEXT,
source_language VARCHAR(10),
target_language VARCHAR(10),
is_from_user BOOLEAN,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(session_id) REFERENCES chat_sessions (id)
);
-- Indexes for chat_messages
CREATE INDEX ix_chat_messages_id ON chat_messages (id);
-- Table: chat_queue
DROP TABLE IF EXISTS chat_queue CASCADE;
CREATE TABLE chat_queue (
id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
conversation_id INTEGER NOT NULL,
position INTEGER NOT NULL,
priority INTEGER,
estimated_wait_time INTEGER,
preferred_agent_id INTEGER,
assignment_criteria TEXT,
skills_required TEXT,
language_preference VARCHAR,
entry_reason VARCHAR,
queue_source VARCHAR,
queued_at TIMESTAMP,
assigned_at TIMESTAMP,
removed_at TIMESTAMP,
status VARCHAR,
abandon_reason VARCHAR,
customer_message_preview TEXT,
urgency_indicators TEXT,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
UNIQUE (conversation_id),
FOREIGN KEY(conversation_id) REFERENCES live_chat_conversations (id),
FOREIGN KEY(preferred_agent_id) REFERENCES agents (id)
);
-- Indexes for chat_queue
CREATE INDEX ix_chat_queue_id ON chat_queue (id);
CREATE INDEX ix_chat_queue_position ON chat_queue (position);
CREATE INDEX ix_chat_queue_priority ON chat_queue (priority);
-- Table: chat_sessions
DROP TABLE IF EXISTS chat_sessions CASCADE;
CREATE TABLE chat_sessions (
id INTEGER NOT NULL,
session_id VARCHAR,
tenant_id INTEGER,
user_identifier VARCHAR,
language_code VARCHAR(10),
is_active BOOLEAN,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP,
user_email VARCHAR,
email_captured_at TIMESTAMP,
email_expires_at TIMESTAMP,
discord_channel_id VARCHAR,
discord_user_id VARCHAR,
discord_guild_id VARCHAR,
platform VARCHAR,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);
-- Indexes for chat_sessions
CREATE INDEX ix_chat_sessions_id ON chat_sessions (id);
CREATE UNIQUE INDEX ix_chat_sessions_session_id ON chat_sessions (session_id);
CREATE INDEX ix_chat_sessions_user_identifier ON chat_sessions (user_identifier);
-- Table: conversation_sessions
DROP TABLE IF EXISTS conversation_sessions CASCADE;
CREATE TABLE conversation_sessions (
id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
user_identifier VARCHAR NOT NULL,
platform VARCHAR NOT NULL,
started_at TIMESTAMP NOT NULL,
last_activity TIMESTAMP NOT NULL,
is_active BOOLEAN,
message_count INTEGER,
duration_minutes INTEGER,
counted_for_billing BOOLEAN,
billing_period_start TIMESTAMP,
extra_data TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);
-- Indexes for conversation_sessions
CREATE INDEX ix_conversation_sessions_id ON conversation_sessions (id);
-- Table: conversation_tagging
DROP TABLE IF EXISTS conversation_tagging CASCADE;
CREATE TABLE conversation_tagging (
id INTEGER NOT NULL,
conversation_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
confidence_score FLOAT,
detection_method VARCHAR(50) NOT NULL,
detected_keywords JSON,
message_text TEXT,
message_id INTEGER,
influenced_routing BOOLEAN,
routing_weight FLOAT,
human_verified BOOLEAN,
verified_by INTEGER,
verified_at TIMESTAMP,
detected_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(conversation_id) REFERENCES live_chat_conversations (id),
FOREIGN KEY(tag_id) REFERENCES agent_tags (id),
FOREIGN KEY(message_id) REFERENCES live_chat_messages (id),
FOREIGN KEY(verified_by) REFERENCES agents (id)
);
-- Indexes for conversation_tagging
CREATE INDEX ix_conversation_tagging_id ON conversation_tagging (id);
-- Table: conversation_tags
DROP TABLE IF EXISTS conversation_tags CASCADE;
CREATE TABLE conversation_tags (
id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
name VARCHAR NOT NULL,
color VARCHAR,
description VARCHAR,
usage_count INTEGER,
created_by_agent_id INTEGER,
created_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
FOREIGN KEY(created_by_agent_id) REFERENCES agents (id)
);
-- Indexes for conversation_tags
CREATE INDEX ix_conversation_tags_id ON conversation_tags (id);
-- Table: conversation_transfers
DROP TABLE IF EXISTS conversation_transfers CASCADE;
CREATE TABLE conversation_transfers (
id INTEGER NOT NULL,
conversation_id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
from_agent_id INTEGER NOT NULL,
to_agent_id INTEGER,
transfer_reason VARCHAR,
transfer_notes TEXT,
status VARCHAR,
initiated_at TIMESTAMP,
completed_at TIMESTAMP,
conversation_summary TEXT,
customer_context TEXT,
PRIMARY KEY (id),
FOREIGN KEY(conversation_id) REFERENCES live_chat_conversations (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
FOREIGN KEY(from_agent_id) REFERENCES agents (id),
FOREIGN KEY(to_agent_id) REFERENCES agents (id)
);
-- Indexes for conversation_transfers
CREATE INDEX ix_conversation_transfers_id ON conversation_transfers (id);
-- Table: customer_devices
DROP TABLE IF EXISTS customer_devices CASCADE;
CREATE TABLE customer_devices (
id INTEGER NOT NULL,
customer_profile_id INTEGER NOT NULL,
device_fingerprint VARCHAR NOT NULL,
device_type VARCHAR,
browser_name VARCHAR,
browser_version VARCHAR,
operating_system VARCHAR,
screen_resolution VARCHAR,
supports_websockets BOOLEAN,
supports_file_upload BOOLEAN,
supports_notifications BOOLEAN,
first_seen TIMESTAMP,
last_seen TIMESTAMP,
total_sessions INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(customer_profile_id) REFERENCES customer_profiles (id)
);
-- Indexes for customer_devices
CREATE INDEX ix_customer_devices_device_fingerprint ON customer_devices (device_fingerprint);
CREATE INDEX ix_customer_devices_id ON customer_devices (id);
-- Table: customer_preferences
DROP TABLE IF EXISTS customer_preferences CASCADE;
CREATE TABLE customer_preferences (
id INTEGER NOT NULL,
customer_profile_id INTEGER NOT NULL,
preferred_language VARCHAR,
preferred_agent_gender VARCHAR,
preferred_communication_style VARCHAR,
email_notifications BOOLEAN,
sms_notifications BOOLEAN,
browser_notifications BOOLEAN,
requires_accessibility_features BOOLEAN,
accessibility_preferences JSON,
data_retention_preference VARCHAR,
third_party_sharing_consent BOOLEAN,
created_at TIMESTAMP,
updated_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(customer_profile_id) REFERENCES customer_profiles (id)
);
-- Indexes for customer_preferences
CREATE INDEX ix_customer_preferences_id ON customer_preferences (id);
-- Table: customer_profiles
DROP TABLE IF EXISTS customer_profiles CASCADE;
CREATE TABLE customer_profiles (
id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
customer_identifier VARCHAR NOT NULL,
first_seen TIMESTAMP,
last_seen TIMESTAMP,
total_conversations INTEGER,
total_sessions INTEGER,
preferred_language VARCHAR,
time_zone VARCHAR,
preferred_contact_method VARCHAR,
customer_satisfaction_avg FLOAT,
average_session_duration INTEGER,
total_messages_sent INTEGER,
data_collection_consent BOOLEAN,
marketing_consent BOOLEAN,
last_consent_update TIMESTAMP,
created_at TIMESTAMP,
updated_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);
-- Indexes for customer_profiles
CREATE INDEX ix_customer_profiles_customer_identifier ON customer_profiles (customer_identifier);
CREATE INDEX ix_customer_profiles_id ON customer_profiles (id);
-- Table: customer_sessions
DROP TABLE IF EXISTS customer_sessions CASCADE;
CREATE TABLE customer_sessions (
id INTEGER NOT NULL,
customer_profile_id INTEGER NOT NULL,
session_id VARCHAR NOT NULL,
started_at TIMESTAMP,
ended_at TIMESTAMP,
duration_seconds INTEGER,
ip_address VARCHAR,
user_agent TEXT,
device_fingerprint VARCHAR,
country VARCHAR,
region VARCHAR,
city VARCHAR,
page_views INTEGER,
conversations_started INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(customer_profile_id) REFERENCES customer_profiles (id),
UNIQUE (session_id)
);
-- Indexes for customer_sessions
CREATE INDEX ix_customer_sessions_id ON customer_sessions (id);
-- Table: faqs
DROP TABLE IF EXISTS faqs CASCADE;
CREATE TABLE faqs (
id INTEGER NOT NULL,
tenant_id INTEGER,
question TEXT,
answer TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);
-- Indexes for faqs
CREATE INDEX ix_faqs_id ON faqs (id);
-- Table: instagram_conversations
DROP TABLE IF EXISTS instagram_conversations CASCADE;
CREATE TABLE instagram_conversations (
id INTEGER NOT NULL,
integration_id INTEGER,
tenant_id INTEGER,
instagram_user_id VARCHAR NOT NULL,
instagram_username VARCHAR,
user_profile_name VARCHAR,
user_profile_picture VARCHAR,
conversation_id VARCHAR,
thread_id VARCHAR,
is_active BOOLEAN,
conversation_status VARCHAR,
conversation_source VARCHAR,
initial_message_type VARCHAR,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP,
last_message_at TIMESTAMP,
last_user_message_at TIMESTAMP,
last_bot_message_at TIMESTAMP,
total_messages INTEGER,
user_messages INTEGER,
bot_messages INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(integration_id) REFERENCES instagram_integrations (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);
-- Indexes for instagram_conversations
CREATE UNIQUE INDEX ix_instagram_conversations_conversation_id ON instagram_conversations (conversation_id);
CREATE INDEX ix_instagram_conversations_id ON instagram_conversations (id);
CREATE INDEX ix_instagram_conversations_instagram_user_id ON instagram_conversations (instagram_user_id);
CREATE INDEX ix_instagram_conversations_integration_id ON instagram_conversations (integration_id);
CREATE INDEX ix_instagram_conversations_tenant_id ON instagram_conversations (tenant_id);
-- Table: instagram_integrations
DROP TABLE IF EXISTS instagram_integrations CASCADE;
CREATE TABLE instagram_integrations (
id INTEGER NOT NULL,
tenant_id INTEGER,
meta_app_id VARCHAR NOT NULL,
meta_app_secret VARCHAR NOT NULL,
instagram_business_account_id VARCHAR NOT NULL,
instagram_username VARCHAR NOT NULL,
facebook_page_id VARCHAR NOT NULL,
facebook_page_name VARCHAR,
page_access_token TEXT NOT NULL,
token_expires_at TIMESTAMP,
webhook_verify_token VARCHAR NOT NULL,
webhook_subscribed BOOLEAN,
webhook_subscription_fields JSON,
bot_enabled BOOLEAN,
bot_status VARCHAR,
auto_reply_enabled BOOLEAN,
business_verification_required BOOLEAN,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP,
last_message_at TIMESTAMP,
last_error TEXT,
error_count INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);
-- Indexes for instagram_integrations
CREATE INDEX ix_instagram_integrations_facebook_page_id ON instagram_integrations (facebook_page_id);
CREATE INDEX ix_instagram_integrations_id ON instagram_integrations (id);
CREATE INDEX ix_instagram_integrations_instagram_business_account_id ON instagram_integrations (instagram_business_account_id);
CREATE UNIQUE INDEX ix_instagram_integrations_tenant_id ON instagram_integrations (tenant_id);
-- Table: instagram_messages
DROP TABLE IF EXISTS instagram_messages CASCADE;
CREATE TABLE instagram_messages (
id INTEGER NOT NULL,
conversation_id INTEGER,
tenant_id INTEGER,
instagram_message_id VARCHAR,
message_uuid VARCHAR,
message_type VARCHAR,
content TEXT,
media_url VARCHAR,
media_type VARCHAR,
media_size INTEGER,
is_from_user BOOLEAN,
message_status VARCHAR,
reply_to_story BOOLEAN,
story_id VARCHAR,
quick_reply_payload VARCHAR,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
instagram_timestamp TIMESTAMP,
delivered_at TIMESTAMP,
read_at TIMESTAMP,
send_error TEXT,
retry_count INTEGER,
raw_webhook_data JSON,
PRIMARY KEY (id),
FOREIGN KEY(conversation_id) REFERENCES instagram_conversations (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);
-- Indexes for instagram_messages
CREATE INDEX ix_instagram_messages_conversation_id ON instagram_messages (conversation_id);
CREATE INDEX ix_instagram_messages_id ON instagram_messages (id);
CREATE INDEX ix_instagram_messages_instagram_message_id ON instagram_messages (instagram_message_id);
CREATE UNIQUE INDEX ix_instagram_messages_message_uuid ON instagram_messages (message_uuid);
CREATE INDEX ix_instagram_messages_tenant_id ON instagram_messages (tenant_id);
-- Table: instagram_webhook_events
DROP TABLE IF EXISTS instagram_webhook_events CASCADE;
CREATE TABLE instagram_webhook_events (
id INTEGER NOT NULL,
tenant_id INTEGER,
integration_id INTEGER,
event_type VARCHAR NOT NULL,
event_id VARCHAR,
instagram_user_id VARCHAR,
processing_status VARCHAR,
processing_error TEXT,
processed_at TIMESTAMP,
raw_payload JSON NOT NULL,
headers JSON,
received_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
instagram_timestamp TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
FOREIGN KEY(integration_id) REFERENCES instagram_integrations (id)
);
-- Indexes for instagram_webhook_events
CREATE INDEX ix_instagram_webhook_events_event_id ON instagram_webhook_events (event_id);
CREATE INDEX ix_instagram_webhook_events_event_type ON instagram_webhook_events (event_type);
CREATE INDEX ix_instagram_webhook_events_id ON instagram_webhook_events (id);
CREATE INDEX ix_instagram_webhook_events_instagram_user_id ON instagram_webhook_events (instagram_user_id);
CREATE INDEX ix_instagram_webhook_events_integration_id ON instagram_webhook_events (integration_id);
CREATE INDEX ix_instagram_webhook_events_tenant_id ON instagram_webhook_events (tenant_id);
-- Table: knowledge_bases
DROP TABLE IF EXISTS knowledge_bases CASCADE;
CREATE TABLE knowledge_bases (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
name TEXT NOT NULL,
description TEXT,
file_path TEXT,
document_type TEXT NOT NULL,
vector_store_id TEXT UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP,
processing_status TEXT DEFAULT 'pending',
processing_error TEXT,
processed_at TIMESTAMP,
base_url TEXT,
crawl_depth INTEGER DEFAULT 3,
crawl_frequency_hours INTEGER DEFAULT 24,
last_crawled_at TIMESTAMP,
pages_crawled INTEGER DEFAULT 0,
include_patterns TEXT,
exclude_patterns TEXT,
FOREIGN KEY (tenant_id) REFERENCES tenants (id)
);
-- Table: live_chat_conversations
DROP TABLE IF EXISTS live_chat_conversations CASCADE;
CREATE TABLE live_chat_conversations (
id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
customer_identifier VARCHAR NOT NULL,
customer_email VARCHAR,
customer_name VARCHAR,
customer_phone VARCHAR,
customer_ip VARCHAR,
customer_user_agent TEXT,
chatbot_session_id VARCHAR,
handoff_reason VARCHAR,
handoff_trigger VARCHAR,
handoff_context TEXT,
original_question TEXT,
status VARCHAR,
queue_position INTEGER,
priority_level INTEGER,
queue_entry_time TIMESTAMP,
assigned_agent_id INTEGER,
assigned_at TIMESTAMP,
assignment_method VARCHAR,
previous_agent_id INTEGER,
created_at TIMESTAMP,
first_response_at TIMESTAMP,
last_activity_at TIMESTAMP,
closed_at TIMESTAMP,
wait_time_seconds INTEGER,
response_time_seconds INTEGER,
conversation_duration_seconds INTEGER,
message_count INTEGER,
agent_message_count INTEGER,
customer_message_count INTEGER,
customer_satisfaction INTEGER,
customer_feedback TEXT,
satisfaction_submitted_at TIMESTAMP,
closed_by VARCHAR,
closure_reason VARCHAR,
resolution_status VARCHAR,
agent_notes TEXT,
internal_notes TEXT,
tags TEXT,
category VARCHAR,
department VARCHAR,
updated_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
FOREIGN KEY(assigned_agent_id) REFERENCES agents (id),
FOREIGN KEY(previous_agent_id) REFERENCES agents (id)
);
-- Indexes for live_chat_conversations
CREATE INDEX ix_live_chat_conversations_chatbot_session_id ON live_chat_conversations (chatbot_session_id);
CREATE INDEX ix_live_chat_conversations_customer_identifier ON live_chat_conversations (customer_identifier);
CREATE INDEX ix_live_chat_conversations_id ON live_chat_conversations (id);
CREATE INDEX ix_live_chat_conversations_status ON live_chat_conversations (status);
-- Table: live_chat_messages
DROP TABLE IF EXISTS live_chat_messages CASCADE;
CREATE TABLE live_chat_messages (
id INTEGER NOT NULL,
conversation_id INTEGER NOT NULL,
content TEXT NOT NULL,
message_type VARCHAR,
raw_content TEXT,
sender_type VARCHAR NOT NULL,
sender_id VARCHAR,
agent_id INTEGER,
sender_name VARCHAR,
sender_avatar VARCHAR,
sent_at TIMESTAMP,
delivered_at TIMESTAMP,
read_at TIMESTAMP,
edited_at TIMESTAMP,
is_internal BOOLEAN,
is_edited BOOLEAN,
is_deleted BOOLEAN,
deleted_at TIMESTAMP,
attachment_url VARCHAR,
attachment_name VARCHAR,
attachment_type VARCHAR,
attachment_size INTEGER,
system_event_type VARCHAR,
system_event_data TEXT,
client_message_id VARCHAR,
reply_to_message_id INTEGER,
thread_id VARCHAR,
PRIMARY KEY (id),
FOREIGN KEY(conversation_id) REFERENCES live_chat_conversations (id),
FOREIGN KEY(agent_id) REFERENCES agents (id),
FOREIGN KEY(reply_to_message_id) REFERENCES live_chat_messages (id)
);
-- Indexes for live_chat_messages
CREATE INDEX ix_live_chat_messages_id ON live_chat_messages (id);
-- Table: live_chat_settings
DROP TABLE IF EXISTS live_chat_settings CASCADE;
CREATE TABLE live_chat_settings (
id INTEGER NOT NULL,
tenant_id INTEGER NOT NULL,
is_enabled BOOLEAN,
welcome_message TEXT,
offline_message TEXT,
pre_chat_form_enabled BOOLEAN,
post_chat_survey_enabled BOOLEAN,
max_queue_size INTEGER,
max_wait_time_minutes INTEGER,
queue_timeout_message TEXT,
auto_assignment_enabled BOOLEAN,
assignment_method VARCHAR,
max_chats_per_agent INTEGER,
business_hours_enabled BOOLEAN,
business_hours TEXT,
timezone VARCHAR,
email_notifications_enabled BOOLEAN,
escalation_email VARCHAR,
notification_triggers TEXT,
widget_color VARCHAR,
widget_position VARCHAR,
company_logo_url VARCHAR,
file_upload_enabled BOOLEAN,
file_size_limit_mb INTEGER,
allowed_file_types TEXT,
customer_info_retention_days INTEGER,
require_email_verification BOOLEAN,
created_at TIMESTAMP,
updated_at TIMESTAMP,
PRIMARY KEY (id),
UNIQUE (tenant_id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);
-- Indexes for live_chat_settings
CREATE INDEX ix_live_chat_settings_id ON live_chat_settings (id);
-- Table: password_resets
DROP TABLE IF EXISTS password_resets CASCADE;
CREATE TABLE password_resets (
id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
token VARCHAR NOT NULL,
expires_at TIMESTAMP NOT NULL,
is_used BOOLEAN,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(user_id) REFERENCES users (id)
);
-- Indexes for password_resets
CREATE INDEX ix_password_resets_id ON password_resets (id);
CREATE UNIQUE INDEX ix_password_resets_token ON password_resets (token);
-- Table: pending_feedback
DROP TABLE IF EXISTS pending_feedback CASCADE;
CREATE TABLE pending_feedback (
id INTEGER NOT NULL,
feedback_id VARCHAR,
tenant_id INTEGER,
session_id VARCHAR,
user_email VARCHAR,
user_question TEXT,
bot_response TEXT,
conversation_context TEXT,
tenant_email_sent BOOLEAN,
tenant_email_id VARCHAR,
tenant_response TEXT,
user_notified BOOLEAN,
user_email_id VARCHAR,
form_accessed BOOLEAN,
form_accessed_at TIMESTAMP,
form_expired BOOLEAN,
add_to_faq BOOLEAN,
faq_question TEXT,
faq_answer TEXT,
faq_created BOOLEAN,
status VARCHAR,
created_at TIMESTAMP,
tenant_notified_at TIMESTAMP,
resolved_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id),
FOREIGN KEY(session_id) REFERENCES chat_sessions (session_id)
);
-- Indexes for pending_feedback
CREATE UNIQUE INDEX ix_pending_feedback_feedback_id ON pending_feedback (feedback_id);
CREATE INDEX ix_pending_feedback_id ON pending_feedback (id);
-- Table: pricing_plans
DROP TABLE IF EXISTS pricing_plans CASCADE;
CREATE TABLE pricing_plans (
id INTEGER NOT NULL,
name VARCHAR,
plan_type VARCHAR,
price_monthly NUMERIC(10, 2),
price_yearly NUMERIC(10, 2),
max_integrations INTEGER,
max_messages_monthly INTEGER,
custom_prompt_allowed BOOLEAN,
website_api_allowed BOOLEAN,
slack_allowed BOOLEAN,
discord_allowed BOOLEAN,
whatsapp_allowed BOOLEAN,
features TEXT,
is_active BOOLEAN,
is_addon BOOLEAN,
is_popular BOOLEAN,
display_order INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
-- Indexes for pricing_plans
CREATE INDEX ix_pricing_plans_id ON pricing_plans (id);
CREATE UNIQUE INDEX ix_pricing_plans_name ON pricing_plans (name);
CREATE INDEX ix_pricing_plans_plan_type ON pricing_plans (plan_type);
-- Table: scraped_emails
DROP TABLE IF EXISTS scraped_emails CASCADE;
CREATE TABLE scraped_emails (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
email VARCHAR(254) NOT NULL,
email_hash VARCHAR(32) UNIQUE NOT NULL,
source VARCHAR(50) NOT NULL,
capture_method VARCHAR(50) NOT NULL,
session_id VARCHAR(255) REFERENCES chat_sessions(session_id) ON DELETE SET NULL,
user_agent TEXT,
referrer_url TEXT,
ip_address VARCHAR(45),
consent_given BOOLEAN DEFAULT 0 NOT NULL,
verified BOOLEAN DEFAULT 0 NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);
-- Indexes for scraped_emails
CREATE INDEX idx_scraped_emails_created_at ON scraped_emails(created_at);
CREATE INDEX idx_scraped_emails_email ON scraped_emails(email);
CREATE INDEX idx_scraped_emails_session_id ON scraped_emails(session_id);
CREATE INDEX idx_scraped_emails_source ON scraped_emails(source);
CREATE INDEX idx_scraped_emails_tenant_id ON scraped_emails(tenant_id);
CREATE INDEX idx_scraped_emails_verified ON scraped_emails(verified);
-- Table: security_incidents
DROP TABLE IF EXISTS security_incidents CASCADE;
CREATE TABLE security_incidents (
id INTEGER NOT NULL,
tenant_id INTEGER,
session_id VARCHAR,
user_identifier VARCHAR,
platform VARCHAR,
risk_type VARCHAR(50),
user_message TEXT,
security_response TEXT,
matched_patterns TEXT,
severity_score INTEGER,
detected_at TIMESTAMP,
reviewed BOOLEAN,
reviewer_notes TEXT,
PRIMARY KEY (id),
FOREIGN KEY(tenant_id) REFERENCES tenants (id)
);