@meith/db 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/LICENSE.md +165 -0
  2. package/migrations/0000_initial_schema.sql +538 -0
  3. package/migrations/0001_seed_usergroups.sql +111 -0
  4. package/migrations/0002_group_promotions.sql +25 -0
  5. package/migrations/0003_counter_maintenance.sql +34 -0
  6. package/migrations/0004_post_render_cache.sql +7 -0
  7. package/migrations/0005_reports.sql +51 -0
  8. package/migrations/0006_warnings.sql +91 -0
  9. package/migrations/0007_notifications.sql +44 -0
  10. package/migrations/0008_subscriptions.sql +48 -0
  11. package/migrations/0009_member_preferences.sql +13 -0
  12. package/migrations/0010_profile_fields.sql +53 -0
  13. package/migrations/0011_private_messages.sql +63 -0
  14. package/migrations/0012_user_relations.sql +18 -0
  15. package/migrations/0013_reputation.sql +45 -0
  16. package/migrations/0014_signatures.sql +16 -0
  17. package/migrations/0015_admin_sessions.sql +24 -0
  18. package/migrations/0016_attachments.sql +51 -0
  19. package/migrations/0017_avatars.sql +33 -0
  20. package/migrations/0018_mass_mail.sql +15 -0
  21. package/migrations/0019_word_filters.sql +8 -0
  22. package/migrations/0020_searches.sql +15 -0
  23. package/migrations/0021_presence_stats.sql +18 -0
  24. package/migrations/0022_api_tokens_webhooks.sql +58 -0
  25. package/migrations/0023_install_state.sql +6 -0
  26. package/migrations/0024_component_versions.sql +13 -0
  27. package/migrations/0025_import.sql +25 -0
  28. package/migrations/0026_polls.sql +40 -0
  29. package/migrations/0027_drafts.sql +13 -0
  30. package/migrations/0028_board_vocabulary.sql +32 -0
  31. package/migrations/0029_announcements.sql +16 -0
  32. package/migrations/0030_antispam.sql +18 -0
  33. package/migrations/0031_markdown.sql +24 -0
  34. package/migrations/0032_theme_enablement.sql +1 -0
  35. package/migrations/0033_group_identity.sql +5 -0
  36. package/migrations/0034_search_document_version.sql +4 -0
  37. package/migrations/0035_categories_hold_no_threads.sql +1 -0
  38. package/migrations/0036_expiring_group_grants.sql +6 -0
  39. package/migrations/0037_automatic_timezone.sql +3 -0
  40. package/migrations/0038_primary_group_grants.sql +3 -0
  41. package/migrations/0039_moderator_log_forum_scope.sql +1 -0
  42. package/migrations/0040_moderator_restore_grants.sql +1 -0
  43. package/migrations/0041_drop_placebo_moderator_rights.sql +3 -0
  44. package/migrations/0042_drop_placebo_delete_others.sql +2 -0
  45. package/migrations/0043_federated_identity.sql +28 -0
  46. package/migrations/0044_second_factor.sql +34 -0
  47. package/migrations/0045_drop_dead_task_due_index.sql +1 -0
  48. package/migrations/0046_member_locale.sql +1 -0
  49. package/migrations/0047_navigation_items.sql +34 -0
  50. package/migrations/0048_web_push.sql +16 -0
  51. package/migrations/0049_plugin_health.sql +7 -0
  52. package/migrations/0050_drop_forum_password_grants.sql +1 -0
  53. package/migrations/0051_glossy_barracuda.sql +1 -0
  54. package/migrations/0052_many_professor_monster.sql +2 -0
  55. package/migrations/0053_strange_maximus.sql +14 -0
  56. package/migrations/0054_legacy_import_sources.sql +25 -0
  57. package/migrations/0055_poll_parity.sql +14 -0
  58. package/migrations/0056_marketplace_catalog.sql +11 -0
  59. package/migrations/meta/0000_snapshot.json +4412 -0
  60. package/migrations/meta/0006_snapshot.json +5411 -0
  61. package/migrations/meta/0007_snapshot.json +5634 -0
  62. package/migrations/meta/0008_snapshot.json +5779 -0
  63. package/migrations/meta/0009_snapshot.json +5816 -0
  64. package/migrations/meta/0010_snapshot.json +6117 -0
  65. package/migrations/meta/0011_snapshot.json +6406 -0
  66. package/migrations/meta/0012_snapshot.json +6517 -0
  67. package/migrations/meta/0013_snapshot.json +6722 -0
  68. package/migrations/meta/0014_snapshot.json +6777 -0
  69. package/migrations/meta/0015_snapshot.json +6914 -0
  70. package/migrations/meta/0016_snapshot.json +7192 -0
  71. package/migrations/meta/0017_snapshot.json +7248 -0
  72. package/migrations/meta/0018_snapshot.json +7355 -0
  73. package/migrations/meta/0019_snapshot.json +7419 -0
  74. package/migrations/meta/0020_snapshot.json +7562 -0
  75. package/migrations/meta/0021_snapshot.json +7653 -0
  76. package/migrations/meta/0031_snapshot.json +8162 -0
  77. package/migrations/meta/0032_snapshot.json +8169 -0
  78. package/migrations/meta/0033_snapshot.json +8193 -0
  79. package/migrations/meta/0034_snapshot.json +8221 -0
  80. package/migrations/meta/0036_snapshot.json +8262 -0
  81. package/migrations/meta/0037_snapshot.json +8262 -0
  82. package/migrations/meta/0038_snapshot.json +8293 -0
  83. package/migrations/meta/0039_snapshot.json +8308 -0
  84. package/migrations/meta/0041_snapshot.json +8287 -0
  85. package/migrations/meta/0042_snapshot.json +8274 -0
  86. package/migrations/meta/0043_snapshot.json +8521 -0
  87. package/migrations/meta/0044_snapshot.json +8814 -0
  88. package/migrations/meta/0045_snapshot.json +8797 -0
  89. package/migrations/meta/0046_snapshot.json +8804 -0
  90. package/migrations/meta/0047_snapshot.json +9018 -0
  91. package/migrations/meta/0048_snapshot.json +9145 -0
  92. package/migrations/meta/0049_snapshot.json +9190 -0
  93. package/migrations/meta/0050_snapshot.json +9126 -0
  94. package/migrations/meta/0051_snapshot.json +9132 -0
  95. package/migrations/meta/0052_snapshot.json +9148 -0
  96. package/migrations/meta/0053_snapshot.json +9268 -0
  97. package/migrations/meta/0054_snapshot.json +9378 -0
  98. package/migrations/meta/0056_snapshot.json +9447 -0
  99. package/migrations/meta/_journal.json +405 -0
  100. package/package.json +64 -0
  101. package/src/account-repos.ts +580 -0
  102. package/src/actor-builder.ts +130 -0
  103. package/src/admin-repo.ts +85 -0
  104. package/src/admin-session-repo.ts +205 -0
  105. package/src/admin-undo-repo.ts +128 -0
  106. package/src/announcement-repo.ts +176 -0
  107. package/src/antispam-repo.ts +145 -0
  108. package/src/api-repo.ts +276 -0
  109. package/src/attachment-admin-repo.ts +161 -0
  110. package/src/attachment-repo.ts +240 -0
  111. package/src/authorization-source.ts +138 -0
  112. package/src/avatar-repo.ts +185 -0
  113. package/src/ban-repos.ts +146 -0
  114. package/src/client.ts +85 -0
  115. package/src/content-admin-repo.ts +298 -0
  116. package/src/content-counters.ts +152 -0
  117. package/src/counter-recount.ts +263 -0
  118. package/src/cursor.ts +16 -0
  119. package/src/denormalised-username.ts +34 -0
  120. package/src/discovery-repo.ts +140 -0
  121. package/src/draft-repo.ts +59 -0
  122. package/src/feed-repo.ts +219 -0
  123. package/src/forum-admin-repo.ts +310 -0
  124. package/src/forum-repo.ts +206 -0
  125. package/src/group-admin-repo.ts +256 -0
  126. package/src/group-identity-repo.ts +84 -0
  127. package/src/identity-link-repo.ts +145 -0
  128. package/src/import-repo.ts +123 -0
  129. package/src/import-sink.ts +1377 -0
  130. package/src/index.ts +316 -0
  131. package/src/inline-moderation.ts +344 -0
  132. package/src/install-repo.ts +67 -0
  133. package/src/latest-repo.ts +115 -0
  134. package/src/maintenance-repo.ts +54 -0
  135. package/src/marketplace-repo.ts +111 -0
  136. package/src/member-profile-repo.ts +82 -0
  137. package/src/member-settings-repo.ts +160 -0
  138. package/src/message-repo.ts +384 -0
  139. package/src/migrate-run.ts +18 -0
  140. package/src/migrate.ts +129 -0
  141. package/src/modcp-repo.ts +253 -0
  142. package/src/moderation-queue.ts +279 -0
  143. package/src/navigation-repo.ts +288 -0
  144. package/src/notification-repo.ts +402 -0
  145. package/src/orphan-keys.ts +19 -0
  146. package/src/outbox-repo.ts +78 -0
  147. package/src/permission-version.ts +24 -0
  148. package/src/permissions-map.ts +52 -0
  149. package/src/pglite.fixture.ts +87 -0
  150. package/src/plugin-data.ts +88 -0
  151. package/src/plugin-grants.ts +369 -0
  152. package/src/plugin-health-repo.ts +80 -0
  153. package/src/plugin-purge-repo.ts +91 -0
  154. package/src/plugin-users.ts +39 -0
  155. package/src/poll-repo.ts +334 -0
  156. package/src/post-repo.ts +261 -0
  157. package/src/post-writes.ts +227 -0
  158. package/src/presence-repo.ts +220 -0
  159. package/src/profile-field-repo.ts +182 -0
  160. package/src/promotion-repo.ts +152 -0
  161. package/src/read-state-repo.ts +81 -0
  162. package/src/relation-repo.ts +113 -0
  163. package/src/render-backfill.ts +110 -0
  164. package/src/render-signature.ts +33 -0
  165. package/src/report-repo.ts +349 -0
  166. package/src/reputation-repo.ts +295 -0
  167. package/src/result-rows.ts +13 -0
  168. package/src/row-values.ts +7 -0
  169. package/src/schema/content.ts +451 -0
  170. package/src/schema/identity.ts +699 -0
  171. package/src/schema/index.ts +10 -0
  172. package/src/schema/messages.ts +76 -0
  173. package/src/schema/permission-columns.ts +34 -0
  174. package/src/schema/platform.ts +376 -0
  175. package/src/schema/structure.ts +164 -0
  176. package/src/search-repo.ts +359 -0
  177. package/src/search-store.ts +113 -0
  178. package/src/seed-groups.ts +11 -0
  179. package/src/settings-repo.ts +32 -0
  180. package/src/signature-repo.ts +102 -0
  181. package/src/sql-lists.ts +17 -0
  182. package/src/staff-groups.ts +50 -0
  183. package/src/stats-repo.ts +151 -0
  184. package/src/subscription-repo.ts +350 -0
  185. package/src/system-health-repo.ts +130 -0
  186. package/src/task-repo.ts +104 -0
  187. package/src/theme-admin-repo.ts +172 -0
  188. package/src/theme-repo.ts +43 -0
  189. package/src/thread-audience.ts +45 -0
  190. package/src/thread-counters.ts +107 -0
  191. package/src/thread-repo.ts +255 -0
  192. package/src/thread-surgery.ts +282 -0
  193. package/src/thread-tools.ts +311 -0
  194. package/src/thread-views.ts +41 -0
  195. package/src/thread-writes.ts +356 -0
  196. package/src/two-factor-repo.ts +235 -0
  197. package/src/upgrade-repo.ts +66 -0
  198. package/src/user-admin-repo.ts +367 -0
  199. package/src/user-bulk-repo.ts +397 -0
  200. package/src/user-merge-map.ts +111 -0
  201. package/src/user-merge-repo.ts +304 -0
  202. package/src/visibility-counters.ts +190 -0
  203. package/src/visibility.ts +17 -0
  204. package/src/vocabulary-repo.ts +54 -0
  205. package/src/warning-repo.ts +328 -0
