Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
73540f0
feat: drizzle database implementation
Maximus7474 Jul 24, 2026
da4bca0
feat(utils): config loader
Maximus7474 Jul 24, 2026
6e34c5d
fix(db/schema): missing fk references from warns & bans on issuer
Maximus7474 Jul 24, 2026
d829590
Merge branch 'feat/db-connector' into feat/moderation-tools
Maximus7474 Jul 24, 2026
2bd050c
feat: missing logic to handle commands
Maximus7474 Jul 24, 2026
4bbc68e
feat(commands): ban command
Maximus7474 Jul 24, 2026
f5a3100
feat(db): added kicks table
Maximus7474 Jul 24, 2026
7a9d21a
feat(commands): kick command
Maximus7474 Jul 24, 2026
328a0ed
feat(commands): warn command
Maximus7474 Jul 24, 2026
a729dac
fix(db/relations): missing relation user -> kicks
Maximus7474 Jul 24, 2026
64b2f14
fix(db/relations): ambigious relations
Maximus7474 Jul 24, 2026
d2d41dd
fix(db/schema): using CURRENT_TIMESTAMP instead of unixepoch
Maximus7474 Jul 24, 2026
e75f461
Merge branch 'feat/db-connector' into feat/moderation-tools
Maximus7474 Jul 24, 2026
64dd4b1
feat(db): seeding database for development & testing
Maximus7474 Jul 24, 2026
dbb113c
fix(db/schema): using CURRENT_TIMESTAMP instead of unixepoch
Maximus7474 Jul 24, 2026
6d5eda3
feat(commands): view moderation history command
Maximus7474 Jul 24, 2026
ce4f3e2
chore: prettier cleanup
Maximus7474 Jul 24, 2026
19f2a9b
refactor(utils/checks): allow handling both User & GuildUser to avoid
Maximus7474 Jul 24, 2026
a337a42
chore(config): added member to roles
Maximus7474 Jul 24, 2026
f0645ca
feat(events): join event to add default roles & log user to database
Maximus7474 Jul 24, 2026
db35d49
feat(db): revokedAt & By fields
Maximus7474 Jul 25, 2026
374970d
chore(drizzle): squash migrations
Maximus7474 Jul 25, 2026
be7ed15
fix(db/schema): incorrect column name for revokedBy
Maximus7474 Jul 25, 2026
6459400
feat(commands): revoke action command
Maximus7474 Jul 25, 2026
ecf3e11
refactor(command/history): include action id & and revoked details
Maximus7474 Jul 25, 2026
c38b61b
tweak(command/history): on collector close add footer
Maximus7474 Jul 25, 2026
75ee7d6
feat(utils/logger): log to discord method
Maximus7474 Jul 25, 2026
fa4cc71
chore(commands): implement log to discord
Maximus7474 Jul 25, 2026
7f25ee8
chore(config): added join/leave channel log
Maximus7474 Jul 25, 2026
8d4dadf
fix(utils/logger): fix undefined var
Maximus7474 Jul 25, 2026
c55b07c
feat(events): join & leave logs
Maximus7474 Jul 25, 2026
2e57a83
fix(commands): various typos, missing checks (i.e. in guild / already
Maximus7474 Jul 25, 2026
b9d7fb3
feat(commands): docs command
Maximus7474 Jul 25, 2026
8ae82e7
feat(commands): release zip command
Maximus7474 Jul 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ TOKEN=
CLIENT_ID=
GUILD_ID=
NODE_ENV=
DB_FILE_NAME="data.db"
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ dist/
!.env.example
.vscode/
.idea/
.DS_Store
.DS_Store
data.db
config.json
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,17 @@ Official Discord Bot for <a href="https://overextended.dev">Overextended</a>.
## Disclaimer

This bot is still in development and is intended as a future replacement for the current bot used in the Overextended Discord. If you plan to use it for your own Discord, please review the code to tailor it to your needs. **We will not provide support for this bot**; the code is shared for transparency and because most Overextended projects are open-source.

## Database Management

We use **Drizzle Kit** to manage schema migrations and inspect the database. All CLI interactions run through `nubx drizzle-kit ...`

| Command | Action |
| --- | --- |
| `nubx drizzle-kit generate` | Creates a new SQL migration based on schema changes. |
| `nubx drizzle-kit migrate` | Executes pending SQL migrations against the database. |
| `nubx drizzle-kit push` | Directly syncs schema changes without migration files. |
| `nubx drizzle-kit studio` | Opens a web-based UI to view and edit database rows. |

> [!WARNING]
> `push` directly alters your database schema without generating version-controlled SQL migration files. Use this primarily in local development.
12 changes: 12 additions & 0 deletions config.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"roles": {
"moderation": ["role_id", "role_id"],
"blacklisted": ["role_id"],
"member": ["role_id"]
},
"channels": {
"actionlog": "channel_id",
"messagelog": "channel_id",
"joinleavelog": "channel_id"
}
}
11 changes: 11 additions & 0 deletions drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineConfig } from "drizzle-kit";
import { env } from "./src/env"

