added file domain logic, updated drizzle package

This commit is contained in:
user
2026-03-01 05:56:15 +02:00
parent 1c2584df58
commit 5a5f565377
27 changed files with 5757 additions and 223 deletions

View File

@@ -0,0 +1,55 @@
CREATE TABLE IF NOT EXISTS "file" (
"id" text PRIMARY KEY NOT NULL,
"filename" text NOT NULL,
"original_name" text NOT NULL,
"mime_type" text NOT NULL,
"size" integer NOT NULL,
"hash" text NOT NULL,
"bucket_name" text NOT NULL,
"object_key" text NOT NULL,
"r2_url" text NOT NULL,
"metadata" json,
"tags" json,
"visibility" varchar(16) DEFAULT 'private' NOT NULL,
"user_id" text NOT NULL,
"status" varchar(16) DEFAULT 'processing' NOT NULL,
"processing_error" text,
"uploaded_at" timestamp NOT NULL,
"last_accessed_at" timestamp,
"expires_at" timestamp,
"created_at" timestamp NOT NULL,
"updated_at" timestamp NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "file_access" (
"id" serial PRIMARY KEY NOT NULL,
"file_id" text NOT NULL,
"user_id" text NOT NULL,
"can_read" boolean DEFAULT false NOT NULL,
"can_write" boolean DEFAULT false NOT NULL,
"can_delete" boolean DEFAULT false NOT NULL,
"can_share" boolean DEFAULT false NOT NULL,
"accessed_at" timestamp,
"granted_at" timestamp NOT NULL,
"expires_at" timestamp,
"created_at" timestamp NOT NULL,
"updated_at" timestamp NOT NULL
);
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "file" ADD CONSTRAINT "file_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "file_access" ADD CONSTRAINT "file_access_file_id_file_id_fk" FOREIGN KEY ("file_id") REFERENCES "public"."file"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "file_access" ADD CONSTRAINT "file_access_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

View File

@@ -0,0 +1,920 @@
{
"id": "32691d1d-382d-4db0-96ca-a49c46ece173",
"prevId": "333bfb88-9996-4dab-bbf5-724a6eadd745",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.two_factor": {
"name": "two_factor",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"secret": {
"name": "secret",
"type": "text",
"primaryKey": false,
"notNull": true
},
"backup_codes": {
"name": "backup_codes",
"type": "json",
"primaryKey": false,
"notNull": false
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"two_factor_user_id_user_id_fk": {
"name": "two_factor_user_id_user_id_fk",
"tableFrom": "two_factor",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.twofa_sessions": {
"name": "twofa_sessions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"session_id": {
"name": "session_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"verification_token": {
"name": "verification_token",
"type": "text",
"primaryKey": false,
"notNull": true
},
"code_used": {
"name": "code_used",
"type": "text",
"primaryKey": false,
"notNull": false
},
"status": {
"name": "status",
"type": "varchar(16)",
"primaryKey": false,
"notNull": true
},
"attempts": {
"name": "attempts",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"max_attempts": {
"name": "max_attempts",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 5
},
"verified_at": {
"name": "verified_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"ip_address": {
"name": "ip_address",
"type": "text",
"primaryKey": false,
"notNull": false,
"default": "''"
},
"user_agent": {
"name": "user_agent",
"type": "text",
"primaryKey": false,
"notNull": false,
"default": "''"
}
},
"indexes": {},
"foreignKeys": {
"twofa_sessions_user_id_user_id_fk": {
"name": "twofa_sessions_user_id_user_id_fk",
"tableFrom": "twofa_sessions",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"twofa_sessions_verification_token_unique": {
"name": "twofa_sessions_verification_token_unique",
"nullsNotDistinct": false,
"columns": [
"verification_token"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.account": {
"name": "account",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"account_id": {
"name": "account_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"provider_id": {
"name": "provider_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"access_token": {
"name": "access_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"refresh_token": {
"name": "refresh_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"id_token": {
"name": "id_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"access_token_expires_at": {
"name": "access_token_expires_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"refresh_token_expires_at": {
"name": "refresh_token_expires_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"scope": {
"name": "scope",
"type": "text",
"primaryKey": false,
"notNull": false
},
"password": {
"name": "password",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"account_userId_idx": {
"name": "account_userId_idx",
"columns": [
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"account_user_id_user_id_fk": {
"name": "account_user_id_user_id_fk",
"tableFrom": "account",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email_verified": {
"name": "email_verified",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"image": {
"name": "image",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": false
},
"display_username": {
"name": "display_username",
"type": "text",
"primaryKey": false,
"notNull": false
},
"role": {
"name": "role",
"type": "text",
"primaryKey": false,
"notNull": false
},
"banned": {
"name": "banned",
"type": "boolean",
"primaryKey": false,
"notNull": false,
"default": false
},
"ban_reason": {
"name": "ban_reason",
"type": "text",
"primaryKey": false,
"notNull": false
},
"ban_expires": {
"name": "ban_expires",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"onboarding_done": {
"name": "onboarding_done",
"type": "boolean",
"primaryKey": false,
"notNull": false,
"default": false
},
"last2_fa_verified_at": {
"name": "last2_fa_verified_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"parent_id": {
"name": "parent_id",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"user_email_unique": {
"name": "user_email_unique",
"nullsNotDistinct": false,
"columns": [
"email"
]
},
"user_username_unique": {
"name": "user_username_unique",
"nullsNotDistinct": false,
"columns": [
"username"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.verification": {
"name": "verification",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"identifier": {
"name": "identifier",
"type": "text",
"primaryKey": false,
"notNull": true
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
"notNull": true
},
"expires_at": {
"name": "expires_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"verification_identifier_idx": {
"name": "verification_identifier_idx",
"columns": [
{
"expression": "identifier",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.file": {
"name": "file",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"filename": {
"name": "filename",
"type": "text",
"primaryKey": false,
"notNull": true
},
"original_name": {
"name": "original_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"mime_type": {
"name": "mime_type",
"type": "text",
"primaryKey": false,
"notNull": true
},
"size": {
"name": "size",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"hash": {
"name": "hash",
"type": "text",
"primaryKey": false,
"notNull": true
},
"bucket_name": {
"name": "bucket_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"object_key": {
"name": "object_key",
"type": "text",
"primaryKey": false,
"notNull": true
},
"r2_url": {
"name": "r2_url",
"type": "text",
"primaryKey": false,
"notNull": true
},
"metadata": {
"name": "metadata",
"type": "json",
"primaryKey": false,
"notNull": false
},
"tags": {
"name": "tags",
"type": "json",
"primaryKey": false,
"notNull": false
},
"visibility": {
"name": "visibility",
"type": "varchar(16)",
"primaryKey": false,
"notNull": true,
"default": "'private'"
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"status": {
"name": "status",
"type": "varchar(16)",
"primaryKey": false,
"notNull": true,
"default": "'processing'"
},
"processing_error": {
"name": "processing_error",
"type": "text",
"primaryKey": false,
"notNull": false
},
"uploaded_at": {
"name": "uploaded_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"last_accessed_at": {
"name": "last_accessed_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"file_user_id_user_id_fk": {
"name": "file_user_id_user_id_fk",
"tableFrom": "file",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.file_access": {
"name": "file_access",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"file_id": {
"name": "file_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"can_read": {
"name": "can_read",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"can_write": {
"name": "can_write",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"can_delete": {
"name": "can_delete",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"can_share": {
"name": "can_share",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"accessed_at": {
"name": "accessed_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"granted_at": {
"name": "granted_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"expires_at": {
"name": "expires_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"file_access_file_id_file_id_fk": {
"name": "file_access_file_id_file_id_fk",
"tableFrom": "file_access",
"tableTo": "file",
"columnsFrom": [
"file_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"file_access_user_id_user_id_fk": {
"name": "file_access_user_id_user_id_fk",
"tableFrom": "file_access",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.notifications": {
"name": "notifications",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"title": {
"name": "title",
"type": "text",
"primaryKey": false,
"notNull": true
},
"body": {
"name": "body",
"type": "text",
"primaryKey": false,
"notNull": true
},
"priority": {
"name": "priority",
"type": "varchar(12)",
"primaryKey": false,
"notNull": true,
"default": "'normal'"
},
"type": {
"name": "type",
"type": "varchar(12)",
"primaryKey": false,
"notNull": true
},
"category": {
"name": "category",
"type": "varchar(64)",
"primaryKey": false,
"notNull": false
},
"is_read": {
"name": "is_read",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"is_archived": {
"name": "is_archived",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"action_url": {
"name": "action_url",
"type": "text",
"primaryKey": false,
"notNull": false
},
"action_type": {
"name": "action_type",
"type": "varchar(16)",
"primaryKey": false,
"notNull": false
},
"action_data": {
"name": "action_data",
"type": "json",
"primaryKey": false,
"notNull": false
},
"icon": {
"name": "icon",
"type": "varchar(64)",
"primaryKey": false,
"notNull": false
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"sent_at": {
"name": "sent_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"read_at": {
"name": "read_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"notifications_user_id_user_id_fk": {
"name": "notifications_user_id_user_id_fk",
"tableFrom": "notifications",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View File

@@ -8,6 +8,13 @@
"when": 1772288650927,
"tag": "0000_lucky_karma",
"breakpoints": true
},
{
"idx": 1,
"version": "7",
"when": 1772335785371,
"tag": "0001_silly_venus",
"breakpoints": true
}
]
}

View File

@@ -13,13 +13,13 @@
"dependencies": {
"@pkg/settings": "workspace:*",
"dotenv": "^16.4.7",
"drizzle-orm": "^0.36.1",
"drizzle-orm": "^0.45.1",
"postgres": "^3.4.8"
},
"devDependencies": {
"@types/bun": "latest",
"@types/pg": "^8.11.10",
"drizzle-kit": "^0.28.0"
"drizzle-kit": "^0.31.9"
},
"peerDependencies": {
"typescript": "^5.9.3"

View File

@@ -0,0 +1,88 @@
import {
boolean,
integer,
json,
pgTable,
serial,
text,
timestamp,
varchar,
} from "drizzle-orm/pg-core";
import { user } from "./better.auth.schema";
import { relations } from "drizzle-orm";
// Add this to your existing schema file
export const file = pgTable("file", {
id: text("id").primaryKey(), // UUID
// File Information
filename: text("filename").notNull(),
originalName: text("original_name").notNull(),
mimeType: text("mime_type").notNull(),
size: integer("size").notNull(), // in bytes
hash: text("hash").notNull(), // SHA-256 for deduplication
// R2 Storage Information
bucketName: text("bucket_name").notNull(),
objectKey: text("object_key").notNull(),
r2Url: text("r2_url").notNull(),
// Metadata
metadata: json("metadata").$type<Record<string, any>>(),
tags: json("tags").$type<string[]>(),
// Access Control
visibility: varchar("visibility", { length: 16 })
.default("private")
.notNull(), // "public", "private", "restricted"
userId: text("user_id")
.notNull()
.references(() => user.id, { onDelete: "cascade" }),
// File Status
status: varchar("status", { length: 16 }).default("processing").notNull(), // "processing", "ready", "error", "deleted"
processingError: text("processing_error"),
// Timestamps
uploadedAt: timestamp("uploaded_at").notNull(),
lastAccessedAt: timestamp("last_accessed_at"),
expiresAt: timestamp("expires_at"), // For temporary files
createdAt: timestamp("created_at").notNull(),
updatedAt: timestamp("updated_at").notNull(),
});
export const fileAccess = pgTable("file_access", {
id: serial("id").primaryKey(),
fileId: text("file_id")
.notNull()
.references(() => file.id, { onDelete: "cascade" }),
userId: text("user_id")
.notNull()
.references(() => user.id, { onDelete: "cascade" }),
// Access permissions
canRead: boolean("can_read").default(false).notNull(),
canWrite: boolean("can_write").default(false).notNull(),
canDelete: boolean("can_delete").default(false).notNull(),
canShare: boolean("can_share").default(false).notNull(),
// Access tracking
accessedAt: timestamp("accessed_at"),
grantedAt: timestamp("granted_at").notNull(),
expiresAt: timestamp("expires_at"),
createdAt: timestamp("created_at").notNull(),
updatedAt: timestamp("updated_at").notNull(),
});
// Relations
export const filesRelations = relations(file, ({ one, many }) => ({
owner: one(user, { fields: [file.userId], references: [user.id] }),
fileAccess: many(fileAccess),
}));
export const fileAccessRelations = relations(fileAccess, ({ one }) => ({
file: one(file, { fields: [fileAccess.fileId], references: [file.id] }),
user: one(user, { fields: [fileAccess.userId], references: [user.id] }),
}));

View File

@@ -1,3 +1,4 @@
export * from "./auth.schema";
export * from "./better.auth.schema";
export * from "./file.schema";
export * from "./general.schema";