@@ -0,0 +1,111 @@
1
+ INSERT INTO "usergroups" ("id", "key", "title", "description", "display_order", "is_system", "is_staff_group", "badge_token",
2
+ "can_view", "can_view_threads", "can_view_others_threads", "can_search",
3
+ "can_view_profiles", "can_view_member_list", "can_download_attachments")
4
+ VALUES (1, 'guests', 'Guests', 'Visitors who are not logged in.', 0, true, false, NULL,
5
+ true, true, true, true,
6
+ true, true, true);
7
+ --> statement-breakpoint
8
+
9
+ INSERT INTO "usergroups" ("id", "key", "title", "description", "display_order", "is_system", "is_staff_group", "badge_token",
10
+ "can_view", "can_view_threads", "can_view_others_threads", "can_search",
11
+ "can_post_threads", "can_post_replies", "can_post_polls", "can_vote_polls", "can_rate_threads",
12
+ "can_edit_own_posts", "can_delete_own_posts", "can_delete_own_threads",
13
+ "can_upload_attachments", "can_download_attachments", "can_subscribe",
14
+ "can_view_profiles", "can_view_member_list", "can_use_private_messages",
15
+ "can_use_signature", "can_upload_avatar", "can_report_content",
16
+ "requires_thread_approval", "requires_post_approval", "requires_approval_on_edit")
17
+ VALUES (2, 'registered', 'Registered', 'Members with an activated account.', 10, true, false, NULL,
18
+ true, true, true, true,
19
+ true, true, true, true, true,
20
+ true, true, true,
21
+ true, true, true,
22
+ true, true, true,
23
+ true, true, true,
24
+ false, false, false);
25
+ --> statement-breakpoint
26
+
27
+ INSERT INTO "usergroups" ("id", "key", "title", "description", "display_order", "is_system", "is_staff_group", "badge_token",
28
+ "can_view", "can_view_threads", "can_view_others_threads", "can_search",
29
+ "can_post_threads", "can_post_replies", "can_post_polls", "can_vote_polls", "can_rate_threads",
30
+ "can_edit_own_posts", "can_delete_own_posts", "can_delete_own_threads",
31
+ "can_edit_others_posts", "can_delete_others_posts", "can_soft_delete_posts",
32
+ "can_view_unapproved", "can_view_deleted", "can_approve_content",
33
+ "can_upload_attachments", "can_download_attachments", "can_subscribe",
34
+ "can_view_profiles", "can_view_member_list", "can_use_private_messages",
35
+ "can_use_signature", "can_upload_avatar", "can_report_content",
36
+ "can_view_board_offline", "can_bypass_flood_check", "can_access_mod_cp",
37
+ "is_super_moderator", "is_administrator", "can_access_admin_cp",
38
+ "requires_thread_approval", "requires_post_approval", "requires_approval_on_edit")
39
+ VALUES (3, 'administrators', 'Administrators', 'Full control of the board.', 40, true, true, 'group-admin',
40
+ true, true, true, true,
41
+ true, true, true, true, true,
42
+ true, true, true,
43
+ true, true, true,
44
+ true, true, true,
45
+ true, true, true,
46
+ true, true, true,
47
+ true, true, true,
48
+ true, true, true,
49
+ true, true, true,
50
+ false, false, false);
51
+ --> statement-breakpoint
52
+
53
+ INSERT INTO "usergroups" ("id", "key", "title", "description", "display_order", "is_system", "is_staff_group", "badge_token",
54
+ "can_view", "can_view_threads", "can_view_others_threads", "can_search",
55
+ "can_post_threads", "can_post_replies", "can_post_polls", "can_vote_polls", "can_rate_threads",
56
+ "can_edit_own_posts", "can_delete_own_posts", "can_delete_own_threads",
57
+ "can_edit_others_posts", "can_delete_others_posts", "can_soft_delete_posts",
58
+ "can_view_unapproved", "can_view_deleted", "can_approve_content",
59
+ "can_upload_attachments", "can_download_attachments", "can_subscribe",
60
+ "can_view_profiles", "can_view_member_list", "can_use_private_messages",
61
+ "can_use_signature", "can_upload_avatar", "can_report_content",
62
+ "can_bypass_flood_check", "can_access_mod_cp", "is_super_moderator",
63
+ "requires_thread_approval", "requires_post_approval", "requires_approval_on_edit")
64
+ VALUES (4, 'super_moderators', 'Super Moderators', 'Moderates every forum.', 30, true, true, 'group-supermod',
65
+ true, true, true, true,
66
+ true, true, true, true, true,
67
+ true, true, true,
68
+ true, true, true,
69
+ true, true, true,
70
+ true, true, true,
71
+ true, true, true,
72
+ true, true, true,
73
+ true, true, true,
74
+ false, false, false);
75
+ --> statement-breakpoint
76
+
77
+ INSERT INTO "usergroups" ("id", "key", "title", "description", "display_order", "is_system", "is_staff_group", "badge_token",
78
+ "can_view", "can_view_threads", "can_view_others_threads", "can_search",
79
+ "can_post_threads", "can_post_replies", "can_post_polls", "can_vote_polls", "can_rate_threads",
80
+ "can_edit_own_posts", "can_delete_own_posts", "can_delete_own_threads",
81
+ "can_edit_others_posts", "can_delete_others_posts", "can_soft_delete_posts",
82
+ "can_view_unapproved", "can_view_deleted", "can_approve_content",
83
+ "can_upload_attachments", "can_download_attachments", "can_subscribe",
84
+ "can_view_profiles", "can_view_member_list", "can_use_private_messages",
85
+ "can_use_signature", "can_upload_avatar", "can_report_content",
86
+ "can_bypass_flood_check", "can_access_mod_cp",
87
+ "requires_thread_approval", "requires_post_approval", "requires_approval_on_edit")
88
+ VALUES (5, 'moderators', 'Moderators', 'Moderates the forums they are assigned to.', 20, true, true, 'group-mod',
89
+ true, true, true, true,
90
+ true, true, true, true, true,
91
+ true, true, true,
92
+ true, true, true,
93
+ true, true, true,
94
+ true, true, true,
95
+ true, true, true,
96
+ true, true, true,
97
+ true, true,
98
+ false, false, false);
99
+ --> statement-breakpoint
100
+
101
+ INSERT INTO "usergroups" ("id", "key", "title", "description", "display_order", "is_system", "is_staff_group", "badge_token",
102
+ "can_view", "can_view_threads", "can_view_others_threads", "can_search", "can_view_profiles")
103
+ VALUES (6, 'awaiting_activation', 'Awaiting Activation', 'Registered but not yet activated.', 5, true, false, NULL,
104
+ true, true, true, true, true);
105
+ --> statement-breakpoint
106
+
107
+ INSERT INTO "usergroups" ("id", "key", "title", "description", "display_order", "is_system", "is_staff_group", "badge_token")
108
+ VALUES (7, 'banned', 'Banned', 'Denied access to the board.', 50, true, false, 'group-banned');
109
+ --> statement-breakpoint
110
+
111
+ SELECT setval(pg_get_serial_sequence('usergroups', 'id'), (SELECT MAX("id") FROM "usergroups"));
@@ -0,0 +1,25 @@
1
+ CREATE TABLE "group_promotions" (
2
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
3
+
4
+ "title" text NOT NULL,
5
+ "enabled" boolean NOT NULL DEFAULT true,
6
+ "display_order" integer NOT NULL DEFAULT 0,
7
+
8
+ "min_post_count" integer,
9
+ "min_reputation" integer,
10
+ "min_days_registered" integer,
11
+
12
+ "from_primary_group_id" integer REFERENCES "usergroups"("id") ON DELETE cascade,
13
+ "to_primary_group_id" integer NOT NULL REFERENCES "usergroups"("id") ON DELETE cascade,
14
+
15
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
16
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now()
17
+ );
18
+ --> statement-breakpoint
19
+
20
+ CREATE INDEX "group_promotions_order_idx" ON "group_promotions" ("display_order", "id");
21
+ --> statement-breakpoint
22
+
23
+ CREATE INDEX IF NOT EXISTS "users_promotion_scan_idx"
24
+ ON "users" ("id")
25
+ INCLUDE ("primary_group_id", "post_count", "reputation", "created_at");
@@ -0,0 +1,34 @@
1
+ CREATE TABLE "content_counter_rollups" (
2
+ "post_id" integer PRIMARY KEY REFERENCES "posts"("id") ON DELETE cascade,
3
+ "applied_at" timestamp with time zone NOT NULL DEFAULT now()
4
+ );
5
+ --> statement-breakpoint
6
+
7
+ CREATE TABLE "thread_view_buffer" (
8
+ "thread_id" integer PRIMARY KEY REFERENCES "threads"("id") ON DELETE cascade,
9
+ "pending" integer NOT NULL DEFAULT 0,
10
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now()
11
+ );
12
+ --> statement-breakpoint
13
+
14
+ CREATE TABLE "counter_recount_state" (
15
+ "id" text PRIMARY KEY,
16
+ "phase" text NOT NULL DEFAULT 'threads',
17
+ "cursor" integer NOT NULL DEFAULT 0,
18
+ "passes" integer NOT NULL DEFAULT 0,
19
+ "corrected" integer NOT NULL DEFAULT 0,
20
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now()
21
+ );
22
+ --> statement-breakpoint
23
+
24
+ CREATE INDEX "thread_view_buffer_updated_idx" ON "thread_view_buffer" ("updated_at");
25
+ --> statement-breakpoint
26
+
27
+ CREATE INDEX IF NOT EXISTS "posts_author_visible_idx"
28
+ ON "posts" ("author_user_id")
29
+ WHERE "visibility" = 'visible';
30
+ --> statement-breakpoint
31
+
32
+ CREATE INDEX IF NOT EXISTS "threads_author_visible_idx"
33
+ ON "threads" ("author_user_id")
34
+ WHERE "visibility" = 'visible';
@@ -0,0 +1,7 @@
1
+ ALTER TABLE "posts" ADD COLUMN "message_html" text;
2
+ --> statement-breakpoint
3
+ ALTER TABLE "posts" ADD COLUMN "render_version" smallint DEFAULT 0 NOT NULL;
4
+ --> statement-breakpoint
5
+
6
+ CREATE INDEX IF NOT EXISTS "posts_render_version_idx"
7
+ ON "posts" ("render_version", "id");
@@ -0,0 +1,51 @@
1
+ CREATE TABLE "reports" (
2
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
3
+
4
+ "target_kind" text NOT NULL,
5
+ "target_id" integer NOT NULL,
6
+
7
+ "forum_id" integer REFERENCES "forums"("id") ON DELETE SET NULL,
8
+ "thread_id" integer REFERENCES "threads"("id") ON DELETE SET NULL,
9
+ "target_label" text NOT NULL DEFAULT '',
10
+
11
+ "reporter_user_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
12
+ "reason" text NOT NULL,
13
+
14
+ "status" text NOT NULL DEFAULT 'open',
15
+ "assigned_to_user_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
16
+
17
+ "resolved_by_user_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
18
+ "resolved_at" timestamp with time zone,
19
+
20
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
21
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now()
22
+ );
23
+ --> statement-breakpoint
24
+
25
+ CREATE TABLE "report_events" (
26
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
27
+ "report_id" integer NOT NULL REFERENCES "reports"("id") ON DELETE cascade,
28
+ "actor_user_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
29
+ "kind" text NOT NULL,
30
+ "note" text,
31
+ "created_at" timestamp with time zone NOT NULL DEFAULT now()
32
+ );
33
+ --> statement-breakpoint
34
+
35
+ CREATE INDEX IF NOT EXISTS "reports_open_idx"
36
+ ON "reports" ("forum_id", "created_at")
37
+ WHERE "status" = 'open';
38
+ --> statement-breakpoint
39
+
40
+ CREATE INDEX IF NOT EXISTS "reports_open_global_idx"
41
+ ON "reports" ("created_at")
42
+ WHERE "status" = 'open' AND "forum_id" IS NULL;
43
+ --> statement-breakpoint
44
+
45
+ CREATE UNIQUE INDEX IF NOT EXISTS "reports_one_open_per_reporter_key"
46
+ ON "reports" ("reporter_user_id", "target_kind", "target_id")
47
+ WHERE "status" = 'open' AND "reporter_user_id" IS NOT NULL;
48
+ --> statement-breakpoint
49
+
50
+ CREATE INDEX IF NOT EXISTS "report_events_report_idx"
51
+ ON "report_events" ("report_id", "created_at");
@@ -0,0 +1,91 @@
1
+ CREATE TABLE "warning_types" (
2
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
3
+ "title" text NOT NULL,
4
+ "points" smallint NOT NULL DEFAULT 1,
5
+ "expiry_days" integer,
6
+ "is_active" boolean NOT NULL DEFAULT true,
7
+ "display_order" integer NOT NULL DEFAULT 0,
8
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
9
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now()
10
+ );
11
+ --> statement-breakpoint
12
+
13
+ CREATE TABLE "warning_levels" (
14
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
15
+ "points" smallint NOT NULL,
16
+ "action" text NOT NULL,
17
+ "duration_days" integer,
18
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
19
+ CONSTRAINT "warning_levels_points_unique" UNIQUE ("points")
20
+ );
21
+ --> statement-breakpoint
22
+
23
+ CREATE TABLE "warnings" (
24
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
25
+
26
+ "user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
27
+ "issued_by_user_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
28
+
29
+ "type_id" integer REFERENCES "warning_types"("id") ON DELETE SET NULL,
30
+ "title" text NOT NULL,
31
+ "points" smallint NOT NULL,
32
+ "reason" text NOT NULL DEFAULT '',
33
+
34
+ "post_id" integer REFERENCES "posts"("id") ON DELETE SET NULL,
35
+ "report_id" integer REFERENCES "reports"("id") ON DELETE SET NULL,
36
+
37
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
38
+ "expires_at" timestamp with time zone,
39
+
40
+ "revoked_at" timestamp with time zone,
41
+ "revoked_by_user_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
42
+ "revoke_reason" text
43
+ );
44
+ --> statement-breakpoint
45
+
46
+ CREATE INDEX "warnings_user_idx" ON "warnings" ("user_id", "created_at" DESC, "id" DESC);
47
+ --> statement-breakpoint
48
+
49
+ CREATE INDEX "warnings_live_idx"
50
+ ON "warnings" ("user_id")
51
+ INCLUDE ("points", "expires_at")
52
+ WHERE "revoked_at" IS NULL;
53
+ --> statement-breakpoint
54
+
55
+ CREATE INDEX "warnings_expiry_idx"
56
+ ON "warnings" ("expires_at")
57
+ WHERE "revoked_at" IS NULL AND "expires_at" IS NOT NULL;
58
+ --> statement-breakpoint
59
+
60
+ ALTER TABLE "users" ADD COLUMN "suspended_posting_until" timestamp with time zone;
61
+ --> statement-breakpoint
62
+ ALTER TABLE "users" ADD COLUMN "moderated_posting_until" timestamp with time zone;
63
+ --> statement-breakpoint
64
+
65
+ INSERT INTO "warning_types" ("id", "title", "points", "expiry_days", "display_order") VALUES
66
+ (1, 'Spamming', 2, 90, 10),
67
+ (2, 'Advertising', 3, 180, 20),
68
+ (3, 'Offensive language', 2, 90, 30),
69
+ (4, 'Trolling or flaming', 2, 90, 40),
70
+ (5, 'Posting in the wrong forum', 1, 30, 50),
71
+ (6, 'Ignoring a moderator', 3, 180, 60);
72
+ --> statement-breakpoint
73
+
74
+ SELECT setval(
75
+ pg_get_serial_sequence('warning_types', 'id'),
76
+ (SELECT max(id) FROM "warning_types")
77
+ );
78
+ --> statement-breakpoint
79
+
80
+ INSERT INTO "warning_levels" ("points", "action", "duration_days") VALUES
81
+ (4, 'moderate_posting', 30),
82
+ (7, 'suspend_posting', 14),
83
+ (10, 'ban', NULL);
84
+ --> statement-breakpoint
85
+
86
+ ALTER TABLE "usergroups"
87
+ ADD COLUMN "can_warn_users" boolean NOT NULL DEFAULT false;
88
+ --> statement-breakpoint
89
+
90
+ UPDATE "usergroups" SET "can_warn_users" = true
91
+ WHERE "key" IN ('administrators', 'super_moderators', 'moderators');
@@ -0,0 +1,44 @@
1
+ CREATE TABLE "notifications" (
2
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
3
+
4
+ "user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
5
+
6
+ "kind" text NOT NULL,
7
+
8
+ "data" jsonb NOT NULL DEFAULT '{}'::jsonb,
9
+
10
+ "href" text,
11
+
12
+ "dedupe_key" text,
13
+ "occurrences" integer NOT NULL DEFAULT 1,
14
+
15
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
16
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now(),
17
+
18
+ "read_at" timestamp with time zone,
19
+
20
+ "email_sent_at" timestamp with time zone
21
+ );
22
+ --> statement-breakpoint
23
+
24
+ CREATE INDEX "notifications_user_idx"
25
+ ON "notifications" ("user_id", "created_at" DESC NULLS LAST, "id" DESC NULLS LAST);
26
+ --> statement-breakpoint
27
+
28
+ CREATE INDEX "notifications_unread_idx"
29
+ ON "notifications" ("user_id")
30
+ WHERE "read_at" IS NULL;
31
+ --> statement-breakpoint
32
+
33
+ CREATE UNIQUE INDEX "notifications_dedupe_idx"
34
+ ON "notifications" ("user_id", "dedupe_key")
35
+ WHERE "read_at" IS NULL AND "dedupe_key" IS NOT NULL;
36
+ --> statement-breakpoint
37
+
38
+ CREATE TABLE "notification_preferences" (
39
+ "user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
40
+ "kind" text NOT NULL,
41
+ "email" boolean NOT NULL,
42
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now(),
43
+ CONSTRAINT "notification_preferences_pkey" PRIMARY KEY ("user_id", "kind")
44
+ );
@@ -0,0 +1,48 @@
1
+ ALTER TABLE "thread_subscriptions" RENAME COLUMN "notify_via" TO "mode";
2
+ --> statement-breakpoint
3
+
4
+ UPDATE "thread_subscriptions" SET "mode" = 'instant' WHERE "mode" <> 'none';
5
+ --> statement-breakpoint
6
+
7
+ ALTER TABLE "thread_subscriptions" ALTER COLUMN "mode" SET DEFAULT 'instant';
8
+ --> statement-breakpoint
9
+
10
+ ALTER TABLE "thread_subscriptions"
11
+ ADD COLUMN "last_notified_post_id" integer DEFAULT 0 NOT NULL;
12
+ --> statement-breakpoint
13
+
14
+ CREATE INDEX "thread_subscriptions_user_idx"
15
+ ON "thread_subscriptions" ("user_id", "created_at" DESC NULLS LAST);
16
+ --> statement-breakpoint
17
+
18
+ CREATE INDEX "thread_subscriptions_mode_idx"
19
+ ON "thread_subscriptions" ("mode", "user_id");
20
+ --> statement-breakpoint
21
+
22
+ ALTER TABLE "forum_subscriptions" RENAME COLUMN "notify_via" TO "mode";
23
+ --> statement-breakpoint
24
+
25
+ UPDATE "forum_subscriptions" SET "mode" = 'instant' WHERE "mode" <> 'none';
26
+ --> statement-breakpoint
27
+
28
+ ALTER TABLE "forum_subscriptions" ALTER COLUMN "mode" SET DEFAULT 'instant';
29
+ --> statement-breakpoint
30
+
31
+ ALTER TABLE "forum_subscriptions"
32
+ ADD COLUMN "last_notified_post_id" integer DEFAULT 0 NOT NULL;
33
+ --> statement-breakpoint
34
+
35
+ CREATE INDEX "forum_subscriptions_user_idx"
36
+ ON "forum_subscriptions" ("user_id", "created_at" DESC NULLS LAST);
37
+ --> statement-breakpoint
38
+
39
+ CREATE INDEX "forum_subscriptions_mode_idx"
40
+ ON "forum_subscriptions" ("mode", "user_id");
41
+ --> statement-breakpoint
42
+
43
+ CREATE TABLE "digest_runs" (
44
+ "user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
45
+ "cadence" text NOT NULL,
46
+ "last_sent_at" timestamp with time zone DEFAULT now() NOT NULL,
47
+ CONSTRAINT "digest_runs_pkey" PRIMARY KEY ("user_id", "cadence")
48
+ );
@@ -0,0 +1,13 @@
1
+ ALTER TABLE "users" ADD COLUMN "timezone" text DEFAULT 'UTC' NOT NULL;
2
+ --> statement-breakpoint
3
+
4
+ ALTER TABLE "users" ADD COLUMN "posts_per_page" smallint;
5
+ --> statement-breakpoint
6
+ ALTER TABLE "users" ADD COLUMN "threads_per_page" smallint;
7
+ --> statement-breakpoint
8
+
9
+ ALTER TABLE "users" ADD COLUMN "location" text;
10
+ --> statement-breakpoint
11
+ ALTER TABLE "users" ADD COLUMN "website" text;
12
+ --> statement-breakpoint
13
+ ALTER TABLE "users" ADD COLUMN "bio" text;
@@ -0,0 +1,53 @@
1
+ CREATE TABLE "profile_fields" (
2
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
3
+
4
+ "key" text NOT NULL,
5
+ "label" text NOT NULL,
6
+ "description" text,
7
+
8
+ "type" text NOT NULL DEFAULT 'text',
9
+
10
+ "options" jsonb NOT NULL DEFAULT '[]'::jsonb,
11
+
12
+ "max_length" integer,
13
+
14
+ "display_order" integer NOT NULL DEFAULT 0,
15
+ "is_active" boolean NOT NULL DEFAULT true,
16
+
17
+ "required_at_registration" boolean NOT NULL DEFAULT false,
18
+
19
+ "default_visible" boolean NOT NULL DEFAULT true,
20
+ "default_editable" boolean NOT NULL DEFAULT true,
21
+
22
+ "show_in_postbit" boolean NOT NULL DEFAULT false,
23
+
24
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
25
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now(),
26
+
27
+ CONSTRAINT "profile_fields_key_unique" UNIQUE ("key")
28
+ );
29
+ --> statement-breakpoint
30
+
31
+ CREATE INDEX "profile_fields_order_idx"
32
+ ON "profile_fields" ("display_order", "id");
33
+ --> statement-breakpoint
34
+
35
+ CREATE TABLE "profile_field_groups" (
36
+ "field_id" integer NOT NULL REFERENCES "profile_fields"("id") ON DELETE cascade,
37
+ "group_id" integer NOT NULL REFERENCES "usergroups"("id") ON DELETE cascade,
38
+ "can_view" boolean,
39
+ "can_edit" boolean,
40
+ CONSTRAINT "profile_field_groups_pkey" PRIMARY KEY ("field_id", "group_id")
41
+ );
42
+ --> statement-breakpoint
43
+
44
+ CREATE TABLE "profile_field_values" (
45
+ "user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
46
+ "field_id" integer NOT NULL REFERENCES "profile_fields"("id") ON DELETE cascade,
47
+ "value" text NOT NULL DEFAULT '',
48
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now(),
49
+ CONSTRAINT "profile_field_values_pkey" PRIMARY KEY ("user_id", "field_id")
50
+ );
51
+ --> statement-breakpoint
52
+
53
+ CREATE INDEX "profile_field_values_user_idx" ON "profile_field_values" ("user_id");
@@ -0,0 +1,63 @@
1
+ CREATE TABLE "private_messages" (
2
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
3
+
4
+ "author_user_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
5
+ "author_username" text NOT NULL DEFAULT '',
6
+
7
+ "subject" text NOT NULL,
8
+
9
+ "message" text NOT NULL,
10
+ "message_html" text,
11
+ "render_version" smallint NOT NULL DEFAULT 0,
12
+
13
+ "reply_to_id" integer REFERENCES "private_messages"("id") ON DELETE SET NULL,
14
+
15
+ "receipt_requested" boolean NOT NULL DEFAULT false,
16
+
17
+ "sent_at" timestamp with time zone NOT NULL DEFAULT now()
18
+ );
19
+ --> statement-breakpoint
20
+
21
+ CREATE TABLE "private_message_copies" (
22
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
23
+ "message_id" integer NOT NULL REFERENCES "private_messages"("id") ON DELETE cascade,
24
+ "owner_user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
25
+
26
+ "folder" text NOT NULL DEFAULT 'inbox',
27
+
28
+ "role" text NOT NULL DEFAULT 'to',
29
+
30
+ "read_at" timestamp with time zone,
31
+
32
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
33
+
34
+ CONSTRAINT "private_message_copies_unique" UNIQUE ("message_id", "owner_user_id")
35
+ );
36
+ --> statement-breakpoint
37
+
38
+ CREATE INDEX "private_message_copies_folder_idx"
39
+ ON "private_message_copies" ("owner_user_id", "folder", "id" DESC);
40
+ --> statement-breakpoint
41
+
42
+ CREATE INDEX "private_message_copies_unread_idx"
43
+ ON "private_message_copies" ("owner_user_id")
44
+ WHERE "read_at" IS NULL AND "folder" = 'inbox';
45
+ --> statement-breakpoint
46
+
47
+ CREATE INDEX "private_message_copies_message_idx"
48
+ ON "private_message_copies" ("message_id");
49
+ --> statement-breakpoint
50
+
51
+ CREATE INDEX "private_messages_render_version_idx"
52
+ ON "private_messages" ("render_version", "id");
53
+ --> statement-breakpoint
54
+
55
+ ALTER TABLE "usergroups" ADD COLUMN "private_message_quota" integer DEFAULT 0 NOT NULL;
56
+ --> statement-breakpoint
57
+
58
+ UPDATE "usergroups" SET "private_message_quota" = 100 WHERE "key" = 'registered';
59
+ --> statement-breakpoint
60
+ UPDATE "usergroups" SET "private_message_quota" = 100 WHERE "key" = 'awaiting_activation';
61
+ --> statement-breakpoint
62
+ UPDATE "usergroups" SET "private_message_quota" = 0
63
+ WHERE "key" IN ('administrators', 'super_moderators', 'moderators');
@@ -0,0 +1,18 @@
1
+ CREATE TABLE "user_relations" (
2
+ "user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
3
+ "other_user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
4
+
5
+ "kind" text NOT NULL,
6
+
7
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
8
+
9
+ CONSTRAINT "user_relations_pkey" PRIMARY KEY ("user_id", "other_user_id")
10
+ );
11
+ --> statement-breakpoint
12
+
13
+ CREATE INDEX "user_relations_kind_idx"
14
+ ON "user_relations" ("user_id", "kind", "other_user_id");
15
+ --> statement-breakpoint
16
+
17
+ CREATE INDEX "user_relations_reverse_idx"
18
+ ON "user_relations" ("other_user_id", "kind");
@@ -0,0 +1,45 @@
1
+ CREATE TABLE "reputation" (
2
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
3
+
4
+ "user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
5
+
6
+ "given_by_user_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
7
+
8
+ "post_id" integer REFERENCES "posts"("id") ON DELETE cascade,
9
+
10
+ "points" smallint NOT NULL DEFAULT 1,
11
+
12
+ "comment" text NOT NULL DEFAULT '',
13
+
14
+ "created_at" timestamp with time zone NOT NULL DEFAULT now(),
15
+ "updated_at" timestamp with time zone NOT NULL DEFAULT now()
16
+ );
17
+ --> statement-breakpoint
18
+
19
+ CREATE UNIQUE INDEX "reputation_profile_unique"
20
+ ON "reputation" ("given_by_user_id", "user_id")
21
+ WHERE "post_id" IS NULL;
22
+ --> statement-breakpoint
23
+
24
+ CREATE UNIQUE INDEX "reputation_post_unique"
25
+ ON "reputation" ("given_by_user_id", "post_id")
26
+ WHERE "post_id" IS NOT NULL;
27
+ --> statement-breakpoint
28
+
29
+ CREATE INDEX "reputation_user_idx" ON "reputation" ("user_id", "id" DESC);
30
+ --> statement-breakpoint
31
+
32
+ CREATE INDEX "reputation_given_idx"
33
+ ON "reputation" ("given_by_user_id", "created_at" DESC);
34
+ --> statement-breakpoint
35
+
36
+ ALTER TABLE "usergroups" ADD COLUMN "can_give_reputation" boolean DEFAULT false NOT NULL;
37
+ --> statement-breakpoint
38
+ ALTER TABLE "usergroups" ADD COLUMN "max_reputation_per_day" integer DEFAULT 0 NOT NULL;
39
+ --> statement-breakpoint
40
+
41
+ UPDATE "usergroups" SET "can_give_reputation" = true, "max_reputation_per_day" = 10
42
+ WHERE "key" = 'registered';
43
+ --> statement-breakpoint
44
+ UPDATE "usergroups" SET "can_give_reputation" = true, "max_reputation_per_day" = 0
45
+ WHERE "key" IN ('administrators', 'super_moderators', 'moderators');
@@ -0,0 +1,16 @@
1
+ ALTER TABLE "users" ADD COLUMN "signature" text NOT NULL DEFAULT '';
2
+ --> statement-breakpoint
3
+ ALTER TABLE "users" ADD COLUMN "signature_html" text;
4
+ --> statement-breakpoint
5
+ ALTER TABLE "users" ADD COLUMN "signature_render_version" smallint NOT NULL DEFAULT 0;
6
+ --> statement-breakpoint
7
+
8
+ ALTER TABLE "users" ADD COLUMN "signature_locked" boolean NOT NULL DEFAULT false;
9
+ --> statement-breakpoint
10
+
11
+ ALTER TABLE "users" ADD COLUMN "signature_locked_reason" text;
12
+ --> statement-breakpoint
13
+
14
+ CREATE INDEX "users_signature_render_version_idx"
15
+ ON "users" ("signature_render_version", "id")
16
+ WHERE "signature" <> '';
@@ -0,0 +1,24 @@
1
+ CREATE TABLE "admin_sessions" (
2
+ "id" integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
3
+ "user_id" integer NOT NULL REFERENCES "users"("id") ON DELETE cascade,
4
+
5
+ "token_hash" text NOT NULL,
6
+
7
+ "ip_prefix" text,
8
+
9
+ "authenticated_at" timestamp with time zone NOT NULL DEFAULT now(),
10
+ "last_seen_at" timestamp with time zone NOT NULL DEFAULT now(),
11
+
12
+ "expires_at" timestamp with time zone NOT NULL,
13
+ "revoked_at" timestamp with time zone,
14
+ "created_at" timestamp with time zone NOT NULL DEFAULT now()
15
+ );
16
+ --> statement-breakpoint
17
+
18
+ CREATE UNIQUE INDEX "admin_sessions_token_hash_key"
19
+ ON "admin_sessions" ("token_hash");
20
+ --> statement-breakpoint
21
+
22
+ CREATE INDEX "admin_sessions_user_idx" ON "admin_sessions" ("user_id");
23
+ --> statement-breakpoint
24
+ CREATE INDEX "admin_sessions_expiry_idx" ON "admin_sessions" ("expires_at");