refactor: purge legacy server_members.role column, single source of truth via member_roles

Remove the legacy TEXT role column ('owner'/'admin'/'member') from
server_members and make the bitwise RBAC member_roles junction table
the sole authority for role assignments. Owner detection now uses
servers.ownerId exclusively.

- Remove MemberRole type and role field from shared types
- Remove role from Drizzle schema, raw SQL CREATE TABLE, and seed data
- Rewrite PATCH /members/:uid to accept { roleIds: string[] }
- Fix GET /members to populate roles array (was TODO)
- Replace member.role === 'owner' guard with isServerOwner()
- Remove getMemberRole() helper and legacy bridge code
- MemberSidebar groups by highest-positioned role instead of legacy string
- ServerSettings replaces admin/member dropdown with role checkboxes
- Message.tsx derives color from roles[] with owner fallback via ownerId
- Existing DBs keep vestigial column (Drizzle ignores it); new DBs omit it
This commit is contained in:
Jannis Braun
2026-02-25 22:46:50 +01:00
parent 76b8a43be2
commit 0a157de162
10 changed files with 295 additions and 141 deletions
-6
View File
@@ -1,6 +1,5 @@
import { eq, and } from 'drizzle-orm';
import { getDb, schema } from '../db/index.js';
import type { MemberRole } from '@opencord/shared';
import {
PermissionBits,
ALL_PERMISSIONS,
@@ -134,11 +133,6 @@ export function isMember(serverId: string, userId: string): boolean {
return getMember(serverId, userId) !== undefined;
}
export function getMemberRole(serverId: string, userId: string): MemberRole | null {
const member = getMember(serverId, userId);
return member ? (member.role as MemberRole) : null;
}
export function isServerOwner(serverId: string, userId: string): boolean {
const db = getDb();
const server = db.select().from(schema.servers).where(eq(schema.servers.id, serverId)).get();