From 5234428cc35cc9c614e10fed1b2f27c38bddad12 Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Thu, 27 Nov 2025 12:49:33 +0100 Subject: [PATCH] chore: init --- .cursor/.DS_Store | Bin 0 -> 6148 bytes .cursor/rules/api-routes.mdc | 32 ++ .cursor/rules/business-logic-separation.mdc | 167 +++++++++++ .cursor/rules/clients.mdc | 31 ++ .cursor/rules/components.mdc | 28 ++ .cursor/rules/css-variables-theme.mdc | 167 +++++++++++ .cursor/rules/project-structure.mdc | 30 ++ .cursor/rules/server-actions.mdc | 113 +++++++ .cursor/rules/services.mdc | 42 +++ .cursor/rules/todo-tracking.mdc | 54 ++++ devbook.md | 313 ++++++++++++++++++++ 11 files changed, 977 insertions(+) create mode 100644 .cursor/.DS_Store create mode 100644 .cursor/rules/api-routes.mdc create mode 100644 .cursor/rules/business-logic-separation.mdc create mode 100644 .cursor/rules/clients.mdc create mode 100644 .cursor/rules/components.mdc create mode 100644 .cursor/rules/css-variables-theme.mdc create mode 100644 .cursor/rules/project-structure.mdc create mode 100644 .cursor/rules/server-actions.mdc create mode 100644 .cursor/rules/services.mdc create mode 100644 .cursor/rules/todo-tracking.mdc create mode 100644 devbook.md diff --git a/.cursor/.DS_Store b/.cursor/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..29c219af62b40668953951840e9e8e2cb7c6be6a GIT binary patch literal 6148 zcmeH~J&pn~427S8m5^vCDbsKOZV;j21bYFr3*AUaAo?7ApB*>MZjDB(XUTc76VK0A zOvV80_`Do|Er2!M6?-2hW{f{@#}gy2cw8Rej9nDcwNtBi3o^*2#A0P zh`@{p#39b}e>0~34a%#zaHMMo^<*;l%EbnaI#n7ym!wLhM)esFLAOaHt%N}q2{6EqE>i;Jt z3PnH!{uu#V4WGl2FO_HOuh;YZIkP@*bZTtp@bVMDz>ne`J&fzcC)AqSx-vu4k3eA1 JAOdeC@B?MJ6QlqD literal 0 HcmV?d00001 diff --git a/.cursor/rules/api-routes.mdc b/.cursor/rules/api-routes.mdc new file mode 100644 index 0000000..36409d5 --- /dev/null +++ b/.cursor/rules/api-routes.mdc @@ -0,0 +1,32 @@ +--- +globs: app/api/**/*.ts +--- + +# API Routes Rules + +1. Routes MUST only use services for data access +2. Routes MUST handle input validation +3. Routes MUST return typed responses +4. Routes MUST use proper error handling + +Example of correct API route: + +```typescript +import { MyService } from "@/services/my-service"; + +export async function GET(request: Request) { + try { + const service = new MyService(pool); + const data = await service.getData(); + return Response.json(data); + } catch (error) { + return Response.error(); + } +} +``` + +❌ FORBIDDEN: + +- Direct database queries +- Business logic implementation +- Untyped responses diff --git a/.cursor/rules/business-logic-separation.mdc b/.cursor/rules/business-logic-separation.mdc new file mode 100644 index 0000000..7694c79 --- /dev/null +++ b/.cursor/rules/business-logic-separation.mdc @@ -0,0 +1,167 @@ +--- +alwaysApply: true +description: Enforce business logic separation between frontend and backend +--- + +# Business Logic Separation Rules + +## Core Principle: NO Business Logic in Frontend + +All business logic, data processing, and domain rules MUST be implemented in the backend services layer. The frontend is purely for presentation and user interaction. + +## ✅ ALLOWED in Frontend ([src/components/](mdc:src/components/), [src/hooks/](mdc:src/hooks/), [src/clients/](mdc:src/clients/)) + +### Components +- UI rendering and presentation logic +- Form validation (UI-level only, not business rules) +- User interaction handling (clicks, inputs, navigation) +- Visual state management (loading, errors, UI states) +- Data formatting for display purposes only + +### Hooks +- React state management +- API call orchestration (using clients) +- UI-specific logic (modals, forms, animations) +- Data fetching and caching coordination + +### Clients +- HTTP requests to API routes +- Request/response transformation (serialization only) +- Error handling and retry logic +- Authentication token management + +## ❌ FORBIDDEN in Frontend + +### Business Rules +```typescript +// ❌ BAD: Business logic in component +const TaskCard = ({ task }) => { + const canEdit = task.status === 'open' && task.assignee === currentUser.id; + const priority = task.dueDate < new Date() ? 'high' : 'normal'; + // This is business logic! +} + +// ✅ GOOD: Get computed values from backend +const TaskCard = ({ task }) => { + const { canEdit, priority } = task; // Computed by backend service +} +``` + +### Data Processing +```typescript +// ❌ BAD: Data transformation in frontend +const processJiraTasks = (tasks) => { + return tasks.map(task => ({ + ...task, + normalizedStatus: mapJiraStatus(task.status), + estimatedHours: calculateEstimate(task.storyPoints) + })); +} + +// ✅ GOOD: Data already processed by backend service +const { processedTasks } = await tasksClient.getTasks(); +``` + +### Domain Logic +```typescript +// ❌ BAD: Domain calculations in frontend +const calculateTeamVelocity = (sprints) => { + // Complex business calculation +} + +// ✅ GOOD: Domain logic in service +// This belongs in services/team-analytics.ts +``` + +## ✅ REQUIRED in Backend ([src/services/](mdc:src/services/), [src/app/api/](mdc:src/app/api/)) + +### Services Layer +- All business rules and domain logic +- Data validation and processing +- Integration with external APIs (Jira, macOS Reminders) +- Complex calculations and algorithms +- Data aggregation and analytics +- Permission and authorization logic + +### API Routes +- Input validation and sanitization +- Service orchestration +- Response formatting +- Error handling and logging +- Authentication and authorization + +## Implementation Pattern + +### ✅ Correct Flow +``` +User Action → Component → Client → API Route → Service → Database + ↑ ↓ + Pure UI Logic Business Logic +``` + +### ❌ Incorrect Flow +``` +User Action → Component with Business Logic → Database +``` + +## Examples + +### Task Status Management +```typescript +// ❌ BAD: In component +const updateTaskStatus = (taskId, newStatus) => { + if (newStatus === 'done' && !task.hasAllSubtasks) { + throw new Error('Cannot complete task with pending subtasks'); + } + // Business rule in frontend! +} + +// ✅ GOOD: In services/task-processor.ts +export const updateTaskStatus = async (taskId: string, newStatus: TaskStatus) => { + const task = await getTask(taskId); + + // Business rules in service + if (newStatus === 'done' && !await hasAllSubtasksCompleted(taskId)) { + throw new BusinessError('Cannot complete task with pending subtasks'); + } + + return await updateTask(taskId, { status: newStatus }); +} +``` + +### Team Analytics +```typescript +// ❌ BAD: In component +const TeamDashboard = () => { + const calculateBurndown = (tasks) => { + // Complex business calculation in component + } +} + +// ✅ GOOD: In services/team-analytics.ts +export const getTeamBurndown = async (teamId: string, sprintId: string) => { + // All calculation logic in service + const tasks = await getSprintTasks(sprintId); + return calculateBurndownMetrics(tasks); +} +``` + +## Enforcement + +When reviewing code: +1. **Components**: Should only contain JSX, event handlers, and UI state +2. **Hooks**: Should only orchestrate API calls and manage React state +3. **Clients**: Should only make HTTP requests and handle responses +4. **Services**: Should contain ALL business logic and data processing +5. **API Routes**: Should validate input and call appropriate services + +## Red Flags + +Watch for these patterns that indicate business logic in frontend: +- Complex calculations in components/hooks +- Business rule validation in forms +- Data transformation beyond display formatting +- Domain-specific constants and rules +- Integration logic with external systems + +Remember: **The frontend is a thin presentation layer. All intelligence lives in the backend.** \ No newline at end of file diff --git a/.cursor/rules/clients.mdc b/.cursor/rules/clients.mdc new file mode 100644 index 0000000..3f35f89 --- /dev/null +++ b/.cursor/rules/clients.mdc @@ -0,0 +1,31 @@ +--- +globs: clients/**/*.ts +--- + +# HTTP Clients Rules + +1. All HTTP calls MUST be in clients/domains/ +2. Each domain MUST have its own client +3. Clients MUST use the base HTTP client +4. Clients MUST type their responses + +Example of correct client: + +```typescript +import { HttpClient } from "@/clients/base/http-client"; +import { MyData } from "@/lib/types"; + +export class MyClient { + constructor(private httpClient: HttpClient) {} + + async getData(): Promise { + return this.httpClient.get("/api/data"); + } +} +``` + +❌ FORBIDDEN: + +- Direct fetch calls +- Business logic in clients +- Untyped responses diff --git a/.cursor/rules/components.mdc b/.cursor/rules/components.mdc new file mode 100644 index 0000000..62c178d --- /dev/null +++ b/.cursor/rules/components.mdc @@ -0,0 +1,28 @@ +--- +globs: src/components/**/*.tsx +--- + +# Components Rules + +1. UI components MUST be in src/components/ui/ +2. Feature components MUST be in their feature folder +3. Components MUST use clients for data fetching +4. Components MUST be properly typed + +Example of correct component: + +```typescript +import { useMyClient } from '@/hooks/use-my-client'; + +export const MyComponent = () => { + const { data } = useMyClient(); + return
{data.map(item => )}
; +}; +``` + +❌ FORBIDDEN: + +- Direct service usage +- Direct database queries +- Direct fetch calls +- Untyped props diff --git a/.cursor/rules/css-variables-theme.mdc b/.cursor/rules/css-variables-theme.mdc new file mode 100644 index 0000000..e8beda0 --- /dev/null +++ b/.cursor/rules/css-variables-theme.mdc @@ -0,0 +1,167 @@ +--- +alwaysApply: true +description: CSS Variables theme system best practices +--- + +# CSS Variables Theme System + +## Core Principle: Pure CSS Variables for Theming + +This project uses **CSS Variables exclusively** for theming. No Tailwind `dark:` classes or conditional CSS classes. + +## ✅ Architecture Pattern + +### CSS Structure +```css +:root { + /* Light theme (default values) */ + --background: #f1f5f9; + --foreground: #0f172a; + --primary: #0891b2; + --success: #059669; + --destructive: #dc2626; + --accent: #d97706; + --purple: #8b5cf6; + --yellow: #eab308; + --green: #059669; + --blue: #2563eb; + --gray: #6b7280; + --gray-light: #e5e7eb; +} + +.dark { + /* Dark theme (override values) */ + --background: #1e293b; + --foreground: #f1f5f9; + --primary: #06b6d4; + --success: #10b981; + --destructive: #ef4444; + --accent: #f59e0b; + --purple: #8b5cf6; + --yellow: #eab308; + --green: #10b981; + --blue: #3b82f6; + --gray: #9ca3af; + --gray-light: #374151; +} +``` + +### Theme Application +- **Single source of truth**: [ThemeContext.tsx](mdc:src/contexts/ThemeContext.tsx) applies theme class to `document.documentElement` +- **No duplication**: Theme is applied only once, not in multiple places +- **SSR safe**: Initial theme from server-side preferences + +## ✅ Component Usage Patterns + +### Correct: Using CSS Variables +```tsx +// ✅ GOOD: CSS Variables in className +
+ +// ✅ GOOD: CSS Variables in style prop +
+ +// ✅ GOOD: CSS Variables with color-mix for transparency +
+``` + +### ❌ Forbidden: Tailwind Dark Mode Classes +```tsx +// ❌ BAD: Tailwind dark: classes +
+ +// ❌ BAD: Conditional classes +
+ +// ❌ BAD: Hardcoded colors +
+``` + +## ✅ Color System + +### Semantic Color Tokens +- `--background`: Main background color +- `--foreground`: Main text color +- `--card`: Card/panel background +- `--card-hover`: Card hover state +- `--card-column`: Column background (darker than cards) +- `--border`: Border color +- `--input`: Input field background +- `--primary`: Primary brand color +- `--primary-foreground`: Text on primary background +- `--muted`: Muted text color +- `--muted-foreground`: Secondary text color +- `--accent`: Accent color (orange/amber) +- `--destructive`: Error/danger color (red) +- `--success`: Success color (green) +- `--purple`: Purple accent +- `--yellow`: Yellow accent +- `--green`: Green accent +- `--blue`: Blue accent +- `--gray`: Gray color +- `--gray-light`: Light gray background + +### Color Mixing Patterns +```css +/* Background with transparency */ +background-color: color-mix(in srgb, var(--primary) 10%, transparent); + +/* Border with transparency */ +border-color: color-mix(in srgb, var(--primary) 20%, var(--border)); + +/* Text with opacity */ +color: color-mix(in srgb, var(--destructive) 80%, transparent); +``` + +## ✅ Theme Context Usage + +### ThemeProvider Setup +```tsx +// In layout.tsx + + {children} + +``` + +### Component Usage +```tsx +import { useTheme } from '@/contexts/ThemeContext'; + +function MyComponent() { + const { theme, toggleTheme, setTheme } = useTheme(); + + return ( + + ); +} +``` + +## ✅ Future Extensibility + +This system is designed to support: +- **Custom color themes**: Easy to add new color variables +- **User preferences**: Colors can be dynamically changed +- **Theme presets**: Multiple predefined themes +- **Accessibility**: High contrast modes + +## 🚨 Anti-patterns to Avoid + +1. **Don't mix approaches**: Never use both CSS variables and Tailwind dark: classes +2. **Don't duplicate theme application**: Theme should be applied only in ThemeContext +3. **Don't hardcode colors**: Always use semantic color tokens +4. **Don't use conditional classes**: Use CSS variables instead +5. **Don't forget transparency**: Use `color-mix()` for semi-transparent colors + +## 📁 Key Files + +- [globals.css](mdc:src/app/globals.css) - CSS Variables definitions +- [ThemeContext.tsx](mdc:src/contexts/ThemeContext.tsx) - Theme management +- [UserPreferencesContext.tsx](mdc:src/contexts/UserPreferencesContext.tsx) - Preferences sync +- [layout.tsx](mdc:src/app/layout.tsx) - Theme provider setup + +Remember: **CSS Variables are the single source of truth for theming. Keep it pure and consistent.** \ No newline at end of file diff --git a/.cursor/rules/project-structure.mdc b/.cursor/rules/project-structure.mdc new file mode 100644 index 0000000..73690b5 --- /dev/null +++ b/.cursor/rules/project-structure.mdc @@ -0,0 +1,30 @@ +--- +alwaysApply: true +--- + +# Project Structure Rules + +1. Backend: + - [src/services/](mdc:src/services/) - ALL database access + - [src/app/api/](mdc:src/app/api/) - API routes using services + +2. Frontend: + - [src/clients/](mdc:src/clients/) - HTTP clients + - [src/components/](mdc:src/components/) - React components (organized by domain) + - [src/hooks/](mdc:src/hooks/) - React hooks + +3. Shared: + - [src/lib/](mdc:src/lib/) - Types and utilities + - [scripts/](mdc:scripts/) - Utility scripts + +Key Files: + +- [src/services/database.ts](mdc:src/services/database.ts) - Database pool +- [src/clients/base/http-client.ts](mdc:src/clients/base/http-client.ts) - Base HTTP client +- [src/lib/types.ts](mdc:src/lib/types.ts) - Shared types + +❌ FORBIDDEN: + +- Database access outside src/services/ +- HTTP calls outside src/clients/ +- Business logic in src/components/ diff --git a/.cursor/rules/server-actions.mdc b/.cursor/rules/server-actions.mdc new file mode 100644 index 0000000..ec2fdb1 --- /dev/null +++ b/.cursor/rules/server-actions.mdc @@ -0,0 +1,113 @@ +--- +alwaysApply: true +description: Guide for when to use Server Actions vs API Routes in Next.js App Router +--- + +# Server Actions vs API Routes - Decision Guide + +## ✅ USE SERVER ACTIONS for: + +### Quick Actions & Mutations +- **TaskCard actions**: `updateTaskStatus()`, `updateTaskTitle()`, `deleteTask()` +- **Daily checkboxes**: `toggleCheckbox()`, `addCheckbox()`, `updateCheckbox()` +- **User preferences**: `updateTheme()`, `updateViewPreferences()`, `updateFilters()` +- **Simple CRUD**: `createTag()`, `updateTag()`, `deleteTag()` + +### Characteristics of Server Action candidates: +- Simple, frequent mutations +- No complex business logic +- Used in interactive components (forms, buttons, toggles) +- Need immediate UI feedback with `useTransition` +- Benefit from automatic cache revalidation + +## ❌ KEEP API ROUTES for: + +### Complex Endpoints +- **Initial data fetching**: `GET /api/tasks` with complex filters +- **External integrations**: `POST /api/jira/sync` with complex logic +- **Analytics & reports**: Complex data aggregation +- **Public API**: Endpoints that might be called from mobile/external + +### Characteristics that require API Routes: +- Complex business logic or data processing +- Multiple service orchestration +- Need for HTTP monitoring/logging +- External consumption (mobile apps, webhooks) +- Real-time features (WebSockets, SSE) +- File uploads or special content types + +## 🔄 Implementation Pattern + +### Server Actions Structure +```typescript +// actions/tasks.ts +'use server' + +import { tasksService } from '@/services/tasks'; +import { revalidatePath } from 'next/cache'; + +export async function updateTaskStatus(taskId: string, status: TaskStatus) { + try { + const task = await tasksService.updateTask(taskId, { status }); + revalidatePath('/'); // Auto cache invalidation + return { success: true, data: task }; + } catch (error) { + return { success: false, error: error.message }; + } +} +``` + +### Component Usage with useTransition +```typescript +// components/TaskCard.tsx +'use client'; + +import { updateTaskStatus } from '@/actions/tasks'; +import { useTransition } from 'react'; + +export function TaskCard({ task }) { + const [isPending, startTransition] = useTransition(); + + const handleStatusChange = (status) => { + startTransition(async () => { + const result = await updateTaskStatus(task.id, status); + if (!result.success) { + // Handle error + } + }); + }; + + return ( +
+ {/* UI with loading state */} +
+ ); +} +``` + +## 🏗️ Migration Strategy + +When migrating from API Routes to Server Actions: + +1. **Create server action** in `actions/` directory +2. **Update component** to use server action directly +3. **Remove API route** (PATCH, POST, DELETE for mutations) +4. **Simplify client** (remove mutation methods, keep GET only) +5. **Update hooks** to use server actions instead of HTTP calls + +## 🎯 Benefits of Server Actions + +- **🚀 Performance**: No HTTP serialization overhead +- **🔄 Cache intelligence**: Automatic revalidation with `revalidatePath()` +- **📦 Bundle reduction**: Less client-side HTTP code +- **⚡ UX**: Native loading states with `useTransition` +- **🎯 Simplicity**: Direct service calls, less boilerplate + +## 🚨 Anti-patterns to Avoid + +- Don't use server actions for complex data fetching +- Don't use server actions for endpoints that need HTTP monitoring +- Don't use server actions for public API endpoints +- Don't mix server actions with client-side state management for the same data + +Remember: Server Actions are for **direct mutations**, API Routes are for **complex operations** and **public interfaces**. \ No newline at end of file diff --git a/.cursor/rules/services.mdc b/.cursor/rules/services.mdc new file mode 100644 index 0000000..1314414 --- /dev/null +++ b/.cursor/rules/services.mdc @@ -0,0 +1,42 @@ +--- +globs: src/services/*.ts +--- + +# Services Rules + +1. Services MUST contain ALL PostgreSQL queries +2. Services are the ONLY layer allowed to communicate with the database +3. Each service MUST: + - Use the pool from [src/services/database.ts](mdc:src/services/database.ts) + - Implement proper transaction management + - Handle errors and logging + - Validate data before insertion + - Have a clear interface + +Example of correct service implementation: + +```typescript +export class MyService { + constructor(private pool: Pool) {} + + async myMethod(): Promise { + const client = await this.pool.connect(); + try { + await client.query("BEGIN"); + // ... queries + await client.query("COMMIT"); + } catch (error) { + await client.query("ROLLBACK"); + throw error; + } finally { + client.release(); + } + } +} +``` + +❌ FORBIDDEN: + +- Direct database queries outside src/services +- Raw SQL in API routes +- Database logic in components diff --git a/.cursor/rules/todo-tracking.mdc b/.cursor/rules/todo-tracking.mdc new file mode 100644 index 0000000..3ce0f8c --- /dev/null +++ b/.cursor/rules/todo-tracking.mdc @@ -0,0 +1,54 @@ +--- +alwaysApply: true +description: Automatic TODO tracking and task completion management +--- + +# TODO Task Tracking Rules + +## Automatic Task Completion + +Whenever you complete a task or implement a feature mentioned in [TODO.md](mdc:TODO.md), you MUST: + +1. **Immediately update the TODO.md** by changing `- [ ]` to `- [x]` for the completed task +2. **Use the exact task description** from the TODO - don't modify the text +3. **Update related sub-tasks** if completing a parent task affects them +4. **Add completion timestamp** in a comment if the task was significant + +## Task Completion Examples + +### ✅ Correct completion marking: +```markdown +- [x] Initialiser Next.js avec TypeScript +- [x] Configurer ESLint, Prettier +- [x] Setup structure de dossiers selon les règles du workspace +``` + +### ✅ With timestamp for major milestones: +```markdown +- [x] Créer `services/database.ts` - Pool de connexion DB +``` + +## When to Update TODO.md + +Update the TODO immediately after: +- Creating/modifying files mentioned in tasks +- Implementing features described in tasks +- Completing configuration steps +- Finishing any work item listed in the TODO + +## Task Dependencies + +When completing tasks, consider: +- **Parent tasks**: Mark parent complete only when ALL sub-tasks are done +- **Blocking tasks**: Some tasks may unblock others - mention this in updates +- **Phase completion**: Note when entire phases are completed + +## Progress Tracking + +Always maintain visibility of: +- Current phase progress +- Next logical task to tackle +- Any blockers or issues encountered +- Completed vs remaining work ratio + +This ensures the TODO.md remains an accurate reflection of project progress and helps maintain momentum. \ No newline at end of file diff --git a/devbook.md b/devbook.md new file mode 100644 index 0000000..689f0b7 --- /dev/null +++ b/devbook.md @@ -0,0 +1,313 @@ +# SWOT Manager - Development Book + +Application de gestion d'ateliers SWOT pour entretiens managériaux. + +## Stack Technique + +- **Framework**: Next.js 15 (App Router) +- **Styling**: Tailwind CSS + CSS Variables theming +- **Auth**: NextAuth.js v5 +- **Database**: PostgreSQL + Prisma +- **Drag & Drop**: @hello-pangea/dnd (fork maintenu de react-beautiful-dnd) +- **State**: React Context + Server Actions + +--- + +## Phase 1 : Setup Initial + +- [ ] Initialiser Next.js 15 avec TypeScript +- [ ] Configurer Tailwind CSS avec le système de CSS Variables +- [ ] Setup ESLint + Prettier +- [ ] Créer la structure de dossiers + ``` + src/ + ├── app/ + │ ├── api/ + │ ├── (auth)/ + │ │ ├── login/ + │ │ └── register/ + │ ├── sessions/ + │ │ ├── [id]/ + │ │ └── new/ + │ └── layout.tsx + ├── components/ + │ ├── ui/ # Composants réutilisables + │ ├── swot/ # Composants SWOT + │ └── layout/ # Header, Sidebar, etc. + ├── services/ # Logique métier + DB + ├── lib/ # Types, utils + ├── contexts/ # React Contexts + └── actions/ # Server Actions + ``` +- [ ] Configurer les CSS Variables pour le theming (light/dark) + +--- + +## Phase 2 : Base de Données + +- [ ] Installer et configurer Prisma +- [ ] Créer le schéma de base de données : + ```prisma + model User { + id String @id @default(cuid()) + email String @unique + name String? + password String + sessions Session[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + } + + model Session { + id String @id @default(cuid()) + title String + collaborator String # Nom du collaborateur évalué + date DateTime @default(now()) + userId String + user User @relation(fields: [userId], references: [id]) + items SwotItem[] + actions Action[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + } + + enum SwotCategory { + STRENGTH + WEAKNESS + OPPORTUNITY + THREAT + } + + model SwotItem { + id String @id @default(cuid()) + content String + category SwotCategory + order Int @default(0) + sessionId String + session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade) + actionLinks ActionLink[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + } + + model Action { + id String @id @default(cuid()) + title String + description String? + priority Int @default(0) # 0=low, 1=medium, 2=high + status String @default("todo") # todo, in_progress, done + dueDate DateTime? + sessionId String + session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade) + links ActionLink[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + } + + model ActionLink { + id String @id @default(cuid()) + actionId String + action Action @relation(fields: [actionId], references: [id], onDelete: Cascade) + swotItemId String + swotItem SwotItem @relation(fields: [swotItemId], references: [id], onDelete: Cascade) + + @@unique([actionId, swotItemId]) + } + ``` +- [ ] Générer le client Prisma +- [ ] Créer les migrations initiales +- [ ] Créer le service database.ts (pool de connexion) + +--- + +## Phase 3 : Authentification + +- [ ] Installer NextAuth.js v5 +- [ ] Configurer le provider Credentials (email/password) +- [ ] Créer les pages : + - [ ] `/login` - Page de connexion + - [ ] `/register` - Page d'inscription +- [ ] Créer le service auth.ts +- [ ] Protéger les routes avec middleware +- [ ] Créer le composant AuthProvider + +--- + +## Phase 4 : Layout & Navigation + +- [ ] Créer le layout principal avec : + - [ ] Header avec navigation et user menu + - [ ] Theme toggle (dark/light) +- [ ] Créer les composants UI de base : + - [ ] Button + - [ ] Card + - [ ] Input + - [ ] Modal + - [ ] Badge +- [ ] Créer la page d'accueil `/` - Dashboard avec liste des sessions + +--- + +## Phase 5 : Gestion des Sessions SWOT + +- [ ] Créer le service `sessions.ts` +- [ ] Créer les Server Actions pour les sessions : + - [ ] `createSession` + - [ ] `updateSession` + - [ ] `deleteSession` + - [ ] `getSession` + - [ ] `getUserSessions` +- [ ] Créer les pages : + - [ ] `/sessions` - Liste des sessions + - [ ] `/sessions/new` - Création de session + - [ ] `/sessions/[id]` - Vue détaillée de la session SWOT +- [ ] Créer les composants : + - [ ] `SessionCard` - Carte de session dans la liste + - [ ] `SessionForm` - Formulaire création/édition + +--- + +## Phase 6 : Matrice SWOT Interactive + +- [ ] Installer @hello-pangea/dnd +- [ ] Créer les composants SWOT : + - [ ] `SwotBoard` - Container principal de la matrice + - [ ] `SwotQuadrant` - Un quadrant (S, W, O, T) + - [ ] `SwotCard` - Une carte dans un quadrant + - [ ] `SwotCardForm` - Formulaire ajout/édition de carte +- [ ] Implémenter le drag & drop : + - [ ] Réorganisation dans un même quadrant + - [ ] Déplacement entre quadrants +- [ ] Créer les Server Actions pour les items : + - [ ] `createSwotItem` + - [ ] `updateSwotItem` + - [ ] `deleteSwotItem` + - [ ] `reorderSwotItems` +- [ ] Édition inline des cartes + +--- + +## Phase 7 : Système de Liaison & Actions + +- [ ] Créer le mode "liaison" : + - [ ] Bouton pour activer le mode liaison + - [ ] Sélection multiple d'items SWOT + - [ ] Visualisation des items sélectionnés (highlight) +- [ ] Créer les composants Actions : + - [ ] `ActionPanel` - Panneau des actions croisées + - [ ] `ActionCard` - Une action avec ses liens + - [ ] `ActionForm` - Formulaire création/édition d'action + - [ ] `LinkedItemsBadges` - Badges des items liés +- [ ] Créer les Server Actions pour les actions : + - [ ] `createAction` + - [ ] `updateAction` + - [ ] `deleteAction` + - [ ] `linkItemToAction` + - [ ] `unlinkItemFromAction` +- [ ] Visualisation des liens sur la matrice (highlight on hover) + +--- + +## Phase 8 : Roadmap & Priorisation + +- [ ] Créer la vue Roadmap : + - [ ] `RoadmapView` - Vue timeline des actions + - [ ] Filtres par statut, priorité + - [ ] Tri par date d'échéance +- [ ] Drag & drop pour réordonner les priorités +- [ ] Mise à jour du statut des actions (todo → in_progress → done) +- [ ] Vue Kanban alternative des actions + +--- + +## Phase 9 : Export & Partage + +- [ ] Export PDF de la matrice SWOT +- [ ] Export PDF de la roadmap +- [ ] Génération de lien de partage en lecture seule +- [ ] Copie au format texte pour coller dans un email + +--- + +## Phase 10 : Polish & UX + +- [ ] Animations et transitions fluides +- [ ] États de chargement (skeletons) +- [ ] Messages de confirmation et toasts +- [ ] Raccourcis clavier : + - [ ] `N` - Nouvelle carte + - [ ] `Escape` - Annuler + - [ ] `Enter` - Valider +- [ ] Responsive design (tablette minimum) +- [ ] Mode présentation (masquer les contrôles) + +--- + +## Phase 11 : Bonus (Optionnel) + +- [ ] Templates de sessions SWOT prédéfinis +- [ ] Collaboration temps réel (plusieurs personnes sur la même session) +- [ ] Historique des modifications +- [ ] Import depuis Miro/Trello +- [ ] Intégration calendrier pour les échéances +- [ ] Notifications par email pour les deadlines + +--- + +## Notes Techniques + +### Structure des Server Actions + +```typescript +// actions/swot-items.ts +'use server' + +import { swotService } from '@/services/swot'; +import { revalidatePath } from 'next/cache'; + +export async function createSwotItem(sessionId: string, data: CreateSwotItemInput) { + const item = await swotService.createItem(sessionId, data); + revalidatePath(`/sessions/${sessionId}`); + return { success: true, data: item }; +} +``` + +### Pattern de Liaison + +```typescript +// Mode liaison : state dans le composant parent +const [linkMode, setLinkMode] = useState(false); +const [selectedItems, setSelectedItems] = useState([]); + +// Quand 2+ items sélectionnés, proposer création d'action +if (selectedItems.length >= 2) { + // Ouvrir modal de création d'action avec items pré-sélectionnés +} +``` + +### Visualisation des Liens + +- Au hover d'une action : highlight des items liés +- Au hover d'un item : highlight des actions liées +- Couleurs par type de croisement (SO, ST, WO, WT) + +--- + +## Commandes Utiles + +```bash +# Lancer le dev server +npm run dev + +# Prisma +npx prisma migrate dev --name +npx prisma generate +npx prisma studio + +# Build +npm run build + +# Lint +npm run lint +``` +