- File model + migration: file metadata, content lives in object storage - IFileStorage port with local disk and S3-compatible (RustFS/MinIO) adapters - POST /files, GET /files/:id/download, DELETE /files/:id - MIME sniffed from content; only safe images served inline, nosniff header - FileOwnerRegistry: owner modules register to grant visibility and keep their files from GC; FileGcService removes orphaned files hourly - TransformResponseInterceptor passes StreamableFile through Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
26 lines
720 B
SQL
26 lines
720 B
SQL
-- CreateTable
|
|
CREATE TABLE "file" (
|
|
"id" TEXT NOT NULL,
|
|
"storageKey" TEXT NOT NULL,
|
|
"fileName" TEXT NOT NULL,
|
|
"mimeType" TEXT NOT NULL,
|
|
"size" INTEGER NOT NULL,
|
|
"uploaderId" TEXT,
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "file_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "file_uploaderId_idx" ON "file"("uploaderId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "file_createdAt_idx" ON "file"("createdAt");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "file_storageKey_key" ON "file"("storageKey");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "file" ADD CONSTRAINT "file_uploaderId_fkey" FOREIGN KEY ("uploaderId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|