forked from duolicious/duolicious-backend
-
Notifications
You must be signed in to change notification settings - Fork 0
/
init.sql
1310 lines (1122 loc) · 53.7 KB
/
init.sql
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
--------------------------------------------------------------------------------
-- EXTENSIONS
--------------------------------------------------------------------------------
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION IF NOT EXISTS plpython3u;
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS btree_gist;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
--------------------------------------------------------------------------------
-- FUNCTIONS (1)
--------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION array_full(dimensions INT, fill_value FLOAT4)
RETURNS FLOAT4[] AS $$
SELECT ARRAY(SELECT fill_value FROM generate_series(1, dimensions));
$$ LANGUAGE sql IMMUTABLE LEAKPROOF PARALLEL SAFE;
CREATE OR REPLACE FUNCTION array_full(dimensions INT, fill_value INT)
RETURNS INT[] AS $$
SELECT ARRAY(SELECT fill_value FROM generate_series(1, dimensions));
$$ LANGUAGE sql IMMUTABLE LEAKPROOF PARALLEL SAFE;
CREATE OR REPLACE FUNCTION clamp(lo FLOAT, hi FLOAT, val FLOAT)
RETURNS FLOAT AS $$
SELECT LEAST(hi, GREATEST(lo, val));
$$ LANGUAGE sql IMMUTABLE LEAKPROOF PARALLEL SAFE;
CREATE OR REPLACE FUNCTION base62_encode(num bigint) RETURNS text AS $$
DECLARE
characters text := '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
result text := '';
current int;
BEGIN
IF num = 0 THEN
RETURN '0';
END IF;
WHILE num > 0 LOOP
current := num % 62;
result := substr(characters, current + 1, 1) || result;
num := num / 62;
END LOOP;
RETURN result;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION uuid_or_null(str text)
RETURNS uuid AS $$
BEGIN
RETURN str::uuid;
EXCEPTION WHEN invalid_text_representation THEN
RETURN NULL;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
--------------------------------------------------------------------------------
-- BLOCKED EMAIL DOMAINS
--------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS bad_email_domain (
domain TEXT PRIMARY KEY
);
CREATE TABLE IF NOT EXISTS good_email_domain (
domain TEXT PRIMARY KEY
);
--------------------------------------------------------------------------------
-- BANNED CLUBS
--------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS banned_club (
name TEXT PRIMARY KEY,
CONSTRAINT name CHECK (name = LOWER(name))
);
--------------------------------------------------------------------------------
-- BASICS
--------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS verification_level (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS gender (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS orientation (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS ethnicity (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS location (
id SERIAL PRIMARY KEY,
short_friendly TEXT NOT NULL,
long_friendly TEXT NOT NULL,
city TEXT NOT NULL,
subdivision TEXT NOT NULL,
country TEXT NOT NULL,
coordinates GEOGRAPHY(Point, 4326) NOT NULL,
UNIQUE (short_friendly),
UNIQUE (long_friendly)
);
CREATE TABLE IF NOT EXISTS looking_for (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS yes_no (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS yes_no_optional (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS yes_no_maybe (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS frequency (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS relationship_status (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS religion (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS star_sign (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS unit (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS immediacy (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
UNIQUE (name)
);
--------------------------------------------------------------------------------
-- MAIN TABLES
--------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS person (
id SERIAL,
id_salt INT DEFAULT FLOOR(RANDOM() * 1000000),
tiny_id TEXT GENERATED ALWAYS AS (base62_encode(id::BIGINT * 1000000 + id_salt)) STORED,
uuid UUID NOT NULL DEFAULT uuid_generate_v4(),
-- Required during sign-up
email TEXT NOT NULL,
normalized_email TEXT NOT NULL,
name TEXT NOT NULL,
date_of_birth DATE NOT NULL,
coordinates GEOGRAPHY(Point, 4326) NOT NULL,
gender_id SMALLINT REFERENCES gender(id) NOT NULL,
about TEXT NOT NULL,
-- TODO: CREATE INDEX ON person USING ivfflat (personality2 vector_ip_ops) WITH (lists = 100);
-- There's 46 `trait`s. In principle, it's possible for someone to have a
-- score of 0 for each trait. We add an extra, constant, non-zero dimension
-- to avoid that.
personality VECTOR(47) NOT NULL DEFAULT array_full(47, 0),
presence_score INT[] NOT NULL DEFAULT array_full(46, 0),
absence_score INT[] NOT NULL DEFAULT array_full(46, 0),
count_answers SMALLINT NOT NULL DEFAULT 0,
-- Verification
has_profile_picture_id SMALLINT REFERENCES yes_no(id) NOT NULL DEFAULT 2,
verification_level_id SMALLINT REFERENCES verification_level(id) NOT NULL DEFAULT 1,
verified_age BOOLEAN NOT NULL DEFAULT FALSE,
verified_gender BOOLEAN NOT NULL DEFAULT FALSE,
verified_ethnicity BOOLEAN NOT NULL DEFAULT FALSE,
-- Basics
orientation_id SMALLINT REFERENCES orientation(id) NOT NULL DEFAULT 1,
ethnicity_id SMALLINT REFERENCES ethnicity(id) NOT NULL DEFAULT 1,
occupation TEXT,
education TEXT,
height_cm SMALLINT,
looking_for_id SMALLINT REFERENCES looking_for(id) NOT NULL DEFAULT 1,
smoking_id SMALLINT REFERENCES yes_no_optional(id) NOT NULL DEFAULT 1,
drinking_id SMALLINT REFERENCES frequency(id) NOT NULL DEFAULT 1,
drugs_id SMALLINT REFERENCES yes_no_optional(id) NOT NULL DEFAULT 1,
long_distance_id SMALLINT REFERENCES yes_no_optional(id) NOT NULL DEFAULT 1,
relationship_status_id SMALLINT REFERENCES relationship_status(id) NOT NULL DEFAULT 1,
has_kids_id SMALLINT REFERENCES yes_no_optional(id) NOT NULL DEFAULT 1,
wants_kids_id SMALLINT REFERENCES yes_no_maybe(id) NOT NULL DEFAULT 1,
exercise_id SMALLINT REFERENCES frequency(id) NOT NULL DEFAULT 1,
religion_id SMALLINT REFERENCES religion(id) NOT NULL DEFAULT 1,
star_sign_id SMALLINT REFERENCES star_sign(id) NOT NULL DEFAULT 1,
-- General Settings
unit_id SMALLINT REFERENCES unit(id) NOT NULL,
-- Notification Settings
chats_notification SMALLINT REFERENCES immediacy(id) NOT NULL DEFAULT 1,
intros_notification SMALLINT REFERENCES immediacy(id) NOT NULL DEFAULT 2,
-- Privacy Settings
show_my_location BOOLEAN NOT NULL DEFAULT TRUE,
show_my_age BOOLEAN NOT NULL DEFAULT TRUE,
hide_me_from_strangers BOOLEAN NOT NULL DEFAULT FALSE,
-- Bookkeeping
sign_up_time TIMESTAMP NOT NULL DEFAULT NOW(),
sign_in_count INT NOT NULL DEFAULT 1,
sign_in_time TIMESTAMP NOT NULL DEFAULT NOW(),
-- Whether the user deactivated their account via the settings
activated BOOLEAN NOT NULL DEFAULT TRUE,
-- Primary keys and constraints
UNIQUE (email),
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS onboardee (
email TEXT NOT NULL,
name TEXT,
date_of_birth DATE,
coordinates GEOGRAPHY(Point, 4326),
gender_id SMALLINT REFERENCES gender(id),
about TEXT,
-- Bookkeeping
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
PRIMARY KEY (email)
);
CREATE TABLE IF NOT EXISTS onboardee_search_preference_gender (
email TEXT REFERENCES onboardee(email) ON DELETE CASCADE,
gender_id SMALLINT REFERENCES gender(id) ON DELETE CASCADE,
PRIMARY KEY (email, gender_id)
);
CREATE TABLE IF NOT EXISTS onboardee_photo (
email TEXT NOT NULL REFERENCES onboardee(email) ON DELETE CASCADE,
position SMALLINT NOT NULL,
uuid TEXT NOT NULL,
blurhash TEXT NOT NULL,
PRIMARY KEY (email, position)
);
CREATE TABLE IF NOT EXISTS duo_session (
session_token_hash TEXT NOT NULL,
person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
email TEXT NOT NULL,
otp TEXT NOT NULL,
ip_address inet,
signed_in BOOLEAN NOT NULL DEFAULT FALSE,
session_expiry TIMESTAMP NOT NULL DEFAULT (NOW() + INTERVAL '6 months'),
otp_expiry TIMESTAMP NOT NULL DEFAULT (NOW() + INTERVAL '10 minutes'),
PRIMARY KEY (session_token_hash)
);
CREATE TABLE IF NOT EXISTS photo (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
position SMALLINT NOT NULL,
uuid TEXT NOT NULL,
blurhash TEXT NOT NULL,
verified BOOLEAN NOT NULL DEFAULT FALSE,
nsfw_score FLOAT4,
PRIMARY KEY (person_id, position)
);
CREATE TABLE IF NOT EXISTS undeleted_photo (
uuid TEXT PRIMARY KEY
);
CREATE TABLE IF NOT EXISTS question (
id SMALLSERIAL,
question TEXT NOT NULL,
topic TEXT NOT NULL,
presence_given_yes INT[] NOT NULL,
presence_given_no INT[] NOT NULL,
absence_given_yes INT[] NOT NULL,
absence_given_no INT[] NOT NULL,
count_yes BIGINT NOT NULL DEFAULT 0,
count_no BIGINT NOT NULL DEFAULT 0,
UNIQUE (question),
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS question_order (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
question_id SMALLINT NOT NULL REFERENCES question(id) ON DELETE CASCADE ON UPDATE CASCADE,
position SMALLINT NOT NULL,
PRIMARY KEY (person_id, question_id)
);
CREATE TABLE IF NOT EXISTS answer (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
question_id SMALLINT NOT NULL REFERENCES question(id) ON DELETE CASCADE ON UPDATE CASCADE,
answer BOOLEAN,
public_ BOOLEAN NOT NULL,
PRIMARY KEY (person_id, question_id)
);
CREATE TABLE IF NOT EXISTS trait (
id SMALLSERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT NOT NULL,
min_label TEXT,
max_label TEXT,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS trait_topic (
trait_id SMALLINT NOT NULL REFERENCES trait(id) ON DELETE CASCADE ON UPDATE CASCADE,
name TEXT,
PRIMARY KEY (trait_id, name)
);
DO $$ BEGIN
CREATE TYPE verification_job_status AS ENUM (
'uploading-photo',
'queued',
'running',
'success',
'failure'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
CREATE TABLE IF NOT EXISTS verification_job (
id SERIAL PRIMARY KEY,
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
status verification_job_status NOT NULL DEFAULT 'uploading-photo',
message TEXT NOT NULL DEFAULT 'Verifying',
photo_uuid TEXT NOT NULL,
raw_json TEXT NOT NULL DEFAULT '',
expires_at TIMESTAMP NOT NULL DEFAULT (NOW() + INTERVAL '1 day')
);
--------------------------------------------------------------------------------
-- TABLES TO CONNECT PEOPLE TO THEIR SEARCH PREFERENCES
--------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS search_preference_answer (
person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
question_id SMALLINT REFERENCES question(id) ON DELETE CASCADE,
answer BOOLEAN NOT NULL,
accept_unanswered BOOLEAN NOT NULL,
PRIMARY KEY (person_id, question_id)
);
CREATE TABLE IF NOT EXISTS search_preference_gender (
person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
gender_id SMALLINT REFERENCES gender(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, gender_id)
);
CREATE TABLE IF NOT EXISTS search_preference_orientation (
person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
orientation_id SMALLINT REFERENCES orientation(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, orientation_id)
);
CREATE TABLE IF NOT EXISTS search_preference_ethnicity (
person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
ethnicity_id SMALLINT REFERENCES ethnicity(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, ethnicity_id)
);
CREATE TABLE IF NOT EXISTS search_preference_age (
person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
min_age SMALLINT,
max_age SMALLINT,
PRIMARY KEY (person_id)
);
CREATE TABLE IF NOT EXISTS search_preference_distance (
person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
distance SMALLINT,
PRIMARY KEY (person_id)
);
CREATE TABLE IF NOT EXISTS search_preference_height_cm (
person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
min_height_cm SMALLINT,
max_height_cm SMALLINT,
PRIMARY KEY (person_id)
);
CREATE TABLE IF NOT EXISTS search_preference_has_profile_picture (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
has_profile_picture_id SMALLINT REFERENCES yes_no(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, has_profile_picture_id)
);
CREATE TABLE IF NOT EXISTS search_preference_looking_for (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
looking_for_id SMALLINT REFERENCES looking_for(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, looking_for_id)
);
CREATE TABLE IF NOT EXISTS search_preference_smoking (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
smoking_id SMALLINT REFERENCES yes_no_optional(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, smoking_id)
);
CREATE TABLE IF NOT EXISTS search_preference_drinking (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
drinking_id SMALLINT REFERENCES frequency(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, drinking_id)
);
CREATE TABLE IF NOT EXISTS search_preference_drugs (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
drugs_id SMALLINT REFERENCES yes_no_optional(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, drugs_id)
);
CREATE TABLE IF NOT EXISTS search_preference_long_distance (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
long_distance_id SMALLINT REFERENCES yes_no_optional(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, long_distance_id)
);
CREATE TABLE IF NOT EXISTS search_preference_relationship_status (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
relationship_status_id SMALLINT REFERENCES relationship_status(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, relationship_status_id)
);
CREATE TABLE IF NOT EXISTS search_preference_has_kids (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
has_kids_id SMALLINT REFERENCES yes_no_optional(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, has_kids_id)
);
CREATE TABLE IF NOT EXISTS search_preference_wants_kids (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
wants_kids_id SMALLINT REFERENCES yes_no_maybe(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, wants_kids_id)
);
CREATE TABLE IF NOT EXISTS search_preference_exercise (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
exercise_id SMALLINT REFERENCES frequency(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, exercise_id)
);
CREATE TABLE IF NOT EXISTS search_preference_religion (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
religion_id SMALLINT REFERENCES religion(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, religion_id)
);
CREATE TABLE IF NOT EXISTS search_preference_star_sign (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
star_sign_id SMALLINT REFERENCES star_sign(id) ON DELETE CASCADE,
PRIMARY KEY (person_id, star_sign_id)
);
CREATE TABLE IF NOT EXISTS search_preference_messaged (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
messaged_id SMALLINT REFERENCES yes_no(id) ON DELETE CASCADE,
PRIMARY KEY (person_id)
);
CREATE TABLE IF NOT EXISTS search_preference_skipped (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
skipped_id SMALLINT REFERENCES yes_no(id) ON DELETE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
PRIMARY KEY (person_id)
);
CREATE TABLE IF NOT EXISTS messaged (
subject_person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
object_person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
PRIMARY KEY (subject_person_id, object_person_id)
);
CREATE TABLE IF NOT EXISTS skipped (
subject_person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
object_person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
reported BOOLEAN NOT NULL DEFAULT FALSE,
report_reason TEXT NOT NULL DEFAULT '',
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
PRIMARY KEY (subject_person_id, object_person_id)
);
CREATE TABLE IF NOT EXISTS club (
name TEXT NOT NULL,
count_members INT NOT NULL DEFAULT 0,
PRIMARY KEY (name)
);
CREATE TABLE IF NOT EXISTS person_club (
person_id INT NOT NULL REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
club_name TEXT NOT NULL REFERENCES club(name) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (person_id, club_name)
);
CREATE TABLE IF NOT EXISTS deleted_photo_admin_token (
token UUID PRIMARY KEY DEFAULT gen_random_uuid(),
photo_uuid TEXT NOT NULL,
generated_at TIMESTAMP NOT NULL DEFAULT NOW(),
expires_at TIMESTAMP NOT NULL DEFAULT (NOW() + INTERVAL '1 month')
);
CREATE TABLE IF NOT EXISTS banned_person_admin_token (
token UUID PRIMARY KEY DEFAULT gen_random_uuid(),
person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
generated_at TIMESTAMP NOT NULL DEFAULT NOW(),
expires_at TIMESTAMP NOT NULL DEFAULT (NOW() + INTERVAL '1 month')
);
CREATE TABLE IF NOT EXISTS banned_person (
normalized_email TEXT NOT NULL,
ip_address inet NOT NULL DEFAULT '127.0.0.1',
banned_at TIMESTAMP NOT NULL DEFAULT NOW(),
expires_at TIMESTAMP NOT NULL DEFAULT (NOW() + INTERVAL '1 month'),
report_reasons TEXT[] NOT NULL DEFAULT '{}'::TEXT[],
PRIMARY KEY (normalized_email, ip_address)
);
--------------------------------------------------------------------------------
-- TABLES TO SPEED UP SEARCHING
--------------------------------------------------------------------------------
CREATE UNLOGGED TABLE IF NOT EXISTS search_cache (
searcher_person_id INT REFERENCES person(id) ON DELETE CASCADE ON UPDATE CASCADE,
position SMALLINT,
prospect_person_id INT NOT NULL,
prospect_uuid UUID NOT NULL,
has_mutual_club BOOLEAN NOT NULL DEFAULT FALSE,
profile_photo_uuid TEXT,
name TEXT NOT NULL,
age SMALLINT,
match_percentage SMALLINT NOT NULL,
personality VECTOR(47) NOT NULL,
PRIMARY KEY (searcher_person_id, position)
);
--------------------------------------------------------------------------------
-- INDEXES
--------------------------------------------------------------------------------
CREATE INDEX IF NOT EXISTS idx__person__activated__coordinates__gender_id
ON person
USING GIST(coordinates, gender_id)
WHERE activated;
CREATE INDEX IF NOT EXISTS idx__search_cache__searcher_person_id__position ON search_cache(searcher_person_id, position);
CREATE INDEX IF NOT EXISTS idx__answer__question_id ON answer(question_id);
CREATE INDEX IF NOT EXISTS idx__answer__person_id_public_answer ON answer(person_id, public_, answer);
CREATE INDEX IF NOT EXISTS idx__duo_session__email
ON duo_session(email);
CREATE INDEX IF NOT EXISTS idx__duo_session__session_expiry
ON duo_session(session_expiry);
CREATE INDEX IF NOT EXISTS idx__location__coordinates ON location USING GIST(coordinates);
CREATE INDEX IF NOT EXISTS idx__location__long_friendly ON location USING GIST(long_friendly gist_trgm_ops);
CREATE INDEX IF NOT EXISTS idx__question__question ON question USING GIST(question gist_trgm_ops);
CREATE INDEX IF NOT EXISTS idx__person__sign_up_time ON person(sign_up_time);
CREATE INDEX IF NOT EXISTS idx__person__tiny_id ON person(tiny_id);
CREATE INDEX IF NOT EXISTS idx__person__email ON person(email);
CREATE INDEX IF NOT EXISTS idx__person__uuid ON person(uuid);
CREATE INDEX IF NOT EXISTS idx__person__normalized_email
ON person(normalized_email);
CREATE INDEX IF NOT EXISTS idx__club__name ON club USING GIST(name gist_trgm_ops);
CREATE INDEX IF NOT EXISTS idx__banned_person__ip_address ON banned_person(ip_address);
CREATE INDEX IF NOT EXISTS idx__banned_person__expires_at ON banned_person(expires_at);
CREATE INDEX IF NOT EXISTS idx__banned_person_admin_token__expires_at
ON banned_person_admin_token(expires_at);
CREATE INDEX IF NOT EXISTS idx__deleted_photo_admin_token__expires_at
ON deleted_photo_admin_token(expires_at);
CREATE INDEX IF NOT EXISTS idx__photo__uuid
ON photo(uuid);
CREATE INDEX IF NOT EXISTS idx__photo__nsfw_score
ON photo(nsfw_score);
CREATE INDEX IF NOT EXISTS idx__onboardee_photo__uuid
ON onboardee_photo(uuid);
CREATE INDEX IF NOT EXISTS idx__onboardee__created_at
ON onboardee(created_at);
CREATE INDEX IF NOT EXISTS idx__bad_email_domain__domain
ON bad_email_domain(domain);
CREATE INDEX IF NOT EXISTS idx__good_email_domain__domain
ON good_email_domain(domain);
CREATE INDEX IF NOT EXISTS idx__skipped__object_person_id__created_at__reported
ON skipped(object_person_id, created_at)
WHERE reported;
CREATE INDEX IF NOT EXISTS idx__verification_job__status
ON verification_job(status);
CREATE INDEX IF NOT EXISTS idx__verification_job__person_id
ON verification_job(person_id);
CREATE INDEX IF NOT EXISTS idx__verification_job__expires_at
ON verification_job(expires_at);
--------------------------------------------------------------------------------
-- DATA
--------------------------------------------------------------------------------
INSERT INTO verification_level (name) VALUES ('No verification') ON CONFLICT (name) DO NOTHING;
INSERT INTO verification_level (name) VALUES ('Basics only') ON CONFLICT (name) DO NOTHING;
INSERT INTO verification_level (name) VALUES ('Photos') ON CONFLICT (name) DO NOTHING;
INSERT INTO gender (name) VALUES ('Man') ON CONFLICT (name) DO NOTHING;
INSERT INTO gender (name) VALUES ('Woman') ON CONFLICT (name) DO NOTHING;
INSERT INTO gender (name) VALUES ('Agender') ON CONFLICT (name) DO NOTHING;
INSERT INTO gender (name) VALUES ('Intersex') ON CONFLICT (name) DO NOTHING;
INSERT INTO gender (name) VALUES ('Non-binary') ON CONFLICT (name) DO NOTHING;
INSERT INTO gender (name) VALUES ('Transgender') ON CONFLICT (name) DO NOTHING;
INSERT INTO gender (name) VALUES ('Trans woman') ON CONFLICT (name) DO NOTHING;
INSERT INTO gender (name) VALUES ('Trans man') ON CONFLICT (name) DO NOTHING;
INSERT INTO gender (name) VALUES ('Other') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Unanswered') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Straight') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Gay') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Lesbian') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Bisexual') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Asexual') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Demisexual') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Pansexual') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Queer') ON CONFLICT (name) DO NOTHING;
INSERT INTO orientation (name) VALUES ('Other') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('Unanswered') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('Black/African Descent') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('East Asian') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('Hispanic/Latino') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('Middle Eastern') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('Native American') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('Pacific Islander') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('South Asian') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('Southeast Asian') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('White/Caucasian') ON CONFLICT (name) DO NOTHING;
INSERT INTO ethnicity (name) VALUES ('Other') ON CONFLICT (name) DO NOTHING;
INSERT INTO looking_for (name) VALUES ('Unanswered') ON CONFLICT (name) DO NOTHING;
INSERT INTO looking_for (name) VALUES ('Friends') ON CONFLICT (name) DO NOTHING;
INSERT INTO looking_for (name) VALUES ('Short-term dating') ON CONFLICT (name) DO NOTHING;
INSERT INTO looking_for (name) VALUES ('Long-term dating') ON CONFLICT (name) DO NOTHING;
INSERT INTO looking_for (name) VALUES ('Marriage') ON CONFLICT (name) DO NOTHING;
INSERT INTO relationship_status (name) VALUES ('Unanswered') ON CONFLICT (name) DO NOTHING;
INSERT INTO relationship_status (name) VALUES ('Single') ON CONFLICT (name) DO NOTHING;
INSERT INTO relationship_status (name) VALUES ('Seeing someone') ON CONFLICT (name) DO NOTHING;
INSERT INTO relationship_status (name) VALUES ('Engaged') ON CONFLICT (name) DO NOTHING;
INSERT INTO relationship_status (name) VALUES ('Married') ON CONFLICT (name) DO NOTHING;
INSERT INTO relationship_status (name) VALUES ('Divorced') ON CONFLICT (name) DO NOTHING;
INSERT INTO relationship_status (name) VALUES ('Widowed') ON CONFLICT (name) DO NOTHING;
INSERT INTO relationship_status (name) VALUES ('Other') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Unanswered') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Agnostic') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Atheist') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Buddhist') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Christian') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Hindu') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Jewish') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Muslim') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Zoroastrian') ON CONFLICT (name) DO NOTHING;
INSERT INTO religion (name) VALUES ('Other') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Unanswered') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Aquarius') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Aries') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Cancer') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Capricorn') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Gemini') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Leo') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Libra') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Pisces') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Sagittarius') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Scorpio') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Taurus') ON CONFLICT (name) DO NOTHING;
INSERT INTO star_sign (name) VALUES ('Virgo') ON CONFLICT (name) DO NOTHING;
INSERT INTO unit (name) VALUES ('Imperial') ON CONFLICT (name) DO NOTHING;
INSERT INTO unit (name) VALUES ('Metric') ON CONFLICT (name) DO NOTHING;
INSERT INTO immediacy (name) VALUES ('Immediately') ON CONFLICT (name) DO NOTHING;
INSERT INTO immediacy (name) VALUES ('Daily') ON CONFLICT (name) DO NOTHING;
INSERT INTO immediacy (name) VALUES ('Every 3 days') ON CONFLICT (name) DO NOTHING;
INSERT INTO immediacy (name) VALUES ('Weekly') ON CONFLICT (name) DO NOTHING;
INSERT INTO immediacy (name) VALUES ('Never') ON CONFLICT (name) DO NOTHING;
INSERT INTO frequency (name) VALUES ('Unanswered') ON CONFLICT (name) DO NOTHING;
INSERT INTO frequency (name) VALUES ('Often') ON CONFLICT (name) DO NOTHING;
INSERT INTO frequency (name) VALUES ('Sometimes') ON CONFLICT (name) DO NOTHING;
INSERT INTO frequency (name) VALUES ('Never') ON CONFLICT (name) DO NOTHING;
INSERT INTO yes_no (name) VALUES ('Yes') ON CONFLICT (name) DO NOTHING;
INSERT INTO yes_no (name) VALUES ('No') ON CONFLICT (name) DO NOTHING;
INSERT INTO yes_no_optional (name) VALUES ('Unanswered') ON CONFLICT (name) DO NOTHING;
INSERT INTO yes_no_optional (name) VALUES ('Yes') ON CONFLICT (name) DO NOTHING;
INSERT INTO yes_no_optional (name) VALUES ('No') ON CONFLICT (name) DO NOTHING;
INSERT INTO yes_no_maybe (name) VALUES ('Unanswered') ON CONFLICT (name) DO NOTHING;
INSERT INTO yes_no_maybe (name) VALUES ('Yes') ON CONFLICT (name) DO NOTHING;
INSERT INTO yes_no_maybe (name) VALUES ('No') ON CONFLICT (name) DO NOTHING;
INSERT INTO yes_no_maybe (name) VALUES ('Maybe') ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Agreeableness',
'Captures an individual''s range of social behaviors, from demonstrating empathy, cooperation, and consideration for others to expressing assertiveness and independence in social situations.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Anxious Attachment',
'Measures the extent to which a person seeks reassurance and fears abandonment in close relationships. If a person scores low on this and the "Avoidant Attachment" scale, they''re said to be "securely" attached. Secure attachment is associated with longer, more stable relationships.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Avoidant Attachment',
'Measures the preference for emotional distance and self-reliance in relationships. If a person scores low on this and the "Anxious Attachment" scale, they''re said to be "securely" attached. Secure attachment is associated with longer, more stable relationships.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Conscientiousness',
'Represents an individual''s approach to organization, reliability, and goal-setting, encompassing both highly structured and responsible behavior as well as a more flexible and spontaneous approach.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Neuroticism',
'Depicts the diversity in how people experience and cope with emotions, spanning the range from calmness and emotional steadiness to sensitivity and emotional responsiveness.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Career Focus',
'This trait reflects the importance you place on your career. Those scoring high value their career and tend to prioritize it, while those scoring low might prioritize other aspects of life over their career.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Drug Friendliness',
'This trait measures your openness to drug use. High scores could indicate a liberal attitude towards drugs or personal use, while low scores may represent a more conservative view or no personal use of drugs.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Emotional Openness in Relationships',
'This trait measures how comfortable you are with expressing emotions in a relationship. High scores mean you are open to discussing your feelings, while low scores might indicate a more reserved emotional style.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Empathy',
'This trait indicates how well you understand and share the feelings of others. High empathy means you easily connect with others'' emotions, while low empathy might indicate a more logical, detached approach.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Emphasis on Boundaries',
'This trait signifies a person''s tendency to define, communicate, and respect personal limits and spaces. People who score high on this trait believe in the importance of setting clear personal boundaries in their relationships.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Environmentalism/Anthropocentrism',
'Measures prioritization of preserving the environment and non-human species versus human-centered resource utilization and economic development.',
'Environmentalism',
'Anthropocentrism'
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Equanimity',
'This trait pertains to a person''s ability to maintain calm and composure, especially during stressful situations. Individuals who score high on this trait are able to keep their cool and think clearly, regardless of the circumstances.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Equity/Meritocracy',
'Measures a person''s preference for a system that rewards individuals based on their abilities and achievements versus a system that prioritizes fairness and equal opportunities for everyone.',
'Equity',
'Meritocracy'
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Family Focus',
'This trait is about how much a person values family relationships and commitments. Individuals who score high on this trait often place their family as a top priority and enjoy spending quality time with their loved ones.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Fitness Focus',
'This trait indicates the importance a person places on maintaining physical fitness and living a healthy lifestyle. Those with high scores for this trait are likely to enjoy activities like regular exercise, eating balanced meals, and living an overall active lifestyle.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Honesty',
'This trait describes a person''s tendency to speak the truth, behave transparently, and avoid deception. Individuals who score high on this trait value truthfulness and believe in being straightforward in their communications.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Humility',
'This trait reflects a person''s ability to remain modest and unpretentious, even in the face of success. Those who score high on this trait believe in acknowledging the role of others in their achievements and avoiding arrogance.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Independence',
'Do you take charge of your own life and make decisions without leaning on others? This trait measures your self-reliance and ability to handle things on your own.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Individualism/Collectivism',
'This trait measures a person''s preference for individual rights and freedoms versus collective good and social cohesion.',
'Individualism',
'Collectivism'
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Introversion/Extraversion',
'Measures a person''s preference for engaging with the world, ranging from drawing energy from social interactions and being action-oriented (Extraversion) to finding energy in solitude and focusing on thoughts and feelings (Introversion).',
'Introversion',
'Extraversion'
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Isolationism/Internationalism',
'This trait measures preference for national self-reliance and limited global engagement versus active participation in international affairs and cooperation.',
'Isolationism',
'Internationalism'
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Judging/Perceiving',
'This trait captures someone''s approach to organizing and structuring their life, ranging from preferring a planned, orderly, and decisive lifestyle (Judging), to embracing spontaneity, flexibility, and adaptability (Perceiving).',
'Judging',
'Perceiving'
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Libertarianism/Authoritarianism',
'This trait measures the preference for individual liberties and minimal government intervention, versus strong central authority and extensive government control.',
'Libertarianism',
'Authoritarianism'
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Love Focus',
'How central is love in your life? This trait captures the importance you place on romantic relationships and the effort you''re willing to put into finding and maintaining them.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Loyalty',
'This trait shows us how committed you are. When you make a promise, do you keep it?',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Maturity',
'A measure of how much a person takes responsibility for their actions, understands the world around them, and is ready to deal with complex issues. It is not about age, but about mindset and experience.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Non-interventionism/Interventionism',
'Measures a person''s preference for an active foreign policy with military and diplomatic interventions versus a non-interventionist approach that emphasizes diplomacy and trade.',
'Non-interventionism',
'Interventionism'
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Openness to Experience',
'Represents a person''s willingness to explore new ideas, activities, and experiences. People high in this trait tend to be imaginative, creative, and curious. Those lower might appreciate routine, predictability, and familiar surroundings.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Patience',
'Measures your ability to stay calm and tolerant when facing challenges.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Persistence',
'Indicates how much you''re willing to stick with tasks, goals or beliefs, even in the face of adversity. Those lower in this trait might be more flexible, adaptive, and ready to pivot when needed.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Playfulness',
'This trait measures your tendency to seek joy, humor, and fun in life. High scores often enjoy spontaneity, games, and laughter. Those scoring lower might appreciate seriousness, focus, and quiet reflection.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Preference for Monogamy',
'This trait measures your inclination towards having one partner at a time. A low score doesn''t necessarily mean a preference for multiple partners simultaneously, but might reflect a desire for serial monogamy, or simply being open to different relationship structures.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Rationality',
'This trait determines the extent to which you prefer using logical reasoning and objective analysis over emotional intuition. Both approaches have their advantages, and neither is inherently better or worse than the other.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Religiosity',
'This trait measures the extent to which religious beliefs influence your life. It doesn''t indicate which religion you follow, or how devout you are, just the importance religion holds for you. It includes both traditionally religious and spiritual orientations.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Security/Freedom',
'Measures how much a person values national security and public safety versus individual freedoms and civil liberties.',
'Security',
'Freedom'
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Self-acceptance',
'This trait measures your level of acceptance and appreciation for who you are as an individual. It doesn''t mean being complacent or avoiding personal growth, but rather denotes a healthy self-perception and an acceptance of one''s strengths and weaknesses.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Self-esteem',
'This trait signifies your overall subjective emotional evaluation of your own worth. High self-esteem doesn''t mean arrogance but refers to a positive, balanced view of oneself. Low self-esteem doesn''t necessarily indicate lack of confidence but may reflect humility or a more critical self-view.',
NULL,
NULL
) ON CONFLICT (name) DO NOTHING;
INSERT INTO trait (name, description, min_label, max_label) VALUES (
'Sensing/Intuition',
'This trait represents someone''s preferred way of processing information, covering the spectrum from focusing on concrete, tangible details and experiences (Sensing), to exploring abstract concepts, patterns, and possibilities (Intuition).',
'Sensing',
'Intuition'
) ON CONFLICT (name) DO NOTHING;