feat(Tags): implement user-specific tag management and enhance related services

- Added ownerId field to Tag model to associate tags with users.
- Updated tagsService methods to enforce user ownership in tag operations.
- Enhanced API routes to include user authentication and ownership checks for tag retrieval and management.
- Modified seeding script to assign tags to the first user found in the database.
- Updated various components and services to ensure user-specific tag handling throughout the application.
This commit is contained in:
Julien Froidefond
2025-10-11 15:03:59 +02:00
parent 583efaa8c5
commit 7952459b42
17 changed files with 329 additions and 177 deletions

View File

@@ -0,0 +1,59 @@
-- Migration pour ajouter ownerId aux tags
-- Les tags existants seront assignés au premier utilisateur
-- Cette version préserve les relations TaskTag existantes
-- Étape 1: Ajouter la colonne ownerId temporairement nullable
ALTER TABLE "tags" ADD COLUMN "ownerId" TEXT;
-- Étape 2: Assigner tous les tags existants au premier utilisateur
UPDATE "tags"
SET "ownerId" = (
SELECT "id" FROM "users"
ORDER BY "createdAt" ASC
LIMIT 1
)
WHERE "ownerId" IS NULL;
-- Étape 3: Sauvegarder les relations TaskTag existantes avec les noms des tags
CREATE TEMPORARY TABLE "temp_task_tag_names" AS
SELECT tt."taskId", t."name" as "tagName"
FROM "task_tags" tt
JOIN "tags" t ON tt."tagId" = t."id";
-- Étape 4: Supprimer les anciennes relations TaskTag
DELETE FROM "task_tags";
-- Étape 5: Créer la nouvelle table avec ownerId non-nullable
CREATE TABLE "new_tags" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"color" TEXT NOT NULL DEFAULT '#6b7280',
"isPinned" BOOLEAN NOT NULL DEFAULT false,
"ownerId" TEXT NOT NULL,
CONSTRAINT "new_tags_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- Étape 6: Copier les données des tags
INSERT INTO "new_tags" ("id", "name", "color", "isPinned", "ownerId")
SELECT "id", "name", "color", "isPinned", "ownerId" FROM "tags";
-- Étape 7: Supprimer l'ancienne table
DROP TABLE "tags";
-- Étape 8: Renommer la nouvelle table
ALTER TABLE "new_tags" RENAME TO "tags";
-- Étape 9: Créer l'index unique pour (name, ownerId)
CREATE UNIQUE INDEX "tags_name_ownerId_key" ON "tags"("name", "ownerId");
-- Étape 10: Restaurer les relations TaskTag en utilisant les noms des tags
INSERT INTO "task_tags" ("taskId", "tagId")
SELECT tt."taskId", t."id" as "tagId"
FROM "temp_task_tag_names" tt
JOIN "tags" t ON tt."tagName" = t."name"
WHERE EXISTS (
SELECT 1 FROM "tasks" WHERE "tasks"."id" = tt."taskId"
);
-- Étape 11: Nettoyer la table temporaire
DROP TABLE "temp_task_tag_names";

View File

@@ -24,6 +24,7 @@ model User {
notes Note[]
dailyCheckboxes DailyCheckbox[]
tasks Task[] @relation("TaskOwner")
tags Tag[] @relation("TagOwner")
@@map("users")
}
@@ -63,13 +64,16 @@ model Task {
model Tag {
id String @id @default(cuid())
name String @unique
name String
color String @default("#6b7280")
isPinned Boolean @default(false)
ownerId String // Chaque tag appartient à un utilisateur
owner User @relation("TagOwner", fields: [ownerId], references: [id], onDelete: Cascade)
taskTags TaskTag[]
primaryTasks Task[] @relation("PrimaryTag")
noteTags NoteTag[]
@@unique([name, ownerId]) // Un nom de tag unique par utilisateur
@@map("tags")
}