Files
DiscordClone/convex/schema.js
Bryan1029384756 958cf56b23
Some checks failed
Build and Release / build-and-release (push) Failing after 0s
feat: Implement core chat application UI, including chat, voice, members, DMs, and shared components.
2026-02-14 01:57:15 -06:00

124 lines
5.4 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var server_1 = require("convex/server");
var values_1 = require("convex/values");
exports.default = (0, server_1.defineSchema)({
userProfiles: (0, server_1.defineTable)({
username: values_1.v.string(),
clientSalt: values_1.v.string(),
encryptedMasterKey: values_1.v.string(),
hashedAuthKey: values_1.v.string(),
publicIdentityKey: values_1.v.string(),
publicSigningKey: values_1.v.string(),
encryptedPrivateKeys: values_1.v.string(),
isAdmin: values_1.v.boolean(),
status: values_1.v.optional(values_1.v.string()),
displayName: values_1.v.optional(values_1.v.string()),
avatarStorageId: values_1.v.optional(values_1.v.id("_storage")),
aboutMe: values_1.v.optional(values_1.v.string()),
customStatus: values_1.v.optional(values_1.v.string()),
joinSoundStorageId: values_1.v.optional(values_1.v.id("_storage")),
}).index("by_username", ["username"]),
categories: (0, server_1.defineTable)({
name: values_1.v.string(),
position: values_1.v.number(),
}).index("by_position", ["position"]),
channels: (0, server_1.defineTable)({
name: values_1.v.string(),
type: values_1.v.string(), // 'text' | 'voice' | 'dm'
categoryId: values_1.v.optional(values_1.v.id("categories")),
topic: values_1.v.optional(values_1.v.string()),
position: values_1.v.optional(values_1.v.number()),
}).index("by_name", ["name"])
.index("by_category", ["categoryId"]),
messages: (0, server_1.defineTable)({
channelId: values_1.v.id("channels"),
senderId: values_1.v.id("userProfiles"),
ciphertext: values_1.v.string(),
nonce: values_1.v.string(),
signature: values_1.v.string(),
keyVersion: values_1.v.number(),
replyTo: values_1.v.optional(values_1.v.id("messages")),
editedAt: values_1.v.optional(values_1.v.number()),
pinned: values_1.v.optional(values_1.v.boolean()),
}).index("by_channel", ["channelId"])
.index("by_channel_pinned", ["channelId", "pinned"]),
messageReactions: (0, server_1.defineTable)({
messageId: values_1.v.id("messages"),
userId: values_1.v.id("userProfiles"),
emoji: values_1.v.string(),
})
.index("by_message", ["messageId"])
.index("by_message_user_emoji", ["messageId", "userId", "emoji"]),
channelKeys: (0, server_1.defineTable)({
channelId: values_1.v.id("channels"),
userId: values_1.v.id("userProfiles"),
encryptedKeyBundle: values_1.v.string(),
keyVersion: values_1.v.number(),
})
.index("by_channel", ["channelId"])
.index("by_user", ["userId"])
.index("by_channel_and_user", ["channelId", "userId"]),
roles: (0, server_1.defineTable)({
name: values_1.v.string(),
color: values_1.v.string(),
position: values_1.v.number(),
permissions: values_1.v.any(), // JSON object of permissions
isHoist: values_1.v.boolean(),
}),
userRoles: (0, server_1.defineTable)({
userId: values_1.v.id("userProfiles"),
roleId: values_1.v.id("roles"),
})
.index("by_user", ["userId"])
.index("by_role", ["roleId"])
.index("by_user_and_role", ["userId", "roleId"]),
invites: (0, server_1.defineTable)({
code: values_1.v.string(),
encryptedPayload: values_1.v.string(),
createdBy: values_1.v.id("userProfiles"),
maxUses: values_1.v.optional(values_1.v.number()),
uses: values_1.v.number(),
expiresAt: values_1.v.optional(values_1.v.number()), // timestamp
keyVersion: values_1.v.number(),
}).index("by_code", ["code"]),
dmParticipants: (0, server_1.defineTable)({
channelId: values_1.v.id("channels"),
userId: values_1.v.id("userProfiles"),
})
.index("by_channel", ["channelId"])
.index("by_user", ["userId"]),
typingIndicators: (0, server_1.defineTable)({
channelId: values_1.v.id("channels"),
userId: values_1.v.id("userProfiles"),
username: values_1.v.string(),
expiresAt: values_1.v.number(), // timestamp
}).index("by_channel", ["channelId"]),
voiceStates: (0, server_1.defineTable)({
channelId: values_1.v.id("channels"),
userId: values_1.v.id("userProfiles"),
username: values_1.v.string(),
isMuted: values_1.v.boolean(),
isDeafened: values_1.v.boolean(),
isScreenSharing: values_1.v.boolean(),
isServerMuted: values_1.v.boolean(),
watchingStream: values_1.v.optional(values_1.v.id("userProfiles")),
})
.index("by_channel", ["channelId"])
.index("by_user", ["userId"]),
channelReadState: (0, server_1.defineTable)({
userId: values_1.v.id("userProfiles"),
channelId: values_1.v.id("channels"),
lastReadTimestamp: values_1.v.number(),
})
.index("by_user", ["userId"])
.index("by_channel", ["channelId"])
.index("by_user_and_channel", ["userId", "channelId"]),
serverSettings: (0, server_1.defineTable)({
serverName: values_1.v.optional(values_1.v.string()),
afkChannelId: values_1.v.optional(values_1.v.id("channels")),
afkTimeout: values_1.v.number(), // seconds (default 300 = 5 min)
iconStorageId: values_1.v.optional(values_1.v.id("_storage")),
}),
});