diff --git a/backend/src/database/schemas/reports.ts b/backend/src/database/schemas/reports.ts new file mode 100644 index 0000000..f195ba8 --- /dev/null +++ b/backend/src/database/schemas/reports.ts @@ -0,0 +1,33 @@ +import { pgTable, varchar, timestamp, uuid, pgEnum, index, text } from 'drizzle-orm/pg-core'; +import { users } from './users'; +import { contents } from './content'; +import { tags } from './tags'; + +export const reportStatus = pgEnum('report_status', ['pending', 'reviewed', 'resolved', 'dismissed']); +export const reportReason = pgEnum('report_reason', ['inappropriate', 'spam', 'copyright', 'other']); + +export const reports = pgTable('reports', { + id: uuid('id').primaryKey().defaultRandom(), + reporterId: uuid('reporter_id').notNull().references(() => users.uuid, { onDelete: 'cascade' }), + + // Le signalement peut porter sur un contenu OU un tag + contentId: uuid('content_id').references(() => contents.id, { onDelete: 'cascade' }), + tagId: uuid('tag_id').references(() => tags.id, { onDelete: 'cascade' }), + + reason: reportReason('reason').notNull(), + description: text('description'), + status: reportStatus('status').default('pending').notNull(), + + expiresAt: timestamp('expires_at', { withTimezone: true }), // Pour purge automatique RGPD + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(), +}, (table) => ({ + reporterIdx: index('reports_reporter_id_idx').on(table.reporterId), + contentIdx: index('reports_content_id_idx').on(table.contentId), + tagIdx: index('reports_tag_id_idx').on(table.tagId), + statusIdx: index('reports_status_idx').on(table.status), + expiresAtIdx: index('reports_expires_at_idx').on(table.expiresAt), +})); + +export type ReportInDb = typeof reports.$inferSelect; +export type NewReportInDb = typeof reports.$inferInsert;