From 912394477b88d2c0f6f13044a4cfa2f405c29578 Mon Sep 17 00:00:00 2001 From: Mathis HERRIOT <197931332+0x485254@users.noreply.github.com> Date: Thu, 8 Jan 2026 15:25:51 +0100 Subject: [PATCH] feat: add categories and favorites schemas with integrations Added `categories` and `favorites` database schemas with full type inference support. Integrated categories into `content` schema with new properties (`categoryId`, `slug`, `views`, and `usageCount`). Updated `tags` schema to include `userId` with reference to `users`. Exported new schemas in index for broader usage. --- backend/src/database/schemas/categories.ts | 24 ++++++++++++++++++++++ backend/src/database/schemas/content.ts | 7 +++++++ backend/src/database/schemas/favorites.ts | 24 ++++++++++++++++++++++ backend/src/database/schemas/index.ts | 2 ++ backend/src/database/schemas/tags.ts | 4 ++++ 5 files changed, 61 insertions(+) create mode 100644 backend/src/database/schemas/categories.ts create mode 100644 backend/src/database/schemas/favorites.ts diff --git a/backend/src/database/schemas/categories.ts b/backend/src/database/schemas/categories.ts new file mode 100644 index 0000000..85db079 --- /dev/null +++ b/backend/src/database/schemas/categories.ts @@ -0,0 +1,24 @@ +import { index, pgTable, timestamp, uuid, varchar } from "drizzle-orm/pg-core"; + +export const categories = pgTable( + "categories", + { + id: uuid("id").primaryKey().defaultRandom(), + name: varchar("name", { length: 64 }).notNull().unique(), + slug: varchar("slug", { length: 64 }).notNull().unique(), + description: varchar("description", { length: 255 }), + iconUrl: varchar("icon_url", { length: 512 }), + createdAt: timestamp("created_at", { withTimezone: true }) + .notNull() + .defaultNow(), + updatedAt: timestamp("updated_at", { withTimezone: true }) + .notNull() + .defaultNow(), + }, + (table) => ({ + slugIdx: index("categories_slug_idx").on(table.slug), + }), +); + +export type CategoryInDb = typeof categories.$inferSelect; +export type NewCategoryInDb = typeof categories.$inferInsert; diff --git a/backend/src/database/schemas/content.ts b/backend/src/database/schemas/content.ts index 6afc254..0c1c43c 100644 --- a/backend/src/database/schemas/content.ts +++ b/backend/src/database/schemas/content.ts @@ -8,6 +8,7 @@ import { uuid, varchar, } from "drizzle-orm/pg-core"; +import { categories } from "./categories"; import { tags } from "./tags"; import { users } from "./users"; @@ -21,10 +22,16 @@ export const contents = pgTable( .notNull() .references(() => users.uuid, { onDelete: "cascade" }), type: contentType("type").notNull(), + categoryId: uuid("category_id").references(() => categories.id, { + onDelete: "set null", + }), title: varchar("title", { length: 255 }).notNull(), + slug: varchar("slug", { length: 255 }).notNull().unique(), storageKey: varchar("storage_key", { length: 512 }).notNull().unique(), // Clé interne S3 mimeType: varchar("mime_type", { length: 128 }).notNull(), // Pour le Content-Type HTTP fileSize: integer("file_size").notNull(), // Taille en octets + views: integer("views").notNull().default(0), + usageCount: integer("usage_count").notNull().default(0), createdAt: timestamp("created_at", { withTimezone: true }) .notNull() .defaultNow(), diff --git a/backend/src/database/schemas/favorites.ts b/backend/src/database/schemas/favorites.ts new file mode 100644 index 0000000..8fdb195 --- /dev/null +++ b/backend/src/database/schemas/favorites.ts @@ -0,0 +1,24 @@ +import { pgTable, primaryKey, timestamp, uuid } from "drizzle-orm/pg-core"; +import { contents } from "./content"; +import { users } from "./users"; + +export const favorites = pgTable( + "favorites", + { + userId: uuid("user_id") + .notNull() + .references(() => users.uuid, { onDelete: "cascade" }), + contentId: uuid("content_id") + .notNull() + .references(() => contents.id, { onDelete: "cascade" }), + createdAt: timestamp("created_at", { withTimezone: true }) + .notNull() + .defaultNow(), + }, + (t) => ({ + pk: primaryKey({ columns: [t.userId, t.contentId] }), + }), +); + +export type FavoriteInDb = typeof favorites.$inferSelect; +export type NewFavoriteInDb = typeof favorites.$inferInsert; diff --git a/backend/src/database/schemas/index.ts b/backend/src/database/schemas/index.ts index 84583c0..4858b3d 100644 --- a/backend/src/database/schemas/index.ts +++ b/backend/src/database/schemas/index.ts @@ -1,6 +1,8 @@ export * from "./api_keys"; export * from "./audit_logs"; +export * from "./categories"; export * from "./content"; +export * from "./favorites"; export * from "./rbac"; export * from "./reports"; export * from "./sessions"; diff --git a/backend/src/database/schemas/tags.ts b/backend/src/database/schemas/tags.ts index c55e009..88e05cd 100644 --- a/backend/src/database/schemas/tags.ts +++ b/backend/src/database/schemas/tags.ts @@ -1,4 +1,5 @@ import { index, pgTable, timestamp, uuid, varchar } from "drizzle-orm/pg-core"; +import { users } from "./users"; export const tags = pgTable( "tags", @@ -6,6 +7,9 @@ export const tags = pgTable( id: uuid("id").primaryKey().defaultRandom(), name: varchar("name", { length: 64 }).notNull().unique(), slug: varchar("slug", { length: 64 }).notNull().unique(), + userId: uuid("user_id").references(() => users.uuid, { + onDelete: "set null", + }), // Créateur du tag createdAt: timestamp("created_at", { withTimezone: true }) .notNull() .defaultNow(),