- Added organization model and membership management to support multi-tenancy. - Updated file and folder routes to include organization context for ownership checks. - Integrated Google Drive connection management per organization, ensuring proper authorization and folder structure. - Enhanced user account deletion to prevent removal if the user owns organizations. - Introduced middleware for organization validation and admin role checks. - Created organization admin routes for managing memberships and retrieving statistics. - Implemented token encryption/decryption for secure Google Drive token storage. - Updated serializers to include organization data in user memberships. - Added database migration for new organization and membership tables.
79 lines
4.3 KiB
SQL
79 lines
4.3 KiB
SQL
CREATE TABLE "Organization" (
|
|
"id" TEXT NOT NULL,
|
|
"code" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"status" TEXT NOT NULL DEFAULT 'ACTIVE',
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
CONSTRAINT "Organization_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
CREATE TABLE "Membership" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"organizationId" TEXT NOT NULL,
|
|
"role" TEXT NOT NULL DEFAULT 'MEMBER',
|
|
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
|
"rejectionReason" TEXT,
|
|
"driveFolderId" TEXT,
|
|
"reviewedAt" TIMESTAMP(3),
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
CONSTRAINT "Membership_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
CREATE TABLE "GoogleDriveConnection" (
|
|
"id" TEXT NOT NULL,
|
|
"organizationId" TEXT NOT NULL,
|
|
"tokenCiphertext" TEXT NOT NULL,
|
|
"storageType" TEXT NOT NULL DEFAULT 'MY_DRIVE',
|
|
"sharedDriveId" TEXT,
|
|
"rootFolderId" TEXT,
|
|
"status" TEXT NOT NULL DEFAULT 'CONNECTED',
|
|
"scope" TEXT,
|
|
"connectedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
CONSTRAINT "GoogleDriveConnection_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
ALTER TABLE "Folder" ADD COLUMN "organizationId" TEXT;
|
|
ALTER TABLE "FileAsset" ADD COLUMN "organizationId" TEXT;
|
|
|
|
INSERT INTO "Organization" ("id", "code", "name", "status", "updatedAt")
|
|
VALUES ('00000000-0000-0000-0000-000000000001', 'METATRON', 'Metatron Drive Legacy', 'ACTIVE', CURRENT_TIMESTAMP);
|
|
|
|
INSERT INTO "Membership" ("id", "userId", "organizationId", "role", "status", "driveFolderId", "reviewedAt", "updatedAt")
|
|
SELECT "id", "id", '00000000-0000-0000-0000-000000000001',
|
|
CASE WHEN "id" = (SELECT "id" FROM "User" ORDER BY "createdAt" ASC LIMIT 1) THEN 'OWNER' ELSE 'MEMBER' END,
|
|
|
|
CASE WHEN "isSuspended" THEN 'SUSPENDED' ELSE 'APPROVED' END,
|
|
"driveFolderId", CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
|
|
FROM "User";
|
|
|
|
UPDATE "Folder" SET "organizationId" = '00000000-0000-0000-0000-000000000001';
|
|
UPDATE "FileAsset" SET "organizationId" = '00000000-0000-0000-0000-000000000001';
|
|
ALTER TABLE "Folder" ALTER COLUMN "organizationId" SET NOT NULL;
|
|
ALTER TABLE "FileAsset" ALTER COLUMN "organizationId" SET NOT NULL;
|
|
ALTER TABLE "User" DROP COLUMN "driveFolderId";
|
|
|
|
DROP INDEX IF EXISTS "Folder_userId_parentId_name_key";
|
|
DROP INDEX IF EXISTS "Folder_userId_parentId_idx";
|
|
DROP INDEX IF EXISTS "FileAsset_userId_folderId_createdAt_idx";
|
|
|
|
CREATE UNIQUE INDEX "Organization_code_key" ON "Organization"("code");
|
|
CREATE INDEX "Organization_status_createdAt_idx" ON "Organization"("status", "createdAt");
|
|
CREATE UNIQUE INDEX "Membership_driveFolderId_key" ON "Membership"("driveFolderId");
|
|
CREATE UNIQUE INDEX "Membership_userId_organizationId_key" ON "Membership"("userId", "organizationId");
|
|
CREATE INDEX "Membership_organizationId_status_createdAt_idx" ON "Membership"("organizationId", "status", "createdAt");
|
|
CREATE INDEX "Membership_userId_status_idx" ON "Membership"("userId", "status");
|
|
CREATE UNIQUE INDEX "GoogleDriveConnection_organizationId_key" ON "GoogleDriveConnection"("organizationId");
|
|
CREATE UNIQUE INDEX "Folder_organizationId_userId_parentId_name_key" ON "Folder"("organizationId", "userId", "parentId", "name");
|
|
CREATE INDEX "Folder_organizationId_userId_parentId_idx" ON "Folder"("organizationId", "userId", "parentId");
|
|
CREATE INDEX "FileAsset_organizationId_userId_folderId_createdAt_idx" ON "FileAsset"("organizationId", "userId", "folderId", "createdAt");
|
|
|
|
ALTER TABLE "Membership" ADD CONSTRAINT "Membership_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
ALTER TABLE "Membership" ADD CONSTRAINT "Membership_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
ALTER TABLE "GoogleDriveConnection" ADD CONSTRAINT "GoogleDriveConnection_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
ALTER TABLE "Folder" ADD CONSTRAINT "Folder_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
ALTER TABLE "FileAsset" ADD CONSTRAINT "FileAsset_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|