init codebase
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
{:server {:host "0.0.0.0" :port 3001}
|
||||
:db {:host "localhost" :port 5432 :dbname "ajet_chat"
|
||||
:user "ajet" :password "ajet_dev" :pool-size 10
|
||||
:migrations {:enabled true :location "migrations"}}
|
||||
:nats {:url "nats://localhost:4222"
|
||||
:stream-name "ajet-events"
|
||||
:publish-timeout-ms 5000}
|
||||
:minio {:endpoint "http://localhost:9000"
|
||||
:access-key "minioadmin" :secret-key "minioadmin"
|
||||
:bucket "ajet-chat"}
|
||||
:limits {:max-message-length 4000
|
||||
:max-upload-size 10485760
|
||||
:edit-window-minutes 60
|
||||
:default-page-size 50
|
||||
:max-page-size 100}
|
||||
|
||||
:profiles
|
||||
{:test {:db {:host "localhost" :port 5433 :dbname "ajet_chat_test"
|
||||
:password "ajet_test"}
|
||||
:nats {:url "nats://localhost:4223"}
|
||||
:minio {:endpoint "http://localhost:9002"}}
|
||||
:prod {:db {:pool-size 20}
|
||||
:nats {:publish-timeout-ms 10000}}}}
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS users;
|
||||
@@ -0,0 +1,10 @@
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
username text UNIQUE NOT NULL,
|
||||
display_name text,
|
||||
email text,
|
||||
avatar_url text,
|
||||
status_text text,
|
||||
last_seen_at timestamptz,
|
||||
created_at timestamptz DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS oauth_accounts;
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE IF NOT EXISTS oauth_accounts (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
provider text NOT NULL,
|
||||
provider_user_id text NOT NULL,
|
||||
provider_username text,
|
||||
created_at timestamptz DEFAULT now(),
|
||||
UNIQUE (provider, provider_user_id)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS communities;
|
||||
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE IF NOT EXISTS communities (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name text NOT NULL,
|
||||
slug text UNIQUE NOT NULL,
|
||||
created_at timestamptz DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS community_members;
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE IF NOT EXISTS community_members (
|
||||
community_id uuid NOT NULL REFERENCES communities (id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
role text NOT NULL CHECK (role IN ('owner', 'admin', 'member')),
|
||||
nickname text,
|
||||
avatar_url text,
|
||||
joined_at timestamptz DEFAULT now(),
|
||||
PRIMARY KEY (community_id, user_id)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS channel_categories;
|
||||
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE IF NOT EXISTS channel_categories (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
community_id uuid NOT NULL REFERENCES communities (id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
position int NOT NULL DEFAULT 0
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS channels;
|
||||
@@ -0,0 +1,10 @@
|
||||
CREATE TABLE IF NOT EXISTS channels (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
community_id uuid REFERENCES communities (id) ON DELETE CASCADE,
|
||||
category_id uuid REFERENCES channel_categories (id) ON DELETE SET NULL,
|
||||
name text NOT NULL,
|
||||
type text NOT NULL CHECK (type IN ('text', 'dm', 'group_dm')),
|
||||
visibility text NOT NULL DEFAULT 'public' CHECK (visibility IN ('public', 'private')),
|
||||
topic text,
|
||||
created_at timestamptz DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS channel_members;
|
||||
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS channel_members (
|
||||
channel_id uuid NOT NULL REFERENCES channels (id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
joined_at timestamptz DEFAULT now(),
|
||||
last_read_message_id uuid,
|
||||
PRIMARY KEY (channel_id, user_id)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS messages;
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE IF NOT EXISTS messages (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
channel_id uuid NOT NULL REFERENCES channels (id) ON DELETE CASCADE,
|
||||
user_id uuid REFERENCES users (id) ON DELETE SET NULL,
|
||||
parent_id uuid REFERENCES messages (id) ON DELETE SET NULL,
|
||||
body_md text NOT NULL,
|
||||
created_at timestamptz DEFAULT now(),
|
||||
edited_at timestamptz
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS attachments;
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS attachments (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
message_id uuid NOT NULL REFERENCES messages (id) ON DELETE CASCADE,
|
||||
filename text NOT NULL,
|
||||
content_type text NOT NULL,
|
||||
size_bytes bigint NOT NULL,
|
||||
storage_key text NOT NULL
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS reactions;
|
||||
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS reactions (
|
||||
message_id uuid NOT NULL REFERENCES messages (id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
emoji text NOT NULL,
|
||||
created_at timestamptz DEFAULT now(),
|
||||
PRIMARY KEY (message_id, user_id, emoji)
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS mentions;
|
||||
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE IF NOT EXISTS mentions (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
message_id uuid NOT NULL REFERENCES messages (id) ON DELETE CASCADE,
|
||||
target_type text NOT NULL CHECK (target_type IN ('user', 'channel', 'here')),
|
||||
target_id uuid
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS notifications;
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS notifications (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
type text NOT NULL CHECK (type IN ('mention', 'dm', 'thread_reply', 'invite', 'system')),
|
||||
source_id uuid,
|
||||
read boolean DEFAULT false,
|
||||
created_at timestamptz DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS sessions;
|
||||
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
token_hash text NOT NULL,
|
||||
expires_at timestamptz NOT NULL,
|
||||
created_at timestamptz DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS api_users;
|
||||
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS api_users (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name text NOT NULL,
|
||||
community_id uuid NOT NULL REFERENCES communities (id) ON DELETE CASCADE,
|
||||
created_by uuid REFERENCES users (id),
|
||||
created_at timestamptz DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS api_tokens;
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS api_tokens (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
api_user_id uuid NOT NULL REFERENCES api_users (id) ON DELETE CASCADE,
|
||||
token_hash text NOT NULL,
|
||||
scopes text[] DEFAULT '{}',
|
||||
expires_at timestamptz,
|
||||
created_at timestamptz DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS webhooks;
|
||||
@@ -0,0 +1,10 @@
|
||||
CREATE TABLE IF NOT EXISTS webhooks (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
community_id uuid NOT NULL REFERENCES communities (id) ON DELETE CASCADE,
|
||||
channel_id uuid NOT NULL REFERENCES channels (id) ON DELETE CASCADE,
|
||||
name text NOT NULL,
|
||||
avatar_url text,
|
||||
token_hash text NOT NULL,
|
||||
created_by uuid REFERENCES users (id),
|
||||
created_at timestamptz DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS invites;
|
||||
@@ -0,0 +1,10 @@
|
||||
CREATE TABLE IF NOT EXISTS invites (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
community_id uuid NOT NULL REFERENCES communities (id) ON DELETE CASCADE,
|
||||
created_by uuid REFERENCES users (id),
|
||||
code text UNIQUE NOT NULL,
|
||||
max_uses int,
|
||||
uses int DEFAULT 0,
|
||||
expires_at timestamptz,
|
||||
created_at timestamptz DEFAULT now()
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
DROP INDEX IF EXISTS idx_messages_channel_created;
|
||||
DROP INDEX IF EXISTS idx_messages_parent;
|
||||
DROP INDEX IF EXISTS idx_messages_search;
|
||||
DROP INDEX IF EXISTS idx_notifications_user_unread;
|
||||
DROP INDEX IF EXISTS idx_channel_members_user;
|
||||
DROP INDEX IF EXISTS idx_community_members_user;
|
||||
@@ -0,0 +1,20 @@
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_channel_created
|
||||
ON messages (channel_id, created_at);
|
||||
--;;
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_parent
|
||||
ON messages (parent_id)
|
||||
WHERE parent_id IS NOT NULL;
|
||||
--;;
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_search
|
||||
ON messages
|
||||
USING GIN (to_tsvector('english', body_md));
|
||||
--;;
|
||||
CREATE INDEX IF NOT EXISTS idx_notifications_user_unread
|
||||
ON notifications (user_id, created_at)
|
||||
WHERE read = false;
|
||||
--;;
|
||||
CREATE INDEX IF NOT EXISTS idx_channel_members_user
|
||||
ON channel_members (user_id);
|
||||
--;;
|
||||
CREATE INDEX IF NOT EXISTS idx_community_members_user
|
||||
ON community_members (user_id);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS bans;
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS bans (
|
||||
community_id uuid NOT NULL REFERENCES communities (id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
reason text,
|
||||
banned_by uuid REFERENCES users (id),
|
||||
created_at timestamptz DEFAULT now(),
|
||||
PRIMARY KEY (community_id, user_id)
|
||||
);
|
||||
@@ -0,0 +1,2 @@
|
||||
DROP INDEX IF EXISTS idx_mutes_expires;
|
||||
DROP TABLE IF EXISTS mutes;
|
||||
@@ -0,0 +1,12 @@
|
||||
CREATE TABLE IF NOT EXISTS mutes (
|
||||
community_id uuid NOT NULL REFERENCES communities (id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
expires_at timestamptz,
|
||||
muted_by uuid REFERENCES users (id),
|
||||
created_at timestamptz DEFAULT now(),
|
||||
PRIMARY KEY (community_id, user_id)
|
||||
);
|
||||
--;;
|
||||
CREATE INDEX IF NOT EXISTS idx_mutes_expires
|
||||
ON mutes (expires_at)
|
||||
WHERE expires_at IS NOT NULL;
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS oauth_providers;
|
||||
@@ -0,0 +1,16 @@
|
||||
CREATE TABLE oauth_providers (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
provider_type text NOT NULL CHECK (provider_type IN ('github', 'gitea', 'oidc')),
|
||||
display_name text NOT NULL,
|
||||
slug text UNIQUE NOT NULL,
|
||||
client_id text NOT NULL,
|
||||
client_secret text NOT NULL,
|
||||
base_url text,
|
||||
issuer_url text,
|
||||
enabled boolean NOT NULL DEFAULT true,
|
||||
sort_order integer NOT NULL DEFAULT 0,
|
||||
created_at timestamptz DEFAULT now(),
|
||||
updated_at timestamptz DEFAULT now()
|
||||
);
|
||||
--;;
|
||||
CREATE INDEX idx_oauth_providers_enabled ON oauth_providers (enabled, sort_order);
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS system_settings;
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE system_settings (
|
||||
key text PRIMARY KEY,
|
||||
value text NOT NULL,
|
||||
updated_at timestamptz DEFAULT now()
|
||||
);
|
||||
--;;
|
||||
INSERT INTO system_settings (key, value) VALUES ('setup_completed', 'false')
|
||||
ON CONFLICT (key) DO NOTHING;
|
||||
Reference in New Issue
Block a user