---
stepsCompleted: [1, 2, 3, 4, 5, 6, 7, 8]
inputDocuments:
  - _bmad-output/analysis/brainstorming-session-2026-01-09.md
  - _bmad-output/planning-artifacts/prd-phase1-mvp-ai.md
  - _bmad-output/planning-artifacts/ux-design-specification.md
  - docs/architecture-keep-notes.md
  - docs/data-models.md
  - docs/component-inventory.md
  - docs/integration-architecture.md
workflowType: 'architecture'
lastStep: 8
project_name: 'Keep'
user_name: 'Ramez'
date: '2026-01-10'
completedAt: '2026-01-10'
communication_language: 'French'
document_output_language: 'English'
status: 'complete'
focusArea: 'Phase 1 MVP AI - AI-Powered Note Taking Features'
---

# Architecture Decision Document

_This document builds collaboratively through step-by-step discovery. Sections are appended as we work through each architectural decision together._

---

## Project Context Analysis

### Requirements Overview

**Functional Requirements:**

Le projet **Keep (Memento Phase 1 MVP AI)** est une application brownfield qui étend une solution existante de prise de notes avec des fonctionnalités d'IA contextuelle. Les exigences fonctionnelles architecturales significatives incluent :

1. **Intelligent Title Suggestions** - Déclenchement automatique après 50+ mots sans titre, avec toast non-intrusif et 3 suggestions IA. **Implication architecturale** : Nécessite un système de détection en temps réel, débounce, et génération de titres via IA avec latence < 2s.

2. **Hybrid Semantic Search** - Recherche unifiée combinant mots-clés exacts et correspondance sémantique avec badges distinctifs. **Implication architecturale** : Vector search sur embeddings existants + indexation texte traditionnelle, fusion transparente des résultats, latence < 300ms pour 1000 notes.

3. **Paragraph-Level Reformulation** - Menu contextuel pour réécrire des paragraphes avec options (Clarifier, Raccourcir, Améliorer style). **Implication architecturale** : Composants modaux réutilisables, gestion d'état pour sélection de texte, appels IA à la demande.

4. **Memory Echo (Proactive Connections)** ⭐ - Analyse en arrière-plan des embeddings pour identifier des connexions entre notes (max 1 insight/jour). **Implication architecturale** : Traitement asynchrone non-bloquant (< 100ms UI freeze), système de scoring cosine similarity > 0.75, notification contextuelle.

5. **AI Settings Panel** - Page `/settings/ai` avec contrôles granulaires ON/OFF par feature et slider de fréquence. **Implication architecturale** : Persistance des préférences utilisateur, architecture de configuration extensible.

**Non-Functional Requirements:**

Les NFRs critiques qui façonneront l'architecture :

**Performance:**
- Recherche sémantique < 300ms (1000 notes)
- Suggestions titres < 2s après détection
- Memory Echo: traitement background avec UI freeze < 100ms
- Auto-tagging suggestions < 1.5s après fin de saisie

