When a permission is set on a nested folder, traverse is automatically granted on all ancestor folders so users can navigate to it. Traverse only shows subfolders in listings — files are hidden. This prevents orphaned permissions where a user has access to a nested folder but can't reach it. Hierarchy: traverse < view < edit < admin
56 lines
2.2 KiB
TypeScript
56 lines
2.2 KiB
TypeScript
import {
|
|
pgTable,
|
|
uuid,
|
|
varchar,
|
|
text,
|
|
timestamp,
|
|
boolean,
|
|
integer,
|
|
pgEnum,
|
|
} from 'drizzle-orm/pg-core'
|
|
import { users } from './users.js'
|
|
import { roles } from './rbac.js'
|
|
|
|
export const storageFolderAccessEnum = pgEnum('storage_folder_access', ['traverse', 'view', 'edit', 'admin'])
|
|
|
|
export const storageFolders = pgTable('storage_folder', {
|
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
parentId: uuid('parent_id'),
|
|
name: varchar('name', { length: 255 }).notNull(),
|
|
path: text('path').notNull().default('/'),
|
|
createdBy: uuid('created_by').references(() => users.id),
|
|
isPublic: boolean('is_public').notNull().default(true),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
|
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
|
})
|
|
|
|
export const storageFolderPermissions = pgTable('storage_folder_permission', {
|
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
folderId: uuid('folder_id')
|
|
.notNull()
|
|
.references(() => storageFolders.id, { onDelete: 'cascade' }),
|
|
roleId: uuid('role_id').references(() => roles.id),
|
|
userId: uuid('user_id').references(() => users.id),
|
|
accessLevel: storageFolderAccessEnum('access_level').notNull().default('view'),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
|
})
|
|
|
|
export const storageFiles = pgTable('storage_file', {
|
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
folderId: uuid('folder_id')
|
|
.notNull()
|
|
.references(() => storageFolders.id, { onDelete: 'cascade' }),
|
|
filename: varchar('filename', { length: 255 }).notNull(),
|
|
path: varchar('path', { length: 1000 }).notNull(),
|
|
contentType: varchar('content_type', { length: 100 }).notNull(),
|
|
sizeBytes: integer('size_bytes').notNull(),
|
|
uploadedBy: uuid('uploaded_by').references(() => users.id),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
|
})
|
|
|
|
export type StorageFolder = typeof storageFolders.$inferSelect
|
|
export type StorageFolderInsert = typeof storageFolders.$inferInsert
|
|
export type StorageFolderPermission = typeof storageFolderPermissions.$inferSelect
|
|
export type StorageFile = typeof storageFiles.$inferSelect
|
|
export type StorageFileInsert = typeof storageFiles.$inferInsert
|