Skip to content

Commit 323d595

Browse files
committed
chore(database): update db schema
1 parent 9593b92 commit 323d595

File tree

5 files changed

+75
-131
lines changed

5 files changed

+75
-131
lines changed

bun.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@typescript-eslint/eslint-plugin": "8.11.0",
1717
"@typescript-eslint/parser": "8.11.0",
1818
"concurrently": "^9.1.2",
19+
"cross-env": "^7.0.3",
1920
"drizzle-kit": "^0.31.4",
2021
"eslint": "^8.57.0",
2122
"eslint-config-prettier": "9.1.0",
@@ -222,6 +223,8 @@
222223

223224
"cron": ["cron@4.3.0", "", { "dependencies": { "@types/luxon": "~3.6.0", "luxon": "~3.6.0" } }, "sha512-ciiYNLfSlF9MrDqnbMdRWFiA6oizSF7kA1osPP9lRzNu0Uu+AWog1UKy7SkckiDY2irrNjeO6qLyKnXC8oxmrw=="],
224225

226+
"cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="],
227+
225228
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
226229

227230
"data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="],

drizzle.config.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import { defineConfig } from "drizzle-kit";
22

3-
import { config } from "./src/config";
3+
const databaseUrl =
4+
process.env.NODE_ENV === "development"
5+
? process.env.POSTGRES_DEV_URL
6+
: process.env.POSTGRES_URL;
47

5-
console.log("Using database URL:", config.databaseUrl);
8+
console.log("Using database URL:", databaseUrl);
69

710
export default defineConfig({
811
out: "./drizzle",
912
schema: "./src/db/schema.ts",
1013
dialect: "postgresql",
1114
dbCredentials: {
12-
url: config.databaseUrl!,
15+
url: databaseUrl!,
1316
},
1417
});

new.dbml

Lines changed: 0 additions & 98 deletions
This file was deleted.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"@typescript-eslint/eslint-plugin": "8.11.0",
1010
"@typescript-eslint/parser": "8.11.0",
1111
"concurrently": "^9.1.2",
12+
"cross-env": "^7.0.3",
1213
"drizzle-kit": "^0.31.4",
1314
"eslint": "^8.57.0",
1415
"eslint-config-prettier": "9.1.0",
@@ -22,6 +23,8 @@
2223
},
2324
"scripts": {
2425
"db:generate": "bun drizzle-kit generate",
26+
"db:push:dev": "cross-env NODE_ENV=development bun drizzle-kit push",
27+
"db:push:prod": "bun drizzle-kit push",
2528
"dev": "concurrently --names \"WEB,API,BOT\" --prefix-colors \"blue,green,magenta\" \"cd web && bun dev\" \"cd api && cargo watch -x \\\"run -- --dev\\\"\" \"bun --watch . --dev\"",
2629
"dev:bot": "bun --watch . --dev",
2730
"test:jetstream": "bun --watch src/utils/bluesky/jetstream.ts",

src/db/schema.ts

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
// To make it easier to work with the database, disable prettier for this file
22
/* eslint-disable prettier/prettier */
3-
import { pgTable, serial, text, boolean, integer, timestamp, date } from "drizzle-orm/pg-core";
3+
import { pgTable, serial, text, boolean, timestamp, decimal, unique, index, pgEnum, jsonb, integer } from "drizzle-orm/pg-core";
44

55
export const dbDiscordTable = pgTable("discord", {
66
guildId: text("guild_id").primaryKey(),
77
allowedPublicSharing: boolean("allowed_public_sharing").notNull().default(false),
88
feedrUpdatesChannelId: text("feedr_updates_channel_id"),
9-
9+
isInServer: boolean("is_in_server").notNull().default(true),
1010
});
1111

1212
export const dbBlueskyTable = pgTable("bluesky", {
1313
blueskyUserId: text("bluesky_user_id").primaryKey(),
1414
latestPostId: text("latest_post_id"),
1515
latestReplyId: text("latest_reply_id"),
16-
});
16+
}, (table) => [
17+
index("idx_bluesky_user_id").on(table.blueskyUserId),
18+
]);
1719

1820
export const dbYouTubeTable = pgTable("youtube", {
1921
youtubeChannelId: text("youtube_channel_id").primaryKey(),
@@ -23,13 +25,18 @@ export const dbYouTubeTable = pgTable("youtube", {
2325
latestShortIdUpdated: timestamp("latest_short_id_updated"),
2426
latestStreamId: text("latest_stream_id"),
2527
latestStreamIdUpdated: timestamp("latest_stream_id_updated"),
26-
youtubeChannelIsLive: boolean("youtube_channel_is_live"),
27-
});
28+
youtubeChannelIsLive: boolean("youtube_channel_is_live").notNull().default(false),
29+
youtubeLiveIds: text("youtube_live_ids").array().notNull().default([]),
30+
}, (table) => [
31+
index("idx_youtube_channel_id").on(table.youtubeChannelId),
32+
]);
2833

2934
export const dbTwitchTable = pgTable("twitch", {
3035
twitchChannelId: text("twitch_channel_id").primaryKey(),
31-
twitchChannelIsLive: boolean("twitch_channel_is_live").notNull(),
32-
});
36+
twitchChannelIsLive: boolean("twitch_channel_is_live").notNull().default(false),
37+
}, (table) => [
38+
index("idx_twitch_channel_id").on(table.twitchChannelId),
39+
]);
3340