**Privacy & Security:**
- Support Ollama 100% local (zéro appel API externe)
- Support OpenAI cloud avec chiffrage des clés API
- Données utilisateur never quittent l'infrastructure locale avec Ollama
- Vérifiable dans DevTools (Max's use case)

**Multilingual Architecture:**
- Prompts système en anglais (stabilité des modèles)
- Détection automatique langue par note (FR, EN, ES, DE minimum)
- Données utilisateur en langue locale
- Architecture prête pour expansion internationale

**Compatibility & Maintainability:**
- **Zero Breaking Changes** : Toutes features existantes doivent continuer à fonctionner
- Multi-provider support via factory pattern (existant)
- Extensions Prisma schema (pas de réécriture)
- API Routes namespace `/api/ai/` (respect structure existante)

**Scalability Constraints:**
- Zéro DevOps (hosting managé Vercel/Netlify)
- SQLite en prod (pas de vector DB séparée)
- Modèles locaux via Ollama ou API externes
- Rate limiting par utilisateur (Léa's admin use case)

**Scale & Complexity:**

- **Primary domain:** Full-stack web application with AI integration (brownfield extension)
- **Complexity level:** Medium
- **Estimated architectural components:** 12-15 major components

**Complexity Drivers:**
- Real-time features (détection contextuelle 50+ mots, toast notifications)
- Multi-provider AI abstraction (Ollama local + OpenAI cloud)
- Vector search + traditional search fusion
- Background processing without UI blocking
- Granular per-feature ON/OFF settings
- Multilingual detection and processing
- Privacy-first architecture (local vs cloud)

### Technical Constraints & Dependencies

**Existing Stack (Must Preserve):**
- Next.js 16.1.1 (App Router) + React 19.2.3 + TypeScript 5
- Prisma 5.22.0 ORM + SQLite (better-sqlite3)
- Vercel AI SDK 6.0.23 + OpenAI/Ollama providers
- NextAuth 5.0.0-beta.30 (authentication)

**Current AI Capabilities (Already Implemented):**
- ✅ Auto-tagging with embeddings
- ✅ Multi-provider support (OpenAI, Ollama)
- ✅ Factory pattern for AI providers

**Phase 1 Must Integrate With:**
- API Routes in `/api/ai/` namespace
- Components in shared structure
- Prisma schema extensions (not rewrites)
- Existing user authentication system
- Current note storage (SQLite)

**Technical Constraints:**
- No native mobile apps (web responsive only)
- Offline mode: None for MVP (Phase 2: PWA)
- SQLite with embeddings in same DB (no separate vector DB)
- No dedicated infrastructure (Vercel/Netlify hosting)

**External Dependencies:**
- Ollama (local installation optional for users)
- OpenAI API (cloud option for non-technical users)
- Embeddings models (multi-language support)
- Next.js 16+ (App Router patterns)

### Cross-Cutting Concerns Identified

**1. Privacy & Data Protection**
- **Impact:** Toute l'architecture IA doit supporter deux modes : local (Ollama, 0 data exfiltration) et cloud (OpenAI)
- **Requirement:** Vérifiable dans DevTools, indicateurs de connexion clairs, chiffrage des clés API
- **Affected Components:** AI provider factory, settings UI, connection status indicators

**2. Performance & Non-Blocking AI**
- **Impact:** Les appels IA ne doivent jamais bloquer l'UI
- **Requirement:** Traitement asynchrone pour Memory Echo, debounce pour suggestions, loading states clairs
- **Affected Components:** Title suggestions (debounce), Memory Echo (background job), search (optimistic UI)

**3. Multilingual Processing**
- **Impact:** Architecture doit supporter prompts système anglais + données utilisateur multi-langues
- **Requirement:** Détection automatique par note, embeddings multi-langues, respect des langues (FR, EN, ES, DE)
- **Affected Components:** AI service layer, embedding generation, language detection service

**4. User Control & Transparency**
- **Impact:** Chaque feature IA doit être contrôlable indépendamment
- **Requirement:** Settings granulaires ON/OFF, feedback 👍👎 pour apprentissage, indicateurs visuels (badges)
- **Affected Components:** Settings panel, all AI UI components, feedback tracking system

**5. Extensibility for Future Phases**
- **Impact:** Architecture Phase 1 ne doit pas bloquer Phase 2/3 (score confiance, feedback généralisé, mode conservateur)
- **Requirement:** Factory pattern existant, schema extensible, préparation pour système de confiance 3 couches
- **Affected Components:** AI provider factory, Prisma schema design, feedback collection (préparer pour généralisation)

**6. Brownfield Integration**
- **Impact:** Toutes nouvelles features doivent coexister avec features existantes sans breaking changes
- **Requirement:** Respect patterns existants, extensions pas réécritures, tests de non-régression
- **Affected Components:** Toutes les nouvelles routes API, components, Prisma migrations

**7. Analytics & Monitoring**
- **Impact:** Nécessité de tracker l'adoption et l'efficacité des features IA
- **Requirement:** Métriques temps réel (usage, coûts, feedback), dashboard admin (Léa's use case)
- **Affected Components:** Analytics service, admin dashboard, cost tracking per user

---

## Existing Architecture Review

### Primary Technology Domain

**Application Type:** Full-stack brownfield web application with AI integration
**Current Stack:** Next.js 16.1.1 (App Router) + React 19.2.3 + Prisma 5.22.0 + SQLite

### Architecture Overview

**Current Foundation - Keep Notes (Memento Web App):**

Le projet dispose d'une architecture JAMstack mature avec :

**Frontend:**
- React 19.2.3 avec Server Components (App Router)
- Tailwind CSS 4 pour le styling
- Radix UI pour les primitives accessibles
- 20+ composants métier organisés par domaine
- Masonry grid layout (Muuri) avec drag-and-drop (@dnd-kit)

**Backend (Integrated):**
- Next.js API Routes (REST)
- Server Actions pour les mutations
- Prisma 5.22.0 ORM avec better-sqlite3
- NextAuth 5.0.0-beta.30 (authentification)
- Vercel AI SDK 6.0.23 (OpenAI + Ollama providers)

**Database:**
- SQLite (prisma/dev.db)
- 7 modèles : User, Account, Session, VerificationToken, Note, Label, SystemConfig
- Embeddings vectoriels stockés en JSON dans Note.embedding
- 13 migrations déjà appliquées

### Architectural Patterns Established

**1. Factory Pattern pour AI Providers** ✅ (DÉJÀ IMPLÉMENTÉ)

Localisation : `lib/ai/providers/`

```typescript
// Factory existant
export function createProvider(provider: string) {
  switch (provider) {
    case 'openai': return new OpenAIProvider()
    case 'ollama': return new OllamaProvider()
  }
}
```

**Implication pour Phase 1 :** Ce pattern est déjà en place et doit être étendu, pas remplacé. Les nouveaux endpoints IA (titles, refactor, echo) s'intégreront dans cette architecture.

**2. State Management Strategy**

- **Aucune librairie d'état global** (Pas de Redux, Zustand)
- React Cache pour le cache serveur
- Server Actions pour les mutations
- Context pour session utilisateur et thème
- URL State pour les filtres/recherche

**Implication pour Phase 1 :** Maintenir cette approche légère. Les features IA utiliseront React Query ou équivalent si nécessaire pour le cache client.

**3. Component Architecture**

**Hiérarchie existante :**
```
Layout Components (Header, Sidebar, MasonryGrid)
  └── NoteCard
      ├── NoteEditor
      │   ├── NoteChecklist
      │   ├── NoteImages
      │   └── EditorImages
      └── NoteActions

Label Management
  ├── LabelBadge, LabelFilter, LabelSelector
  ├── LabelManager → LabelManagementDialog
  └── GhostTags (floating tags)
```

**20+ composants métier** documentés dans `docs/component-inventory.md`

**Implication pour Phase 1 :** Les nouveaux composants IA (`<AiSuggestion />`, `<AiSettingsPanel />`, `<MemoryEchoNotification />`) doivent suivre les mêmes patterns de composition et de styling.

**4. API Architecture**

**Routes existantes :**
- `/api/notes` (CRUD)
- `/api/labels` (CRUD)
- `/api/auth/[...nextauth]` (auth)
- `/api/ai/tags` (auto-tagging DÉJÀ implémenté)
- `/api/upload` (file upload)
- `/api/admin/*` (admin endpoints)

**Response Format standardisé :**
```json
{
  "success": true|false,
  "data": any,
  "error": string  // seulement quand success: false
}
```

**Implication pour Phase 1 :** Les nouveaux endpoints IA doivent suivre ce format :
- `POST /api/ai/titles` (suggestions de titres)
- `POST /api/ai/search` (recherche sémantique)
- `POST /api/ai/refactor` (reformulation)
- `POST /api/ai/echo` (Memory Echo)

**5. Database Schema Extensions**

**Modèle Note existant :**
```prisma
model Note {
  id                  String    @id
  title               String?
  content             String
  embedding           String?   // DÉJÀ EXISTE pour auto-tagging
  userId              String?
  isPinned            Boolean   @default(false)
  isArchived          Boolean   @default(false)
  // ... autres champs
}
```

**Implication pour Phase 1 :** Extensions nécessaires (PAS de réécriture) :
```prisma
// Extensions proposées pour Phase 1
model Note {
  // ... champs existants

  // Nouveaux champs Phase 1
  autoGenerated       Boolean   @default(false)  // True si titre/tags par IA
  aiConfidence        Int?                        // Score 0-100 si généré par IA
  language            String?                     // Langue détectée: 'fr', 'en', etc.
  lastAiAnalysis      DateTime?                   // Timestamp dernière analyse IA
}

// Nouveau modèle pour feedback utilisateur
model AiFeedback {
  id                String    @id @default(cuid())
  noteId            String
  userId            String?
  feedbackType      String    // thumbs_up, thumbs_down, correction
  feature           String    // title_suggestion, memory_echo, search
  originalContent   String
  correctedContent  String?
  createdAt         DateTime  @default(now())

  note              Note      @relation(fields: [noteId], references: [id], onDelete: Cascade)
  user              User?     @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@index([noteId])
  @@index([userId])
  @@index([feature])
}
```

**6. Data Flow Pattern**

**Pattern actuel :**
```
User Action
    ↓
Server Action / API Call
    ↓
Prisma Mutation
    ↓
Database Update
    ↓
Revalidate / Refetch
    ↓
UI Update
```

**Implication pour Phase 1 :** Les features IA asynchrones (Memory Echo, suggestions en arrière-plan) nécessiteront une variante :
```
Background Trigger
    ↓
Async Job (Cron ou Server Action)
    ↓
AI Processing (non-blocking)
    ↓
Database Update
    ↓
Revalidate + Optimistic UI
    ↓
Toast Notification / Badge Update
```

### What Must Be Preserved

**✅ Constraints Non-Negotiables :**

1. **Zero Breaking Changes** - Toutes les features existantes doivent continuer à fonctionner
2. **Factory Pattern AI** - Conserver `lib/ai/providers/` et l'abstraction
3. **API Namespace `/api/ai/`** - Respecter la structure existante
4. **Response Format** - Maintenir `{success, data, error}`
5. **Component Patterns** - Suivre les conventions existantes (controlled components, compound components)
6. **SQLite + Prisma** - Pas de migration vers une autre DB pour Phase 1
7. **Authentification NextAuth** - Utiliser la session existante pour les endpoints IA

**⚠️ Technical Debt à Conserver Temporairement :**

- Labels: `Label.userId` optional (migration artifact)
- `Note.labels` JSON array + `Label` table (deux approches coexistent)
- Images: Base64 dans `Note.images` (considérer migration vers CDN plus tard)

### What Can Be Extended

**🚀 Extensions pour Phase 1 MVP AI :**

**1. Nouveaux Services**
- `lib/ai/services/title-suggestion.service.ts`
- `lib/ai/services/semantic-search.service.ts`
- `lib/ai/services/paragraph-refactor.service.ts`
- `lib/ai/services/memory-echo.service.ts`
- `lib/ai/services/language-detection.service.ts`
- `lib/ai/services/embedding.service.ts` (extension du code existant)

**2. Nouveaux Composants**
- `components/ai/ai-suggestion.tsx`
- `components/ai/ai-settings-panel.tsx`
- `components/ai/memory-echo-notification.tsx`
- `components/ai/confidence-badge.tsx`
- `components/ai/feedback-buttons.tsx`

**3. Nouvelles API Routes**
- `app/api/ai/titles/route.ts`
- `app/api/ai/search/route.ts`
- `app/api/ai/refactor/route.ts`
- `app/api/ai/echo/route.ts`
- `app/api/ai/feedback/route.ts`

**4. Nouvelles Server Actions**
- `app/actions/ai-suggestions.ts`
- `app/actions/ai-feedback.ts`

**5. Extension Settings**
- `app/(main)/settings/ai/page.tsx` (nouveau)
- Préférences utilisateur stockées dans `SystemConfig` ou nouvelle table `UserSettings`

### Integration Points Identified

**Point 1: Auto-Tagging Existant**

L'auto-tagging est déjà implémenté avec embeddings. Phase 1 doit :
- ✅ Réutiliser le même système d'embeddings
- ✅ Étendre pour la recherche sémantique hybride
- ✅ Partager le même `embedding.service.ts`

**Point 2: Multi-Provider Pattern**

OpenAI (cloud) et Ollama (local) sont déjà supportés. Phase 1 doit :
- ✅ Utiliser la même factory pour tous les nouveaux features IA
- ✅ Respecter la configuration utilisateur existante
- ✅ Indicateurs de connexion (local vs cloud) pour Max's use case

**Point 3: Component Library**

Radix UI + Tailwind + Lucide Icons. Phase 1 doit :
- ✅ Utiliser Radix Dialog pour modaux IA
- ✅ Utiliser Radix Toast pour notifications
- ✅ Suivre les conventions Tailwind existantes
- ✅ Utiliser Lucide Icons pour badges/buttons IA

**Point 4: Database Constraints**

SQLite avec embeddings en JSON. Phase 1 doit :
- ✅ Stocker les nouveaux embeddings dans le même champ `Note.embedding`
- ✅ Ajouter des indexes pour les requêtes Memory Echo
- ⚠️ Surveiller la taille DB avec beaucoup d'embeddings
- ⚠️ Pas de vector DB séparée pour Phase 1

### Development Experience Features

**Outils existants :**
- Hot reloading (Next.js dev server)
- TypeScript 5 (type safety)
- Playwright (E2E testing)
- Prisma Migrate (13 migrations déjà appliquées)
- ESLint + Prettier (probablement configuré)

**Implication pour Phase 1 :**
- Maintenir la configuration TypeScript stricte
- Ajouter des tests Playwright pour les features IA
- Utiliser Zod pour valider les inputs IA (déjà en place)

### Scalability & Performance

**Limitations actuelles identifiées :**
- SQLite: Single writer limitation
- Embeddings JSON: Pas de vector DB optimisée
- Base64 images: Peut augmenter taille DB rapidement

**Implication pour Phase 1 :**
- ✅ Acceptable pour MVP (single-user/small teams)
- ⚠️ Surveillance taille DB requise
- ⚠️ Performance Memory Echo doit être optimisée (background jobs)
- 📝 Préparer la migration vers PostgreSQL pour Phase 2+

### Security & Privacy

**Posture actuelle :**
- ✅ NextAuth (password hashing bcrypt)
- ✅ HTTP-only cookies
- ✅ Prisma (SQL injection protection)
- ⚠️ Pas de rate limiting
- ❌ mcp-server sans auth (OK pour local, pas pour prod)

**Implication pour Phase 1 :**
- ✅ Utiliser NextAuth session pour tous les endpoints IA
- ✅ Ne jamais exposer les clés API au client
- ✅ Vérifier que Ollama = 0 appels externes (Max's use case)
- ⚠️ Ajouter rate limiting pour endpoints IA (Léa's admin use case)

### Deployment Architecture

**Current:** Local development avec `npm run dev`
**Production Plan:** Docker + Docker Compose

**Implication pour Phase 1 :**
- ✅ Conserver la simplicité (zéro DevOps)
- ✅ Hosting managé (Vercel/Netlify) pour le frontend
- ✅ SQLite file-based (pas d'infrastructure DB séparée)
- ⚠️ Monitoring/analytics à implémenter pour Léa's use case

### Summary

**Keep dispose d'une architecture mature et bien documentée :**

✅ **Fondations solides :** Next.js 16 + Prisma + SQLite + Radix UI
✅ **Factory Pattern AI :** Déjà implémenté pour multi-provider
✅ **20+ Composants :** Architecture cohérente à étendre
✅ **13 Migrations :** Database schema stable
✅ **Documentation complète :** architecture, data models, components, integration

**Pour Phase 1 MVP AI :**

🎯 **Strategy:** Extension brownfield (PAS réécriture)
🎯 **Approche:** Extensions Prisma schema (PAS breaking changes)
🎯 **Pattern:** Respecter factory pattern existant + nouveaux services
🎯 **Integration:** `/api/ai/*` namespace + composants React conformes
🎯 **Performance:** Background jobs pour Memory Echo (non-blocking UI)
🎯 **Privacy:** Ollama local = 0 data exfiltration (vérifiable)

**Risque principal :** Taille database SQLite avec embeddings
**Mitigation :** Surveillance active + préparation migration PostgreSQL Phase 2
---

## Core Architectural Decisions

### Decision Priority Analysis

**Critical Decisions (Block Implementation):**

1. ✅ **Database Schema Extensions** - Prisma schema extensions for Phase 1 AI features (Note model extensions + AiFeedback table + MemoryEchoInsight table + UserAISettings table)
2. ✅ **Language Detection Strategy** - Hybrid approach using TinyLD library (TypeScript native, 62 languages including Persian)

**Important Decisions (Shape Architecture):**

3. ✅ **Memory Echo Architecture** - Server Action + Queue in DB pattern with background processing
4. ✅ **AI Settings Storage** - Dedicated UserAISettings table with typed fields

**Deferred Decisions (Post-MVP):**

- **Trust Score System** (Phase 3) - Schema prepared but UI deferred
- **Advanced Feedback Analytics** - Basic feedback collection in Phase 1, advanced analytics Phase 2+

---

## Phase 1 Specific Architectural Decisions

### Decision 1: Database Schema Extensions

**Status:** ✅ APPROVED

**Rationale:** Extend existing Note model and add new models for AI features while maintaining zero breaking changes.

**Implementation:**

```prisma
// Extensions to existing Note model
model Note {
  // ... existing fields (title, content, embedding, etc.)

  // Phase 1 AI Extensions
  autoGenerated       Boolean?    @default(false)
  aiProvider          String?                      // 'openai' | 'ollama' | null
  aiConfidence        Int?                         // 0-100 (collected Phase 1, UI Phase 3)
  language            String?                      // ISO 639-1: 'fr', 'en', 'es', 'de', 'fa', etc.
  languageConfidence  Float?                       // 0.0-1.0 (detection confidence)
  lastAiAnalysis      DateTime?                    // timestamp of last AI analysis

  // ... existing indexes
}

// New model for AI feedback collection
model AiFeedback {
  id                String    @id @default(cuid())
  noteId            String
  userId            String?
  feedbackType      String    // 'thumbs_up' | 'thumbs_down' | 'correction'
  feature           String    // 'title_suggestion' | 'memory_echo' | 'semantic_search' | 'paragraph_refactor'
  originalContent   String    // original AI-generated content
  correctedContent  String?   // user-corrected content (if applicable)
  metadata          String?   // JSON: { aiProvider, confidence, model, timestamp, etc. }
  createdAt         DateTime  @default(now())

  note              Note      @relation(fields: [noteId], references: [id], onDelete: Cascade)
  user              User?     @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@index([noteId])
  @@index([userId])
  @@index([feature])
  @@index([createdAt])
}

// New model for Memory Echo insights storage
model MemoryEchoInsight {
  id              String    @id @default(cuid())
  userId          String?
  note1Id         String    // first connected note
  note2Id         String    // second connected note
  similarityScore Float     // cosine similarity score
  insightDate     DateTime  @default(now())
  viewed          Boolean   @default(false)
  feedback        String?   // 'thumbs_up' | 'thumbs_down' | null

  note1           Note      @relation("EchoNote1", fields: [note1Id], references: [id], onDelete: Cascade)
  note2           Note      @relation("EchoNote2", fields: [note2Id], references: [id], onDelete: Cascade)
  user            User?     @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([userId, insightDate])  // max 1 insight per user per day
  @@index([userId, insightDate])
}

// Dedicated table for AI user settings
model UserAISettings {
  userId                String    @id

  // Feature Flags (granular ON/OFF)
  titleSuggestions      Boolean   @default(true)
  semanticSearch        Boolean   @default(true)
  paragraphRefactor     Boolean   @default(true)
  memoryEcho            Boolean   @default(true)

  // Configuration
  memoryEchoFrequency   String    @default("daily")  // 'daily' | 'weekly' | 'custom'
  aiProvider            String    @default("auto")    // 'auto' | 'openai' | 'ollama'

  // Relation
  user                  User      @relation(fields: [userId], references: [id], onDelete: Cascade)

  // Indexes for analytics
  @@index([memoryEcho])
  @@index([aiProvider])
  @@index([memoryEchoFrequency])
}
```

**Cascading Implications:**
- Prisma migration required (`npx prisma migrate dev`)
- AI feedback tracking system ready for Phase 3 trust scoring
- Analytics queries enabled for admin dashboard (Léa's use case)

**Affected Components:**
- All AI service layer services
- `/settings/ai` page
- Admin analytics dashboard

---

### Decision 2: Memory Echo Implementation Strategy

**Status:** ✅ APPROVED - Option B (Server Action + Queue in DB)

**Rationale:** Balance scalability, UX, and simplicity without external dependencies or cron jobs.

**Architecture Pattern:**

```
User logs in → Check if insight available today
                    ↓
              If NO insight and < 1 today:
              Trigger background server action (non-blocking)
                    ↓
              Analyze embeddings (cosine similarity > 0.75)
                    ↓
              Store result in MemoryEchoInsight table
                    ↓
              Next user login → Display toast with insight
                    ↓
              User clicks 👍/👎 → Update feedback field
```

**Implementation Details:**

**Server Action:** `app/actions/ai-memory-echo.ts`
```typescript
'use server'

import { auth } from '@/auth'
import { prisma } from '@/lib/prisma'

export async function generateMemoryEcho() {
  const session = await auth()
  if (!session?.user) return { success: false }

  // Check if already generated today
  const today = new Date()
  today.setHours(0, 0, 0, 0)

  const existing = await prisma.memoryEchoInsight.findFirst({
    where: {
      userId: session.user.id,
      insightDate: { gte: today }
    }
  })

  if (existing) {
    return { success: true, insight: existing }
  }

  // Generate new insight (async, non-blocking)
  const notes = await prisma.note.findMany({
    where: { userId: session.user.id },
    select: { id: true, embedding: true, content: true }
  })

  // Calculate cosine similarity between all pairs
  const insights = calculateSimilarities(notes)
  const topInsight = insights[0] // highest similarity > 0.75

  if (topInsight && topInsight.score > 0.75) {
    const insight = await prisma.memoryEchoInsight.create({
      data: {
        userId: session.user.id,
        note1Id: topInsight.note1Id,
        note2Id: topInsight.note2Id,
        similarityScore: topInsight.score
      }
    })

    return { success: true, insight }
  }

  return { success: true, insight: null }
}
```

**Performance Characteristics:**
- **UI blocking:** < 100ms (only checks DB, no computation)
- **Background processing:** Runs asynchronously after check
- **Max frequency:** 1 insight per user per day (enforced via DB constraint)

**Cascading Implications:**
- Requires cosine similarity calculation utility
- Toast notification component for insight display
- Feedback collection UI (thumbs up/down buttons)

---

### Decision 3: Language Detection Strategy

**Status:** ✅ APPROVED - Hybrid Approach with TinyLD

**Technology Choice:** **TinyLD** (TypeScript-native language detection)

**Rationale for Choosing TinyLD:**

| Criteria | TinyLD | ELD | CLD3 | Franc |
|----------|--------|-----|------|-------|
| TypeScript Native | ✅ Yes | ❌ No | ❌ No | ❌ No |
| Persian Support | ✅ Yes | ❓ Unclear | ❓ Probable | ✅ Yes |
| Bundle Size | ~10KB | ~30KB | ~2MB | ~30KB |
| Speed | Fast | Fastest | Fastest | Slow |
| Languages | 62 | 60 | 95 | 300+ |
| Build Complexity | Simple | Simple | Complex (native) | Simple |

**Sources:**
- [TinyLD GitHub](https://github.com/komodojp/tinyld)
- [TinyLD Language List](https://github.com/komodojp/tinyld/blob/develop/docs/langs.md)
- [ELD GitHub](https://github.com/nitotm/efficient-language-detector-js)
- [Franc npm](http://www.npmjs.com/package/franc)

**Hybrid Strategy:**

```typescript
// lib/ai/services/language-detection.service.ts

import { tinyld } from 'tinyld'
import { generateText } from 'ai'

export class LanguageDetectionService {
  private readonly MIN_WORDS_FOR_AI = 50
  private readonly MIN_CONFIDENCE = 0.7

  async detectLanguage(content: string): Promise<{
    language: string      // 'fr' | 'en' | 'es' | 'de' | 'fa' | 'unknown'
    confidence: number   // 0.0-1.0
    method: 'tinyld' | 'ai' | 'manual'
  }> {
    const wordCount = content.split(/\s+/).length

    // Short notes: TinyLD (fast, TypeScript native)
    if (wordCount < this.MIN_WORDS_FOR_AI) {
      const result = tinyld(content)
      return {
        language: this.mapToISO(result.language),
        confidence: result.confidence || 0.8,
        method: 'tinyld'
      }
    }

    // Long notes: AI for better accuracy
    const response = await generateText({
      model: openai('gpt-4o-mini'), // or ollama/llama3.2
      prompt: `Detect the language of this text. Respond ONLY with ISO 639-1 code (fr, en, es, de, fa):\n\n${content.substring(0, 500)}`
    })

    return {
      language: response.text.toLowerCase().trim(),
      confidence: 0.9,
      method: 'ai'
    }
  }

  private mapToISO(code: string): string {
    const mapping = {
      'fra': 'fr', 'eng': 'en', 'spa': 'es', 'deu': 'de',
      'fas': 'fa', 'pes': 'fa',  // Persian (Farsi)
      'por': 'pt', 'ita': 'it', 'rus': 'ru', 'zho': 'zh'
    }
    return mapping[code] || code.substring(0, 2)
  }
}
```

**Installation:**
```bash
npm install tinyld
```

**Supported Languages (Phase 1 Focus):**
- ✅ French (fr)
- ✅ English (en)
- ✅ Spanish (es)
- ✅ German (de)
- ✅ Persian/Farsi (fa) **confirmed support**
- + 57 other languages via TinyLD

**Performance:**
- TinyLD detection: ~8ms for 50 words
- AI detection: ~200-500ms (only for notes ≥ 50 words)
- Overall impact: Negligible for UX

**Cascading Implications:**
- Language detection called on note creation/update
- Results stored in `Note.language` and `Note.languageConfidence`
- Used for multilingual prompt engineering (system prompts in English, user data in local language)

---

### Decision 4: AI Settings Architecture

**Status:** ✅ APPROVED - Dedicated UserAISettings Table

**Rationale:** Type-safe, analytics-ready, and optimized for queries.

**Why Not SystemConfig (JSON blob):**
- ❌ No type safety
- ❌ No validation at database level
- ❌ Difficult to query for analytics
- ❌ No indexes on individual fields

**Why Dedicated Table:**
- ✅ **Type-safe** - Prisma validates types
- ✅ **Analytics-ready** - Simple SQL queries for admin dashboard
- ✅ **Performance** - Indexes on queried fields
- ✅ **Clarity** - Explicit structure in schema

**Schema:** (See Decision 1 for full schema)

**Example Analytics Queries for Léa:**

```typescript
// How many users have Memory Echo enabled?
const echoEnabled = await prisma.userAISettings.count({
  where: { memoryEcho: true }
})

// AI Provider distribution
const providerDist = await prisma.userAISettings.groupBy({
  by: ['aiProvider'],
  _count: true
})

// Users with selective feature adoption
const selectiveUsers = await prisma.userAISettings.findMany({
  where: {
    titleSuggestions: true,
    semanticSearch: true,
    memoryEcho: true,
    paragraphRefactor: false
  },
  include: { user: { select: { name: true, email: true } } }
})

// Memory Echo frequency preferences
const frequencyStats = await prisma.userAISettings.groupBy({
  by: ['memoryEchoFrequency'],
  where: { memoryEcho: true },
  _count: true
})
```

**Frontend Implementation:**

**Route:** `app/(main)/settings/ai/page.tsx`

```tsx
// Settings UI with granular controls
export default function AISettingsPage() {
  const { data: settings } = useAISettings()

  return (
    <div className="space-y-6">
      <h2>AI Settings</h2>

      {/* Feature toggles */}
      <FeatureToggle
        name="titleSuggestions"
        label="Title Suggestions"
        description="Suggest titles for untitled notes after 50+ words"
        checked={settings?.titleSuggestions}
        onChange={(checked) => updateSetting('titleSuggestions', checked)}
      />

      <FeatureToggle
        name="semanticSearch"
        label="Semantic Search"
        description="Find notes by meaning, not just keywords"
        checked={settings?.semanticSearch}
        onChange={(checked) => updateSetting('semanticSearch', checked)}
      />

      {/* Memory Echo with frequency slider */}
      <div className="space-y-2">
        <FeatureToggle
          name="memoryEcho"
          label="Memory Echo"
          description="Daily proactive connections between your notes"
          checked={settings?.memoryEcho}
          onChange={(checked) => updateSetting('memoryEcho', checked)}
        />

        {settings?.memoryEcho && (
          <FrequencySlider
            value={settings.memoryEchoFrequency}
            onChange={(value) => updateSetting('memoryEchoFrequency', value)}
            options={['daily', 'weekly', 'custom']}
          />
        )}
      </div>

      {/* AI Provider selection */}
      <ProviderSelector
        value={settings?.aiProvider}
        onChange={(value) => updateSetting('aiProvider', value)}
        options={[
          { value: 'auto', label: 'Auto (Recommended)', description: 'Ollama when available, OpenAI fallback' },
          { value: 'ollama', label: 'Ollama (Local)', description: '100% private, runs locally' },
          { value: 'openai', label: 'OpenAI (Cloud)', description: 'Most accurate, requires API key' }
        ]}
      />
    </div>
  )
}
```

**Cascading Implications:**
- Server action for updating settings: `app/actions/ai-settings.ts`
- Settings validation using Zod
- Default settings on first user signup
- Settings sync with AI provider factory

---

## Decision Impact Analysis

### Implementation Sequence

**Phase 1 - Foundation (Week 1-2):**
1. Prisma schema extensions (all 4 tables)
2. Database migration
3. Base AI service layer structure

**Phase 2 - Core Features (Week 3-6):**
4. Language detection service (TinyLD integration)
5. UserAISettings table + `/settings/ai` page
6. AI provider factory extensions

**Phase 3 - AI Features (Week 7-10):**
7. Title suggestions feature
8. Semantic search hybrid
9. Paragraph refactor
10. Memory Echo (background processing)

**Phase 4 - Polish & Analytics (Week 11-12):**
11. Feedback collection UI
12. Admin analytics dashboard
13. Performance optimization
14. Testing & validation

### Cross-Component Dependencies

**Critical Path:**
```
Prisma Schema → Migration → AI Services → UI Components → Testing
```

**Parallel Development Opportunities:**
- Language detection service (independent)
- Settings UI (independent of AI features)
- Individual AI features (can be developed in parallel)

**Integration Points:**
- All AI services → Language detection (for multilingual prompts)
- All AI features → UserAISettings (for feature flags)
- Memory Echo → Existing embeddings system
- Admin dashboard → All AI tables (analytics)

---

## Technology Stack Summary

**Selected Libraries & Versions:**

| Component | Technology | Version | Rationale |
|-----------|-----------|---------|-----------|
| Language Detection | **TinyLD** | Latest | TypeScript native, Persian support, 62 languages, fast |
| AI SDK | **Vercel AI SDK** | 6.0.23 | Already integrated, multi-provider support |
| AI Providers | **OpenAI + Ollama** | Latest | Factory pattern existing, extend for Phase 1 |
| Database | **SQLite + Prisma** | 5.22.0 | Existing infrastructure, zero DevOps |
| Backend | **Next.js 16** | 16.1.1 | Existing App Router, server actions |
| Frontend | **React 19** | 19.2.3 | Existing server components, Radix UI |
**Already Decided (Existing Stack):**
- Next.js 16.1.1 (App Router)
- React 19.2.3
- Prisma 5.22.0 + SQLite
- NextAuth 5.0.0-beta.30
- Vercel AI SDK 6.0.23
- Radix UI components
- Tailwind CSS 4

**No changes to existing stack** - pure brownfield extension approach.

---

## Deferred Decisions

**Explicitly Deferred to Phase 2/3:**

1. **Trust Score UI** - Schema fields ready (`aiConfidence`), but Phase 3 for UI exposure
2. **Advanced Feedback Analytics** - Basic collection Phase 1, ML-based analysis Phase 2
3. **PostgreSQL Migration** - When SQLite limits reached (planned Phase 2)
4. **Vector DB (Pinecone/Weaviate)** - Phase 2 if embeddings size becomes problematic
5. **Real-time Collaboration** - Phase 3 (WebSocket/CRDT)
6. **Mobile Apps** - Phase 3 (React Native or PWA Phase 2)
---

## Implementation Patterns & Consistency Rules

### Pattern Categories Defined

**Critical Conflict Points Identified:**
38 areas where AI agents could make different choices, documented from existing brownfield codebase

### Naming Patterns

**Database Naming Conventions:**

**Table Naming:**
- ✅ **PascalCase** pour les tables Prisma : `User`, `Note`, `Label`, `NoteShare`
- ✅ Tables de jointure composées : `NoteShare` (pas `Note_Shares`)

**Column Naming:**
- ✅ **camelCase** pour les colonnes Prisma : `userId`, `isPinned`, `checkItems`, `createdAt`
- ✅ Clés étrangères : `{table}Id` format (ex: `userId`, `noteId`)
- ✅ Booléens : préfixe `is` pour les flags (`isPinned`, `isArchived`, `isMarkdown`)
- ✅ Timestamps : suffixe `At` pour les dates (`createdAt`, `updatedAt`, `respondedAt`)

**Index Naming:**
- ✅ Prisma gère automatiquement via annotations `@@index`
- Exemple : `@@index([userId, insightDate])`

---

**API Naming Conventions:**

**REST Endpoint Structure:**
- ✅ **Plural** pour les collections : `/api/notes`, `/api/labels`, `/api/ai/tags`
- ✅ **Singular** pour les items individuels : `/api/notes/[id]`, `/api/labels/[id]`
- ✅ Namespace par domaine : `/api/ai/*` pour AI features, `/api/admin/*` pour admin

**Route Parameter Format:**
- ✅ Next.js App Router format : `[id]`, `[...nextauth]`
- ✅ Query params : `camelCase` (`?archived=true`, `?search=query`)

**Example AI Endpoints to Follow:**
```
/api/ai/titles/route.ts
/api/ai/search/route.ts
/api/ai/refactor/route.ts
/api/ai/echo/route.ts
/api/ai/feedback/route.ts
```

---

**Code Naming Conventions:**

**Component Naming:**
- ✅ **PascalCase** pour les composants React : `NoteCard`, `LabelBadge`, `NoteEditor`
- ✅ **kebab-case** pour les fichiers composants : `note-card.tsx`, `label-badge.tsx`
- ✅ UI components dans sous-dossier : `components/ui/button.tsx`
- ✅ Composants métiers à la racine : `components/note-card.tsx`

**File Naming:**
- ✅ **kebab-case** pour tous les fichiers : `note-card.tsx`, `label-selector.tsx`
- ✅ Server actions : `notes.ts`, `auth.ts`, `profile.ts`
- ✅ API routes : `route.ts` dans chaque dossier endpoint

**Function Naming:**
- ✅ **camelCase** pour les fonctions : `getNotes`, `createNote`, `togglePin`
- ✅ Verbs d'abord : `get`, `create`, `update`, `delete`, `toggle`
- ✅ Handler functions : `handleDelete`, `handleTogglePin`, `handleSubmit`

**Variable Naming:**
- ✅ **camelCase** pour les variables : `userId`, `noteId`, `isPinned`
- ✅ Types/interfaces : **PascalCase** : `Note`, `CheckItem`, `NoteCardProps`

### Structure Patterns

**Project Organization:**

```
keep-notes/
├── app/
│   ├── (main)/          # Route groups pour layout
│   ├── (auth)/          # Routes authentifiées
│   ├── actions/         # Server actions (kebab-case filenames)
│   ├── api/             # API routes
│   │   ├── notes/       # REST endpoints
│   │   ├── labels/      # REST endpoints
│   │   ├── ai/          # AI endpoints (NAMESPACE)
│   │   └── admin/       # Admin endpoints
│   └── auth/            # NextAuth routes
├── components/
│   ├── ui/              # Radix UI primitives (réutilisables)
│   └── *.tsx            # Composants métiers (root level)
├── lib/
│   ├── ai/              # AI services et providers
│   ├── prisma.ts        # Prisma client singleton
│   ├── utils.ts         # Utilitaires généraux
│   └── config.ts        # Configuration système
└── prisma/
    └── schema.prisma    # Database schema
```

**Test Organization:**
- Tests co-localisés avec le fichier testé : `notes.test.ts` à côté de `notes.ts`
- Tests E2E dans dossier séparé : `keep-notes/tests/e2e/` (Playwright)

**Shared Utilities Location:**
- `lib/utils.ts` - Utilitaires généraux (cn(), calculateRRFK(), etc.)
- `lib/ai/` - Services IA spécifiques
- `lib/types.ts` - Types TypeScript partagés

---

### Format Patterns

**API Response Formats:**

**Success Response:**
```typescript
{
  success: true,
  data: any,           // Les données retournées
  // optionnel: message
}
```

**Error Response:**
```typescript
{
  success: false,
  error: string        // Message d'erreur humainement lisible
}
```

**Status Codes:**
- ✅ 200 - Success (GET, PUT)
- ✅ 201 - Created (POST)
- ✅ 400 - Bad Request (validation error)
- ✅ 401 - Unauthorized (missing auth)
- ✅ 500 - Server Error

**Example from existing code:**
```typescript
// Success
return NextResponse.json({
  success: true,
  data: notes.map(parseNote)
})

// Error
return NextResponse.json(
  { success: false, error: 'Failed to fetch notes' },
  { status: 500 }
)
```

---

**Data Exchange Formats:**

**JSON Field Naming:**
- ✅ **camelCase** pour tous les champs JSON : `userId`, `checkItems`, `isPinned`
- ✅ Prisma convertit automatiquement camelCase ↔ snake_case en DB

**Boolean Representations:**
- ✅ `true`/`false` (JavaScript booleans) - PAS `1`/`0`

**Null Handling:**
- ✅ `null` pour les champs optionnels vides
- ✅ Empty string `""` pour les champs texte requis vides
- ✅ Empty array `[]` pour les tableaux vides

**Array vs Object:**
- ✅ Toujours retourner un array pour les collections : `data: Note[]`
- ✅ Objects pour les items individuels

---

### Communication Patterns

**Event Naming Convention:**
- Pas de système d'événements custom - utilisez React state ou server actions

**State Update Patterns:**
- ✅ **Immutable updates** avec spread operator : `{ ...state, newProp: value }`
- ✅ **useOptimistic** pour les mises à jour immédiates : `addOptimisticNote({ isPinned: !note.isPinned })`
- ✅ **useTransition** pour les mises à jour non-bloquantes : `startTransition(async () => { ... })`

**Action Naming Conventions:**
- ✅ Server actions : verbe + nommage explicite : `getNotes`, `createNote`, `togglePin`, `updateColor`
- ✅ Handler functions : préfixe `handle` : `handleDelete`, `handleTogglePin`
- ✅ Toggle functions : préfixe `toggle` : `togglePin`, `toggleArchive`

---

### Process Patterns

**Error Handling Patterns:**

**Global Error Handling:**
```typescript
// API Routes
try {
  // ... code
} catch (error) {
  console.error('GET /api/notes error:', error)
  return NextResponse.json(
    { success: false, error: 'Failed to fetch notes' },
    { status: 500 }
  )
}

// Server Actions
try {
  // ... code
} catch (error) {
  console.error('Error creating note:', error)
  throw new Error('Failed to create note')
}
```

**User-Facing Error Messages:**
- ✅ Messages clairs et humains : `"Failed to fetch notes"`
- ✅ PAS de stack traces exposées aux utilisateurs
- ✅ Log en console pour debugging (`console.error`)

---

**Loading State Patterns:**

**Loading State Naming:**
- ✅ Préfixe `is` pour les états booléens : `isPending`, `isDeleting`, `isLoading`
- ✅ `useTransition` hook : `const [isPending, startTransition] = useTransition()`

**Global vs Local Loading:**
- ✅ **Local loading states** (par composant) - PAS de loading state global
- ✅ **Optimistic UI** pour feedback immédiat : `useOptimistic` hook

**Loading UI Patterns:**
- ✅ Spinners ou skeletons pendant chargement
- ✅ Disabled buttons pendant mutations
- ✅ Toast notifications après completion (PAS pendant)

---

### AI-Specific Patterns

**AI Service Architecture:**

**Service Layer Organization:**
```
lib/ai/
├── factory.ts              # Provider factory (EXISTING)
├── providers/              # Provider implementations
│   ├── openai.ts
│   └── ollama.ts
└── services/               # NEW: Feature-specific services
    ├── title-suggestion.service.ts
    ├── semantic-search.service.ts
    ├── paragraph-refactor.service.ts
    ├── memory-echo.service.ts
    ├── language-detection.service.ts
    └── embedding.service.ts
```

**AI Component Organization:**
```
components/ai/              # NEW: AI-specific components
├── ai-suggestion.tsx       # Title suggestions UI
├── ai-settings-panel.tsx   # Settings page
├── memory-echo-notification.tsx
├── confidence-badge.tsx
└── feedback-buttons.tsx
```

**API Route Pattern for AI:**
```typescript
// keep-notes/app/api/ai/titles/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'

const requestSchema = z.object({
  content: z.string().min(1, "Content required"),
})

export async function POST(req: NextRequest) {
  try {
    const body = await req.json()
    const { content } = requestSchema.parse(body)

    // ... AI processing

    return NextResponse.json({
      success: true,
      data: { titles: [...] }
    })
  } catch (error: any) {
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { success: false, error: error.issues },
        { status: 400 }
      )
    }

    console.error('Error generating titles:', error)
    return NextResponse.json(
      { success: false, error: 'Failed to generate titles' },
      { status: 500 }
    )
  }
}
```

**Server Action Pattern for AI:**
```typescript
// keep-notes/app/actions/ai-suggestions.ts
'use server'

import { auth } from '@/auth'
import { TitleSuggestionService } from '@/lib/ai/services/title-suggestion.service'

export async function generateTitleSuggestions(noteId: string) {
  const session = await auth()
  if (!session?.user?.id) throw new Error('Unauthorized')

  try {
    const service = new TitleSuggestionService()
    const titles = await service.generateSuggestions(noteId)

    return { success: true, titles }
  } catch (error) {
    console.error('Error generating titles:', error)
    throw new Error('Failed to generate title suggestions')
  }
}
```

---

### Enforcement Guidelines

**All AI Agents MUST:**

- ✅ **Suivre les patterns de nommage existants** (camelCase pour variables, PascalCase pour composants)
- ✅ **Utiliser le format de réponse API existant** : `{success: true|false, data: any, error: string}`
- ✅ **Créer des fichiers AI dans les dossiers appropriés** : `app/api/ai/*`, `lib/ai/services/*`, `components/ai/*`
- ✅ **Utiliser 'use server' pour les server actions** et `'use client'` pour les composants interactifs
- ✅ **Authentification via `auth()`** dans toutes les server actions
- ✅ **Validation avec Zod** pour les inputs API
- ✅ **Error handling avec try/catch** et logging via `console.error`
- ✅ **RevalidatePath après mutations** dans les server actions
- ✅ **TypeScript strict** - tous les fichiers doivent avoir des types
- ✅ **Importer depuis les alias** (`@/components/ui/*`, `@/lib/*`, `@/app/*`)

**Pattern Enforcement:**

**Comment vérifier les patterns:**
1. Linter configuré (ESLint + Prettier)
2. TypeScript strict mode activé
3. Review du code avant merge
4. Tests pour valider les formats d'API

**Où documenter les violations de patterns:**
- Commentaires inline avec `// FIXME: Pattern violation - should be ...`
- GitHub issues pour les violations systématiques
- `docs/pattern-decisions.md` pour les décisions d'exception

**Process pour mettre à jour les patterns:**
1. Proposer le changement via GitHub issue
2. Discuter avec l'équipe
3. Mettre à jour ce document (`architecture.md`)
4. Appliquer le changement à tout le code existant

---

### Pattern Examples

**Good Examples:**

✅ **API Route (Correct):**
```typescript
// app/api/ai/titles/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'

const schema = z.object({ content: z.string().min(1) })

export async function POST(req: NextRequest) {
  try {
    const { content } = schema.parse(await req.json())
    const titles = await generateTitles(content)
    return NextResponse.json({ success: true, data: { titles } })
  } catch (error) {
    return NextResponse.json(
      { success: false, error: 'Failed to generate titles' },
      { status: 500 }
    )
  }
}
```

✅ **Server Action (Correct):**
```typescript
// app/actions/ai-suggestions.ts
'use server'

import { auth } from '@/auth'
import { revalidatePath } from 'next/cache'

export async function generateTitleSuggestions(noteId: string) {
  const session = await auth()
  if (!session?.user?.id) throw new Error('Unauthorized')

  const titles = await titleService.generate(noteId)
  revalidatePath('/')
  return { success: true, titles }
}
```

✅ **Component (Correct):**
```typescript
// components/ai/ai-suggestion.tsx
'use client'

import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { useState, useTransition } from 'react'

interface AiSuggestionProps {
  noteId: string
  onAccept: (title: string) => void
}

export function AiSuggestion({ noteId, onAccept }: AiSuggestionProps) {
  const [suggestions, setSuggestions] = useState<string[]>([])
  const [isPending, startTransition] = useTransition()

  // ... component logic
}
```

---

**Anti-Patterns (À éviter):**

❌ **MAUVAIS - Response format incorrect:**
```typescript
// NE PAS FAIRE - Format non-standard
return NextResponse.json({ titles: [...] })
// MANQUE: success field, error handling
```

❌ **MAUVAIS - Pas d'authentification:**
```typescript
// NE PAS FAIRE - Server action sans auth
export async function generateTitles(noteId: string) {
  // MANQUE: const session = await auth()
  // ...
}
```

❌ **MAUVAIS - Pas de validation:**
```typescript
// NE PAS FAIRE - API sans validation
export async function POST(req: NextRequest) {
  const { content } = await req.json()
  // MANQUE: Zod validation
}
```

❌ **MAUVAIS - Erreur exposée:**
```typescript
// NE PAS FAIRE - Expose stack trace
return NextResponse.json({
  success: false,
  error: error.message  // Expose internal details
})
```

❌ **MAUVAIS - RevalidatePath oublié:**
```typescript
// NE PAS FAIRE - Mutation sans revalidation
export async function updateNote(id: string, data: any) {
  await prisma.note.update({ where: { id }, data })
  // MANQUE: revalidatePath('/')
}
```

❌ **MAUVAIS - Composant sans 'use client':**
```typescript
// NE PAS FAIRE - Client component sans directive
export function InteractiveComponent() {
  const [count, setCount] = useState(0)
  // MANQUE: 'use client' au début du fichier
}
```

---

### Quick Reference Card

**Pour implémenter une nouvelle feature IA :**

1. **API Route** → `app/api/ai/{feature}/route.ts`
   - Import `NextRequest`, `NextResponse`
   - Valider avec Zod
   - Return `{success, data}` ou `{success, error}`
   - Log errors avec `console.error`

2. **Server Action** → `app/actions/ai-{feature}.ts`
   - `'use server'` directive
   - Auth via `auth()`
   - `revalidatePath('/')` après mutations
   - Throw `Error` pour les failures

3. **AI Service** → `lib/ai/services/{feature}-service.ts`
   - Class exportée : `export class {Feature}Service`
   - Méthodes nommées : `async generate()`, `async process()`
   - Error handling complet

4. **Component** → `components/ai/{feature}.tsx`
   - `'use client'` directive
   - PascalCase pour composant
   - Props en interface TypeScript
   - `useOptimistic` pour feedback immédiat
   - Import depuis `@/components/ui/*`

5. **Types** → `lib/types.ts`
   - Exporter interfaces/types
   - PascalCase pour les types
---

## Project Structure & Boundaries

### Complete Project Directory Structure

**Keep (Memento) - Phase 1 MVP AI Structure:**

```
Keep/
├── README.md
├── package.json
├── next.config.js
├── tailwind.config.js
├── tsconfig.json
├── .env.local
├── .env.example
├── .gitignore
├── .github/
│   └── workflows/
│       └── ci.yml
│
├── docs/                           # EXISTING - Project documentation
│   ├── index.md                    # Main guide
│   ├── project-overview.md
│   ├── architecture-keep-notes.md
│   ├── architecture-mcp-server.md
│   ├── integration-architecture.md
│   ├── data-models.md
│   ├── component-inventory.md
│   ├── development-guide-keep-notes.md
│   ├── deployment-guide.md
│   ├── api-contracts-keep-notes.md
│   ├── api-contracts-mcp-server.md
│   └── source-tree-analysis.md
│
├── keep-notes/                     # MAIN APPLICATION
│   ├── app/
│   │   ├── (main)/                 # Main routes (authenticated)
│   │   │   ├── layout.tsx
│   │   │   ├── page.tsx            # Dashboard
│   │   │   └── settings/
│   │   │       ├── layout.tsx
│   │   │       ├── page.tsx        # General settings
│   │   │       └── ai/
│   │   │           └── page.tsx    # NEW: AI settings page
│   │   │
│   │   ├── (auth)/                 # Auth routes (public)
│   │   │   ├── login/
│   │   │   └── register/
│   │   │
│   │   ├── actions/                # Server actions
│   │   │   ├── auth.ts             # EXISTING
│   │   │   ├── notes.ts            # EXISTING
│   │   │   ├── profile.ts          # EXISTING
│   │   │   ├── admin.ts            # EXISTING
│   │   │   ├── ai-suggestions.ts   # NEW: Title suggestions
│   │   │   ├── ai-feedback.ts      # NEW: Feedback collection
│   │   │   └── ai-memory-echo.ts   # NEW: Memory Echo
│   │   │
│   │   ├── api/                    # API routes
│   │   │   ├── notes/
│   │   │   │   ├── route.ts        # EXISTING: GET/POST/PUT/DELETE notes
│   │   │   │   └── [id]/route.ts   # EXISTING: Individual note
│   │   │   ├── labels/
│   │   │   │   ├── route.ts        # EXISTING: GET/POST labels
│   │   │   │   └── [id]/route.ts   # EXISTING: Individual label
│   │   │   ├── ai/                 # EXISTING + NEW: AI endpoints
│   │   │   │   ├── tags/
│   │   │   │   │   └── route.ts    # EXISTING: Auto-tagging
│   │   │   │   ├── test/
│   │   │   │   │   └── route.ts    # EXISTING: AI provider test
│   │   │   │   ├── config/
│   │   │   │   │   └── route.ts    # EXISTING: AI config
│   │   │   │   ├── models/
│   │   │   │   │   └── route.ts    # EXISTING: AI models
│   │   │   │   ├── titles/
│   │   │   │   │   └── route.ts    # NEW: Title suggestions
│   │   │   │   ├── search/
│   │   │   │   │   └── route.ts    # NEW: Semantic search
│   │   │   │   ├── refactor/
│   │   │   │   │   └── route.ts    # NEW: Paragraph refactor
│   │   │   │   ├── echo/
│   │   │   │   │   └── route.ts    # NEW: Memory Echo
│   │   │   │   ├── feedback/
│   │   │   │   │   └── route.ts    # NEW: AI feedback
│   │   │   │   └── language/
│   │   │   │       └── route.ts    # NEW: Language detection
│   │   │   ├── upload/
│   │   │   │   └── route.ts        # EXISTING: File upload
│   │   │   ├── admin/
│   │   │   │   ├── randomize-labels/route.ts
│   │   │   │   ├── sync-labels/route.ts
│   │   │   │   ├── embeddings/
│   │   │   │   │   └── validate/route.ts
│   │   │   │   └── ...
│   │   │   ├── auth/
│   │   │   │   └── [...nextauth]/route.ts
│   │   │   └── cron/
│   │   │       └── reminders/route.ts
│   │   │
│   │   ├── auth.ts                 # EXISTING: NextAuth config
│   │   ├── globals.css
│   │   └── layout.tsx
│   │
│   ├── components/
│   │   ├── ui/                      # EXISTING: Radix UI primitives
│   │   │   ├── button.tsx
│   │   │   ├── card.tsx
│   │   │   ├── dialog.tsx
│   │   │   ├── toast.tsx
│   │   │   ├── dropdown-menu.tsx
│   │   │   ├── avatar.tsx
│   │   │   ├── badge.tsx
│   │   │   └── ...
│   │   │
│   │   ├── ai/                     # NEW: AI-specific components
│   │   │   ├── ai-suggestion.tsx           # Title suggestions UI
│   │   │   ├── ai-settings-panel.tsx       # Settings controls
│   │   │   ├── memory-echo-notification.tsx # Insight display
│   │   │   ├── confidence-badge.tsx         # Confidence score badge
│   │   │   ├── feedback-buttons.tsx         # 👍👎 buttons
│   │   │   ├── semantic-search-results.tsx  # Search results with badges
│   │   │   └── paragraph-refactor.tsx       # Refactor UI
│   │   │
│   │   ├── note-card.tsx           # EXISTING
│   │   ├── note-editor.tsx         # EXISTING
│   │   ├── note-actions.tsx       # EXISTING
│   │   ├── label-badge.tsx         # EXISTING
│   │   ├── label-filter.tsx        # EXISTING
│   │   ├── label-manager.tsx       # EXISTING
│   │   ├── ghost-tags.tsx          # EXISTING
│   │   ├── masonry-grid.tsx        # EXISTING
│   │   ├── header.tsx             # EXISTING
│   │   ├── sidebar.tsx            # EXISTING
│   │   └── ... (20+ components)
│   │
│   ├── lib/
│   │   ├── ai/                     # AI Layer
│   │   │   ├── factory.ts                    # EXISTING: Provider factory
│   │   │   ├── providers/                    # EXISTING
│   │   │   │   ├── openai.ts
│   │   │   │   └── ollama.ts
│   │   │   │
│   │   │   └── services/                     # NEW: Feature services
│   │   │       ├── title-suggestion.service.ts
│   │   │       ├── semantic-search.service.ts
│   │   │       ├── paragraph-refactor.service.ts
│   │   │       ├── memory-echo.service.ts
│   │   │       ├── language-detection.service.ts
│   │   │       └── embedding.service.ts       # Extended
│   │   │
│   │   ├── prisma.ts               # EXISTING: Prisma client
│   │   ├── config.ts               # EXISTING: System config
│   │   ├── utils.ts                # EXISTING: Utilities
│   │   └── types.ts                # EXISTING: TypeScript types
│   │
│   ├── prisma/
│   │   ├── schema.prisma           # EXISTING + EXTENDED for Phase 1
│   │   └── migrations/             # EXISTING + NEW migrations
│   │       ├── 013_*
│   │       ├── 014_add_ai_feedback.ts          # NEW
│   │       ├── 015_add_memory_echo_insights.ts # NEW
│   │       └── 016_add_user_ai_settings.ts     # NEW
│   │
│   └── tests/
│       ├── e2e/                    # EXISTING: Playwright E2E tests
│       │   └── ai-features.spec.ts            # NEW: AI E2E tests
│       └── __mocks__/
│
├── mcp-server/                     # EXISTING: MCP server (separate)
│
├── _bmad/                          # BMAD framework (dev workflow)
│   └── ...
│
└── _bmad-output/                   # BMAD artifacts
    ├── analysis/
    │   └── brainstorming-session-2026-01-09.md
    └── planning-artifacts/
        ├── prd-phase1-mvp-ai.md
        ├── ux-design-specification.md
        ├── architecture.md          # THIS DOCUMENT
        └── epics.md                # TO BE RECREATED
```

---

### Architectural Boundaries

**API Boundaries:**

**External API Boundaries:**
- `/api/auth/[...nextauth]` → NextAuth service (authentication)
- `/api/ai/providers/*` → OpenAI API (https://api.openai.com)
- `/api/ai/providers/*` → Ollama API (http://localhost:11434)

**Internal Service Boundaries:**
- `/api/notes` → Note CRUD operations
- `/api/labels` → Label CRUD operations
- `/api/ai/*` → AI feature operations (namespace isolation)

**Authentication Boundaries:**
- All server actions require `auth()` session check
- All API routes under `/api/ai/*` require valid NextAuth session
- Public routes: `/api/auth/*`, login/register pages

**Data Access Layer Boundaries:**
- Prisma ORM as single data access point
- No direct SQL queries (use Prisma Query API)
- Database connection via singleton `lib/prisma.ts`

---

**Component Boundaries:**

**Frontend Component Communication:**
- Server Components → Data fetching via Prisma
- Client Components → Interactions via Server Actions
- Parent → Child: Props (downward flow)
- Child → Parent: Callback props (upward flow)

**State Management Boundaries:**
- **Local state:** useState per component
- **Shared state:** React Context (User session, Theme, Labels)
- **Server state:** React Cache + revalidatePath()
- **Optimistic UI:** useOptimistic hook

**Service Communication Patterns:**
- **Server Actions** → Direct function calls from client components
- **API Routes** → fetch() from client or server components
- **AI Services** → Factory pattern → Provider abstraction

**Event-Driven Integration Points:**
- No custom event system (React state preferred)
- Real-time updates: revalidatePath() + router.refresh()
- Toast notifications: Radix Toast from Sonner

---

**Service Boundaries:**

**AI Service Architecture:**
```
lib/ai/services/
    ├── TitleSuggestionService
    ├── SemanticSearchService
    ├── ParagraphRefactorService
    ├── MemoryEchoService
    ├── LanguageDetectionService
    └── EmbeddingService (extension)

All services use:
- getAIProvider() factory
- OpenAI or Ollama provider instances
- Consistent error handling
- Logging via console.error()
```

**Service Integration Patterns:**
- Services are stateless classes
- Constructor injection of dependencies
- Methods return promises with consistent error handling
- No direct database access (via Prisma)

---

**Data Boundaries:**

**Database Schema Boundaries:**
- **Prisma schema.prisma** as single source of truth
- **Migrations** as version control for schema changes
- **Foreign keys** enforce referential integrity
- **Indexes** optimize query performance

**Data Access Patterns:**
- **Read operations:** Prisma findMany() with where clauses
- **Write operations:** Prisma create/update/delete with transaction support
- **Embeddings:** Stored as JSON string in Note.embedding field
- **JSON arrays:** checkItems, labels, images stored as JSON strings

**Caching Boundaries:**
- **React Cache:** Server-side data caching
- **No Redis:** Phase 1 uses direct database queries
- **Optimistic UI:** useOptimistic for immediate feedback
- **Revalidation:** revalidatePath() after mutations

**External Data Integration Points:**
- **OpenAI API:** Used via Vercel AI SDK (text + embeddings)
- **Ollama API:** Used via Vercel AI SDK (local inference)
- **No external file storage:** Images stored as Base64 in DB

---

### Requirements to Structure Mapping

**Feature/Epic Mapping:**

**Epic 1: Title Suggestions**
- API: `app/api/ai/titles/route.ts`
- Service: `lib/ai/services/title-suggestion.service.ts`
- Server Action: `app/actions/ai-suggestions.ts`
- Component: `components/ai/ai-suggestion.tsx`
- Database: Uses existing Note table + new AiFeedback table

**Epic 2: Semantic Search**
- API: `app/api/ai/search/route.ts`
- Service: `lib/ai/services/semantic-search.service.ts`
- Component: `components/ai/semantic-search-results.tsx`
- Database: Uses existing Note.embedding field

**Epic 3: Paragraph Reformulation**
- API: `app/api/ai/refactor/route.ts`
- Service: `lib/ai/services/paragraph-refactor.service.ts`
- Component: `components/ai/paragraph-refactor.tsx`
- Database: Uses Note.content (no schema change)

**Epic 4: Memory Echo** ⭐
- API: `app/api/ai/echo/route.ts`
- Service: `lib/ai/services/memory-echo.service.ts`
- Server Action: `app/actions/ai-memory-echo.ts`
- Component: `components/ai/memory-echo-notification.tsx`
- Database: New MemoryEchoInsight table

**Epic 5: AI Settings**
- Page: `app/(main)/settings/ai/page.tsx`
- Component: `components/ai/ai-settings-panel.tsx`
- Server Action: `app/actions/ai-settings.ts`
- Database: New UserAISettings table

**Epic 6: Language Detection**
- Service: `lib/ai/services/language-detection.service.ts`
- Integration: Called by all AI services
- Database: Note.language + Note.languageConfidence fields

---

**Cross-Cutting Concerns:**

**Authentication System**
- Middleware: `app/auth.ts` (NextAuth configuration)
- Guards: Server actions check `auth()` session
- Session: NextAuth JWT in HTTP-only cookies
- Components: `components/session-provider-wrapper.tsx`

**Error Handling**
- API Routes: try/catch with `{success, error}` response
- Server Actions: try/catch with thrown Error objects
- Client: Toast notifications for user feedback
- Logging: console.error() for debugging

**AI Provider Abstraction**
- Factory: `lib/ai/factory.ts` (EXISTING)
- Providers: `lib/ai/providers/openai.ts`, `lib/ai/providers/ollama.ts` (EXISTING)
- Config: SystemConfig table stores active provider
- UI: Settings page for provider selection

**Feedback Collection**
- API: `app/api/ai/feedback/route.ts`
- Database: AiFeedback table (NEW)
- Components: `components/ai/feedback-buttons.tsx` (NEW)
- Analytics: Admin dashboard queries AiFeedback table

**Multi-language Support**
- Service: `lib/ai/services/language-detection.service.ts` (NEW)
- Storage: Note.language field (NEW)
- Processing: System prompts in English, user data in local language
- Supported: FR, EN, ES, DE, FA (Persian) + 57 others via TinyLD

---

### Integration Points

**Internal Communication:**

**Component → Server Action → Database Flow:**
```
Client Component (use client)
    ↓ Server Action call
Server Action ('use server')
    ↓ auth() check
Prisma Query
    ↓ Database operation
revalidatePath()
    ↓ Cache invalidation
Client Component update
    ↓ router.refresh() or optimistic update
UI reflects new state
```

**Component → API Route → AI Service Flow:**
```
Client Component
    ↓ fetch() call
API Route (POST /api/ai/*)
    ↓ Zod validation
AI Service
    ↓ getAIProvider() call
Provider (OpenAI/Ollama)
    ↓ API call
AI Response
    ↓ Process result
NextResponse.json({success, data})
    ↓ JSON response
Client Component
    ↓ Update state
UI reflects AI result
```

**Background Processing Flow (Memory Echo):**
```
User Login
    ↓ Check if insight today
Server Action: generateMemoryEcho()
    ↓ Query MemoryEchoInsight table
If exists → Return cached insight
If none → Background processing:
    ↓ Fetch all user notes
    ↓ Calculate cosine similarities
    ↓ Store top result in MemoryEchoInsight
    ↓ Return insight
Toast Notification display
    ↓ User views insight
User feedback (👍/👎)
    ↓ Update MemoryEchoInsight.feedback
```

---

**External Integrations:**

**OpenAI Integration:**
- SDK: Vercel AI SDK 6.0.23
- Models: gpt-4o-mini (titles, refactor, language), text-embedding-3-small
- API Key: Stored in SystemConfig (encrypted)
- Usage: Pay-per-use (cost tracking via AiFeedback metadata)

**Ollama Integration:**
- SDK: Vercel AI SDK with Ollama provider
- Models: llama3.2, mistral, etc.
- Endpoint: http://localhost:11434 (configurable)
- Usage: 100% free, 100% local (Max's use case)

**TinyLD Integration:**
- Package: tinyld (npm)
- Purpose: Language detection for notes
- Supported: 62 languages including Persian
- Usage: Called by AI services before AI processing

**NextAuth Integration:**
- Package: next-auth@5.0.0-beta.30
- Providers: Credentials (email/password)
- Session: JWT in HTTP-only cookies
- Database: Prisma User/Account/Session models

---

**Data Flow:**

**Note Creation with AI:**
```
User types note content
    ↓ Real-time character count
50+ words reached
    ↓ Trigger detection
Background call to TitleSuggestionService
    ↓ getAIProvider() → OpenAI or Ollama
Generate 3 title suggestions
    ↓ Store in memory
Toast notification appears
    ↓ User sees "Title suggestions available"
User clicks toast or continues typing
    ↓ If user clicks: Show suggestions
User accepts/rejects suggestions
    ↓ If accepted: Update note title via updateNote()
    ↓ Log feedback to AiFeedback
```

**Search Flow (Hybrid):**
```
User types search query
    ↓ Debounce 300ms
searchNotes() called
    ↓ Load query embedding
Semantic Search Service
    ↓ getAIProvider() → OpenAI/Ollama
Generate query embedding
    ↓ Fetch all user notes
Calculate scores:
    ↓ Keyword matching (title/content/labels)
    ↓ Semantic similarity (cosine similarity)
    ↓ Reciprocal Rank Fusion (RRF)
Return ranked results
    ↓ Sort by combined score
Display results with badges:
    ↓ "Exact Match" badge (keyword)
    ↓ "Related" badge (semantic)
User clicks result
    ↓ Open note in editor
```

**Memory Echo Background Flow:**
```
User logs in
    ↓ Check MemoryEchoInsight for today
If insight exists:
    ↓ Show notification immediately
If no insight:
    ↓ Trigger background job
MemoryEchoService
    ↓ Load all user notes with embeddings
Calculate pairwise cosine similarities
    ↓ Filter by threshold (> 0.75)
    ↓ Sort by similarity score
Store top result in MemoryEchoInsight
    ↓ Generate insight (note1Id, note2Id, similarityScore)
Next user login
    ↓ Fetch insight
Display toast with connection details
    ↓ "Note X relates to Note Y (85% match)"
User views connection
    ↓ Mark insight as viewed
User clicks 👍/👎
    ↓ Update MemoryEchoInsight.feedback
```

---

### File Organization Patterns

**Configuration Files:**

**Root Level:**
- `package.json` - Dependencies (Next.js 16, React 19, Prisma, etc.)
- `next.config.js` - Next.js configuration
- `tailwind.config.js` - Tailwind CSS 4 configuration
- `tsconfig.json` - TypeScript strict mode
- `.env.local` - Local environment variables (gitignored)
- `.env.example` - Template for environment variables
- `.gitignore` - Git ignore rules
- `README.md` - Project documentation

**AI-Specific Configuration:**
- `lib/config.ts` - SystemConfig access (getAIProvider, etc.)
- Prisma SystemConfig table - Stores AI provider selection
- Environment variables: `OPENAI_API_KEY`, `OLLAMA_ENDPOINT`

---

**Source Organization:**

**App Router Structure:**
- `(main)/` - Main application routes (authenticated)
- `(auth)/` - Authentication routes (public)
- `actions/` - Server actions ('use server' directive)
- `api/` - API routes (REST endpoints)

**Component Organization:**
- `components/ui/` - Radix UI primitives (reusable, generic)
- `components/ai/` - AI-specific components (feature-specific)
- `components/*.tsx` - Domain components (notes, labels, etc.)

**Library Organization:**
- `lib/ai/services/` - AI feature services
- `lib/ai/providers/` - AI provider implementations
- `lib/ai/factory.ts` - Provider factory
- `lib/prisma.ts` - Database client
- `lib/utils.ts` - General utilities
- `lib/types.ts` - TypeScript types

---

**Test Organization:**

**Unit Tests:**
- Co-located with source files: `notes.test.ts` alongside `notes.ts`
- Focus: Business logic, utilities, services
- Framework: Jest or Vitest

**E2E Tests:**
- `tests/e2e/` directory
- Framework: Playwright (already configured)
- AI Features: `ai-features.spec.ts` (NEW)
- Coverage: Critical user flows (create note, search, etc.)

---

**Asset Organization:**

**Static Assets:**
- `public/` - Static files (favicon, robots.txt, etc.)
- Images stored as Base64 in Note.images field
- No external CDN for Phase 1

**Documentation Assets:**
- `docs/` - Markdown documentation
- `_bmad-output/planning-artifacts/` - Generated artifacts (PRD, UX, Architecture)

---

### Development Workflow Integration

**Development Server Structure:**

**Local Development:**
- Command: `npm run dev`
- Port: 3000 (default Next.js)
- Hot reload: Enabled for all file changes
- Database: SQLite at `prisma/dev.db`

**AI Development Workflow:**
1. Create feature service in `lib/ai/services/`
2. Create API route in `app/api/ai/{feature}/route.ts`
3. Create server action in `app/actions/ai-{feature}.ts`
4. Create UI component in `components/ai/`
5. Add Prisma migration if needed
6. Test with OpenAI (cloud) or Ollama (local)
7. Run E2E tests with Playwright

---

**Build Process Structure:**

**Production Build:**
- Command: `npm run build`
- Output: `.next/` directory
- Optimization: Automatic code splitting, tree shaking
- Database: Prisma migrations run via `npx prisma migrate deploy`

**Environment-Specific Builds:**
- Development: `npm run dev` (with hot reload)
- Production: `npm run build` + `npm start`
- Staging: Same as production with staging env vars

---

**Deployment Structure:**

**Hosting:**
- Frontend: Vercel (recommended) or Netlify
- Backend: Integrated with frontend (Next.js API routes)
- Database: SQLite file (Vercel supports via `@prisma/adapter-sqlite`)

**Environment Variables:**
```
OPENAI_API_KEY=sk-...          # OpenAI API key (if using OpenAI)
OLLAMA_ENDPOINT=http://...     # Ollama endpoint (if using Ollama)
DATABASE_URL=file:./dev.db     # SQLite database URL
NEXTAUTH_URL=...                # NextAuth URL
NEXTAUTH_SECRET=...            # NextAuth secret
```

**Deployment Commands:**
```bash
npx prisma generate             # Generate Prisma client
npx prisma migrate deploy       # Run migrations
npm run build                   # Build production bundle
npm start                       # Start production server
```

---

### Quick Reference: File Creation Checklist

**For Each New AI Feature:**

1. ✅ **Service Layer** → `lib/ai/services/{feature}-service.ts`
   - Create class: `export class {Feature}Service`
   - Inject AI provider via factory
   - Implement methods with error handling

2. ✅ **API Route** → `app/api/ai/{feature}/route.ts`
   - Import NextRequest, NextResponse
   - Add Zod validation schema
   - Return `{success, data}` or `{success, error}`

3. ✅ **Server Action** → `app/actions/ai-{feature}.ts`
   - Add `'use server'` directive
   - Auth via `auth()`
   - `revalidatePath('/')` after mutations

4. ✅ **Component** → `components/ai/{feature}.tsx`
   - Add `'use client'` directive
   - Use TypeScript interfaces for props
   - Import from `@/components/ui/*`
   - Use `useOptimistic` for feedback

5. ✅ **Types** → `lib/types.ts` (if needed)
   - Export interfaces/types
   - Use PascalCase for type names

6. ✅ **Tests** → `tests/e2e/{feature}.spec.ts`
   - E2E tests with Playwright
   - Test critical user flows

7. ✅ **Migration** → `prisma/migrations/{timestamp}_{description}.ts`
   - Create if schema changes needed
   - Run `npx prisma migrate dev`
---

## Architecture Validation

### Validation Summary

**Date:** 2026-01-10
**Validator:** Winston (Architect Agent)
**Scope:** Phase 1 MVP AI - Complete Architecture Document
**Status:** ✅ VALIDATED - READY FOR IMPLEMENTATION

---

### Coherence Validation

#### Decision Compatibility Analysis

**✅ Decision 1 (Database Schema) ↔ Decision 2 (Memory Echo):**
- **Status:** COHERENT
- **Analysis:** MemoryEchoInsight table properly references Note.id with foreign keys and cascade deletion
- **Verification:** Schema uses proper Prisma relations
- **Impact:** No conflicts, cascading deletes prevent orphaned insights

**✅ Decision 1 (Database Schema) ↔ Decision 3 (Language Detection):**
- **Status:** COHERENT
- **Analysis:** Note.language and Note.languageConfidence fields support TinyLD hybrid approach
- **Impact:** Language detection results can be stored and queried efficiently

**✅ Decision 1 (Database Schema) ↔ Decision 4 (AI Settings):**
- **Status:** COHERENT
- **Analysis:** UserAISettings table provides granular feature flags for all AI services
- **Impact:** Clean separation of user preferences from feature implementation

**✅ Decision 2 (Memory Echo) ↔ Existing Embeddings System:**
- **Status:** COHERENT
- **Analysis:** Memory Echo reuses existing Note.embedding field (JSON-stored vectors)
- **Impact:** Zero duplication, efficient background processing

**✅ Decision 3 (Language Detection) ↔ Multi-Provider Pattern:**
- **Status:** COHERENT
- **Analysis:** TinyLD is library-agnostic, no conflicts with OpenAI/Ollama provider factory
- **Impact:** Clean separation of concerns, no provider coupling

**✅ Decision 4 (AI Settings) ↔ Factory Pattern:**
- **Status:** COHERENT
- **Analysis:** UserAISettings.aiProvider maps to existing factory.getAIProvider()
- **Impact:** Seamless integration with existing provider abstraction

---

#### Pattern Consistency Validation

**✅ Naming Pattern Consistency:**
- **Status:** CONSISTENT across all documented patterns
- **Database:** PascalCase tables, camelCase columns
- **API Routes:** /api/ai/* namespace maintained
- **Components:** PascalCase components, kebab-case files
- **Services:** PascalCase classes, kebab-case files

**✅ Response Format Consistency:**
- **Status:** CONSISTENT with existing brownfield patterns
- **Verification:** All API routes return {success: true|false, data: any, error: string}
- **Impact:** Zero breaking changes for frontend integration

**✅ Error Handling Consistency:**
- **Status:** CONSISTENT across all proposed code examples
- **API Routes:** try/catch with {success, error} response
- **Server Actions:** try/catch with thrown Error objects
- **Client:** Toast notifications for user feedback

**✅ Authentication Consistency:**
- **Status:** CONSISTENT with existing NextAuth implementation
- **Verification:** All server actions include auth() check
- **Impact:** Maintains security posture of existing application

---

#### Structure Alignment Validation

**✅ Directory Structure Alignment:**
- **Status:** ALIGNED with existing brownfield structure
- New AI services in lib/ai/services/
- New AI components in components/ai/
- New API routes in app/api/ai/*
- New server actions in app/actions/ai-*.ts

**✅ Prisma Schema Alignment:**
- **Status:** ALIGNED with existing schema patterns
- All new tables use @default(cuid())
- All new tables use @relation with proper foreign keys
- All new tables include @@index
- All new fields optional (backward compatibility)

**✅ Component Architecture Alignment:**
- **Status:** ALIGNED with React 19 Server Components patterns
- New AI components use 'use client' directive
- Components import from @/components/ui/*
- Components use TypeScript interfaces for props
- Components use useOptimistic and useTransition hooks

---

### Requirements Coverage Validation

#### Epic/Feature Coverage

**✅ Epic 1: Title Suggestions**
- Database, Service, API, Component, Integration, Feedback: 100% covered

**✅ Epic 2: Semantic Search**
- Database, Service, API, Component, Integration, Performance: 100% covered

**✅ Epic 3: Paragraph Reformulation**
- Database, Service, API, Component, Integration, Options: 100% covered

**✅ Epic 4: Memory Echo**
- Database, Service, API, Server Action, Component, Background, Feedback, Performance: 100% covered

**✅ Epic 5: AI Settings**
- Database, Page, Component, Server Action, Features, Providers, Frequency: 100% covered

**✅ Epic 6: Language Detection**
- Library, Service, Database, Integration, Strategy: 100% covered

---

#### Functional Requirements Coverage

**✅ FR1-FR5 (Foundation):** ALREADY IMPLEMENTED
**✅ FR6-FR13 (AI Features):** FULLY COVERED by Phase 1 epics
**✅ FR14-FR16 (Offline PWA):** DEFERRED to Phase 2
**✅ FR17-FR19 (Configuration):** FULLY COVERED by Epic 5

---

#### Non-Functional Requirements Coverage

**✅ Performance - IA Responsiveness:** ADDRESSED
**✅ Performance - Search Latency:** ADDRESSED (< 300ms target)
**✅ Security - API Key Isolation:** ADDRESSED (server-side only)
**✅ Security - Local-First Privacy:** ADDRESSED (Ollama verified)
**✅ Reliability - Vector Integrity:** ADDRESSED (auto-updates)
**✅ Portability - Efficiency:** ADDRESSED (Zero DevOps)

---

### Implementation Readiness Validation

#### Decision Completeness

**✅ Decision 1 (Database Schema):** 100% COMPLETE - READY
**✅ Decision 2 (Memory Echo):** 100% COMPLETE - READY
**✅ Decision 3 (Language Detection):** 100% COMPLETE - READY
**✅ Decision 4 (AI Settings):** 100% COMPLETE - READY

#### Structure Completeness

**✅ Directory Structure:** 100% COMPLETE - READY
**✅ API Boundaries:** 100% COMPLETE - READY
**✅ Component Boundaries:** 100% COMPLETE - READY
**✅ Service Boundaries:** 100% COMPLETE - READY

#### Pattern Completeness

**✅ Naming Patterns:** 100% COMPLETE - READY
**✅ Format Patterns:** 100% COMPLETE - READY
**✅ Communication Patterns:** 100% COMPLETE - READY
**✅ Error Handling Patterns:** 100% COMPLETE - READY
**✅ AI-Specific Patterns:** 100% COMPLETE - READY

---

### Gap Analysis

#### Critical Gaps: NONE IDENTIFIED
#### Important Gaps: NONE IDENTIFIED

#### Nice-to-Have Gaps (Deferred to Phase 2/3):

1. Trust Score UI (Phase 3)
2. Advanced Feedback Analytics (Phase 2+)
3. PostgreSQL Migration (Phase 2)
4. Vector DB (Phase 2+)
5. PWA Offline Mode (Phase 2)
6. Real-Time Collaboration (Phase 3)
7. Mobile Apps (Phase 3)

---

### Architecture Completeness Checklist

**✅ Foundations:** [x] Context, [x] Architecture Review, [x] Stack, [x] Concerns
**✅ Decisions:** [x] Schema, [x] Memory Echo, [x] Language Detection, [x] Settings
**✅ Patterns:** [x] Naming, [x] Structure, [x] Format, [x] Communication, [x] Process, [x] AI
**✅ Structure:** [x] Directory Tree, [x] Boundaries, [x] Mapping, [x] Integration, [x] Organization
**✅ Documentation:** [x] Rationale, [x] Implications, [x] Choices, [x] Targets, [x] Security
**✅ Readiness:** [x] Migrations, [x] API Routes, [x] Server Actions, [x] Services, [x] Components, [x] Tests
**✅ Validation:** [x] Coherence, [x] Coverage, [x] Readiness, [x] Gap Analysis

---

### Readiness Assessment

**🎯 Readiness Level:** PRODUCTION READY

**Confidence Score:** 95%

**Breakdown:**
- Decision Completeness: 100% ✅
- Structure Completeness: 100% ✅
- Pattern Completeness: 100% ✅
- Requirements Coverage: 100% ✅
- Documentation Quality: 95% ✅
- Implementation Clarity: 95% ✅

**Reasoning for 95%:**
- All architectural decisions made and validated
- All patterns documented with good/anti-patterns
- Complete directory structure with epic mappings
- Comprehensive requirements coverage validated
- Only minor deduction: Some implementation details will emerge during development (normal for brownfield projects)

---

### Risk Assessment

**🎯 Overall Risk Level:** LOW

**Risk Categories:**
1. **Technical Risks:** LOW ✅
   - SQLite vector storage acceptable for MVP
   - TinyLD hybrid approach mitigates accuracy risk
   - Memory Echo background processing ensures performance

2. **Integration Risks:** LOW ✅
   - Zero-breaking-change approach enforced
   - Provider factory extended, not replaced
   - NextAuth integration unchanged

3. **Performance Risks:** LOW ✅
   - In-memory cosine similarity < 300ms achievable
   - Debounce + background processing ensures non-blocking UI
   - Language detection within targets

4. **Scope Risks:** LOW ✅
   - Clear PRD scoping, Phase 2/3 features explicitly deferred
   - Medium complexity well-managed through patterns

5. **Security Risks:** LOW ✅
   - Server-side only pattern enforced
   - Ollama local-only path verified
   - Existing NextAuth maintained

---

### Implementation Blockers

**🎯 Blockers: NONE IDENTIFIED**

**Critical Path Clear:**
- ✅ Prisma migrations can be created immediately
- ✅ AI services can be implemented independently
- ✅ API routes follow existing patterns
- ✅ UI components integrate cleanly

---

### Final Validation Statement

**🎯 Architecture Status: VALIDATED AND READY FOR IMPLEMENTATION**

This architecture document provides a complete, coherent, and implementation-ready blueprint for Keep (Memento) Phase 1 MVP AI features.

**Confidence Level: 95% - PRODUCTION READY**

**Recommended Next Steps:**
1. ✅ Present validation to product owner for approval
2. ✅ Proceed to implementation following recommended sequence
3. ✅ Create epics.md (recreate from PRD + Architecture mapping)
4. ✅ Begin Phase 1 Foundation (Prisma migrations + base service layer)

---

*Validation completed: 2026-01-10*
*Validated by: Winston (Architect Agent)*
*Architecture version: 1.0.0 - Phase 1 MVP AI*
---

## Architecture Completion Summary

### Workflow Completion

**Architecture Decision Workflow:** COMPLETED ✅
**Total Steps Completed:** 8
**Date Completed:** 2026-01-10
**Document Location:** _bmad-output/planning-artifacts/architecture.md

---

### Final Architecture Deliverables

**📋 Complete Architecture Document (2800+ lines)**

- All architectural decisions documented with specific versions
- Implementation patterns ensuring AI agent consistency
- Complete project structure with all files and directories
- Requirements to architecture mapping (6 epics → files)
- Validation confirming coherence and completeness (95% confidence)

**🏗️ Implementation Ready Foundation**

- **4 architectural decisions** made (Database Schema, Memory Echo, Language Detection, AI Settings)
- **6 implementation patterns** defined (Naming, Structure, Format, Communication, Process, AI-Specific)
- **38 conflict points** identified and resolved with consistency rules
- **100% requirements coverage** (6 epics, all FRs, all NFRs)
- **6 AI services** architected (Title Suggestion, Semantic Search, Paragraph Refactor, Memory Echo, Language Detection, Embedding)
- **6 AI components** specified (AiSuggestion, SemanticSearchResults, ParagraphRefactor, MemoryEchoNotification, AiSettingsPanel, FeedbackButtons)
- **7 new API routes** documented (/api/ai/titles, search, refactor, echo, feedback, language + existing tags/test)

**📚 AI Agent Implementation Guide**

- Technology stack with verified versions (Next.js 16.1.1, React 19.2.3, Prisma 5.22.0, TinyLD)
- Consistency rules that prevent implementation conflicts
- Project structure with clear boundaries (2260-line directory tree)
- Integration patterns and communication standards
- Good patterns and anti-patterns documented with examples

---

### Implementation Handoff

**For AI Agents:**
This architecture document is your complete guide for implementing Keep (Memento) Phase 1 MVP AI features. Follow all decisions, patterns, and structures exactly as documented.

**First Implementation Priority:**

**Phase 1 - Foundation (Week 1-2):**
```bash
# 1. Create Prisma migrations
npx prisma migrate dev --name add_ai_feedback
npx prisma migrate dev --name add_memory_echo_insights
npx prisma migrate dev --name add_user_ai_settings

# 2. Generate Prisma client
npx prisma generate

# 3. Create base AI service layer structure
mkdir -p keep-notes/lib/ai/services
# Create empty service classes for all 6 services
```

**Development Sequence:**

1. **Initialize** - Create Prisma migrations and base service layer
2. **Infrastructure** - Implement LanguageDetectionService (TinyLD integration) + UserAISettings page
3. **AI Features** - Implement 4 core features (Title Suggestions, Semantic Search, Paragraph Refactor, Memory Echo)
4. **Polish** - Create E2E tests, performance testing, multi-language testing
5. **Deploy** - Verify deployment to Vercel/Netlify, monitor performance

**Critical Success Factors:**
- ✅ Zero breaking changes to existing features
- ✅ Ollama users verify no external API calls (DevTools Network tab)
- ✅ All AI services < 2s response time
- ✅ Semantic search < 300ms for 1000 notes
- ✅ Memory Echo < 100ms UI freeze

---

### Quality Assurance Checklist

**✅ Architecture Coherence**

- [x] All decisions work together without conflicts
- [x] Technology choices are compatible (brownfield extension approach)
- [x] Patterns support the architectural decisions
- [x] Structure aligns with all choices (Next.js 16 + React 19 patterns)

**✅ Requirements Coverage**

- [x] All functional requirements are supported (FR1-FR19)
- [x] All non-functional requirements are addressed (Performance, Security, Reliability, Portability)
- [x] Cross-cutting concerns are handled (Privacy, Multilingual, User Control, Extensibility)
- [x] Integration points are defined (6 epics mapped to files)

**✅ Implementation Readiness**

- [x] Decisions are specific and actionable (4 decisions with implementation details)
- [x] Patterns prevent agent conflicts (38 conflict points resolved)
- [x] Structure is complete and unambiguous (2260-line directory tree)
- [x] Examples are provided for clarity (good patterns + anti-patterns)

---

### Project Success Factors

**🎯 Clear Decision Framework**
Every technology choice was made collaboratively with clear rationale:
- **Database Schema Extensions:** Extended Note model + 3 new tables with zero breaking changes
- **Memory Echo:** Server Action + Queue in DB pattern (background processing, < 100ms UI freeze)
- **Language Detection:** TinyLD hybrid approach (62 languages including Persian verified)
- **AI Settings:** Dedicated UserAISettings table (type-safe, analytics-ready)

**🔧 Consistency Guarantee**
Implementation patterns and rules ensure that multiple AI agents will produce compatible, consistent code:
- **Naming:** PascalCase tables, camelCase columns, /api/ai/* namespace
- **Format:** {success, data, error} response format across all API routes
- **Authentication:** auth() check in all server actions
- **Error Handling:** try/catch with console.error() logging

**📋 Complete Coverage**
All project requirements are architecturally supported:
- **6 Epics** mapped to specific files and components (100% coverage)
- **19 Functional Requirements** addressed (FR1-FR13 implemented, FR14-FR16 deferred Phase 2, FR17-FR19 implemented)
- **6 Non-Functional Categories** validated (Performance, Security, Reliability, Portability, PWA deferred)

**🏗️ Solid Foundation**
The architectural patterns provide a production-ready foundation:
- **Brownfield Extension:** Zero breaking changes, respects existing patterns
- **Multi-Provider Support:** OpenAI (cloud) + Ollama (local) via factory pattern
- **Privacy-First:** Ollama = 100% local, zero data exfiltration (verifiable in DevTools)
- **Zero DevOps:** SQLite file-based, Vercel/Netlify hosting, no dedicated infrastructure

---

### Architecture Document Statistics

**Document Size:**
- **Total Lines:** ~2800 lines
- **Sections:** 7 major sections + validation + completion
- **Decisions:** 4 architectural decisions with full rationale
- **Patterns:** 6 pattern categories with 38 conflict points resolved
- **Structure:** 2260-line project directory tree
- **Epic Mapping:** 6 epics mapped to 50+ files

**Technology Stack:**
- **Frontend:** Next.js 16.1.1, React 19.2.3, Tailwind CSS 4, Radix UI
- **Backend:** Next.js API Routes, Server Actions, Prisma 5.22.0
- **Database:** SQLite (better-sqlite3)
- **AI:** Vercel AI SDK 6.0.23, OpenAI, Ollama, TinyLD
- **Auth:** NextAuth 5.0.0-beta.30

**Validation Results:**
- **Coherence:** ✅ PASS (all decisions compatible)
- **Coverage:** ✅ PASS (100% requirements coverage)
- **Readiness:** ✅ PASS (95% confidence)
- **Risk:** ✅ LOW (5 categories assessed)
- **Blockers:** ✅ NONE

---

### Recommendations for Implementation Phase

**For Development Team:**

1. **Read the complete architecture document** before writing any code
2. **Follow patterns strictly** - they prevent conflicts between AI agents
3. **Test with both providers** - verify Ollama (local) and OpenAI (cloud) paths
4. **Monitor performance metrics** - search latency, AI response times, Memory Echo UI freeze
5. **Collect user feedback** - thumbs up/down for quality assessment

**For Product Owner (Ramez):**

1. **Review validation section** - confirm all requirements are addressed
2. **Verify technology choices** - TinyLD for Persian, hybrid language detection, Memory Echo approach
3. **Approve implementation sequence** - 4 phases (Foundation, Infrastructure, AI Features, Polish)
4. **Create epics.md** - recreate from PRD + Architecture mapping (referenced in structure)
5. **Begin story creation** - use "create-story" workflow to generate implementation-ready user stories

**For AI Agents:**

1. **Load architecture.md** before implementing any feature
2. **Follow naming patterns** - camelCase variables, PascalCase components, kebab-case files
3. **Use response format** - {success: true|false, data: any, error: string}
4. **Add 'use server'** to all server actions, 'use client' to interactive components
5. **Import from aliases** - @/components/ui/*, @/lib/*, @/app/*
6. **Validate with Zod** for all API route inputs
7. **Call auth()** in all server actions for authentication
8. **Use revalidatePath('/')** after mutations in server actions
9. **Log errors** with console.error(), never expose stack traces to users

---

### Architecture Maintenance

**When to Update This Document:**

- ✅ Major technology version changes (Next.js 17, React 20, etc.)
- ✅ New architectural decisions (Phase 2/3 features like PWA, PostgreSQL)
- ✅ Pattern changes (breaking changes to naming or structure conventions)
- ✅ Performance optimizations (algorithm changes, new caching strategy)

**When NOT to Update:**

- ❌ Bug fixes (temporary workarounds don't belong in architecture)
- ❌ Minor refactoring (structure remains the same)
- ❌ Implementation details (code belongs in files, not architecture)

**Update Process:**

1. Discuss architectural change with team
2. Document decision with rationale
3. Update relevant sections
4. Re-validate coherence
5. Communicate change to all AI agents

---

**Architecture Status:** READY FOR IMPLEMENTATION ✅

**Next Phase:** Begin implementation using the architectural decisions and patterns documented herein.

**Recommended Next Steps:**

1. **Review architecture document** - _bmad-output/planning-artifacts/architecture.md
2. **Create project context** - Optional: project-context.md for AI agent optimization
3. **Recreate epics.md** - Map PRD requirements to architecture structure
4. **Generate user stories** - Use "create-story" workflow for implementation-ready stories
5. **Begin Phase 1 Foundation** - Prisma migrations + base service layer

---

*Architecture workflow completed: 2026-01-10*
*Architect: Winston (Architect Agent)*
*Architecture version: 1.0.0 - Phase 1 MVP AI*
*Status: VALIDATED AND READY FOR IMPLEMENTATION*