export default defineConfig({
dialect: "sqlite",
out: './drizzle',
schema: "./src/db/schema.ts",
dbCredentials: {
url: env.DB_FILE_NAME ? `file:${env.DB_FILE_NAME}` : 'file:data.db',
}
});
50 changes: 50 additions & 0 deletions drizzle/0000_productive_guardian.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
CREATE TABLE `bans` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`reason` text NOT NULL,
`issuer_id` text(20) NOT NULL,
`target_id` text(20) NOT NULL,
`issued_at` integer DEFAULT (unixepoch()) NOT NULL,
`revoked_at` integer,
`revoked_by` text(20),
FOREIGN KEY (`issuer_id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE restrict,
FOREIGN KEY (`target_id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE restrict,
FOREIGN KEY (`revoked_by`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE restrict
);
--> statement-breakpoint
CREATE INDEX `idx_bans_targetid` ON `bans` (`target_id`);--> statement-breakpoint
CREATE INDEX `idx_bans_issuerid` ON `bans` (`issuer_id`);--> statement-breakpoint
CREATE TABLE `kicks` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`reason` text NOT NULL,
`issuer_id` text(20) NOT NULL,
`target_id` text(20) NOT NULL,
`issued_at` integer DEFAULT (unixepoch()) NOT NULL,
`revoked_at` integer,
`revoked_by` text(20),
FOREIGN KEY (`issuer_id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE restrict,
FOREIGN KEY (`target_id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE restrict,
FOREIGN KEY (`revoked_by`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE restrict
);
--> statement-breakpoint
CREATE INDEX `idx_kicks_targetid` ON `kicks` (`target_id`);--> statement-breakpoint
CREATE INDEX `idx_kicks_issuerid` ON `kicks` (`issuer_id`);--> statement-breakpoint
CREATE TABLE `users` (
`id` text(20) PRIMARY KEY NOT NULL,
`joined_at` integer DEFAULT CURRENT_TIMESTAMP NOT NULL
);
--> statement-breakpoint
CREATE TABLE `warns` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`reason` text NOT NULL,
`issuer_id` text(20) NOT NULL,
`target_id` text(20) NOT NULL,
`issued_at` integer DEFAULT (unixepoch()) NOT NULL,
`revoked_at` integer,
`revoked_by` text(20),
FOREIGN KEY (`issuer_id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE restrict,
FOREIGN KEY (`target_id`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE restrict,
FOREIGN KEY (`revoked_by`) REFERENCES `users`(`id`) ON UPDATE cascade ON DELETE restrict
);
--> statement-breakpoint
CREATE INDEX `idx_warns_targetid` ON `warns` (`target_id`);--> statement-breakpoint
CREATE INDEX `idx_warns_issuerid` ON `warns` (`issuer_id`);
Loading