3441
export const dbGuildBlueskySubscriptionsTable = pgTable("guild_bluesky_subscriptions", {
3542
id: serial("id").primaryKey(),
@@ -39,7 +46,9 @@ export const dbGuildBlueskySubscriptionsTable = pgTable("guild_bluesky_subscript
3946
notificationRoleId: text("notification_role_id"),
4047
isDm: boolean("is_dm").notNull().default(false),
4148
checkForReplies: boolean("check_for_replies").notNull().default(false),
42-
});
49+
}, (table) => [
50+
unique("guild_bluesky_subscription").on(table.guildId, table.blueskyUserId),
51+
]);
4352

4453
export const dbGuildYouTubeSubscriptionsTable = pgTable("guild_youtube_subscriptions", {
4554
id: serial("id").primaryKey(),
@@ -51,7 +60,9 @@ export const dbGuildYouTubeSubscriptionsTable = pgTable("guild_youtube_subscript
5160
trackVideos: boolean("track_videos").notNull().default(false),
5261
trackShorts: boolean("track_shorts").notNull().default(false),
5362
trackStreams: boolean("track_streams").notNull().default(false),
54-
});
63+
}, (table) => [
64+
unique("guild_youtube_subscription").on(table.guildId, table.youtubeChannelId),
65+
]);
5566

5667
export const dbGuildTwitchSubscriptionsTable = pgTable("guild_twitch_subscriptions", {
5768
id: serial("id").primaryKey(),
@@ -60,42 +71,64 @@ export const dbGuildTwitchSubscriptionsTable = pgTable("guild_twitch_subscriptio
6071
notificationChannelId: text("notification_channel_id").notNull(),
6172
notificationRoleId: text("notification_role_id"),
6273
isDm: boolean("is_dm").notNull().default(false),
63-
});
74+
latestMessageId: text("latest_message_id"),
75+
}, (table) => [
76+
unique("guild_twitch_subscription").on(table.guildId, table.twitchChannelId),
77+
]);
6478

6579
export const dbBotInfoTable = pgTable("bot_info", {
80+
timestamp: timestamp("timestamp").notNull().defaultNow(),
6681
guildsTotal: integer("guilds_total").notNull().default(0),
6782
channelsTracked: integer("channels_tracked").notNull().default(0),
6883
totalMembers: integer("total_members").notNull().default(0),
69-
time: timestamp("time").notNull().defaultNow(),
84+
notificationsSent: integer("notifications_sent").notNull().default(0),
7085
});
7186

7287
export const dbBotInfoNotificationsTable = pgTable("bot_info_notifications", {
73-
date: date("date").notNull(),
74-
totalYouTube: integer("total_youtube").notNull().default(0),
75-
totalTwitch: integer("total_twitch").notNull().default(0),
88+
timestamp: timestamp("timestamp").notNull(),
89+
service: text("service").notNull(),
90+
delay: decimal("delay", { precision: 10, scale: 2 }).notNull().default("0.0"),
7691
});
7792

78-
export const dbBotInfoNotificationsTimingsTable = pgTable("bot_info_notifications_timings", {
79-
time: timestamp("time").notNull(),
80-
channelId: text("channel_id").notNull().references(() => dbYouTubeTable.youtubeChannelId),
81-
timeMs: integer("time_ms").notNull().default(0),
82-
});
93+
// Deprecated, but kept for reference
94+
// export const dbBotInfoNotificationsTimingsTable = pgTable("bot_info_notifications_timings", {
95+
// time: timestamp("time").notNull(),
96+
// channelId: text("channel_id").notNull().references(() => dbYouTubeTable.youtubeChannelId),
97+
// timeMs: integer("time_ms").notNull().default(0),
98+
// });
8399

84-
export const dbBotInfoTopChannelsTable = pgTable("bot_info_top_channels", {
85-
youtubeChannelId: text("youtube_channel_id").primaryKey().references(() => dbYouTubeTable.youtubeChannelId),
86-
guildsTracking: integer("guilds_tracking").notNull().default(0),
87-
});
100+
// Once again, can be aggregated in the API
101+
// export const dbBotInfoTopChannelsTable = pgTable("bot_info_top_channels", {
102+
// youtubeChannelId: text("youtube_channel_id").primaryKey().references(() => dbYouTubeTable.youtubeChannelId),
103+
// guildsTracking: integer("guilds_tracking").notNull().default(0),
104+
// });
88105

89-
export const dbBotInfoTopGuildsTable = pgTable("bot_info_top_guilds", {
90-
guildId: text("guild_id").primaryKey().references(() => dbDiscordTable.guildId),
91-
members: integer("members").notNull().default(0),
92-
});
106+
// Once again, can be aggregated in the API
107+
// export const dbBotInfoTopGuildsTable = pgTable("bot_info_top_guilds", {
108+
// guildId: text("guild_id").primaryKey().references(() => dbDiscordTable.guildId),
109+
// members: integer("members").notNull().default(0),
110+
// });
111+
112+
export const dbAuditLogsEventTypeEnum = pgEnum("event_type", [
113+
"subscription_created",
114+
"subscription_deleted",
115+
"notification_sent",
116+
"guild_joined",
117+
"guild_left",
118+
]);
119+
120+
export const dbAuditLogsSuccessTypeEnum = pgEnum("audit_log_success", [
121+
"success",
122+
"failure",
123+
"info",
124+
"warning",
125+
]);
93126

94127
export const dbAuditLogsTable = pgTable("audit_logs", {
95128
id: serial("id").primaryKey(),
96-
eventType: text("event_type").notNull(),
97129
guildId: text("guild_id").notNull().references(() => dbDiscordTable.guildId),
98-
relatedId: text("related_id").notNull(),
99-
note: text("note"),
130+
eventType: dbAuditLogsEventTypeEnum().notNull(),
131+
successType: dbAuditLogsSuccessTypeEnum().notNull(),
132+
data: jsonb("data"),
100133
occurredAt: timestamp("occurred_at").defaultNow(),
101134
});

0 commit comments

Comments
 (0)