initial commit

This commit is contained in:
BeauTroll
2026-01-19 08:52:38 +01:00
commit 46907ca153
193 changed files with 35051 additions and 0 deletions

2572
docs/architecture.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
# 1. Introduction
## Project Overview
**Dofus Manager** est une application web personnelle conçue pour gérer efficacement plus de 60 personnages du MMORPG Dofus, répartis sur plusieurs comptes. L'application centralise le suivi des progressions (quêtes, donjons, succès) et permet une gestion optimisée via des équipes.
## Goals
- **Centralisation** : Un point unique pour gérer tous les personnages et comptes
- **Suivi des progressions** : Tracker l'avancement des quêtes, donjons et succès
- **Gestion par équipes** : Organiser les personnages en équipes pour faciliter le suivi
- **Efficacité** : Interface rapide avec opérations bulk et filtres avancés
## Scope
| In Scope | Out of Scope |
|----------|--------------|
| Gestion des personnages (CRUD) | Intégration directe avec le jeu |
| Gestion des comptes | Multi-utilisateurs |
| Suivi des progressions | Application mobile native |
| Gestion des équipes | Synchronisation automatique |
| Import données DofusDB | Fonctionnalités sociales |
| Interface responsive | Mode hors-ligne |
## Non-Functional Requirements
| Requirement | Target |
|-------------|--------|
| Performance | < 200ms pour les opérations courantes |
| Disponibilité | 99% uptime (usage personnel) |
| Sécurité | Authentification requise, données protégées |
| Scalabilité | Support de 100+ personnages |
| Maintenabilité | Code typé, tests automatisés |
---

View File

@@ -0,0 +1,187 @@
# 10. Frontend Architecture
## State Management Strategy
```
┌─────────────────────────────────────────────────────────────────┐
│ STATE MANAGEMENT │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ TanStack Query │ │
│ │ (Server State / Cache) │ │
│ │ │ │
│ │ • Characters list │ │
│ │ • Accounts data │ │
│ │ • Teams & members │ │
│ │ • Progressions │ │
│ │ • DofusDB reference data │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Zustand │ │
│ │ (Client/UI State) │ │
│ │ │ │
│ │ • Selected items (multi-select) │ │
│ │ • UI preferences (sidebar collapsed, etc.) │ │
│ │ • Filter states │ │
│ │ • Modal open/close states │ │
│ │ • Theme preference │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ React State │ │
│ │ (Component-local State) │ │
│ │ │ │
│ │ • Form inputs │ │
│ │ • Hover/focus states │ │
│ │ • Animation states │ │
│ │ • Temporary UI states │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
## TanStack Query Setup
```typescript
// src/lib/client/query-client.ts
import { QueryClient } from '@tanstack/react-query';
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 minutes
gcTime: 1000 * 60 * 30, // 30 minutes
retry: 1,
refetchOnWindowFocus: false,
},
mutations: {
onError: (error) => {
console.error('Mutation error:', error);
},
},
},
});
// Query keys factory
export const queryKeys = {
characters: {
all: ['characters'] as const,
list: (filters: CharacterFilters) => [...queryKeys.characters.all, 'list', filters] as const,
detail: (id: string) => [...queryKeys.characters.all, 'detail', id] as const,
},
accounts: {
all: ['accounts'] as const,
list: () => [...queryKeys.accounts.all, 'list'] as const,
detail: (id: string) => [...queryKeys.accounts.all, 'detail', id] as const,
},
teams: {
all: ['teams'] as const,
list: () => [...queryKeys.teams.all, 'list'] as const,
detail: (id: string) => [...queryKeys.teams.all, 'detail', id] as const,
},
progressions: {
all: ['progressions'] as const,
list: (type?: ProgressionType) => [...queryKeys.progressions.all, 'list', type] as const,
byCharacter: (characterId: string) => [...queryKeys.progressions.all, 'character', characterId] as const,
},
} as const;
```
## Zustand Store
```typescript
// src/lib/client/stores/ui-store.ts
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface UIState {
// Sidebar
sidebarCollapsed: boolean;
toggleSidebar: () => void;
// Theme
theme: 'light' | 'dark';
setTheme: (theme: 'light' | 'dark') => void;
// Selection (for bulk actions)
selectedCharacterIds: string[];
selectCharacter: (id: string) => void;
deselectCharacter: (id: string) => void;
selectAllCharacters: (ids: string[]) => void;
clearSelection: () => void;
}
export const useUIStore = create<UIState>()(
persist(
(set) => ({
// Sidebar
sidebarCollapsed: false,
toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),
// Theme
theme: 'dark',
setTheme: (theme) => set({ theme }),
// Selection
selectedCharacterIds: [],
selectCharacter: (id) =>
set((state) => ({
selectedCharacterIds: [...state.selectedCharacterIds, id]
})),
deselectCharacter: (id) =>
set((state) => ({
selectedCharacterIds: state.selectedCharacterIds.filter((i) => i !== id)
})),
selectAllCharacters: (ids) => set({ selectedCharacterIds: ids }),
clearSelection: () => set({ selectedCharacterIds: [] }),
}),
{
name: 'dofus-manager-ui',
partialize: (state) => ({
sidebarCollapsed: state.sidebarCollapsed,
theme: state.theme,
}),
}
)
);
```
## Routing Structure
```typescript
// src/routes/__root.tsx
import { createRootRoute, Outlet } from '@tanstack/react-router';
import { AppShell } from '@/components/layout/app-shell';
export const Route = createRootRoute({
component: () => (
<AppShell>
<Outlet />
</AppShell>
),
});
// Route tree
/*
src/routes/
├── __root.tsx # Root layout with AppShell
├── index.tsx # / → Dashboard
├── characters/
│ ├── index.tsx # /characters → List
│ └── $id.tsx # /characters/:id → Detail
├── accounts/
│ ├── index.tsx # /accounts → List
│ └── $id.tsx # /accounts/:id → Detail
├── teams/
│ ├── index.tsx # /teams → List
│ └── $id.tsx # /teams/:id → Detail
├── progressions/
│ └── index.tsx # /progressions → Tracker
└── settings/
└── index.tsx # /settings → Settings
*/
```
---

View File

@@ -0,0 +1,205 @@
# 11. Backend Architecture
## Server Functions Organization
```
src/server/
├── functions/
│ ├── auth.ts # Authentication functions
│ ├── characters.ts # Character CRUD
│ ├── accounts.ts # Account CRUD
│ ├── teams.ts # Team management
│ ├── progressions.ts # Progression tracking
│ └── dofusdb.ts # DofusDB sync
├── middleware/
│ └── auth.ts # Authentication middleware
└── index.ts # Export all functions
```
## Server Function Example
```typescript
// src/server/functions/characters.ts
import { createServerFn } from '@tanstack/react-start/server';
import { z } from 'zod';
import { db } from '@/lib/server/db';
import { requireAuth } from '@/server/middleware/auth';
// Schemas
const createCharacterSchema = z.object({
name: z.string().min(2).max(50),
level: z.number().int().min(1).max(200),
classId: z.number().int().positive(),
className: z.string(),
serverId: z.number().int().positive(),
serverName: z.string(),
accountId: z.string().cuid(),
});
const characterFiltersSchema = z.object({
search: z.string().optional(),
classIds: z.array(z.number()).optional(),
serverIds: z.array(z.number()).optional(),
accountIds: z.array(z.string()).optional(),
page: z.number().int().positive().default(1),
limit: z.number().int().min(1).max(100).default(20),
});
// Functions
export const getCharacters = createServerFn({ method: 'GET' })
.validator((data: unknown) => characterFiltersSchema.parse(data))
.handler(async ({ data }) => {
const session = await requireAuth();
const { search, classIds, serverIds, accountIds, page, limit } = data;
const where = {
account: { userId: session.userId },
...(search && {
name: { contains: search, mode: 'insensitive' as const },
}),
...(classIds?.length && { classId: { in: classIds } }),
...(serverIds?.length && { serverId: { in: serverIds } }),
...(accountIds?.length && { accountId: { in: accountIds } }),
};
const [characters, total] = await Promise.all([
db.character.findMany({
where,
include: { account: { select: { id: true, name: true } } },
skip: (page - 1) * limit,
take: limit,
orderBy: { name: 'asc' },
}),
db.character.count({ where }),
]);
return {
characters,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit),
},
};
});
export const createCharacter = createServerFn({ method: 'POST' })
.validator((data: unknown) => createCharacterSchema.parse(data))
.handler(async ({ data }) => {
const session = await requireAuth();
// Verify account belongs to user
const account = await db.account.findFirst({
where: { id: data.accountId, userId: session.userId },
});
if (!account) {
throw new Error('Account not found');
}
return db.character.create({ data });
});
export const bulkDeleteCharacters = createServerFn({ method: 'POST' })
.validator((data: unknown) => z.object({ ids: z.array(z.string().cuid()) }).parse(data))
.handler(async ({ data }) => {
const session = await requireAuth();
const result = await db.character.deleteMany({
where: {
id: { in: data.ids },
account: { userId: session.userId },
},
});
return { deleted: result.count };
});
```
## Authentication Middleware
```typescript
// src/server/middleware/auth.ts
import { getWebRequest } from '@tanstack/react-start/server';
import { db } from '@/lib/server/db';
interface Session {
userId: string;
sessionId: string;
}
export async function requireAuth(): Promise<Session> {
const request = getWebRequest();
const sessionId = request.headers.get('cookie')
?.split(';')
.find(c => c.trim().startsWith('session='))
?.split('=')[1];
if (!sessionId) {
throw new Error('Unauthorized');
}
const session = await db.session.findUnique({
where: { id: sessionId },
include: { user: true },
});
if (!session || session.expiresAt < new Date()) {
throw new Error('Session expired');
}
return {
userId: session.userId,
sessionId: session.id,
};
}
export async function getOptionalAuth(): Promise<Session | null> {
try {
return await requireAuth();
} catch {
return null;
}
}
```
## Caching Strategy
```typescript
// src/lib/server/cache.ts
import NodeCache from 'node-cache';
// Different TTLs for different data types
const caches = {
// Reference data (rarely changes)
reference: new NodeCache({ stdTTL: 3600, checkperiod: 600 }), // 1 hour
// User data (changes more frequently)
user: new NodeCache({ stdTTL: 300, checkperiod: 60 }), // 5 minutes
};
export const referenceCache = {
get: <T>(key: string): T | undefined => caches.reference.get(key),
set: <T>(key: string, value: T): boolean => caches.reference.set(key, value),
del: (key: string): number => caches.reference.del(key),
flush: (): void => caches.reference.flushAll(),
};
export const userCache = {
get: <T>(key: string): T | undefined => caches.user.get(key),
set: <T>(key: string, value: T): boolean => caches.user.set(key, value),
del: (key: string | string[]): number => caches.user.del(key),
flush: (): void => caches.user.flushAll(),
// Helper to invalidate all cache for a user
invalidateUser: (userId: string): void => {
const keys = caches.user.keys().filter(k => k.startsWith(`user:${userId}:`));
caches.user.del(keys);
},
};
```
---

View File

@@ -0,0 +1,93 @@
# 12. Project Structure
```
dofus-manager/
├── .github/
│ └── workflows/
│ └── ci.yml
├── docker/
│ ├── Dockerfile
│ └── docker-compose.yml
├── docs/
│ ├── prd.md
│ ├── front-end-spec.md
│ └── architecture.md
├── prisma/
│ ├── schema.prisma
│ └── migrations/
├── public/
│ └── favicon.ico
├── src/
│ ├── components/
│ │ ├── ui/ # shadcn/ui components
│ │ ├── layout/ # Layout components
│ │ ├── characters/ # Character feature
│ │ ├── accounts/ # Account feature
│ │ ├── teams/ # Team feature
│ │ ├── progressions/ # Progression feature
│ │ └── shared/ # Shared components
│ │
│ ├── lib/
│ │ ├── utils.ts # Utility functions (cn, etc.)
│ │ ├── errors.ts # Error types
│ │ ├── schemas/ # Zod schemas
│ │ │ ├── character.ts
│ │ │ ├── account.ts
│ │ │ ├── team.ts
│ │ │ └── progression.ts
│ │ ├── client/ # Client-only code
│ │ │ ├── query-client.ts
│ │ │ └── stores/
│ │ │ └── ui-store.ts
│ │ └── server/ # Server-only code
│ │ ├── db.ts
│ │ ├── cache.ts
│ │ ├── logger.ts
│ │ └── dofusdb.ts
│ │
│ ├── routes/
│ │ ├── __root.tsx
│ │ ├── index.tsx
│ │ ├── characters/
│ │ ├── accounts/
│ │ ├── teams/
│ │ ├── progressions/
│ │ └── settings/
│ │
│ ├── server/
│ │ ├── functions/
│ │ │ ├── auth.ts
│ │ │ ├── characters.ts
│ │ │ ├── accounts.ts
│ │ │ ├── teams.ts
│ │ │ ├── progressions.ts
│ │ │ └── dofusdb.ts
│ │ ├── middleware/
│ │ │ └── auth.ts
│ │ └── index.ts
│ │
│ ├── styles/
│ │ └── globals.css
│ │
│ └── app.tsx # App entry point
├── tests/
│ ├── unit/
│ ├── integration/
│ └── e2e/
├── .env.example
├── .gitignore
├── biome.json
├── package.json
├── tsconfig.json
├── app.config.ts # TanStack Start config
└── README.md
```
---

View File

@@ -0,0 +1,83 @@
# 13. Development Workflow
## Local Development Setup
```bash
# 1. Clone repository
git clone <repo-url>
cd dofus-manager
# 2. Install dependencies
pnpm install
# 3. Setup environment
cp .env.example .env
# Edit .env with your values
# 4. Start database
docker compose up -d postgres
# 5. Run migrations
pnpm prisma migrate dev
# 6. Seed database (optional)
pnpm prisma db seed
# 7. Start development server
pnpm dev
```
## Environment Variables
```bash
# .env.example
# Database
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/dofus_manager?schema=public"
# App
APP_URL="http://localhost:3000"
NODE_ENV="development"
# Session
SESSION_SECRET="your-secret-key-min-32-chars"
# Optional: DofusDB
DOFUSDB_CACHE_TTL="3600"
```
## Git Workflow
```
main (production)
└── develop (staging)
├── feature/add-character-filters
├── feature/team-management
└── fix/progression-update-bug
```
## Branch Naming
- `feature/*` - New features
- `fix/*` - Bug fixes
- `refactor/*` - Code refactoring
- `docs/*` - Documentation updates
- `chore/*` - Maintenance tasks
## Commit Convention
```
<type>(<scope>): <description>
Types: feat, fix, docs, style, refactor, test, chore
Scope: characters, accounts, teams, progressions, auth, ui
Examples:
feat(characters): add bulk delete functionality
fix(progressions): correct date formatting
docs(readme): update setup instructions
```
---

View File

@@ -0,0 +1,215 @@
# 14. Deployment Architecture
## Docker Configuration
```dockerfile
# docker/Dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# Copy package files
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
# Copy source and build
COPY . .
RUN pnpm prisma generate
RUN pnpm build
# Production stage
FROM node:20-alpine AS runner
WORKDIR /app
# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# Create non-root user
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 app
# Copy built application
COPY --from=builder --chown=app:nodejs /app/.output ./.output
COPY --from=builder --chown=app:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=app:nodejs /app/package.json ./package.json
COPY --from=builder --chown=app:nodejs /app/prisma ./prisma
USER app
EXPOSE 3000
ENV NODE_ENV=production
ENV PORT=3000
CMD ["node", ".output/server/index.mjs"]
```
## Docker Compose (Production)
```yaml
# docker/docker-compose.yml
services:
app:
build:
context: ..
dockerfile: docker/Dockerfile
restart: unless-stopped
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/dofus_manager
- SESSION_SECRET=${SESSION_SECRET}
- NODE_ENV=production
depends_on:
postgres:
condition: service_healthy
networks:
- internal
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.dofus.rule=Host(`dofus.example.com`)"
- "traefik.http.routers.dofus.entrypoints=websecure"
- "traefik.http.routers.dofus.tls.certresolver=letsencrypt"
- "traefik.http.services.dofus.loadbalancer.server.port=3000"
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=dofus_manager
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
networks:
- internal
traefik:
image: traefik:v3.0
restart: unless-stopped
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt:/letsencrypt
networks:
- traefik
volumes:
postgres_data:
letsencrypt:
networks:
internal:
traefik:
external: true
```
## GitLab CI/CD Pipeline
```yaml
# .gitlab-ci.yml
stages:
- test
- build
- deploy
variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
# Test stage
test:
stage: test
image: node:20-alpine
before_script:
- corepack enable
- pnpm install --frozen-lockfile
script:
- pnpm lint
- pnpm typecheck
- pnpm test
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
# Build stage
build:
stage: build
image: docker:24
services:
- docker:24-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $DOCKER_IMAGE -f docker/Dockerfile .
- docker push $DOCKER_IMAGE
- docker tag $DOCKER_IMAGE $CI_REGISTRY_IMAGE:latest
- docker push $CI_REGISTRY_IMAGE:latest
only:
- main
- develop
# Deploy staging
deploy_staging:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | ssh-add -
- mkdir -p ~/.ssh
- echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
script:
- ssh $STAGING_USER@$STAGING_HOST "cd /opt/dofus-manager && docker compose pull && docker compose up -d"
environment:
name: staging
url: https://staging.dofus.example.com
only:
- develop
# Deploy production
deploy_production:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | ssh-add -
- mkdir -p ~/.ssh
- echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
script:
- ssh $PROD_USER@$PROD_HOST "cd /opt/dofus-manager && docker compose pull && docker compose up -d && docker compose exec app pnpm prisma migrate deploy"
environment:
name: production
url: https://dofus.example.com
only:
- main
when: manual
```
---

View File

@@ -0,0 +1,68 @@
# 15. Security & Performance
## Security Measures
### Authentication
- Session-based authentication with secure cookies
- Password hashing with bcrypt (cost factor 12)
- Session expiration and rotation
### Input Validation
- All inputs validated with Zod schemas
- Server-side validation mandatory
- Prisma parameterized queries (SQL injection prevention)
### Headers (via Traefik)
```yaml
# Security headers middleware
http:
middlewares:
security-headers:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
contentTypeNosniff: true
frameDeny: true
browserXssFilter: true
referrerPolicy: "strict-origin-when-cross-origin"
contentSecurityPolicy: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
```
## Performance Optimizations
### Database
- Indexes on foreign keys and search fields
- Pagination for all list queries
- Connection pooling via Prisma
### Caching
- node-cache for server-side caching
- TanStack Query for client-side caching
- DofusDB data cached for 1 hour
### Frontend
- Code splitting via TanStack Router
- Lazy loading for routes
- Optimistic updates for better UX
### Bundle Optimization
```typescript
// app.config.ts
export default defineConfig({
vite: {
build: {
rollupOptions: {
output: {
manualChunks: {
'vendor-react': ['react', 'react-dom'],
'vendor-tanstack': ['@tanstack/react-router', '@tanstack/react-query'],
'vendor-ui': ['@radix-ui/react-dialog', '@radix-ui/react-select'],
},
},
},
},
},
});
```
---

View File

@@ -0,0 +1,146 @@
# 16. Testing Strategy
## Testing Pyramid
```
┌───────┐
│ E2E │ ← Few, critical paths
│ Tests │
┌┴───────┴┐
│Integration│ ← API & DB tests
│ Tests │
┌┴─────────┴┐
│ Unit │ ← Many, fast
│ Tests │
└───────────┘
```
## Unit Tests (Vitest)
```typescript
// tests/unit/schemas/character.test.ts
import { describe, it, expect } from 'vitest';
import { createCharacterSchema } from '@/lib/schemas/character';
describe('createCharacterSchema', () => {
it('validates correct input', () => {
const input = {
name: 'TestChar',
level: 200,
classId: 1,
className: 'Cra',
serverId: 1,
serverName: 'Imagiro',
accountId: 'clx123abc',
};
expect(() => createCharacterSchema.parse(input)).not.toThrow();
});
it('rejects invalid level', () => {
const input = {
name: 'TestChar',
level: 250, // Invalid: max is 200
classId: 1,
className: 'Cra',
serverId: 1,
serverName: 'Imagiro',
accountId: 'clx123abc',
};
expect(() => createCharacterSchema.parse(input)).toThrow();
});
});
```
## Integration Tests
```typescript
// tests/integration/characters.test.ts
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { db } from '@/lib/server/db';
describe('Character API', () => {
let testUserId: string;
let testAccountId: string;
beforeAll(async () => {
// Setup test data
const user = await db.user.create({
data: {
email: 'test@test.com',
passwordHash: 'hash',
},
});
testUserId = user.id;
const account = await db.account.create({
data: {
name: 'TestAccount',
userId: testUserId,
},
});
testAccountId = account.id;
});
afterAll(async () => {
// Cleanup
await db.user.delete({ where: { id: testUserId } });
});
it('creates a character', async () => {
const character = await db.character.create({
data: {
name: 'TestChar',
level: 200,
classId: 1,
className: 'Cra',
serverId: 1,
serverName: 'Imagiro',
accountId: testAccountId,
},
});
expect(character.name).toBe('TestChar');
expect(character.level).toBe(200);
});
});
```
## E2E Tests (Playwright)
```typescript
// tests/e2e/characters.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Characters Page', () => {
test.beforeEach(async ({ page }) => {
// Login
await page.goto('/login');
await page.fill('[name="email"]', 'test@test.com');
await page.fill('[name="password"]', 'password');
await page.click('button[type="submit"]');
await page.waitForURL('/');
});
test('displays character list', async ({ page }) => {
await page.goto('/characters');
await expect(page.locator('h1')).toContainText('Personnages');
await expect(page.locator('table')).toBeVisible();
});
test('can create a new character', async ({ page }) => {
await page.goto('/characters');
await page.click('button:has-text("Ajouter")');
await page.fill('[name="name"]', 'NewChar');
await page.fill('[name="level"]', '100');
await page.click('button:has-text("Créer")');
await expect(page.locator('text=NewChar')).toBeVisible();
});
});
```
---

View File

@@ -0,0 +1,343 @@
# 17. Coding Standards
Cette section définit les standards de code minimaux mais critiques pour le développement. Ces règles sont conçues pour les agents IA et les développeurs.
## Critical Fullstack Rules
| Rule | Description |
|------|-------------|
| **Type Sharing** | Toujours définir les types partagés dans `src/types/` et les importer dans les composants et server functions. Ne jamais dupliquer les interfaces. |
| **Server Functions Only** | Ne jamais faire d'appels HTTP directs (fetch, axios). Toujours utiliser les server functions importées depuis `@/server/*`. |
| **Zod Validation** | Toute entrée utilisateur doit être validée avec un schéma Zod. Le schéma doit être colocalisé avec la server function. |
| **Prisma Transactions** | Les opérations multi-tables doivent utiliser `prisma.$transaction()` pour garantir l'atomicité. |
| **Cache Invalidation** | Après chaque mutation, invalider les caches affectés via `cacheService.invalidate()` et `queryClient.invalidateQueries()`. |
| **Error Boundaries** | Chaque page doit être wrappée dans un ErrorBoundary. Les erreurs serveur doivent utiliser les classes de `@/lib/errors.ts`. |
| **No Direct State Mutation** | Ne jamais muter l'état directement. Utiliser les setters de useState ou les mutations TanStack Query. |
| **URL State for Filters** | Les filtres et la pagination doivent être stockés dans l'URL via TanStack Router, pas dans le state local. |
| **Optimistic Updates Pattern** | Pour les actions fréquentes (toggle, update), utiliser les optimistic updates de TanStack Query. |
| **Component Colocation** | Les hooks, types et helpers spécifiques à un composant doivent être dans le même dossier. |
## Naming Conventions
| Element | Frontend | Backend | Example |
|---------|----------|---------|---------|
| Components | PascalCase | — | `CharacterCard.tsx` |
| Component files | kebab-case ou PascalCase | — | `character-card.tsx` |
| Hooks | camelCase + use prefix | — | `useCharacters.ts` |
| Server Functions | camelCase | camelCase | `getCharacters`, `createTeam` |
| Server Function files | kebab-case | kebab-case | `characters.ts` |
| Types/Interfaces | PascalCase | PascalCase | `Character`, `CreateCharacterInput` |
| Enums | PascalCase | PascalCase | `CharacterClass`, `TeamType` |
| Constants | SCREAMING_SNAKE | SCREAMING_SNAKE | `MAX_TEAM_SIZE` |
| Database tables | — | snake_case | `character_progressions` |
| Database columns | — | snake_case | `created_at`, `account_id` |
| URL routes | kebab-case | kebab-case | `/characters`, `/bulk-progressions` |
| Query keys | camelCase arrays | — | `['characters', 'list', filters]` |
| CSS classes | Tailwind utilities | — | `bg-card text-foreground` |
## File Structure Conventions
### Component File Structure
```typescript
// 1. Imports (grouped)
import { useState } from 'react'; // React
import { useQuery } from '@tanstack/react-query'; // External libs
import { Button } from '@/components/ui/button'; // Internal UI
import { getCharacters } from '@/server/characters'; // Server functions
import type { Character } from '@/types'; // Types (last)
// 2. Types (if not in separate file)
interface CharacterListProps {
serverId?: string;
}
// 3. Constants (if any)
const PAGE_SIZE = 20;
// 4. Component
export function CharacterList({ serverId }: CharacterListProps) {
// 4a. Hooks (in order: router, query, state, effects, callbacks)
const navigate = useNavigate();
const { data, isLoading } = useQuery({ ... });
const [selected, setSelected] = useState<string[]>([]);
// 4b. Early returns
if (isLoading) return <Loading />;
if (!data) return <EmptyState />;
// 4c. Render
return (
<div>
{/* JSX */}
</div>
);
}
// 5. Sub-components (if small and only used here)
function CharacterRow({ character }: { character: Character }) {
return <tr>...</tr>;
}
```
### Server Function File Structure
```typescript
// 1. Imports
import { createServerFn } from '@tanstack/start';
import { z } from 'zod';
import { prisma } from '@/lib/prisma';
import { cacheService } from '@/lib/cache';
import { NotFoundError, ValidationError } from '@/lib/errors';
// 2. Schemas (colocated with functions)
const createCharacterSchema = z.object({
name: z.string().min(1).max(50),
class: z.nativeEnum(CharacterClass),
level: z.number().int().min(1).max(200),
serverId: z.string().uuid(),
accountId: z.string().uuid(),
});
// 3. Server Functions (exported)
export const getCharacters = createServerFn('GET', async (filters) => {
// Implementation
});
export const createCharacter = createServerFn('POST', async (input) => {
const data = createCharacterSchema.parse(input);
// Implementation
});
// 4. Helper functions (private, at bottom)
function buildWhereClause(filters: Filters): Prisma.CharacterWhereInput {
// Implementation
}
```
## Code Quality Rules
### TypeScript
```typescript
// ✅ DO: Explicit return types for exported functions
export function calculateTotal(items: Item[]): number {
return items.reduce((sum, item) => sum + item.amount, 0);
}
// ❌ DON'T: Implicit any
function processData(data) { ... }
// ✅ DO: Use type imports
import type { Character } from '@/types';
// ❌ DON'T: Import types as values
import { Character } from '@/types';
// ✅ DO: Discriminated unions for state
type State =
| { status: 'loading' }
| { status: 'error'; error: Error }
| { status: 'success'; data: Character[] };
// ❌ DON'T: Optional properties for state
type State = {
loading?: boolean;
error?: Error;
data?: Character[];
};
```
### React
```typescript
// ✅ DO: Named exports for components
export function CharacterCard({ character }: Props) { ... }
// ❌ DON'T: Default exports (except for routes)
export default function CharacterCard() { ... }
// ✅ DO: Destructure props
function CharacterCard({ character, onSelect }: Props) { ... }
// ❌ DON'T: Props object
function CharacterCard(props: Props) {
const character = props.character;
}
// ✅ DO: useCallback for handlers passed to children
const handleSelect = useCallback((id: string) => {
setSelected(prev => [...prev, id]);
}, []);
// ✅ DO: useMemo for expensive computations
const filteredCharacters = useMemo(
() => characters.filter(c => c.level >= 180),
[characters]
);
// ❌ DON'T: Inline objects/arrays in props (causes re-renders)
<Table columns={[col1, col2]} /> // Creates new array each render
```
### Prisma
```typescript
// ✅ DO: Select only needed fields
const characters = await prisma.character.findMany({
select: {
id: true,
name: true,
level: true,
server: { select: { name: true } },
},
});
// ❌ DON'T: Fetch everything
const characters = await prisma.character.findMany({
include: {
server: true,
account: true,
progressions: true,
currencies: true,
teamMemberships: true,
},
});
// ✅ DO: Use transactions for related operations
await prisma.$transaction([
prisma.teamMember.deleteMany({ where: { teamId } }),
prisma.team.delete({ where: { id: teamId } }),
]);
// ✅ DO: Count separately from data
const [data, total] = await Promise.all([
prisma.character.findMany({ take: 20 }),
prisma.character.count(),
]);
```
## Import Order
ESLint avec `eslint-plugin-import` applique cet ordre :
```typescript
// 1. React
import { useState, useCallback } from 'react';
// 2. External packages (alphabetical)
import { useQuery, useMutation } from '@tanstack/react-query';
import { useNavigate } from '@tanstack/react-router';
import { z } from 'zod';
// 3. Internal absolute imports (alphabetical by path)
import { Button } from '@/components/ui/button';
import { DataTable } from '@/components/data-table/data-table';
import { useCharacters } from '@/hooks/use-characters';
import { prisma } from '@/lib/prisma';
import { getCharacters } from '@/server/characters';
// 4. Relative imports
import { CharacterRow } from './character-row';
// 5. Type imports (at the end)
import type { Character, CharacterFilters } from '@/types';
```
## ESLint & Prettier Config
### .eslintrc.cjs
```javascript
module.exports = {
root: true,
env: { browser: true, es2022: true, node: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
'prettier',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: './tsconfig.json',
},
plugins: ['@typescript-eslint', 'import'],
rules: {
// TypeScript
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/consistent-type-imports': 'error',
'@typescript-eslint/no-explicit-any': 'warn',
// Import order
'import/order': [
'error',
{
groups: [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index',
'type',
],
'newlines-between': 'always',
alphabetize: { order: 'asc' },
},
],
// React
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
// General
'no-console': ['warn', { allow: ['warn', 'error'] }],
},
ignorePatterns: ['node_modules', '.output', 'dist'],
};
```
### .prettierrc
```json
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 100,
"plugins": ["prettier-plugin-tailwindcss"]
}
```
## Git Commit Standards
```bash
# Format
<type>(<scope>): <subject>
# Types
feat # New feature
fix # Bug fix
docs # Documentation
style # Formatting (no code change)
refactor # Refactoring
test # Adding tests
chore # Build, deps, tooling
# Scopes (optional)
characters, teams, accounts, progressions, currencies
ui, api, db, auth, dofusdb
# Examples
feat(characters): add bulk progression update
fix(teams): validate account constraint on member add
refactor(api): extract prisma helpers
test(teams): add integration tests for constraints
chore(deps): upgrade TanStack Query to v5.17
```
---

View File

@@ -0,0 +1,167 @@
# 18. Error Handling
## Unified Error Types
```typescript
// src/lib/errors.ts
export enum ErrorCode {
// Validation (400)
VALIDATION_ERROR = 'VALIDATION_ERROR',
INVALID_INPUT = 'INVALID_INPUT',
// Authentication (401)
UNAUTHORIZED = 'UNAUTHORIZED',
SESSION_EXPIRED = 'SESSION_EXPIRED',
// Authorization (403)
FORBIDDEN = 'FORBIDDEN',
INSUFFICIENT_PERMISSIONS = 'INSUFFICIENT_PERMISSIONS',
// Not Found (404)
NOT_FOUND = 'NOT_FOUND',
RESOURCE_NOT_FOUND = 'RESOURCE_NOT_FOUND',
// Conflict (409)
CONFLICT = 'CONFLICT',
DUPLICATE_ENTRY = 'DUPLICATE_ENTRY',
// External Service (502)
EXTERNAL_API_ERROR = 'EXTERNAL_API_ERROR',
DOFUSDB_ERROR = 'DOFUSDB_ERROR',
// Server (500)
INTERNAL_ERROR = 'INTERNAL_ERROR',
DATABASE_ERROR = 'DATABASE_ERROR',
}
export interface AppErrorData {
code: ErrorCode;
message: string;
details?: Record<string, unknown>;
field?: string;
}
export class AppError extends Error {
public readonly code: ErrorCode;
public readonly statusCode: number;
public readonly details?: Record<string, unknown>;
public readonly field?: string;
public readonly isOperational: boolean;
constructor(data: AppErrorData & { statusCode?: number }) {
super(data.message);
this.name = 'AppError';
this.code = data.code;
this.statusCode = data.statusCode ?? this.getDefaultStatusCode(data.code);
this.details = data.details;
this.field = data.field;
this.isOperational = true;
Error.captureStackTrace(this, this.constructor);
}
private getDefaultStatusCode(code: ErrorCode): number {
const statusMap: Record<ErrorCode, number> = {
[ErrorCode.VALIDATION_ERROR]: 400,
[ErrorCode.INVALID_INPUT]: 400,
[ErrorCode.UNAUTHORIZED]: 401,
[ErrorCode.SESSION_EXPIRED]: 401,
[ErrorCode.FORBIDDEN]: 403,
[ErrorCode.INSUFFICIENT_PERMISSIONS]: 403,
[ErrorCode.NOT_FOUND]: 404,
[ErrorCode.RESOURCE_NOT_FOUND]: 404,
[ErrorCode.CONFLICT]: 409,
[ErrorCode.DUPLICATE_ENTRY]: 409,
[ErrorCode.EXTERNAL_API_ERROR]: 502,
[ErrorCode.DOFUSDB_ERROR]: 502,
[ErrorCode.INTERNAL_ERROR]: 500,
[ErrorCode.DATABASE_ERROR]: 500,
};
return statusMap[code] ?? 500;
}
toJSON(): AppErrorData & { statusCode: number } {
return {
code: this.code,
message: this.message,
statusCode: this.statusCode,
details: this.details,
field: this.field,
};
}
}
```
## Backend Error Handler
```typescript
// src/lib/server/error-handler.ts
import { Prisma } from '@prisma/client';
import { AppError, ErrorCode } from '@/lib/errors';
export function handlePrismaError(error: unknown): AppError {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
switch (error.code) {
case 'P2002':
return new AppError({
code: ErrorCode.DUPLICATE_ENTRY,
message: 'Cette entrée existe déjà',
details: { fields: error.meta?.target },
});
case 'P2025':
return new AppError({
code: ErrorCode.NOT_FOUND,
message: 'Ressource non trouvée',
});
default:
return new AppError({
code: ErrorCode.DATABASE_ERROR,
message: 'Erreur de base de données',
});
}
}
return new AppError({
code: ErrorCode.INTERNAL_ERROR,
message: 'Une erreur inattendue est survenue',
});
}
```
## Frontend Error Handler
```typescript
// src/lib/client/error-handler.ts
import { toast } from 'sonner';
import { AppError, ErrorCode } from '@/lib/errors';
const errorMessages: Record<ErrorCode, string> = {
[ErrorCode.VALIDATION_ERROR]: 'Données invalides',
[ErrorCode.UNAUTHORIZED]: 'Veuillez vous connecter',
[ErrorCode.NOT_FOUND]: 'Ressource non trouvée',
[ErrorCode.DUPLICATE_ENTRY]: 'Cette entrée existe déjà',
[ErrorCode.INTERNAL_ERROR]: 'Erreur serveur',
// ... other codes
};
export function handleError(error: unknown): void {
if (error instanceof AppError) {
const message = error.message || errorMessages[error.code];
if (error.statusCode >= 500) {
toast.error('Erreur serveur', { description: message });
} else {
toast.warning(message);
}
return;
}
console.error('Unexpected error:', error);
toast.error('Une erreur inattendue est survenue');
}
```
---

View File

@@ -0,0 +1,131 @@
# 19. Monitoring & Observability
## Structured Logging (Pino)
```typescript
// src/lib/server/logger.ts
import pino from 'pino';
const isDev = process.env.NODE_ENV === 'development';
export const logger = pino({
level: process.env.LOG_LEVEL ?? (isDev ? 'debug' : 'info'),
transport: isDev
? {
target: 'pino-pretty',
options: {
colorize: true,
translateTime: 'HH:MM:ss',
ignore: 'pid,hostname',
},
}
: undefined,
formatters: {
level: (label) => ({ level: label }),
},
base: {
env: process.env.NODE_ENV,
version: process.env.APP_VERSION ?? '0.0.0',
},
redact: {
paths: ['password', 'token', 'authorization'],
censor: '[REDACTED]',
},
});
export const dbLogger = logger.child({ module: 'database' });
export const apiLogger = logger.child({ module: 'api' });
```
## Health Check Endpoint
```typescript
// src/server/functions/health.ts
import { createServerFn } from '@tanstack/react-start/server';
import { db } from '@/lib/server/db';
interface HealthStatus {
status: 'healthy' | 'degraded' | 'unhealthy';
timestamp: string;
version: string;
checks: {
database: boolean;
cache: boolean;
};
}
export const getHealth = createServerFn({ method: 'GET' }).handler(
async (): Promise<HealthStatus> => {
const checks = {
database: false,
cache: true,
};
try {
await db.$queryRaw`SELECT 1`;
checks.database = true;
} catch {
// Database check failed
}
const allHealthy = Object.values(checks).every(Boolean);
return {
status: allHealthy ? 'healthy' : 'degraded',
timestamp: new Date().toISOString(),
version: process.env.APP_VERSION ?? '0.0.0',
checks,
};
}
);
```
## Application Metrics
```typescript
// src/lib/server/metrics.ts
class MetricsCollector {
private startTime = Date.now();
private data = {
requests: { total: 0, errors: 0 },
database: { queries: 0, slowQueries: 0 },
cache: { hits: 0, misses: 0 },
};
incrementRequest(isError = false): void {
this.data.requests.total++;
if (isError) this.data.requests.errors++;
}
incrementDbQuery(isSlow = false): void {
this.data.database.queries++;
if (isSlow) this.data.database.slowQueries++;
}
incrementCacheHit(): void {
this.data.cache.hits++;
}
incrementCacheMiss(): void {
this.data.cache.misses++;
}
getMetrics() {
return {
...this.data,
uptime: Math.floor((Date.now() - this.startTime) / 1000),
};
}
}
export const metrics = new MetricsCollector();
```
---

View File

@@ -0,0 +1,66 @@
# 2. High-Level Architecture
## System Architecture Diagram
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ DOFUS MANAGER │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ CLIENT (Browser) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │ │
│ │ │ React │ │ TanStack │ │ TanStack │ │ Zustand │ │ │
│ │ │ Components│ │ Router │ │ Query │ │ (UI State)│ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ │ Server Functions (RPC) │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ SERVER (TanStack Start) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │ │
│ │ │ Server │ │ Zod │ │ Prisma │ │ node-cache│ │ │
│ │ │ Functions │ │ Validation │ │ ORM │ │ (Cache) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ DATABASE (PostgreSQL) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │ │
│ │ │ Characters │ │ Accounts │ │ Teams │ │Progressions│ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ EXTERNAL SERVICES │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ DofusDB API │ │ │
│ │ │ (Classes, Quêtes, Donjons, Succès) │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
## Data Flow
```
User Action → React Component → TanStack Query → Server Function → Prisma → PostgreSQL
↑ │
└───────────────────────── Response ────────────────────────────────────────┘
```
## Key Architectural Decisions
| Decision | Choice | Rationale |
|----------|--------|-----------|
| Full-stack Framework | TanStack Start | Type-safe, modern React, server functions |
| Database | PostgreSQL | Robust, JSON support, full-text search |
| ORM | Prisma | Type-safe queries, excellent DX |
| State Management | TanStack Query + Zustand | Server state vs UI state separation |
| Styling | Tailwind + shadcn/ui | Rapid development, consistent design |
| Deployment | Docker + Traefik | Easy SSL, reverse proxy, scalable |
---

View File

@@ -0,0 +1,46 @@
# 20. Architecture Checklist
| Category | Item | Status |
|----------|------|--------|
| **Core Architecture** | | |
| | High-level architecture diagram | ✅ |
| | Technology stack justified | ✅ |
| | Data flow documented | ✅ |
| | Scalability considered | ✅ |
| **Data Layer** | | |
| | Database schema defined | ✅ |
| | Relationships documented | ✅ |
| | Indexes identified | ✅ |
| | Migration strategy | ✅ |
| **API Design** | | |
| | API contracts defined | ✅ |
| | Input validation | ✅ |
| | Error responses standardized | ✅ |
| | Authentication/Authorization | ✅ |
| **Frontend** | | |
| | Component architecture | ✅ |
| | State management | ✅ |
| | Routing strategy | ✅ |
| | Error boundaries | ✅ |
| **Security** | | |
| | Authentication flow | ✅ |
| | Input sanitization | ✅ |
| | CORS/CSP headers | ✅ |
| | Secrets management | ✅ |
| **Performance** | | |
| | Caching strategy | ✅ |
| | Database optimization | ✅ |
| | Bundle optimization | ✅ |
| | Loading states | ✅ |
| **DevOps** | | |
| | CI/CD pipeline | ✅ |
| | Docker configuration | ✅ |
| | Environment separation | ✅ |
| | Deployment strategy | ✅ |
| **Observability** | | |
| | Logging strategy | ✅ |
| | Health checks | ✅ |
| | Metrics collection | ✅ |
| | Error tracking | ✅ |
---

View File

@@ -0,0 +1,52 @@
# 3. Technology Stack
## Frontend
| Technology | Version | Purpose |
|------------|---------|---------|
| React | 19.x | UI library |
| TanStack Router | 1.x | Type-safe routing |
| TanStack Query | 5.x | Server state management |
| Zustand | 5.x | Client state management |
| Tailwind CSS | 4.x | Utility-first styling |
| shadcn/ui | latest | Component library |
| Lucide React | latest | Icons |
| React Hook Form | 7.x | Form management |
| Zod | 3.x | Schema validation |
## Backend
| Technology | Version | Purpose |
|------------|---------|---------|
| TanStack Start | 1.x | Full-stack framework |
| Prisma | 6.x | Database ORM |
| Zod | 3.x | Input validation |
| node-cache | 5.x | In-memory caching |
| Pino | 9.x | Structured logging |
| bcryptjs | 2.x | Password hashing |
## Database
| Technology | Version | Purpose |
|------------|---------|---------|
| PostgreSQL | 16.x | Primary database |
## DevOps
| Technology | Purpose |
|------------|---------|
| Docker | Containerization |
| Docker Compose | Local development & deployment |
| Traefik | Reverse proxy, SSL termination |
| GitLab CI | CI/CD pipeline |
## Development Tools
| Tool | Purpose |
|------|---------|
| TypeScript | Type safety |
| Biome | Linting & formatting |
| Vitest | Unit testing |
| Playwright | E2E testing |
---

View File

@@ -0,0 +1,119 @@
# 4. Data Models
## Entity Relationship Diagram
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ User │ │ Account │ │ Character │
├─────────────┤ ├─────────────┤ ├─────────────┤
│ id │ │ id │ │ id │
│ email │──┐ │ name │──┐ │ name │
│ password │ │ │ userId ◄─┘ │ │ level │
│ createdAt │ └───►│ createdAt │ └───►│ classId │
│ updatedAt │ │ updatedAt │ │ serverId │
└─────────────┘ └─────────────┘ │ accountId ◄─┘
│ createdAt │
│ updatedAt │
└──────┬──────┘
┌────────────────────────────┼────────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Team │ │TeamMember │ │ CharProgress│
├─────────────┤ ├─────────────┤ ├─────────────┤
│ id │◄─────────────│ teamId │ │ id │
│ name │ │ characterId │◄─────────────│ characterId │
│ type │ │ joinedAt │ │ progressId │
│ userId │ └─────────────┘ │ completed │
│ createdAt │ │ completedAt │
│ updatedAt │ └─────────────┘
└─────────────┘ │
┌─────────────┐
│ Progression │
├─────────────┤
│ id │
│ name │
│ type │
│ category │
│ dofusDbId │
└─────────────┘
```
## Core Entities
### User
```typescript
interface User {
id: string;
email: string;
passwordHash: string;
createdAt: Date;
updatedAt: Date;
}
```
### Account
```typescript
interface Account {
id: string;
name: string;
userId: string;
createdAt: Date;
updatedAt: Date;
}
```
### Character
```typescript
interface Character {
id: string;
name: string;
level: number;
classId: number;
className: string;
serverId: number;
serverName: string;
accountId: string;
createdAt: Date;
updatedAt: Date;
}
```
### Team
```typescript
interface Team {
id: string;
name: string;
type: 'MAIN' | 'SECONDARY' | 'CUSTOM';
userId: string;
createdAt: Date;
updatedAt: Date;
}
```
### Progression
```typescript
interface Progression {
id: string;
name: string;
type: 'QUEST' | 'DUNGEON' | 'ACHIEVEMENT' | 'DOFUS';
category: string;
dofusDbId: number | null;
}
```
### CharacterProgression
```typescript
interface CharacterProgression {
id: string;
characterId: string;
progressionId: string;
completed: boolean;
completedAt: Date | null;
}
```
---

View File

@@ -0,0 +1,111 @@
# 5. API Specification
## Server Functions Pattern
TanStack Start utilise des "Server Functions" - des fonctions RPC type-safe qui s'exécutent côté serveur.
```typescript
// Définition
import { createServerFn } from '@tanstack/react-start/server';
import { z } from 'zod';
const inputSchema = z.object({
name: z.string().min(1),
});
export const createCharacter = createServerFn({ method: 'POST' })
.validator((data: unknown) => inputSchema.parse(data))
.handler(async ({ data }) => {
// Logique serveur avec accès DB
return await db.character.create({ data });
});
// Utilisation côté client
const result = await createCharacter({ data: { name: 'MyChar' } });
```
## API Endpoints (Server Functions)
### Characters
| Function | Method | Description |
|----------|--------|-------------|
| `getCharacters` | GET | Liste tous les personnages avec filtres |
| `getCharacter` | GET | Récupère un personnage par ID |
| `createCharacter` | POST | Crée un nouveau personnage |
| `updateCharacter` | POST | Met à jour un personnage |
| `deleteCharacter` | POST | Supprime un personnage |
| `bulkUpdateCharacters` | POST | Met à jour plusieurs personnages |
| `bulkDeleteCharacters` | POST | Supprime plusieurs personnages |
### Accounts
| Function | Method | Description |
|----------|--------|-------------|
| `getAccounts` | GET | Liste tous les comptes |
| `getAccount` | GET | Récupère un compte par ID |
| `createAccount` | POST | Crée un nouveau compte |
| `updateAccount` | POST | Met à jour un compte |
| `deleteAccount` | POST | Supprime un compte |
### Teams
| Function | Method | Description |
|----------|--------|-------------|
| `getTeams` | GET | Liste toutes les équipes |
| `getTeam` | GET | Récupère une équipe avec ses membres |
| `createTeam` | POST | Crée une nouvelle équipe |
| `updateTeam` | POST | Met à jour une équipe |
| `deleteTeam` | POST | Supprime une équipe |
| `addTeamMembers` | POST | Ajoute des personnages à une équipe |
| `removeTeamMembers` | POST | Retire des personnages d'une équipe |
### Progressions
| Function | Method | Description |
|----------|--------|-------------|
| `getProgressions` | GET | Liste toutes les progressions |
| `getCharacterProgressions` | GET | Progressions d'un personnage |
| `updateCharacterProgression` | POST | Met à jour une progression |
| `bulkUpdateProgressions` | POST | Met à jour plusieurs progressions |
| `syncFromDofusDb` | POST | Synchronise depuis DofusDB |
### Auth
| Function | Method | Description |
|----------|--------|-------------|
| `login` | POST | Authentification |
| `logout` | POST | Déconnexion |
| `getSession` | GET | Récupère la session courante |
## Validation Schemas
```typescript
// src/lib/schemas/character.ts
import { z } from 'zod';
export const createCharacterSchema = z.object({
name: z.string().min(2).max(50),
level: z.number().int().min(1).max(200),
classId: z.number().int().positive(),
serverId: z.number().int().positive(),
accountId: z.string().uuid(),
});
export const updateCharacterSchema = createCharacterSchema.partial();
export const characterFiltersSchema = z.object({
search: z.string().optional(),
classIds: z.array(z.number()).optional(),
serverIds: z.array(z.number()).optional(),
accountIds: z.array(z.string()).optional(),
minLevel: z.number().optional(),
maxLevel: z.number().optional(),
page: z.number().int().positive().default(1),
limit: z.number().int().min(1).max(100).default(20),
sortBy: z.enum(['name', 'level', 'class', 'server']).default('name'),
sortOrder: z.enum(['asc', 'desc']).default('asc'),
});
```
---

View File

@@ -0,0 +1,65 @@
# 6. Components Architecture
## Component Hierarchy
```
src/components/
├── ui/ # shadcn/ui primitives
│ ├── button.tsx
│ ├── input.tsx
│ ├── dialog.tsx
│ ├── table.tsx
│ ├── select.tsx
│ ├── checkbox.tsx
│ ├── tabs.tsx
│ ├── card.tsx
│ ├── badge.tsx
│ ├── progress.tsx
│ └── ...
├── layout/ # Layout components
│ ├── app-shell.tsx # Main layout wrapper
│ ├── app-sidebar.tsx # Navigation sidebar
│ └── app-header.tsx # Top header with breadcrumbs
├── characters/ # Character feature components
│ ├── character-list.tsx
│ ├── character-card.tsx
│ ├── character-form.tsx
│ ├── character-filters.tsx
│ └── character-bulk-actions.tsx
├── accounts/ # Account feature components
│ ├── account-list.tsx
│ ├── account-card.tsx
│ └── account-form.tsx
├── teams/ # Team feature components
│ ├── team-list.tsx
│ ├── team-detail.tsx
│ ├── team-form.tsx
│ └── team-member-selector.tsx
├── progressions/ # Progression feature components
│ ├── progression-section.tsx
│ ├── progression-tracker.tsx
│ └── progression-filters.tsx
└── shared/ # Shared components
├── data-table.tsx
├── search-input.tsx
├── pagination.tsx
├── confirmation-modal.tsx
├── loading-spinner.tsx
└── error-boundary.tsx
```
## Component Design Principles
1. **Composition over inheritance** - Prefer composing smaller components
2. **Props interface first** - Define TypeScript interfaces for all props
3. **Controlled components** - Parent manages state when needed
4. **Accessible by default** - Use semantic HTML, ARIA attributes
5. **Responsive design** - Mobile-first approach with Tailwind
---

View File

@@ -0,0 +1,68 @@
# 7. External APIs
## DofusDB API Integration
**Base URL**: `https://api.dofusdb.fr`
### Endpoints Used
| Endpoint | Purpose |
|----------|---------|
| `GET /classes` | Liste des classes de personnages |
| `GET /servers` | Liste des serveurs |
| `GET /quests` | Liste des quêtes |
| `GET /dungeons` | Liste des donjons |
| `GET /achievements` | Liste des succès |
### Integration Service
```typescript
// src/lib/server/dofusdb.ts
import NodeCache from 'node-cache';
const cache = new NodeCache({ stdTTL: 3600 }); // 1 hour cache
const BASE_URL = 'https://api.dofusdb.fr';
interface DofusDbOptions {
lang?: 'fr' | 'en';
limit?: number;
}
export async function fetchFromDofusDb<T>(
endpoint: string,
options: DofusDbOptions = {}
): Promise<T> {
const { lang = 'fr', limit = 100 } = options;
const cacheKey = `dofusdb:${endpoint}:${lang}:${limit}`;
// Check cache
const cached = cache.get<T>(cacheKey);
if (cached) return cached;
// Fetch from API
const url = new URL(endpoint, BASE_URL);
url.searchParams.set('$lang', lang);
url.searchParams.set('$limit', limit.toString());
const response = await fetch(url.toString(), {
headers: { 'Accept': 'application/json' },
});
if (!response.ok) {
throw new Error(`DofusDB API error: ${response.status}`);
}
const data = await response.json();
cache.set(cacheKey, data);
return data as T;
}
// Specific fetchers
export const getClasses = () => fetchFromDofusDb<DofusClass[]>('/classes');
export const getServers = () => fetchFromDofusDb<DofusServer[]>('/servers');
export const getQuests = () => fetchFromDofusDb<DofusQuest[]>('/quests');
export const getDungeons = () => fetchFromDofusDb<DofusDungeon[]>('/dungeons');
```
---

View File

@@ -0,0 +1,114 @@
# 8. Core Workflows
## Character Creation Flow
```
┌─────────────────────────────────────────────────────────────────┐
│ CHARACTER CREATION FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Click │───▶│ Open │───▶│ Fill │───▶│ Validate │ │
│ │ "Add" │ │ Modal │ │ Form │ │ (Zod) │ │
│ └──────────┘ └──────────┘ └──────────┘ └────┬─────┘ │
│ │ │
│ ┌──────────────┴───┐ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Valid │ │ Invalid │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ │
│ │ Server │ │ Show │ │
│ │ Function │ │ Errors │ │
│ └─────┬──────┘ └────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ │
│ │ Prisma │ │
│ │ Create │ │
│ └─────┬──────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ │
│ │ Invalidate │ │
│ │ Query │ │
│ └─────┬──────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ │
│ │ Toast │ │
│ │ Success │ │
│ └────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
## Progression Update Flow
```
┌─────────────────────────────────────────────────────────────────┐
│ PROGRESSION UPDATE FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ │
│ │ Toggle Check │ │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Optimistic │────▶│ Server │────▶│ Database │ │
│ │ Update │ │ Function │ │ Update │ │
│ └──────────────┘ └──────────────┘ └──────┬───────┘ │
│ │ │ │
│ │ ┌──────────┴─────┐ │
│ │ ▼ ▼ │
│ │ ┌──────────┐ ┌──────────┐ │
│ │ │ Success │ │ Error │ │
│ │ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ │ ▼ ▼ │
│ │ ┌──────────┐ ┌──────────┐ │
│ └────────────────────▶│ Confirm │ │ Rollback │ │
│ │ State │ │ + Toast │ │
│ └──────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
## Bulk Operations Flow
```
┌─────────────────────────────────────────────────────────────────┐
│ BULK OPERATIONS FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Select │───▶│ Choose │───▶│ Confirm │───▶│ Process │ │
│ │ Items │ │ Action │ │ Modal │ │ Batch │ │
│ └──────────┘ └──────────┘ └──────────┘ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ │
│ │ Loading │ │
│ │ State │ │
│ └─────┬──────┘ │
│ │ │
│ ┌─────────────┴────────┐ │
│ ▼ ▼ │
│ ┌────────────┐ ┌────────┐│
│ │ Success │ │ Partial││
│ │ Toast │ │ Failure││
│ └─────┬──────┘ └───┬────┘│
│ │ │ │
│ ▼ ▼ │
│ ┌────────────┐ ┌──────────┐ │
│ │ Invalidate │ │ Show │ │
│ │ Queries │ │ Errors │ │
│ └────────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
---

View File

@@ -0,0 +1,175 @@
# 9. Database Schema
## Prisma Schema
```prisma
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ============================================
// USER & AUTHENTICATION
// ============================================
model User {
id String @id @default(cuid())
email String @unique
passwordHash String @map("password_hash")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
accounts Account[]
teams Team[]
sessions Session[]
@@map("users")
}
model Session {
id String @id @default(cuid())
userId String @map("user_id")
expiresAt DateTime @map("expires_at")
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([expiresAt])
@@map("sessions")
}
// ============================================
// CORE ENTITIES
// ============================================
model Account {
id String @id @default(cuid())
name String
userId String @map("user_id")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
characters Character[]
@@unique([userId, name])
@@index([userId])
@@map("accounts")
}
model Character {
id String @id @default(cuid())
name String
level Int @default(1)
classId Int @map("class_id")
className String @map("class_name")
serverId Int @map("server_id")
serverName String @map("server_name")
accountId String @map("account_id")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
account Account @relation(fields: [accountId], references: [id], onDelete: Cascade)
teamMembers TeamMember[]
progressions CharacterProgression[]
@@unique([accountId, name])
@@index([accountId])
@@index([classId])
@@index([serverId])
@@index([level])
@@map("characters")
}
// ============================================
// TEAMS
// ============================================
enum TeamType {
MAIN
SECONDARY
CUSTOM
}
model Team {
id String @id @default(cuid())
name String
type TeamType @default(CUSTOM)
userId String @map("user_id")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
members TeamMember[]
@@unique([userId, name])
@@index([userId])
@@map("teams")
}
model TeamMember {
id String @id @default(cuid())
teamId String @map("team_id")
characterId String @map("character_id")
joinedAt DateTime @default(now()) @map("joined_at")
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
@@unique([teamId, characterId])
@@index([teamId])
@@index([characterId])
@@map("team_members")
}
// ============================================
// PROGRESSIONS
// ============================================
enum ProgressionType {
QUEST
DUNGEON
ACHIEVEMENT
DOFUS
}
model Progression {
id String @id @default(cuid())
name String
type ProgressionType
category String
dofusDbId Int? @unique @map("dofusdb_id")
characterProgressions CharacterProgression[]
@@index([type])
@@index([category])
@@map("progressions")
}
model CharacterProgression {
id String @id @default(cuid())
characterId String @map("character_id")
progressionId String @map("progression_id")
completed Boolean @default(false)
completedAt DateTime? @map("completed_at")
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
progression Progression @relation(fields: [progressionId], references: [id], onDelete: Cascade)
@@unique([characterId, progressionId])
@@index([characterId])
@@index([progressionId])
@@index([completed])
@@map("character_progressions")
}
```
---

View File

@@ -0,0 +1,36 @@
# Architecture Summary
```
┌─────────────────────────────────────────────────────────────────────────┐
│ DOFUS MANAGER - FINAL ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Frontend (React + TanStack) Backend (TanStack Start) │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ • TanStack Router │ │ • Server Functions │ │
│ │ • TanStack Query │◀────────▶│ • Prisma ORM │ │
│ │ • Zustand (UI state) │ RPC │ • Zod Validation │ │
│ │ • shadcn/ui + Tailwind │ │ • node-cache │ │
│ └─────────────────────────┘ └───────────┬─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ PostgreSQL 16 │ │
│ │ • 7 tables │ │
│ │ • Full-text search │ │
│ └─────────────────────────┘ │
│ │
│ Infrastructure │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Docker Compose + Traefik (reverse proxy + SSL) │ │
│ │ GitLab CI/CD → VPS Deployment │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
```
---
*Document généré avec BMAD Framework*
*Version: 1.0.0*
*Date: 2026-01-18*

113
docs/architecture/index.md Normal file
View File

@@ -0,0 +1,113 @@
# Dofus Manager - Architecture Document
## Table of Contents
- [Dofus Manager - Architecture Document](#table-of-contents)
- [Table of Contents](./table-of-contents.md)
- [1. Introduction](./1-introduction.md)
- [Project Overview](./1-introduction.md#project-overview)
- [Goals](./1-introduction.md#goals)
- [Scope](./1-introduction.md#scope)
- [Non-Functional Requirements](./1-introduction.md#non-functional-requirements)
- [2. High-Level Architecture](./2-high-level-architecture.md)
- [System Architecture Diagram](./2-high-level-architecture.md#system-architecture-diagram)
- [Data Flow](./2-high-level-architecture.md#data-flow)
- [Key Architectural Decisions](./2-high-level-architecture.md#key-architectural-decisions)
- [3. Technology Stack](./3-technology-stack.md)
- [Frontend](./3-technology-stack.md#frontend)
- [Backend](./3-technology-stack.md#backend)
- [Database](./3-technology-stack.md#database)
- [DevOps](./3-technology-stack.md#devops)
- [Development Tools](./3-technology-stack.md#development-tools)
- [4. Data Models](./4-data-models.md)
- [Entity Relationship Diagram](./4-data-models.md#entity-relationship-diagram)
- [Core Entities](./4-data-models.md#core-entities)
- [User](./4-data-models.md#user)
- [Account](./4-data-models.md#account)
- [Character](./4-data-models.md#character)
- [Team](./4-data-models.md#team)
- [Progression](./4-data-models.md#progression)
- [CharacterProgression](./4-data-models.md#characterprogression)
- [5. API Specification](./5-api-specification.md)
- [Server Functions Pattern](./5-api-specification.md#server-functions-pattern)
- [API Endpoints (Server Functions)](./5-api-specification.md#api-endpoints-server-functions)
- [Characters](./5-api-specification.md#characters)
- [Accounts](./5-api-specification.md#accounts)
- [Teams](./5-api-specification.md#teams)
- [Progressions](./5-api-specification.md#progressions)
- [Auth](./5-api-specification.md#auth)
- [Validation Schemas](./5-api-specification.md#validation-schemas)
- [6. Components Architecture](./6-components-architecture.md)
- [Component Hierarchy](./6-components-architecture.md#component-hierarchy)
- [Component Design Principles](./6-components-architecture.md#component-design-principles)
- [7. External APIs](./7-external-apis.md)
- [DofusDB API Integration](./7-external-apis.md#dofusdb-api-integration)
- [Endpoints Used](./7-external-apis.md#endpoints-used)
- [Integration Service](./7-external-apis.md#integration-service)
- [8. Core Workflows](./8-core-workflows.md)
- [Character Creation Flow](./8-core-workflows.md#character-creation-flow)
- [Progression Update Flow](./8-core-workflows.md#progression-update-flow)
- [Bulk Operations Flow](./8-core-workflows.md#bulk-operations-flow)
- [9. Database Schema](./9-database-schema.md)
- [Prisma Schema](./9-database-schema.md#prisma-schema)
- [10. Frontend Architecture](./10-frontend-architecture.md)
- [State Management Strategy](./10-frontend-architecture.md#state-management-strategy)
- [TanStack Query Setup](./10-frontend-architecture.md#tanstack-query-setup)
- [Zustand Store](./10-frontend-architecture.md#zustand-store)
- [Routing Structure](./10-frontend-architecture.md#routing-structure)
- [11. Backend Architecture](./11-backend-architecture.md)
- [Server Functions Organization](./11-backend-architecture.md#server-functions-organization)
- [Server Function Example](./11-backend-architecture.md#server-function-example)
- [Authentication Middleware](./11-backend-architecture.md#authentication-middleware)
- [Caching Strategy](./11-backend-architecture.md#caching-strategy)
- [12. Project Structure](./12-project-structure.md)
- [13. Development Workflow](./13-development-workflow.md)
- [Local Development Setup](./13-development-workflow.md#local-development-setup)
- [Environment Variables](./13-development-workflow.md#environment-variables)
- [Git Workflow](./13-development-workflow.md#git-workflow)
- [Branch Naming](./13-development-workflow.md#branch-naming)
- [Commit Convention](./13-development-workflow.md#commit-convention)
- [14. Deployment Architecture](./14-deployment-architecture.md)
- [Docker Configuration](./14-deployment-architecture.md#docker-configuration)
- [Docker Compose (Production)](./14-deployment-architecture.md#docker-compose-production)
- [GitLab CI/CD Pipeline](./14-deployment-architecture.md#gitlab-cicd-pipeline)
- [15. Security & Performance](./15-security-performance.md)
- [Security Measures](./15-security-performance.md#security-measures)
- [Authentication](./15-security-performance.md#authentication)
- [Input Validation](./15-security-performance.md#input-validation)
- [Headers (via Traefik)](./15-security-performance.md#headers-via-traefik)
- [Performance Optimizations](./15-security-performance.md#performance-optimizations)
- [Database](./15-security-performance.md#database)
- [Caching](./15-security-performance.md#caching)
- [Frontend](./15-security-performance.md#frontend)
- [Bundle Optimization](./15-security-performance.md#bundle-optimization)
- [16. Testing Strategy](./16-testing-strategy.md)
- [Testing Pyramid](./16-testing-strategy.md#testing-pyramid)
- [Unit Tests (Vitest)](./16-testing-strategy.md#unit-tests-vitest)
- [Integration Tests](./16-testing-strategy.md#integration-tests)
- [E2E Tests (Playwright)](./16-testing-strategy.md#e2e-tests-playwright)
- [17. Coding Standards](./17-coding-standards.md)
- [Critical Fullstack Rules](./17-coding-standards.md#critical-fullstack-rules)
- [Naming Conventions](./17-coding-standards.md#naming-conventions)
- [File Structure Conventions](./17-coding-standards.md#file-structure-conventions)
- [Component File Structure](./17-coding-standards.md#component-file-structure)
- [Server Function File Structure](./17-coding-standards.md#server-function-file-structure)
- [Code Quality Rules](./17-coding-standards.md#code-quality-rules)
- [TypeScript](./17-coding-standards.md#typescript)
- [React](./17-coding-standards.md#react)
- [Prisma](./17-coding-standards.md#prisma)
- [Import Order](./17-coding-standards.md#import-order)
- [ESLint & Prettier Config](./17-coding-standards.md#eslint-prettier-config)
- [.eslintrc.cjs](./17-coding-standards.md#eslintrccjs)
- [.prettierrc](./17-coding-standards.md#prettierrc)
- [Git Commit Standards](./17-coding-standards.md#git-commit-standards)
- [18. Error Handling](./18-error-handling.md)
- [Unified Error Types](./18-error-handling.md#unified-error-types)
- [Backend Error Handler](./18-error-handling.md#backend-error-handler)
- [Frontend Error Handler](./18-error-handling.md#frontend-error-handler)
- [19. Monitoring & Observability](./19-monitoring-observability.md)
- [Structured Logging (Pino)](./19-monitoring-observability.md#structured-logging-pino)
- [Health Check Endpoint](./19-monitoring-observability.md#health-check-endpoint)
- [Application Metrics](./19-monitoring-observability.md#application-metrics)
- [20. Architecture Checklist](./20-architecture-checklist.md)
- [Architecture Summary](./architecture-summary.md)

View File

@@ -0,0 +1,24 @@
# Table of Contents
1. [Introduction](#1-introduction)
2. [High-Level Architecture](#2-high-level-architecture)
3. [Technology Stack](#3-technology-stack)
4. [Data Models](#4-data-models)
5. [API Specification](#5-api-specification)
6. [Components Architecture](#6-components-architecture)
7. [External APIs](#7-external-apis)
8. [Core Workflows](#8-core-workflows)
9. [Database Schema](#9-database-schema)
10. [Frontend Architecture](#10-frontend-architecture)
11. [Backend Architecture](#11-backend-architecture)
12. [Project Structure](#12-project-structure)
13. [Development Workflow](#13-development-workflow)
14. [Deployment Architecture](#14-deployment-architecture)
15. [Security & Performance](#15-security--performance)
16. [Testing Strategy](#16-testing-strategy)
17. [Coding Standards](#17-coding-standards)
18. [Error Handling](#18-error-handling)
19. [Monitoring & Observability](#19-monitoring--observability)
20. [Architecture Checklist](#20-architecture-checklist)
---

View File

@@ -0,0 +1,367 @@
# Brainstorming Session Results
**Session Date:** 2026-01-17
**Facilitator:** Business Analyst Mary
**Participant:** Theo
---
## Executive Summary
**Topic:** Création d'un site web de gestion de comptes et personnages pour le MMORPG Dofus
**Session Goals:** Idéation ciblée sur le développement produit — remplacer un tableur complexe (60+ personnages, dizaines de comptes) par une application web moderne et fonctionnelle.
**Techniques Used:**
- First Principles Thinking
- Mind Mapping
- SCAMPER (Substitute, Combine, Adapt, Modify, Put to other uses, Eliminate)
**Total Ideas Generated:** 25+
### Key Themes Identified:
- La gestion multi-comptes avec contrainte de non-simultanéité est un besoin fondamental
- Le filtrage et la recherche multicritères sont essentiels pour 60+ personnages
- Les actions groupées (bulk update) réduiront drastiquement le temps de maintenance
- L'intégration avec DofusDB éliminera la saisie manuelle des données de référence
- L'outil doit évoluer d'un simple tracker vers un assistant de jeu complet
---
## Technique Sessions
### First Principles Thinking
**Description:** Identification des problèmes fondamentaux que le tableur actuel résout mal, en partant des besoins réels de l'utilisateur.
#### Problèmes identifiés:
1. **Vue d'ensemble impossible** — 60+ personnages en colonnes horizontales ne tiennent pas à l'écran
2. **Modifications fragiles** — Risque de tout casser, heures perdues à réparer le formatage
3. **Contraintes non gérées** — La règle "pas 2 persos du même compte simultanément" est gérée mentalement
4. **Pas de filtrage** — Parcours visuel fastidieux pour trouver "qui n'a pas fait X"
5. **Manque de dynamisme** — Données statiques, pas de synchronisation, pas de totaux automatiques
#### Cas d'usage principaux:
1. Voir quels personnages sont sur quels comptes
2. Ajouter un nouveau personnage monté
3. Voir sur quels persos/teams un Dofus n'est pas fait
4. Mettre à jour les recherchés faits
5. Voir et gérer les monnaies (Doplons, Orichor, Kamas de glace...)
6. Composer des teams valides (contrainte compte)
7. Planifier les "run kamas brut" (multi-persos même compte pour maximiser kamas)
#### Insights Discovered:
- Les teams sont généralement fixes (team principale de 8, teams succès Panda/Enu/Elio/Iop)
- Mais parfois composition dynamique nécessaire (ex: 3 Cra + 5 mules pour PL)
- L'outil sert à planifier les sessions de jeu ET à vérifier en temps réel pendant le jeu
#### Notable Connections:
- Le système de récompenses Dofus est complexe : ressources/Dofus = 1x par compte, mais kamas = par perso
- Les métiers sont maintenant liés au compte+serveur, pas au personnage
- Le bonus XP par compte favorise la stratégie "run kamas brut"
---
### Mind Mapping
**Description:** Cartographie des entités, relations et fonctionnalités de l'application.
#### Modèle de données identifié:
```
┌─────────────────────────────────────────────────────────────────────┐
│ COMPTE │
│ - Nom │
│ - Ogrines (par compte) │
│ - Récompenses succès débloquées (Dofus, ressources = 1x/compte) │
└─────────────────────┬───────────────────────────────────────────────┘
┌─────────────┴─────────────┐
│ │
▼ ▼
┌───────────────────┐ ┌─────────────────────────┐
│ COMPTE + SERVEUR │ │ PERSONNAGE │
│ - Métiers (niv.) │ │ - Pseudo │
│ - Bonus XP perso │ │ - Classe │
│ le plus haut │ │ - Niveau │
└───────────────────┘ │ - Serveur │
│ - Monnaies │
│ - Progression quêtes │
│ - Recherchés faits │
│ - Donjons (tous succès) │
└───────────┬─────────────┘
│ N:M
┌──────▼──────┐
│ TEAM │
│ - Nom │
│ - Type │
│ - Membres[] │
└─────────────┘
```
#### Modules fonctionnels:
1. **Comptes** — Liste, CRUD, ogrines, récompenses succès
2. **Personnages** — Liste, filtres, CRUD, monnaies, progression
3. **Teams** — Créer, valider contraintes comptes, statut global
4. **Objectifs** — Définir, arborescence quêtes, % progression
5. **Progression** — Quêtes Dofus, donjons (tous types succès), recherchés
6. **Recherche & Filtres** — Multicritères, par team, par compte, "qui n'a pas fait"
7. **Données API** — DofusDB pour import quêtes/succès/donjons
8. **Analytics** — Kamas brut potentiel, stats par compte, tendances
---
### SCAMPER Analysis
#### S — Substitute (Substituer)
| Avant (Tableur) | Après (App) |
|-----------------|-------------|
| Colonnes par personnage | Fiches individuelles avec vue détaillée |
| "x" manuels | Checkboxes avec date auto + bulk update |
| Navigation horizontale infinie | Filtres + recherche + pagination |
| Copier-coller pour nouveau perso | Formulaire de création guidé |
**Retenu:** Checkboxes intelligentes avec bulk update — le plus impactant pour réduire le temps de maintenance.
#### C — Combine (Combiner)
1.**Team + Progression** → Vue "Statut de ma team" avec % completion
2.**Recherche + Action** → Résultats filtrés directement actionnables
3.**Objectif + Notification** → Alertes "Il te reste X pour finir ton objectif"
4.**Import API + Validation** → DofusDB comme source de vérité
#### A — Adapt (Adapter)
1. ❌ Kanban (non retenu)
2.**Filtres façon e-commerce** → Sidebar avec facettes cliquables
3.**Dashboards analytics** → Widgets personnalisables
4.**Multi-select façon Gmail** → Sélection + actions groupées
#### M — Modify (Modifier/Amplifier)
1. ❌ Highlighting des manques (non retenu)
2.**Réduire les clics** → Raccourcis clavier, actions au survol
3.**Amplifier vue compte** → Page dédiée avec tous persos + stats
4.**Simplifier monnaies** → Total agrégé avec drill-down
#### P — Put to other uses (Autres usages)
1.**Planificateur de session** → "J'ai 2h, que faire ?" avec suggestions
2.**Partage guilde/amis** → Export/lien pour coordination
3.**Journal d'activité** → Timeline, stats hebdo/mensuelles
4.**Calculateur rentabilité** → ROI kamas brut par perso
#### E — Eliminate (Éliminer)
1.**Saisie manuelle quêtes/donjons** → Tout depuis DofusDB
2.**Doublons de données** → 1 perso = 1 entité unique
3.**Navigation profonde** → 2 clics max depuis dashboard
4.**Exhaustivité obligatoire** → Tracking opt-in par catégorie
#### R — Reverse (Inverser)
- Non retenu — le modèle mental actuel (perso → compte → team) reste pertinent
---
## Idea Categorization
### Immediate Opportunities
*Ideas ready to implement now (MVP)*
1. **Gestion CRUD Comptes/Personnages/Teams**
- Description: Créer, lire, modifier, supprimer les entités principales
- Why immediate: Fondation de l'application
- Resources needed: PostgreSQL schema, API routes, formulaires React
2. **Filtres multicritères**
- Description: Filtrer par classe, team, compte, niveau, statut progression
- Why immediate: Résout le problème principal de "vue d'ensemble impossible"
- Resources needed: UI filtres sidebar, logique de requêtes
3. **Checkboxes + Bulk Update**
- Description: Cocher fait/pas fait avec date auto, actions groupées par team
- Why immediate: Résout le problème de "modifications fragiles"
- Resources needed: UI checkboxes, bulk actions API
4. **Vue statut team avec % completion**
- Description: Tableau croisé team × succès avec pourcentage d'avancement
- Why immediate: Cas d'usage fréquent "quelle team a pas fait X"
- Resources needed: Calculs agrégés, composant tableau
5. **Validation contrainte compte**
- Description: Empêcher 2 persos du même compte dans une team active
- Why immediate: Règle métier fondamentale du jeu
- Resources needed: Logique de validation, feedback UI
6. **Monnaies par perso + total**
- Description: Tracker les monnaies, afficher total agrégé
- Why immediate: Besoin exprimé, données déjà dans le tableur
- Resources needed: Champs monnaies, widget total
7. **Intégration DofusDB**
- Description: Import des données de référence (quêtes, donjons, succès)
- Why immediate: Élimine la saisie manuelle, réduit les erreurs
- Resources needed: Client API DofusDB, sync initiale
### Future Innovations
*Ideas requiring development/research*
1. **Dashboard avec widgets**
- Description: Vue d'accueil personnalisable avec KPIs
- Development needed: Système de widgets drag & drop
- Timeline estimate: V2
2. **Objectifs + alertes progression**
- Description: Définir des objectifs, recevoir notifications
- Development needed: Système de notifications, tracking objectifs
- Timeline estimate: V2
3. **Raccourcis clavier**
- Description: Navigation et actions rapides au clavier
- Development needed: Hook keyboard, documentation raccourcis
- Timeline estimate: V2
4. **Arborescence quêtes Dofus**
- Description: Visualisation des dépendances de quêtes (style n1ark.com)
- Development needed: Parser DofusDB pour dépendances, UI graphe
- Timeline estimate: V3
5. **Planificateur de session**
- Description: "J'ai 2h" → suggestions basées sur objectifs/rentabilité
- Development needed: Algorithme de priorisation, UI planning
- Timeline estimate: V3
### Moonshots
*Ambitious, transformative concepts*
1. **Partage guilde/amis**
- Description: Liens publics ou export pour coordination multi-joueurs
- Transformative potential: Transformer l'outil solo en outil communautaire
- Challenges to overcome: Authentification, permissions, vie privée
2. **Journal d'activité**
- Description: Timeline des actions, statistiques temporelles
- Transformative potential: Visualiser sa progression sur le long terme
- Challenges to overcome: Volume de données, performance, rétention
3. **Calculateur rentabilité kamas brut**
- Description: ROI par perso (XP investi vs kamas potentiels)
- Transformative potential: Optimisation stratégique du temps de jeu
- Challenges to overcome: Données de kamas par quête, formules complexes
### Insights & Learnings
*Key realizations from the session*
- **Contrainte compte = règle métier centrale**: Toute l'application doit être consciente qu'on ne peut pas jouer 2 persos du même compte simultanément
- **Récompenses 1x/compte vs N/perso**: Le système de récompenses Dofus a une dualité importante à modéliser
- **Run kamas brut = méta actuelle**: L'application doit supporter cette stratégie de jeu populaire
- **Métiers = compte+serveur maintenant**: Changement récent du jeu à prendre en compte dans le modèle
- **Teams fixes + composition dynamique**: Les deux modes coexistent
---
## Action Planning
### Top 3 Priority Ideas
#### #1 Priority: CRUD + Modèle de données robuste
- **Rationale:** Fondation de toute l'application, impossible d'avancer sans
- **Next steps:**
1. Définir le schéma PostgreSQL complet
2. Créer les migrations
3. Implémenter les API routes CRUD
4. Créer les formulaires React
- **Resources needed:** PostgreSQL, Drizzle/Prisma, TanStack Start
- **Timeline:** Premier sprint
#### #2 Priority: Filtres multicritères + Vue liste
- **Rationale:** Résout le problème #1 (vue d'ensemble impossible)
- **Next steps:**
1. Concevoir l'UI des filtres (sidebar facettes)
2. Implémenter la logique de filtrage côté serveur
3. Créer le composant liste avec pagination
4. Ajouter les filtres rapides (classe, team, compte)
- **Resources needed:** TanStack Table, composants UI
- **Timeline:** Deuxième sprint
#### #3 Priority: Intégration DofusDB
- **Rationale:** Élimine la saisie manuelle, source de vérité pour les données de jeu
- **Next steps:**
1. Explorer l'API DofusDB, documenter les endpoints utiles
2. Créer un client API TypeScript
3. Script d'import initial (quêtes, donjons, succès, recherchés)
4. Synchronisation périodique
- **Resources needed:** Documentation API DofusDB, cron jobs
- **Timeline:** En parallèle des sprints 1-2
---
## Reflection & Follow-up
### What Worked Well
- First Principles pour identifier les vrais problèmes vs les symptômes
- SCAMPER pour générer des améliorations concrètes vs le tableur
- Analyse du fichier existant pour comprendre la structure de données réelle
- Focus sur l'idéation produit plutôt qu'exploration technique
### Areas for Further Exploration
- **API DofusDB**: Explorer les endpoints disponibles, limites, authentification
- **Arborescence quêtes**: Étudier comment n1ark.com structure les dépendances
- **UX mobile/tablette**: L'outil sera-t-il utilisé sur second écran pendant le jeu ?
- **Import données existantes**: Comment migrer le tableur actuel vers l'app ?
### Recommended Follow-up Techniques
- **User Story Mapping**: Pour détailler les parcours utilisateur du MVP
- **Event Storming**: Pour modéliser les événements métier (perso créé, succès validé, etc.)
- **Wireframing**: Pour valider l'UX avant développement
### Questions That Emerged
- Faut-il un système d'authentification ou l'app reste-t-elle mono-utilisateur ?
- Comment gérer les mises à jour du jeu (nouveaux donjons, quêtes) ?
- Faut-il supporter plusieurs serveurs Dofus ou juste Agride ?
- Comment importer les données du tableur existant ?
### Next Session Planning
- **Suggested topics:** Architecture technique détaillée, schéma de base de données, wireframes UI
- **Recommended timeframe:** Avant de commencer le développement
- **Preparation needed:** Explorer l'API DofusDB, lister toutes les entités à tracker
---
## Technical Stack
| Composant | Technologie |
|-----------|-------------|
| Frontend | React + TanStack Start |
| Backend | TanStack Start (full-stack) |
| Base de données | PostgreSQL |
| Conteneurisation | Docker |
| Hébergement | Serveur dédié personnel |
| API externe | DofusDB |
---
## Appendix: Données du tableur analysé
Le tableur source contient:
- **60+ personnages** sur plusieurs dizaines de comptes
- **Serveur principal**: Agride
- **Classes représentées**: Cra, Enutrof, Eliotrope, Iop, Pandawa, Sadida, Eniripsa, Huppermage, Steamer, Zobal, Feca, Roublard, Ouginak, Sacrieur, Sram, Xelor, Osamodas
- **Niveaux**: Tous niveau 200
- **Quêtes Dofus trackées**: Turquoise, Pourpre, Émeraude, Des Glaces, Abyssal, Nébuleux, Domakuro, Dorigami, Tacheté, Vulbis
- **Donjons trackés**: Par paliers (1-50, 51-100, 101-150, 151-190, 191-200) avec succès variés
- **Monnaies**: Doplons, Almatons, Pages calendrier, Orichor, Kamas de glace, Perles des profondeurs, Alitons, Trukdivins
- **Recherchés**: Par région (Astrub, Château d'Amakna, Saharach, Frigost I/II/III, Enutrosor, Srambad, Xélorium, etc.)
- **Teams identifiées**: Main Team (8 persos), Songe, PL, Team succès, Team succes vierge
---
*Session facilitated using the BMAD-METHOD brainstorming framework*

596
docs/front-end-spec.md Normal file
View File

@@ -0,0 +1,596 @@
# Dofus Manager UI/UX Specification
## Introduction
Ce document définit les objectifs d'expérience utilisateur, l'architecture de l'information, les flux utilisateur et les spécifications de design visuel pour l'interface de **Dofus Manager**. Il sert de fondation pour le design visuel et le développement frontend, assurant une expérience cohérente et centrée sur l'utilisateur.
---
## Overall UX Goals & Principles
### Target User Persona
**Theo - Le Multi-Compteur Organisé**
| Attribut | Description |
|----------|-------------|
| **Profil** | Joueur passionné de Dofus gérant 60+ personnages niveau 200 |
| **Contexte d'usage** | Joue sur PC avec souvent un second écran pour consulter ses données |
| **Frustrations actuelles** | Tableur Excel illisible, modifications fragiles, contraintes de compte gérées mentalement |
| **Objectifs** | Trouver rapidement qui n'a pas fait quoi, composer des teams valides, mettre à jour efficacement |
| **Expertise technique** | À l'aise avec les outils complexes, préfère la densité d'info à la simplicité |
| **Fréquence d'usage** | Quotidien pendant les sessions de jeu + planification hebdomadaire |
### Usability Goals
1. **Efficacité de navigation** — Trouver n'importe quelle information en moins de 3 clics depuis le dashboard
2. **Mises à jour rapides** — Pouvoir mettre à jour la progression d'une team entière en moins de 30 secondes
3. **Prévention d'erreurs** — Impossible d'ajouter 2 personnages du même compte dans une team active
4. **Vue d'ensemble immédiate** — Voir l'état global (teams, progressions, monnaies) en un coup d'œil
5. **Mémorabilité** — Interface cohérente permettant de retrouver ses repères après plusieurs jours d'absence
### Design Principles
1. **Densité maîtrisée** — Maximiser l'information visible sans surcharger visuellement. Utiliser la hiérarchie typographique et les espaces blancs stratégiquement.
2. **Consistance des patterns** — Tous les tableaux se comportent de la même façon (tri, filtres, pagination). Toutes les actions CRUD suivent le même flow.
3. **Feedback immédiat** — Chaque action utilisateur génère une réponse visuelle instantanée (loading states, toasts, transitions).
4. **Raccourcis pour experts** — Permettre les bulk actions, raccourcis clavier (V2), et filtres combinés pour les utilisateurs avancés.
5. **Fail-safe par design** — Les actions destructives demandent confirmation. Les contraintes métier sont validées avant même que l'utilisateur ne puisse les violer.
### Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2026-01-17 | 0.1 | Création initiale | Sally (UX Expert) |
---
## Information Architecture (IA)
### Site Map / Screen Inventory
```mermaid
graph TD
A[🏠 Dashboard<br/>Vue d'ensemble principale] --> B[👥 Personnages]
A --> C[📁 Comptes]
A --> D[⚔️ Teams]
A --> E[⚙️ Paramètres]
A --> A1[Widget Comptes]
A --> A2[Widget Personnages]
A --> A3[Widget Teams]
A --> A4[Widget Monnaies]
A --> A5[Actions rapides]
B --> B1[Liste Personnages]
B1 --> B2[Fiche Personnage]
B2 --> B2a[Progressions]
B2 --> B2b[Monnaies]
B2 --> B2c[Teams]
C --> C1[Liste Comptes]
C1 --> C2[Fiche Compte]
C2 --> C2a[Personnages du compte]
C2 --> C2b[Métiers]
C2 --> C2c[Récompenses]
D --> D1[Liste Teams]
D1 --> D2[Fiche Team]
D2 --> D2a[Membres]
D2 --> D2b[Statut Progressions]
E --> E1[Serveurs]
E --> E2[Monnaies]
E --> E3[Données DofusDB]
B1 --> F[🔄 Bulk Actions]
F --> F1[Bulk Progressions]
F --> F2[Bulk Monnaies]
```
### Navigation Structure
**Primary Navigation (Sidebar)**
| Icône | Label | Route | Description |
|-------|-------|-------|-------------|
| 🏠 | Dashboard | `/` | Vue d'ensemble, KPIs, accès rapide |
| 👥 | Personnages | `/characters` | Liste principale avec filtres |
| 📁 | Comptes | `/accounts` | Gestion des comptes Dofus |
| ⚔️ | Teams | `/teams` | Composition et statut des teams |
| ⚙️ | Paramètres | `/settings` | Configuration (serveurs, monnaies, sync) |
**Secondary Navigation (Contextuelle)**
- **Onglets sur fiches détail** : Personnage → [Infos | Progressions | Monnaies | Teams]
- **Sous-menu Paramètres** : [Serveurs | Monnaies | Données DofusDB]
- **Actions groupées** : Accessible depuis la toolbar des listes (quand sélection active)
**Breadcrumb Strategy**
Format : `Section > Sous-section > Élément`
Exemples :
- `Personnages > Krosmaster-Cra`
- `Teams > Main Team > Statut Progressions`
- `Paramètres > Données DofusDB`
**Dashboard Content**
| Widget | Contenu | Action au clic |
|--------|---------|----------------|
| **Comptes** | Liste des comptes avec nb persos, ogrines | → Fiche compte |
| **Personnages** | Total, répartition par classe/niveau | → Liste filtrée |
| **Teams** | Teams actives avec % complétion | → Fiche team |
| **Monnaies** | Totaux globaux par type | → Détail par compte |
| **Progressions** | Résumé global (X% Dofus faits, Y donjons) | → Bulk actions |
| **Actions rapides** | Boutons : Nouveau perso, Bulk update, Sync DofusDB | → Action directe |
---
## User Flows
### Flow 1: Trouver les personnages qui n'ont pas fait X
**User Goal:** Identifier rapidement quels personnages n'ont pas complété une progression spécifique
**Entry Points:** Dashboard → Widget Progressions, Sidebar → Personnages, Fiche Team
**Success Criteria:** Liste filtrée affichée en < 3 clics, < 5 secondes
```mermaid
graph TD
A[Dashboard] --> B[Clic Personnages]
B --> C[Liste avec Filtres]
C --> D[Ouvrir filtre Progression]
D --> E[Sélectionner type]
E --> F[Sélectionner N'a pas fait]
F --> G[✅ Liste filtrée affichée]
G --> H{Action suivante?}
H --> I[Voir fiche perso]
H --> J[Sélectionner plusieurs]
J --> K[Bulk Update]
```
**Edge Cases:**
- Aucun résultat → Message "Tous les personnages ont complété X" avec bouton reset
- Filtres combinés complexes → Indicateur des filtres actifs + "Clear all"
### Flow 2: Composer une team valide
**User Goal:** Créer ou modifier une team en respectant la contrainte compte
**Success Criteria:** Team créée avec membres valides, erreur claire si conflit
```mermaid
graph TD
A[Liste Teams] --> B[Nouvelle Team]
B --> C[Modal création]
C --> D[Saisir nom + type]
D --> E[Enregistrer]
E --> F[Fiche Team vide]
F --> G[Ajouter membre]
G --> H[Sélecteur personnages]
H --> I[Sélectionner perso]
I --> K{Même compte dans team?}
K -->|Non| L[✅ Membre ajouté]
K -->|Oui| M[❌ Erreur conflit]
M --> H
L --> O{Continuer?}
O -->|Oui| G
O -->|Non| P[✅ Team complète]
```
### Flow 3: Bulk update progressions pour une team
**User Goal:** Marquer une progression faite pour tous les membres d'une team
**Success Criteria:** Mise à jour de N personnages en < 30 secondes
```mermaid
graph TD
A[Fiche Team] --> B[Section Statut Progressions]
B --> C[Sélectionner progression]
C --> D[Voir statut par membre]
D --> E{Tous faits?}
E -->|Non| G[Bouton Marquer fait pour tous]
G --> H[Modal confirmation]
H --> I[Récap: X persos à mettre à jour]
I --> J{Confirmer?}
J -->|Oui| K[Processing...]
K --> L[✅ Toast: X persos mis à jour]
L --> M[Refresh → 100%]
```
### Flow 4: Ajouter un nouveau personnage
**User Goal:** Créer un personnage avec toutes ses informations
**Success Criteria:** Personnage créé et visible en < 1 minute
```mermaid
graph TD
A[Liste Personnages] --> B[Clic Ajouter]
B --> C[Modal création]
C --> D[Saisir pseudo]
D --> E[Sélectionner classe]
E --> F[Saisir niveau]
F --> G[Sélectionner serveur]
G --> H[Sélectionner compte]
H --> I{Validation}
I -->|OK| J[Enregistrer]
J --> K[✅ Toast confirmation]
K --> L[Liste rafraîchie]
```
### Flow 5: Consulter le Dashboard
**User Goal:** Vue d'ensemble instantanée de tous les comptes et personnages
**Success Criteria:** Toutes les informations clés visibles sans scroll sur desktop
```mermaid
graph TD
A[Accès Dashboard] --> B[Chargement widgets]
B --> C[Affichage simultané]
C --> D[Widget Comptes]
C --> E[Widget Personnages]
C --> F[Widget Teams]
C --> G[Widget Monnaies]
C --> H[Widget Progressions]
D --> I[Clic → Liste comptes]
E --> J[Clic → Liste personnages]
F --> K[Clic → Liste teams]
```
---
## Wireframes & Mockups
### Screen 1: Dashboard
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ☰ DOFUS MANAGER [🌙 Dark Mode] │
├────────────┬────────────────────────────────────────────────────────────────┤
│ │ │
│ 🏠 Dashboard│ DASHBOARD [+ Nouveau ▾] │
│ │ ───────────────────────────────────────────────────────────── │
│ 👥 Persos │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌────────────────┐ │
│ 📁 Comptes│ │ 📁 COMPTES │ │ 👥 PERSONNAGES │ │ ⚔️ TEAMS │ │
│ │ │ 12 comptes │ │ 64 personnages │ │ 3 actives │ │
│ ⚔️ Teams │ │ 45,230 ogrines │ │ Niv. moy: 198 │ │ 87% complete │ │
│ │ │ [Voir tout →] │ │ [Voir tout →] │ │ [Voir tout →] │ │
│ ─────────│ └─────────────────┘ └─────────────────┘ └────────────────┘ │
│ ⚙️ Settings│ │
│ │ ┌─────────────────────────────────┐ ┌──────────────────────┐ │
│ │ │ 💰 MONNAIES │ │ 📊 PROGRESSIONS │ │
│ │ │ Doplons 12,450 │ │ Dofus ████░ 72% │ │
│ │ │ Orichor 3,200 │ │ Donjons ██░░░ 45% │ │
│ │ │ Kamas glace 8,100 │ │ Recherchés███░░ 61% │ │
│ │ │ [Détail par compte →] │ │ [Bulk Update →] │ │
│ │ └─────────────────────────────────┘ └──────────────────────┘ │
│ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ ⚡ ACTIONS RAPIDES │ │
│ │ │ [+ Personnage] [+ Team] [Bulk Progressions] [Sync] │ │
│ │ └─────────────────────────────────────────────────────────┘ │
└────────────┴────────────────────────────────────────────────────────────────┘
```
### Screen 2: Liste Personnages
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ☰ DOFUS MANAGER [🌙] │
├────────────┬────────────────────────────────────────────────────────────────┤
│ │ PERSONNAGES 🔍 [Rechercher... ] │
│ 🏠 Dashboard│ ───────────────────────────────────────────────────────────── │
│ ►👥 Persos │ │
│ │ ┌──────────────┐ ┌──────────────────────────────────────────┐│
│ 📁 Comptes│ │ FILTRES │ │ ☑ Sélection: 3 [Bulk Actions ▾] ││
│ │ │ │ │ ─────────────────────────────────────── ││
│ ⚔️ Teams │ │ ▼ Classe │ │ ☐ │ Nom │Classe│Niv│Serveur│Cpt││
│ │ │ ☑ Cra 12 │ │ ──┼──────────────┼──────┼───┼───────┼───││
│ ─────────│ │ ☑ Iop 8 │ │ ☑ │ Krosmaster │ Cra │200│Imagiro│C1 ││
│ ⚙️ Settings│ │ ☐ Enu 6 │ │ ☐ │ TankMaster │ Iop │200│Imagiro│C1 ││
│ │ │ │ │ ☑ │ MoneyMaker │ Enu │200│Imagiro│C2 ││
│ │ │ ▼ Serveur │ │ ☐ │ HealBot │ Eni │200│Imagiro│C2 ││
│ │ │ ☑ Imagiro │ │ ☑ │ PortalGuy │ Elio │200│Imagiro│C3 ││
│ │ │ │ │ ─────────────────────────────────────── ││
│ │ │ ▼ Progression│ │ Showing 1-20 of 64 [< 1 2 3 4 >] ││
│ │ │ Type: [──▾] │ └──────────────────────────────────────────┘│
│ │ │ ○ A fait │ │
│ │ │ ○ N'a pas │ [+ Ajouter Personnage] │
│ │ │ [Réinitialiser]│ │
│ │ └──────────────┘ │
└────────────┴────────────────────────────────────────────────────────────────┘
```
### Screen 3: Fiche Personnage
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ☰ DOFUS MANAGER [🌙] │
├────────────┬────────────────────────────────────────────────────────────────┤
│ │ ← Personnages / Krosmaster [✏️] [🗑️] │
│ 🏠 Dashboard│ ───────────────────────────────────────────────────────────── │
│ 👥 Persos │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │
│ 📁 Comptes│ │ [Avatar] KROSMASTER │ │
│ │ │ Classe: Cra Niveau: 200 │ │
│ ⚔️ Teams │ │ Serveur: Imagiro Compte: Compte1 │ │
│ │ │ Teams: Main Team, Team Succès │ │
│ ─────────│ └─────────────────────────────────────────────────────────┘ │
│ ⚙️ Settings│ │
│ │ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ [Infos] [Progressions] [Monnaies] [Teams] │ │
│ │ ├─────────────────────────────────────────────────────────┤ │
│ │ │ PROGRESSIONS Filtre: [Tous ▾] │ │
│ │ │ │ │
│ │ │ ▼ Quêtes Dofus (7/10) │ │
│ │ │ ☑ Dofus Turquoise ✓ 2026-01-10 │ │
│ │ │ ☑ Dofus Pourpre ✓ 2026-01-08 │ │
│ │ │ ☐ Dofus des Glaces │ │
│ │ │ │ │
│ │ │ ▼ Donjons 191-200 (12/18) │ │
│ │ │ ☑ Bethel ✓ 2026-01-15 │ │
│ │ │ ☐ Tal Kasha │ │
│ │ └─────────────────────────────────────────────────────────┘ │
└────────────┴────────────────────────────────────────────────────────────────┘
```
### Screen 4: Fiche Team
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ☰ DOFUS MANAGER [🌙] │
├────────────┬────────────────────────────────────────────────────────────────┤
│ │ ← Teams / Main Team [✏️] [🗑️] │
│ 🏠 Dashboard│ │
│ 👥 Persos │ ┌────────────────────────────────────────────────────────┐ │
│ │ │ MAIN TEAM Type: Main │ │
│ 📁 Comptes│ │ 8 membres • ✅ Active • 8 comptes différents │ │
│ │ └────────────────────────────────────────────────────────┘ │
│ ⚔️ Teams │ │
│ │ ┌────────────────────────────────────────────────────────┐ │
│ ─────────│ │ [Membres] [Statut Progressions] │ │
│ ⚙️ Settings│ ├────────────────────────────────────────────────────────┤ │
│ │ │ STATUT PROGRESSIONS │ │
│ │ │ │ │
│ │ │ Progression: [Dofus Turquoise ▾] │ │
│ │ │ │ │
│ │ │ ████████████████████░░░░ 75% (6/8) [Marquer tous] │ │
│ │ │ │ │
│ │ │ │ Perso │ Statut │ Date │ │ │
│ │ │ │ Krosmaster │ ✅ │ 2026-01-10 │ │ │
│ │ │ │ TankMaster │ ✅ │ 2026-01-10 │ │ │
│ │ │ │ HealBot │ ❌ │ — │ │ │
│ │ │ │ SramKiller │ ❌ │ — │ │ │
│ │ └────────────────────────────────────────────────────────┘ │
└────────────┴────────────────────────────────────────────────────────────────┘
```
---
## Component Library / Design System
**Design System:** shadcn/ui (composants copiés, personnalisables)
### Core Components
| Component | Purpose | Variants | States |
|-----------|---------|----------|--------|
| **DataTable** | Listes avec tri, filtres, pagination | default, selectable, compact | loading, empty, error, filtered |
| **FilterSidebar** | Panel de filtres multicritères | default, collapsible, modal | default, active, loading |
| **StatCard** | Widget Dashboard KPI | default, progress, compact | loading, default, hover |
| **EntityCard** | Header fiches détail | character, account, team | default, editing |
| **ProgressionCheckbox** | Toggle fait/pas fait | default, with-date, bulk | unchecked, checked, loading, disabled |
| **BulkActionBar** | Actions sur sélection multiple | floating, inline | hidden, visible, processing |
| **Modal** | Dialogues création/édition/confirmation | form, confirm, selector | default, loading, error |
| **Toast** | Notifications feedback | success, error, warning, info | entering, visible, exiting |
| **Tabs** | Navigation sous-sections | default, pills, underline | default, active, disabled |
| **EmptyState** | Affichage liste vide | no-data, no-results, error | — |
---
## Branding & Style Guide
### Color Palette
#### Dark Mode (Principal)
| Color Type | Hex Code | Usage |
|------------|----------|-------|
| **Background** | `#0F172A` | Fond principal (slate-900) |
| **Foreground** | `#F8FAFC` | Texte principal |
| **Card** | `#1E293B` | Fond cartes (slate-800) |
| **Primary** | `#60A5FA` | Actions principales (blue-400) |
| **Secondary** | `#94A3B8` | Texte secondaire (slate-400) |
| **Accent** | `#A78BFA` | Highlights (violet-400) |
| **Border** | `#475569` | Bordures (slate-600) |
#### Semantic Colors
| Color Type | Hex | Usage |
|------------|-----|-------|
| **Success** | `#4ADE80` | Confirmations, complété |
| **Warning** | `#FBBF24` | Alertes |
| **Error** | `#F87171` | Erreurs |
| **Info** | `#60A5FA` | Informations |
### Typography
| Element | Size | Weight | Line Height |
|---------|------|--------|-------------|
| **H1** | 32px | 700 | 1.2 |
| **H2** | 24px | 600 | 1.3 |
| **H3** | 20px | 600 | 1.4 |
| **Body** | 14px | 400 | 1.5 |
| **Small** | 12px | 400 | 1.4 |
**Font:** Inter (system-ui fallback)
### Iconography
**Library:** Lucide Icons
| Context | Size |
|---------|------|
| Navigation | 20px |
| Buttons | 16px |
| Inline | 14px |
### Spacing Scale (base 4px)
| Token | Value |
|-------|-------|
| `space-1` | 4px |
| `space-2` | 8px |
| `space-3` | 12px |
| `space-4` | 16px |
| `space-6` | 24px |
| `space-8` | 32px |
### Layout Constants
| Element | Value |
|---------|-------|
| Sidebar width | 240px (collapsed: 64px) |
| Max content width | 1280px |
| Border radius | 8px (cards), 6px (buttons) |
---
## Accessibility Requirements
**Standard:** Pas de conformité WCAG formelle (app personnelle)
**Approche pragmatique :** Bonnes pratiques "gratuites" via shadcn/ui
### Key Requirements
| Category | Requirement |
|----------|-------------|
| **Visual** | Contraste 4.5:1, focus visible, états sans couleur seule |
| **Interaction** | Navigation clavier, focus trap modals, touch targets 44px |
| **Content** | Labels formulaires, messages d'erreur associés, structure headings |
---
## Responsiveness Strategy
### Breakpoints
| Breakpoint | Min Width | Target |
|------------|-----------|--------|
| **sm** (Mobile) | 0 | Smartphones |
| **md** (Tablet) | 640px | Tablettes |
| **lg** (Desktop) | 1024px | Laptops |
| **xl** (Wide) | 1280px | Grands moniteurs |
### Adaptation Patterns
| Element | Desktop | Tablet | Mobile |
|---------|---------|--------|--------|
| **Sidebar** | Expanded | Collapsed (icons) | Burger menu |
| **Dashboard** | 3 colonnes | 2 colonnes | 1 colonne |
| **DataTable** | Full | Colonnes prioritaires | Cards |
| **Modals** | Centré 500px | 90vw | Plein écran |
| **Filtres** | Sidebar | Sidebar mini | Modal |
---
## Animation & Micro-interactions
### Motion Principles
1. **Fonctionnel avant décoratif**
2. **Rapide et non-bloquant** (150-300ms)
3. **Subtil et cohérent**
4. **Respect prefers-reduced-motion**
### Key Animations
| Animation | Durée | Usage |
|-----------|-------|-------|
| Hover | 150ms | Buttons, rows |
| Fade in | 200ms | Contenu chargé |
| Slide in | 250ms | Modals, drawers |
| Toast | 300ms in / 200ms out | Notifications |
| Checkbox | 150ms | Toggle état |
### Performance Goals
| Metric | Target |
|--------|--------|
| First Contentful Paint | < 1.5s |
| Time to Interactive | < 3s |
| Interaction Response | < 100ms |
| Animation FPS | 60fps |
---
## Next Steps
### Immediate Actions
1. Générer les maquettes haute-fidélité (v0, Lovable, ou Figma)
2. Setup le projet avec shadcn/ui et configurer le thème
3. Implémenter le Layout principal (sidebar + header)
4. Développer le Dashboard avec widgets mockés
### Design Handoff Checklist
- [x] All user flows documented
- [x] Component inventory complete
- [x] Accessibility requirements defined
- [x] Responsive strategy clear
- [x] Brand guidelines incorporated
- [x] Performance goals established
### Prompt v0.dev (Dashboard)
```
Create a dark mode dashboard for a Dofus MMORPG character management app called "Dofus Manager".
Layout:
- Left sidebar (240px) with navigation: Dashboard (active), Characters, Accounts, Teams, Settings
- Main content area with widgets grid
Widgets (3 columns on desktop):
1. "Comptes" card: showing "12 comptes" and "45,230 ogrines" with folder icon
2. "Personnages" card: showing "64 personnages" and "Niv. moy: 198" with users icon
3. "Teams" card: showing "3 actives" and "87% complete" with swords icon
4. "Monnaies" card (spans 2 cols): list of currencies with amounts
5. "Progressions" card: progress bars for Dofus, Donjons, Recherchés
6. "Actions rapides" section: buttons for + Personnage, + Team, Bulk Progressions, Sync
Style: shadcn/ui, dark slate background (#0F172A), blue primary (#60A5FA), Inter font 14px
```
### Prompt v0.dev (Liste Personnages)
```
Create a character list page for "Dofus Manager" with filters sidebar.
Layout:
- Left filter sidebar (250px): Classe checkboxes, Serveur checkboxes, Progression filter
- Main data table: checkbox, Nom, Classe, Niveau, Serveur, Compte columns
- Top bar: search input, bulk actions when selected, + Ajouter button
- Pagination at bottom
Style: Dark mode, shadcn/ui, dense table rows (48px height), hover shows edit/delete icons
```

View File

@@ -0,0 +1,15 @@
# Accessibility Requirements
**Standard:** Pas de conformité WCAG formelle (app personnelle)
**Approche pragmatique :** Bonnes pratiques "gratuites" via shadcn/ui
## Key Requirements
| Category | Requirement |
|----------|-------------|
| **Visual** | Contraste 4.5:1, focus visible, états sans couleur seule |
| **Interaction** | Navigation clavier, focus trap modals, touch targets 44px |
| **Content** | Labels formulaires, messages d'erreur associés, structure headings |
---

View File

@@ -0,0 +1,29 @@
# Animation & Micro-interactions
## Motion Principles
1. **Fonctionnel avant décoratif**
2. **Rapide et non-bloquant** (150-300ms)
3. **Subtil et cohérent**
4. **Respect prefers-reduced-motion**
## Key Animations
| Animation | Durée | Usage |
|-----------|-------|-------|
| Hover | 150ms | Buttons, rows |
| Fade in | 200ms | Contenu chargé |
| Slide in | 250ms | Modals, drawers |
| Toast | 300ms in / 200ms out | Notifications |
| Checkbox | 150ms | Toggle état |
## Performance Goals
| Metric | Target |
|--------|--------|
| First Contentful Paint | < 1.5s |
| Time to Interactive | < 3s |
| Interaction Response | < 100ms |
| Animation FPS | 60fps |
---

View File

@@ -0,0 +1,67 @@
# Branding & Style Guide
## Color Palette
### Dark Mode (Principal)
| Color Type | Hex Code | Usage |
|------------|----------|-------|
| **Background** | `#0F172A` | Fond principal (slate-900) |
| **Foreground** | `#F8FAFC` | Texte principal |
| **Card** | `#1E293B` | Fond cartes (slate-800) |
| **Primary** | `#60A5FA` | Actions principales (blue-400) |
| **Secondary** | `#94A3B8` | Texte secondaire (slate-400) |
| **Accent** | `#A78BFA` | Highlights (violet-400) |
| **Border** | `#475569` | Bordures (slate-600) |
### Semantic Colors
| Color Type | Hex | Usage |
|------------|-----|-------|
| **Success** | `#4ADE80` | Confirmations, complété |
| **Warning** | `#FBBF24` | Alertes |
| **Error** | `#F87171` | Erreurs |
| **Info** | `#60A5FA` | Informations |
## Typography
| Element | Size | Weight | Line Height |
|---------|------|--------|-------------|
| **H1** | 32px | 700 | 1.2 |
| **H2** | 24px | 600 | 1.3 |
| **H3** | 20px | 600 | 1.4 |
| **Body** | 14px | 400 | 1.5 |
| **Small** | 12px | 400 | 1.4 |
**Font:** Inter (system-ui fallback)
## Iconography
**Library:** Lucide Icons
| Context | Size |
|---------|------|
| Navigation | 20px |
| Buttons | 16px |
| Inline | 14px |
## Spacing Scale (base 4px)
| Token | Value |
|-------|-------|
| `space-1` | 4px |
| `space-2` | 8px |
| `space-3` | 12px |
| `space-4` | 16px |
| `space-6` | 24px |
| `space-8` | 32px |
## Layout Constants
| Element | Value |
|---------|-------|
| Sidebar width | 240px (collapsed: 64px) |
| Max content width | 1280px |
| Border radius | 8px (cards), 6px (buttons) |
---

View File

@@ -0,0 +1,20 @@
# Component Library / Design System
**Design System:** shadcn/ui (composants copiés, personnalisables)
## Core Components
| Component | Purpose | Variants | States |
|-----------|---------|----------|--------|
| **DataTable** | Listes avec tri, filtres, pagination | default, selectable, compact | loading, empty, error, filtered |
| **FilterSidebar** | Panel de filtres multicritères | default, collapsible, modal | default, active, loading |
| **StatCard** | Widget Dashboard KPI | default, progress, compact | loading, default, hover |
| **EntityCard** | Header fiches détail | character, account, team | default, editing |
| **ProgressionCheckbox** | Toggle fait/pas fait | default, with-date, bulk | unchecked, checked, loading, disabled |
| **BulkActionBar** | Actions sur sélection multiple | floating, inline | hidden, visible, processing |
| **Modal** | Dialogues création/édition/confirmation | form, confirm, selector | default, loading, error |
| **Toast** | Notifications feedback | success, error, warning, info | entering, visible, exiting |
| **Tabs** | Navigation sous-sections | default, pills, underline | default, active, disabled |
| **EmptyState** | Affichage liste vide | no-data, no-results, error | — |
---

View File

@@ -0,0 +1,49 @@
# Dofus Manager UI/UX Specification
## Table of Contents
- [Dofus Manager UI/UX Specification](#table-of-contents)
- [Introduction](./introduction.md)
- [Overall UX Goals & Principles](./overall-ux-goals-principles.md)
- [Target User Persona](./overall-ux-goals-principles.md#target-user-persona)
- [Usability Goals](./overall-ux-goals-principles.md#usability-goals)
- [Design Principles](./overall-ux-goals-principles.md#design-principles)
- [Change Log](./overall-ux-goals-principles.md#change-log)
- [Information Architecture (IA)](./information-architecture-ia.md)
- [Site Map / Screen Inventory](./information-architecture-ia.md#site-map-screen-inventory)
- [Navigation Structure](./information-architecture-ia.md#navigation-structure)
- [User Flows](./user-flows.md)
- [Flow 1: Trouver les personnages qui n'ont pas fait X](./user-flows.md#flow-1-trouver-les-personnages-qui-nont-pas-fait-x)
- [Flow 2: Composer une team valide](./user-flows.md#flow-2-composer-une-team-valide)
- [Flow 3: Bulk update progressions pour une team](./user-flows.md#flow-3-bulk-update-progressions-pour-une-team)
- [Flow 4: Ajouter un nouveau personnage](./user-flows.md#flow-4-ajouter-un-nouveau-personnage)
- [Flow 5: Consulter le Dashboard](./user-flows.md#flow-5-consulter-le-dashboard)
- [Wireframes & Mockups](./wireframes-mockups.md)
- [Screen 1: Dashboard](./wireframes-mockups.md#screen-1-dashboard)
- [Screen 2: Liste Personnages](./wireframes-mockups.md#screen-2-liste-personnages)
- [Screen 3: Fiche Personnage](./wireframes-mockups.md#screen-3-fiche-personnage)
- [Screen 4: Fiche Team](./wireframes-mockups.md#screen-4-fiche-team)
- [Component Library / Design System](./component-library-design-system.md)
- [Core Components](./component-library-design-system.md#core-components)
- [Branding & Style Guide](./branding-style-guide.md)
- [Color Palette](./branding-style-guide.md#color-palette)
- [Dark Mode (Principal)](./branding-style-guide.md#dark-mode-principal)
- [Semantic Colors](./branding-style-guide.md#semantic-colors)
- [Typography](./branding-style-guide.md#typography)
- [Iconography](./branding-style-guide.md#iconography)
- [Spacing Scale (base 4px)](./branding-style-guide.md#spacing-scale-base-4px)
- [Layout Constants](./branding-style-guide.md#layout-constants)
- [Accessibility Requirements](./accessibility-requirements.md)
- [Key Requirements](./accessibility-requirements.md#key-requirements)
- [Responsiveness Strategy](./responsiveness-strategy.md)
- [Breakpoints](./responsiveness-strategy.md#breakpoints)
- [Adaptation Patterns](./responsiveness-strategy.md#adaptation-patterns)
- [Animation & Micro-interactions](./animation-micro-interactions.md)
- [Motion Principles](./animation-micro-interactions.md#motion-principles)
- [Key Animations](./animation-micro-interactions.md#key-animations)
- [Performance Goals](./animation-micro-interactions.md#performance-goals)
- [Next Steps](./next-steps.md)
- [Immediate Actions](./next-steps.md#immediate-actions)
- [Design Handoff Checklist](./next-steps.md#design-handoff-checklist)
- [Prompt v0.dev (Dashboard)](./next-steps.md#prompt-v0dev-dashboard)
- [Prompt v0.dev (Liste Personnages)](./next-steps.md#prompt-v0dev-liste-personnages)

View File

@@ -0,0 +1,82 @@
# Information Architecture (IA)
## Site Map / Screen Inventory
```mermaid
graph TD
A[🏠 Dashboard<br/>Vue d'ensemble principale] --> B[👥 Personnages]
A --> C[📁 Comptes]
A --> D[⚔️ Teams]
A --> E[⚙️ Paramètres]
A --> A1[Widget Comptes]
A --> A2[Widget Personnages]
A --> A3[Widget Teams]
A --> A4[Widget Monnaies]
A --> A5[Actions rapides]
B --> B1[Liste Personnages]
B1 --> B2[Fiche Personnage]
B2 --> B2a[Progressions]
B2 --> B2b[Monnaies]
B2 --> B2c[Teams]
C --> C1[Liste Comptes]
C1 --> C2[Fiche Compte]
C2 --> C2a[Personnages du compte]
C2 --> C2b[Métiers]
C2 --> C2c[Récompenses]
D --> D1[Liste Teams]
D1 --> D2[Fiche Team]
D2 --> D2a[Membres]
D2 --> D2b[Statut Progressions]
E --> E1[Serveurs]
E --> E2[Monnaies]
E --> E3[Données DofusDB]
B1 --> F[🔄 Bulk Actions]
F --> F1[Bulk Progressions]
F --> F2[Bulk Monnaies]
```
## Navigation Structure
**Primary Navigation (Sidebar)**
| Icône | Label | Route | Description |
|-------|-------|-------|-------------|
| 🏠 | Dashboard | `/` | Vue d'ensemble, KPIs, accès rapide |
| 👥 | Personnages | `/characters` | Liste principale avec filtres |
| 📁 | Comptes | `/accounts` | Gestion des comptes Dofus |
| ⚔️ | Teams | `/teams` | Composition et statut des teams |
| ⚙️ | Paramètres | `/settings` | Configuration (serveurs, monnaies, sync) |
**Secondary Navigation (Contextuelle)**
- **Onglets sur fiches détail** : Personnage → [Infos | Progressions | Monnaies | Teams]
- **Sous-menu Paramètres** : [Serveurs | Monnaies | Données DofusDB]
- **Actions groupées** : Accessible depuis la toolbar des listes (quand sélection active)
**Breadcrumb Strategy**
Format : `Section > Sous-section > Élément`
Exemples :
- `Personnages > Krosmaster-Cra`
- `Teams > Main Team > Statut Progressions`
- `Paramètres > Données DofusDB`
**Dashboard Content**
| Widget | Contenu | Action au clic |
|--------|---------|----------------|
| **Comptes** | Liste des comptes avec nb persos, ogrines | → Fiche compte |
| **Personnages** | Total, répartition par classe/niveau | → Liste filtrée |
| **Teams** | Teams actives avec % complétion | → Fiche team |
| **Monnaies** | Totaux globaux par type | → Détail par compte |
| **Progressions** | Résumé global (X% Dofus faits, Y donjons) | → Bulk actions |
| **Actions rapides** | Boutons : Nouveau perso, Bulk update, Sync DofusDB | → Action directe |
---

View File

@@ -0,0 +1,5 @@
# Introduction
Ce document définit les objectifs d'expérience utilisateur, l'architecture de l'information, les flux utilisateur et les spécifications de design visuel pour l'interface de **Dofus Manager**. Il sert de fondation pour le design visuel et le développement frontend, assurant une expérience cohérente et centrée sur l'utilisateur.
---

View File

@@ -0,0 +1,51 @@
# Next Steps
## Immediate Actions
1. Générer les maquettes haute-fidélité (v0, Lovable, ou Figma)
2. Setup le projet avec shadcn/ui et configurer le thème
3. Implémenter le Layout principal (sidebar + header)
4. Développer le Dashboard avec widgets mockés
## Design Handoff Checklist
- [x] All user flows documented
- [x] Component inventory complete
- [x] Accessibility requirements defined
- [x] Responsive strategy clear
- [x] Brand guidelines incorporated
- [x] Performance goals established
## Prompt v0.dev (Dashboard)
```
Create a dark mode dashboard for a Dofus MMORPG character management app called "Dofus Manager".
Layout:
- Left sidebar (240px) with navigation: Dashboard (active), Characters, Accounts, Teams, Settings
- Main content area with widgets grid
Widgets (3 columns on desktop):
1. "Comptes" card: showing "12 comptes" and "45,230 ogrines" with folder icon
2. "Personnages" card: showing "64 personnages" and "Niv. moy: 198" with users icon
3. "Teams" card: showing "3 actives" and "87% complete" with swords icon
4. "Monnaies" card (spans 2 cols): list of currencies with amounts
5. "Progressions" card: progress bars for Dofus, Donjons, Recherchés
6. "Actions rapides" section: buttons for + Personnage, + Team, Bulk Progressions, Sync
Style: shadcn/ui, dark slate background (#0F172A), blue primary (#60A5FA), Inter font 14px
```
## Prompt v0.dev (Liste Personnages)
```
Create a character list page for "Dofus Manager" with filters sidebar.
Layout:
- Left filter sidebar (250px): Classe checkboxes, Serveur checkboxes, Progression filter
- Main data table: checkbox, Nom, Classe, Niveau, Serveur, Compte columns
- Top bar: search input, bulk actions when selected, + Ajouter button
- Pagination at bottom
Style: Dark mode, shadcn/ui, dense table rows (48px height), hover shows edit/delete icons
```

View File

@@ -0,0 +1,42 @@
# Overall UX Goals & Principles
## Target User Persona
**Theo - Le Multi-Compteur Organisé**
| Attribut | Description |
|----------|-------------|
| **Profil** | Joueur passionné de Dofus gérant 60+ personnages niveau 200 |
| **Contexte d'usage** | Joue sur PC avec souvent un second écran pour consulter ses données |
| **Frustrations actuelles** | Tableur Excel illisible, modifications fragiles, contraintes de compte gérées mentalement |
| **Objectifs** | Trouver rapidement qui n'a pas fait quoi, composer des teams valides, mettre à jour efficacement |
| **Expertise technique** | À l'aise avec les outils complexes, préfère la densité d'info à la simplicité |
| **Fréquence d'usage** | Quotidien pendant les sessions de jeu + planification hebdomadaire |
## Usability Goals
1. **Efficacité de navigation** — Trouver n'importe quelle information en moins de 3 clics depuis le dashboard
2. **Mises à jour rapides** — Pouvoir mettre à jour la progression d'une team entière en moins de 30 secondes
3. **Prévention d'erreurs** — Impossible d'ajouter 2 personnages du même compte dans une team active
4. **Vue d'ensemble immédiate** — Voir l'état global (teams, progressions, monnaies) en un coup d'œil
5. **Mémorabilité** — Interface cohérente permettant de retrouver ses repères après plusieurs jours d'absence
## Design Principles
1. **Densité maîtrisée** — Maximiser l'information visible sans surcharger visuellement. Utiliser la hiérarchie typographique et les espaces blancs stratégiquement.
2. **Consistance des patterns** — Tous les tableaux se comportent de la même façon (tri, filtres, pagination). Toutes les actions CRUD suivent le même flow.
3. **Feedback immédiat** — Chaque action utilisateur génère une réponse visuelle instantanée (loading states, toasts, transitions).
4. **Raccourcis pour experts** — Permettre les bulk actions, raccourcis clavier (V2), et filtres combinés pour les utilisateurs avancés.
5. **Fail-safe par design** — Les actions destructives demandent confirmation. Les contraintes métier sont validées avant même que l'utilisateur ne puisse les violer.
## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2026-01-17 | 0.1 | Création initiale | Sally (UX Expert) |
---

View File

@@ -0,0 +1,22 @@
# Responsiveness Strategy
## Breakpoints
| Breakpoint | Min Width | Target |
|------------|-----------|--------|
| **sm** (Mobile) | 0 | Smartphones |
| **md** (Tablet) | 640px | Tablettes |
| **lg** (Desktop) | 1024px | Laptops |
| **xl** (Wide) | 1280px | Grands moniteurs |
## Adaptation Patterns
| Element | Desktop | Tablet | Mobile |
|---------|---------|--------|--------|
| **Sidebar** | Expanded | Collapsed (icons) | Burger menu |
| **Dashboard** | 3 colonnes | 2 colonnes | 1 colonne |
| **DataTable** | Full | Colonnes prioritaires | Cards |
| **Modals** | Centré 500px | 90vw | Plein écran |
| **Filtres** | Sidebar | Sidebar mini | Modal |
---

View File

@@ -0,0 +1,123 @@
# User Flows
## Flow 1: Trouver les personnages qui n'ont pas fait X
**User Goal:** Identifier rapidement quels personnages n'ont pas complété une progression spécifique
**Entry Points:** Dashboard → Widget Progressions, Sidebar → Personnages, Fiche Team
**Success Criteria:** Liste filtrée affichée en < 3 clics, < 5 secondes
```mermaid
graph TD
A[Dashboard] --> B[Clic Personnages]
B --> C[Liste avec Filtres]
C --> D[Ouvrir filtre Progression]
D --> E[Sélectionner type]
E --> F[Sélectionner N'a pas fait]
F --> G[✅ Liste filtrée affichée]
G --> H{Action suivante?}
H --> I[Voir fiche perso]
H --> J[Sélectionner plusieurs]
J --> K[Bulk Update]
```
**Edge Cases:**
- Aucun résultat → Message "Tous les personnages ont complété X" avec bouton reset
- Filtres combinés complexes → Indicateur des filtres actifs + "Clear all"
## Flow 2: Composer une team valide
**User Goal:** Créer ou modifier une team en respectant la contrainte compte
**Success Criteria:** Team créée avec membres valides, erreur claire si conflit
```mermaid
graph TD
A[Liste Teams] --> B[Nouvelle Team]
B --> C[Modal création]
C --> D[Saisir nom + type]
D --> E[Enregistrer]
E --> F[Fiche Team vide]
F --> G[Ajouter membre]
G --> H[Sélecteur personnages]
H --> I[Sélectionner perso]
I --> K{Même compte dans team?}
K -->|Non| L[✅ Membre ajouté]
K -->|Oui| M[❌ Erreur conflit]
M --> H
L --> O{Continuer?}
O -->|Oui| G
O -->|Non| P[✅ Team complète]
```
## Flow 3: Bulk update progressions pour une team
**User Goal:** Marquer une progression faite pour tous les membres d'une team
**Success Criteria:** Mise à jour de N personnages en < 30 secondes
```mermaid
graph TD
A[Fiche Team] --> B[Section Statut Progressions]
B --> C[Sélectionner progression]
C --> D[Voir statut par membre]
D --> E{Tous faits?}
E -->|Non| G[Bouton Marquer fait pour tous]
G --> H[Modal confirmation]
H --> I[Récap: X persos à mettre à jour]
I --> J{Confirmer?}
J -->|Oui| K[Processing...]
K --> L[✅ Toast: X persos mis à jour]
L --> M[Refresh → 100%]
```
## Flow 4: Ajouter un nouveau personnage
**User Goal:** Créer un personnage avec toutes ses informations
**Success Criteria:** Personnage créé et visible en < 1 minute
```mermaid
graph TD
A[Liste Personnages] --> B[Clic Ajouter]
B --> C[Modal création]
C --> D[Saisir pseudo]
D --> E[Sélectionner classe]
E --> F[Saisir niveau]
F --> G[Sélectionner serveur]
G --> H[Sélectionner compte]
H --> I{Validation}
I -->|OK| J[Enregistrer]
J --> K[✅ Toast confirmation]
K --> L[Liste rafraîchie]
```
## Flow 5: Consulter le Dashboard
**User Goal:** Vue d'ensemble instantanée de tous les comptes et personnages
**Success Criteria:** Toutes les informations clés visibles sans scroll sur desktop
```mermaid
graph TD
A[Accès Dashboard] --> B[Chargement widgets]
B --> C[Affichage simultané]
C --> D[Widget Comptes]
C --> E[Widget Personnages]
C --> F[Widget Teams]
C --> G[Widget Monnaies]
C --> H[Widget Progressions]
D --> I[Clic → Liste comptes]
E --> J[Clic → Liste personnages]
F --> K[Clic → Liste teams]
```
---

View File

@@ -0,0 +1,128 @@
# Wireframes & Mockups
## Screen 1: Dashboard
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ☰ DOFUS MANAGER [🌙 Dark Mode] │
├────────────┬────────────────────────────────────────────────────────────────┤
│ │ │
│ 🏠 Dashboard│ DASHBOARD [+ Nouveau ▾] │
│ │ ───────────────────────────────────────────────────────────── │
│ 👥 Persos │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌────────────────┐ │
│ 📁 Comptes│ │ 📁 COMPTES │ │ 👥 PERSONNAGES │ │ ⚔️ TEAMS │ │
│ │ │ 12 comptes │ │ 64 personnages │ │ 3 actives │ │
│ ⚔️ Teams │ │ 45,230 ogrines │ │ Niv. moy: 198 │ │ 87% complete │ │
│ │ │ [Voir tout →] │ │ [Voir tout →] │ │ [Voir tout →] │ │
│ ─────────│ └─────────────────┘ └─────────────────┘ └────────────────┘ │
│ ⚙️ Settings│ │
│ │ ┌─────────────────────────────────┐ ┌──────────────────────┐ │
│ │ │ 💰 MONNAIES │ │ 📊 PROGRESSIONS │ │
│ │ │ Doplons 12,450 │ │ Dofus ████░ 72% │ │
│ │ │ Orichor 3,200 │ │ Donjons ██░░░ 45% │ │
│ │ │ Kamas glace 8,100 │ │ Recherchés███░░ 61% │ │
│ │ │ [Détail par compte →] │ │ [Bulk Update →] │ │
│ │ └─────────────────────────────────┘ └──────────────────────┘ │
│ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ ⚡ ACTIONS RAPIDES │ │
│ │ │ [+ Personnage] [+ Team] [Bulk Progressions] [Sync] │ │
│ │ └─────────────────────────────────────────────────────────┘ │
└────────────┴────────────────────────────────────────────────────────────────┘
```
## Screen 2: Liste Personnages
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ☰ DOFUS MANAGER [🌙] │
├────────────┬────────────────────────────────────────────────────────────────┤
│ │ PERSONNAGES 🔍 [Rechercher... ] │
│ 🏠 Dashboard│ ───────────────────────────────────────────────────────────── │
│ ►👥 Persos │ │
│ │ ┌──────────────┐ ┌──────────────────────────────────────────┐│
│ 📁 Comptes│ │ FILTRES │ │ ☑ Sélection: 3 [Bulk Actions ▾] ││
│ │ │ │ │ ─────────────────────────────────────── ││
│ ⚔️ Teams │ │ ▼ Classe │ │ ☐ │ Nom │Classe│Niv│Serveur│Cpt││
│ │ │ ☑ Cra 12 │ │ ──┼──────────────┼──────┼───┼───────┼───││
│ ─────────│ │ ☑ Iop 8 │ │ ☑ │ Krosmaster │ Cra │200│Imagiro│C1 ││
│ ⚙️ Settings│ │ ☐ Enu 6 │ │ ☐ │ TankMaster │ Iop │200│Imagiro│C1 ││
│ │ │ │ │ ☑ │ MoneyMaker │ Enu │200│Imagiro│C2 ││
│ │ │ ▼ Serveur │ │ ☐ │ HealBot │ Eni │200│Imagiro│C2 ││
│ │ │ ☑ Imagiro │ │ ☑ │ PortalGuy │ Elio │200│Imagiro│C3 ││
│ │ │ │ │ ─────────────────────────────────────── ││
│ │ │ ▼ Progression│ │ Showing 1-20 of 64 [< 1 2 3 4 >] ││
│ │ │ Type: [──▾] │ └──────────────────────────────────────────┘│
│ │ │ ○ A fait │ │
│ │ │ ○ N'a pas │ [+ Ajouter Personnage] │
│ │ │ [Réinitialiser]│ │
│ │ └──────────────┘ │
└────────────┴────────────────────────────────────────────────────────────────┘
```
## Screen 3: Fiche Personnage
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ☰ DOFUS MANAGER [🌙] │
├────────────┬────────────────────────────────────────────────────────────────┤
│ │ ← Personnages / Krosmaster [✏️] [🗑️] │
│ 🏠 Dashboard│ ───────────────────────────────────────────────────────────── │
│ 👥 Persos │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │
│ 📁 Comptes│ │ [Avatar] KROSMASTER │ │
│ │ │ Classe: Cra Niveau: 200 │ │
│ ⚔️ Teams │ │ Serveur: Imagiro Compte: Compte1 │ │
│ │ │ Teams: Main Team, Team Succès │ │
│ ─────────│ └─────────────────────────────────────────────────────────┘ │
│ ⚙️ Settings│ │
│ │ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ [Infos] [Progressions] [Monnaies] [Teams] │ │
│ │ ├─────────────────────────────────────────────────────────┤ │
│ │ │ PROGRESSIONS Filtre: [Tous ▾] │ │
│ │ │ │ │
│ │ │ ▼ Quêtes Dofus (7/10) │ │
│ │ │ ☑ Dofus Turquoise ✓ 2026-01-10 │ │
│ │ │ ☑ Dofus Pourpre ✓ 2026-01-08 │ │
│ │ │ ☐ Dofus des Glaces │ │
│ │ │ │ │
│ │ │ ▼ Donjons 191-200 (12/18) │ │
│ │ │ ☑ Bethel ✓ 2026-01-15 │ │
│ │ │ ☐ Tal Kasha │ │
│ │ └─────────────────────────────────────────────────────────┘ │
└────────────┴────────────────────────────────────────────────────────────────┘
```
## Screen 4: Fiche Team
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ ☰ DOFUS MANAGER [🌙] │
├────────────┬────────────────────────────────────────────────────────────────┤
│ │ ← Teams / Main Team [✏️] [🗑️] │
│ 🏠 Dashboard│ │
│ 👥 Persos │ ┌────────────────────────────────────────────────────────┐ │
│ │ │ MAIN TEAM Type: Main │ │
│ 📁 Comptes│ │ 8 membres • ✅ Active • 8 comptes différents │ │
│ │ └────────────────────────────────────────────────────────┘ │
│ ⚔️ Teams │ │
│ │ ┌────────────────────────────────────────────────────────┐ │
│ ─────────│ │ [Membres] [Statut Progressions] │ │
│ ⚙️ Settings│ ├────────────────────────────────────────────────────────┤ │
│ │ │ STATUT PROGRESSIONS │ │
│ │ │ │ │
│ │ │ Progression: [Dofus Turquoise ▾] │ │
│ │ │ │ │
│ │ │ ████████████████████░░░░ 75% (6/8) [Marquer tous] │ │
│ │ │ │ │
│ │ │ │ Perso │ Statut │ Date │ │ │
│ │ │ │ Krosmaster │ ✅ │ 2026-01-10 │ │ │
│ │ │ │ TankMaster │ ✅ │ 2026-01-10 │ │ │
│ │ │ │ HealBot │ ❌ │ — │ │ │
│ │ │ │ SramKiller │ ❌ │ — │ │ │
│ │ └────────────────────────────────────────────────────────┘ │
└────────────┴────────────────────────────────────────────────────────────────┘
```
---

922
docs/prd.md Normal file
View File

@@ -0,0 +1,922 @@
# Dofus Manager - Product Requirements Document (PRD)
## Goals and Background Context
### Goals
- **Remplacer le tableur Excel** de gestion de 60+ personnages Dofus par une application web moderne et maintenable
- **Offrir une vue d'ensemble claire** de tous les personnages avec filtrage multicritères et recherche instantanée
- **Automatiser la gestion des données** via intégration avec l'API DofusDB (quêtes, donjons, succès)
- **Faciliter les mises à jour groupées** (bulk update) pour réduire drastiquement le temps de maintenance
- **Valider automatiquement les contraintes de compte** (pas 2 personnages du même compte simultanément dans une team)
- **Tracker les progressions** (quêtes Dofus, donjons, recherchés, monnaies) par personnage et par team
### Background Context
Theo est un joueur de Dofus gérant **60+ personnages niveau 200** répartis sur plusieurs dizaines de comptes sur plusieurs serveurs (principalement Imagiro). Actuellement, cette gestion est faite via un tableur Excel avec les personnages en colonnes horizontales, ce qui rend la visualisation impossible sans scroll excessif, les modifications fragiles (risque de casser le formatage), et la règle métier fondamentale du jeu ("pas 2 persos du même compte simultanément") gérée uniquement mentalement.
L'application remplacera ce tableur par un système web permettant la gestion CRUD des comptes, personnages, serveurs et teams, avec des filtres avancés façon e-commerce, des actions groupées, et une intégration avec DofusDB pour éliminer la saisie manuelle des données de référence (quêtes, donjons, succès).
### Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2026-01-17 | 0.1 | Création initiale du PRD | John (PM) |
| 2026-01-17 | 0.2 | Ajout documentation API DofusDB (endpoints validés) | John (PM) |
---
## Requirements
### Functional Requirements
- **FR1:** Le système doit permettre la création, lecture, modification et suppression (CRUD) des **comptes** avec les attributs : nom, ogrines, récompenses succès débloquées (Dofus, ressources).
- **FR2:** Le système doit permettre la gestion CRUD des **personnages** avec les attributs : pseudo, classe (17 classes Dofus), niveau, serveur associé, compte associé.
- **FR3:** Le système doit permettre la gestion CRUD des **teams** avec validation automatique de la contrainte "pas 2 personnages du même compte dans une team active".
- **FR4:** Le système doit offrir un **filtrage multicritères** des personnages par : classe, niveau, compte, team, serveur, statut de progression (quêtes, donjons, recherchés).
- **FR5:** Le système doit permettre la **recherche textuelle** sur les noms de personnages, comptes et teams.
- **FR6:** Le système doit permettre les **mises à jour groupées (bulk update)** : cocher/décocher plusieurs progressions pour une sélection de personnages ou une team entière.
- **FR7:** Le système doit tracker les **progressions par personnage** : quêtes Dofus (Turquoise, Pourpre, Émeraude, etc.), donjons par paliers avec types de succès, recherchés par région.
- **FR8:** Le système doit tracker les **monnaies par personnage** : Doplons, Almatons, Orichor, Kamas de glace, Perles des profondeurs, Alitons, Trukdivins, Pages calendrier.
- **FR9:** Le système doit afficher les **totaux agrégés des monnaies** au niveau compte et global.
- **FR10:** Le système doit s'intégrer avec **l'API DofusDB** pour importer les données de référence (liste des quêtes, donjons, succès, recherchés).
- **FR11:** Le système doit afficher une **vue statut team** avec pourcentage de complétion par objectif (ex: "Dofus Turquoise: 6/8 persos = 75%").
- **FR12:** Le système doit gérer les **métiers par couple compte+serveur** (et non par personnage) avec niveau de maîtrise.
- **FR13:** Le système doit permettre la gestion CRUD des **serveurs** (ex: Imagiro, Jahash, Draconiros) avec possibilité d'en ajouter de nouveaux.
### Non-Functional Requirements
- **NFR1:** L'application doit être **responsive** et utilisable sur desktop et tablette (usage sur second écran pendant le jeu).
- **NFR2:** L'application doit offrir une **latence de réponse < 500ms** pour les opérations courantes (filtrage, CRUD).
- **NFR3:** L'application doit supporter **100+ personnages** sans dégradation notable des performances.
- **NFR4:** L'application doit être **auto-hébergeable** sur un serveur dédié personnel via Docker.
- **NFR5:** L'application doit utiliser **PostgreSQL** comme base de données pour la persistance.
- **NFR6:** L'application doit être développée avec **React + TanStack Start** (full-stack TypeScript).
- **NFR7:** Les données doivent être **sauvegardables et restaurables** facilement (backup PostgreSQL).
- **NFR8:** L'application doit fonctionner en **mode mono-utilisateur** (pas d'authentification multi-users dans le MVP).
---
## User Interface Design Goals
### Overall UX Vision
L'application doit offrir une expérience **efficace et dense en informations**, inspirée des outils de gestion de données professionnels. L'objectif est de permettre à l'utilisateur de :
- Trouver rapidement l'information cherchée (quel perso n'a pas fait X ?)
- Effectuer des modifications en masse sans friction
- Avoir une vue d'ensemble claire malgré le volume de données (60+ personnages)
Le design privilégie la **fonctionnalité sur l'esthétique** : interface sobre, contrastes clairs, densité d'information élevée, navigation rapide.
### Key Interaction Paradigms
- **Filtres sidebar façon e-commerce** — Panel latéral avec facettes cliquables (classe, serveur, team, compte, statut)
- **Multi-select façon Gmail** — Checkboxes pour sélection multiple + barre d'actions groupées
- **Tables interactives** — Tri, resize colonnes, pagination, colonnes masquables
- **Actions au survol** — Boutons edit/delete apparaissent au hover pour réduire le bruit visuel
- **Drill-down progressif** — Liste → Fiche détaillée → Sous-sections (progressions, monnaies)
- **Feedback immédiat** — Toasts pour confirmations, indicateurs de chargement, états vides informatifs
### Core Screens and Views
1. **Dashboard** — Vue d'accueil avec KPIs (total persos, teams, progression globale)
2. **Liste Personnages** — Vue principale avec filtres, recherche, tableau paginé
3. **Fiche Personnage** — Détails complets : infos, progressions, monnaies, teams
4. **Liste Comptes** — Gestion des comptes avec leurs personnages associés
5. **Fiche Compte** — Détails compte : ogrines, métiers (par serveur), récompenses
6. **Liste Teams** — Toutes les teams avec statut de complétion
7. **Fiche Team** — Membres, validation contraintes, % progression par objectif
8. **Gestion Serveurs** — CRUD des serveurs disponibles
9. **Données de référence** — Gestion des quêtes/donjons/recherchés (sync DofusDB)
### Accessibility
**Niveau cible : Aucun (pas de conformité WCAG requise)**
Application à usage personnel. Bonnes pratiques de base respectées : contrastes suffisants, navigation clavier, labels sur formulaires.
### Branding
**Aucun branding spécifique.** Design system sobre et moderne (shadcn/ui ou similaire), palette neutre, pas de thématique Dofus (éviter copyright), focus sur lisibilité.
### Target Device and Platforms
**Web Responsive (Desktop-first)**
- **Priorité 1 : Desktop** — Usage principal sur grand écran pendant les sessions de jeu
- **Priorité 2 : Tablette** — Consultation occasionnelle
- **Priorité 3 : Mobile** — Consultation basique acceptable
---
## Technical Assumptions
### Repository Structure: Monorepo
Projet organisé en **monorepo** :
```
/
├── src/
│ ├── routes/ # Pages et API routes (TanStack Start)
│ ├── components/ # Composants React réutilisables
│ ├── lib/ # Utilitaires, clients API, helpers
│ └── server/ # Server functions, services
├── prisma/ # Schéma et migrations Prisma
├── docker/ # Configuration Docker
└── docs/ # Documentation projet
```
### Service Architecture: Monolith Full-Stack
**Architecture monolithique** avec TanStack Start :
- **Frontend** : React avec TanStack Router (file-based routing)
- **Backend** : Server functions intégrées à TanStack Start
- **Base de données** : PostgreSQL avec Prisma ORM
### Testing Requirements: Unit + Integration
| Type | Scope | Outils |
|------|-------|--------|
| **Unit** | Logique métier, validations, helpers | Vitest |
| **Integration** | API routes, queries DB | Vitest + testcontainers |
| **E2E** | Non prioritaire MVP | (Playwright en V2) |
### Additional Technical Assumptions and Requests
**Stack technique :**
- **Framework** : TanStack Start (React full-stack)
- **ORM** : Prisma (type-safe, migrations robustes, écosystème mature)
- **UI Components** : shadcn/ui (composants copiés, personnalisables)
- **Tables** : TanStack Table (tri, filtres, pagination)
- **Database** : PostgreSQL 16+
- **Container** : Docker + Docker Compose
**Infrastructure :**
- **Reverse proxy** : Traefik (existant sur le serveur)
- **CI/CD** : GitLab personnel (pipelines de build et déploiement)
- **Hébergement** : Serveur dédié personnel
**Intégration externe :**
- **DofusDB API** : Client HTTP pour récupérer les données de référence
- Sync manuelle ou cron pour mise à jour des données de jeu
**Conventions de code :**
- TypeScript strict mode
- ESLint + Prettier
- Conventional commits (feat:, fix:, chore:, etc.)
**Déploiement :**
- Docker Compose (app + postgres)
- Pipeline GitLab CI pour build et push des images
- Labels Traefik pour routing automatique
---
## DofusDB API Reference
Documentation de l'API externe utilisée pour l'Epic 6.
### Base URL
`https://api.dofusdb.fr/`
### Caractéristiques techniques
- **Framework:** FeathersJS (REST API)
- **Pagination:** `$limit`, `$skip` (défaut: limit=10)
- **Filtrage:** Style MongoDB (`$regex`, `$in`, `$gt`, etc.)
- **Multilingue:** `name.fr`, `name.en`, `name.de`, `name.es`, `name.pt`
- **Authentification:** Aucune (API publique)
### Endpoints disponibles
| Endpoint | Total | Champs clés |
|----------|-------|-------------|
| `/dungeons` | 187 | id, name, optimalPlayerLevel, monsters[], subarea |
| `/quests` | 1978 | id, name, categoryId, levelMin, levelMax, steps[], rewards[] |
| `/achievements` | 2788 | id, name, description, level, points, categoryId, rewards[] |
| `/monsters` | 5093 | id, name, level, isBoss, stats, drops[], subareas[] |
| `/items` | — | id, name, typeId (23 = Dofus trophées) |
| `/quest-categories` | 43+ | id, name (régions, types de quêtes) |
| `/achievement-categories` | 129 | id, name, parentId |
### Mapping pour le PRD
| Besoin PRD | Endpoint DofusDB | Query |
|------------|------------------|-------|
| **Donjons** | `/dungeons` | `?$limit=200` |
| **Recherchés** | `/quests` | `?categoryId=6` |
| **Items Dofus** | `/items` | `?typeId=23&name.fr[$regex]=Dofus` |
| **Succès donjons** | `/achievements` | `?categoryId=3` |
### Dofus identifiés
| ID Item | Nom |
|---------|-----|
| 739 | Dofus Turquoise |
| 694 | Dofus Pourpre |
| 737 | Dofus Émeraude |
| 7043 | Dofus des Glaces |
| 18043 | Dofus Abyssal |
| 8698 | Dofus Nébuleux |
| 7112 | Dofus Tacheté |
| 6980 | Dofus Vulbis |
| 7754 | Dofus Ocre |
| 7114 | Dofus Ébène |
| 7115 | Dofus Ivoire |
### Exemples de requêtes
```bash
# Tous les donjons
curl "https://api.dofusdb.fr/dungeons?$limit=200"
# Quêtes de recherchés (Avis de recherche)
curl "https://api.dofusdb.fr/quests?categoryId=6"
# Items Dofus
curl "https://api.dofusdb.fr/items?typeId=23&name.fr[\$regex]=Dofus"
# Monstres boss
curl "https://api.dofusdb.fr/monsters?isBoss=true&$limit=50"
```
### Notes d'implémentation
- Les quêtes Dofus ne sont pas directement liées aux items Dofus dans l'API → nécessite un mapping manuel
- Les recherchés sont sous `categoryId=6` dans `/quests`
- Les noms sont multilingues : utiliser `name.fr` pour le français
- Pagination recommandée pour les gros volumes (achievements, monsters)
---
## Epic List
| # | Epic | Objectif |
|---|------|----------|
| **1** | **Foundation & Core Entities** | Établir le projet, le schéma DB, et le CRUD de base pour Serveurs, Comptes et Personnages |
| **2** | **Teams & Constraints** | Implémenter la gestion des Teams avec validation de la contrainte compte |
| **3** | **Filtering & Search** | Ajouter les filtres multicritères et la recherche textuelle sur la liste des personnages |
| **4** | **Progression Tracking** | Tracker les progressions (quêtes Dofus, donjons, recherchés) par personnage |
| **5** | **Currencies & Aggregations** | Gérer les monnaies par personnage et afficher les totaux agrégés |
| **6** | **DofusDB Integration** | Intégrer l'API DofusDB pour les données de référence |
---
## Epic 1: Foundation & Core Entities
**Goal:** Établir les fondations du projet (setup, Docker, Prisma, CI/CD) et implémenter le CRUD complet pour les entités de base : Serveurs, Comptes et Personnages. À la fin de cet epic, l'utilisateur peut créer, consulter, modifier et supprimer des serveurs, comptes et personnages.
### Story 1.1: Project Setup & Infrastructure
**As a** developer,
**I want** a fully configured TanStack Start project with Docker and GitLab CI,
**so that** I can start development with a working local environment and deployment pipeline.
**Acceptance Criteria:**
1. TanStack Start project initialized with TypeScript strict mode
2. Docker Compose configuration with app service and PostgreSQL 16
3. Prisma configured and connected to PostgreSQL
4. shadcn/ui installed with base components (Button, Input, Card, Table)
5. ESLint + Prettier configured with recommended rules
6. GitLab CI pipeline: build, lint, test stages
7. Dockerfile multi-stage pour production build
8. README avec instructions de setup local
9. Application démarre et affiche une page d'accueil "Dofus Manager"
### Story 1.2: Database Schema - Core Entities
**As a** developer,
**I want** a Prisma schema with Server, Account, and Character models,
**so that** the data structure is defined and migrations are ready.
**Acceptance Criteria:**
1. Model `Server`: id, name, createdAt, updatedAt
2. Model `Account`: id, name, ogrines (integer), createdAt, updatedAt
3. Model `Character`: id, name, class (enum 17 classes), level (1-200), serverId (FK), accountId (FK), createdAt, updatedAt
4. Enum `CharacterClass` avec les 17 classes Dofus
5. Relations définies : Character → Server (N:1), Character → Account (N:1)
6. Migration initiale générée et appliquée
7. Seed script avec données de test (2 serveurs, 3 comptes, 10 personnages)
### Story 1.3: Server CRUD
**As a** user,
**I want** to manage servers (create, view, edit, delete),
**so that** I can add the Dofus servers I play on.
**Acceptance Criteria:**
1. Page `/servers` affiche la liste des serveurs en tableau
2. Bouton "Ajouter" ouvre un formulaire modal de création
3. Formulaire avec champ nom (requis, unique)
4. Actions Edit/Delete sur chaque ligne (icônes au hover)
5. Confirmation avant suppression
6. Toast de confirmation après chaque action
7. Validation : nom non vide, unicité vérifiée côté serveur
8. Serveurs triés par nom alphabétique
### Story 1.4: Account CRUD
**As a** user,
**I want** to manage my Dofus accounts (create, view, edit, delete),
**so that** I can organize my characters by account.
**Acceptance Criteria:**
1. Page `/accounts` affiche la liste des comptes en tableau (nom, ogrines, nb personnages)
2. Bouton "Ajouter" ouvre un formulaire modal de création
3. Formulaire avec champs : nom (requis), ogrines (optionnel, défaut 0)
4. Actions Edit/Delete sur chaque ligne
5. Clic sur un compte navigue vers `/accounts/:id` (fiche détail)
6. Page détail affiche infos compte + liste des personnages associés
7. Suppression compte impossible si personnages associés (message d'erreur)
8. Toast de confirmation après chaque action
### Story 1.5: Character CRUD
**As a** user,
**I want** to manage my characters (create, view, edit, delete),
**so that** I can track all my Dofus characters.
**Acceptance Criteria:**
1. Page `/characters` affiche la liste des personnages en tableau (nom, classe, niveau, serveur, compte)
2. Bouton "Ajouter" ouvre un formulaire modal de création
3. Formulaire avec champs : nom (requis), classe (select), niveau (1-200), serveur (select), compte (select)
4. Actions Edit/Delete sur chaque ligne
5. Clic sur un personnage navigue vers `/characters/:id` (fiche détail)
6. Page détail affiche toutes les infos du personnage
7. Icônes de classe affichées (optionnel: images ou emojis)
8. Tableau paginé (20 items par page)
9. Toast de confirmation après chaque action
### Story 1.6: Navigation & Layout
**As a** user,
**I want** a consistent navigation layout,
**so that** I can easily move between sections of the app.
**Acceptance Criteria:**
1. Sidebar de navigation avec liens : Dashboard, Personnages, Comptes, Serveurs
2. Layout responsive : sidebar collapse sur mobile
3. Breadcrumb sur les pages de détail
4. Page active mise en évidence dans la sidebar
5. Header avec titre de l'application
6. Dark mode toggle (état persisté en localStorage)
---
## Epic 2: Teams & Constraints
**Goal:** Implémenter la gestion complète des Teams avec la règle métier fondamentale : impossible d'avoir 2 personnages du même compte dans une team active. L'utilisateur peut créer des teams, y ajouter des personnages, et voir le statut de complétion.
### Story 2.1: Team Database Schema
**As a** developer,
**I want** a Prisma schema for Teams with many-to-many relation to Characters,
**so that** teams can be created and managed.
**Acceptance Criteria:**
1. Model `Team`: id, name, type (enum: MAIN, SUCCESS, PL, CUSTOM), isActive (boolean), createdAt, updatedAt
2. Relation many-to-many Team ↔ Character via table de jonction `TeamMember`
3. Model `TeamMember`: teamId, characterId, joinedAt
4. Enum `TeamType` avec les types identifiés (Main, Succès, PL, Custom)
5. Migration générée et appliquée
6. Seed script mis à jour avec 2-3 teams de test
### Story 2.2: Team CRUD - Basic
**As a** user,
**I want** to create, view, edit and delete teams,
**so that** I can organize my characters into groups.
**Acceptance Criteria:**
1. Page `/teams` affiche la liste des teams en tableau (nom, type, nb membres, statut actif)
2. Bouton "Ajouter" ouvre un formulaire modal de création
3. Formulaire avec champs : nom (requis), type (select), isActive (checkbox)
4. Actions Edit/Delete sur chaque ligne
5. Clic sur une team navigue vers `/teams/:id` (fiche détail)
6. Suppression team supprime aussi les TeamMember associés
7. Badge visuel pour teams actives vs inactives
8. Toast de confirmation après chaque action
### Story 2.3: Team Member Management
**As a** user,
**I want** to add and remove characters from a team,
**so that** I can compose my teams.
**Acceptance Criteria:**
1. Page `/teams/:id` affiche la liste des membres actuels
2. Bouton "Ajouter membre" ouvre un sélecteur de personnages
3. Sélecteur filtrable par nom, classe, compte, serveur
4. Multi-select possible pour ajouter plusieurs personnages à la fois
5. Bouton "Retirer" sur chaque membre pour le supprimer de la team
6. Affichage du compte de chaque personnage dans la liste des membres
7. Ordre des membres modifiable (drag & drop optionnel, sinon ordre d'ajout)
### Story 2.4: Account Constraint Validation
**As a** user,
**I want** the system to prevent adding two characters from the same account to an active team,
**so that** I respect the game's simultaneous play restriction.
**Acceptance Criteria:**
1. Lors de l'ajout d'un membre, vérification que son compte n'est pas déjà dans la team
2. Si conflit détecté : message d'erreur clair indiquant le personnage en conflit
3. Validation côté serveur (impossible de contourner)
4. Validation côté client pour feedback immédiat
5. La contrainte ne s'applique qu'aux teams **actives** (isActive = true)
6. Teams inactives peuvent avoir plusieurs persos du même compte (pour planification)
7. Lors du passage d'une team inactive → active : vérification des conflits
### Story 2.5: Team Status Overview
**As a** user,
**I want** to see a summary of each team's composition,
**so that** I can quickly assess my teams.
**Acceptance Criteria:**
1. Sur `/teams`, colonnes : nom, type, membres (count), statut, classes représentées
2. Sur `/teams/:id`, section récapitulative : nb membres, comptes utilisés, classes
3. Indicateur visuel si team incomplète (< 8 membres pour type MAIN)
4. Liste des comptes utilisés dans la team (pour éviter conflits lors de multi-boxing)
5. Affichage des classes sous forme d'icônes compactes
---
## Epic 3: Filtering & Search
**Goal:** Ajouter un système de filtrage multicritères et de recherche textuelle sur la liste des personnages. L'utilisateur peut rapidement trouver les personnages qui correspondent à ses critères (classe, serveur, compte, team, etc.).
### Story 3.1: Filter Sidebar Component
**As a** user,
**I want** a sidebar with filter options on the characters list,
**so that** I can narrow down the displayed characters.
**Acceptance Criteria:**
1. Sidebar à gauche de la liste des personnages
2. Section "Classe" : checkboxes pour chaque classe (17 classes)
3. Section "Serveur" : checkboxes pour chaque serveur existant
4. Section "Compte" : checkboxes pour chaque compte existant
5. Section "Team" : checkboxes pour chaque team existante
6. Section "Niveau" : slider ou inputs min/max (1-200)
7. Bouton "Réinitialiser les filtres"
8. Sidebar collapsible sur mobile (bouton toggle)
9. Compteur de résultats mis à jour en temps réel
### Story 3.2: Filter Logic Implementation
**As a** developer,
**I want** server-side filtering with URL state,
**so that** filters are shareable and persist on refresh.
**Acceptance Criteria:**
1. Filtres stockés dans les query params de l'URL (ex: `?class=CRA,IOP&server=1`)
2. API endpoint accepte les paramètres de filtre
3. Requête Prisma optimisée avec WHERE dynamique
4. Filtres combinés en AND (classe ET serveur ET compte...)
5. Au sein d'un même filtre, valeurs combinées en OR (Cra OU Iop)
6. État des filtres synchronisé avec l'URL au changement
7. Chargement initial lit les filtres depuis l'URL
8. Debounce sur les changements pour éviter trop de requêtes
### Story 3.3: Text Search
**As a** user,
**I want** to search characters by name,
**so that** I can quickly find a specific character.
**Acceptance Criteria:**
1. Champ de recherche au-dessus du tableau
2. Recherche sur le nom du personnage (insensible à la casse)
3. Recherche également sur le nom du compte
4. Résultats filtrés en temps réel (debounce 300ms)
5. Recherche combinable avec les filtres sidebar
6. Icône "clear" pour vider la recherche
7. Placeholder : "Rechercher un personnage..."
8. Recherche stockée dans l'URL (`?q=...`)
### Story 3.4: Column Sorting
**As a** user,
**I want** to sort the characters table by clicking column headers,
**so that** I can organize the data as needed.
**Acceptance Criteria:**
1. Colonnes triables : nom, classe, niveau, serveur, compte
2. Clic sur header = tri ascendant, second clic = descendant, troisième = reset
3. Indicateur visuel de la colonne triée (flèche up/down)
4. Tri côté serveur pour performance
5. Tri par défaut : niveau descendant (200 en premier)
6. Tri stocké dans l'URL (`?sort=level&order=desc`)
7. Un seul tri actif à la fois
### Story 3.5: Saved Filter Presets
**As a** user,
**I want** to save and reuse filter combinations,
**so that** I don't have to reconfigure common filters.
**Acceptance Criteria:**
1. Bouton "Sauvegarder ce filtre" quand filtres actifs
2. Modal pour nommer le preset
3. Liste des presets sauvegardés dans la sidebar (section "Mes filtres")
4. Clic sur preset applique tous ses filtres
5. Bouton supprimer sur chaque preset
6. Presets stockés en base de données (model `FilterPreset`)
7. Limite de 10 presets maximum
8. Presets spécifiques à l'utilisateur (pour futur multi-user)
---
## Epic 4: Progression Tracking
**Goal:** Implémenter le tracking des progressions par personnage : quêtes Dofus, donjons par paliers, et recherchés par région. L'utilisateur peut marquer les progressions comme complétées et voir les statistiques par team.
### Story 4.1: Progression Database Schema
**As a** developer,
**I want** a flexible schema for tracking character progressions,
**so that** different types of progressions can be managed uniformly.
**Acceptance Criteria:**
1. Model `ProgressionType`: id, category (enum: DOFUS_QUEST, DUNGEON, WANTED), name, region (nullable), levelRange (nullable), createdAt
2. Model `CharacterProgression`: characterId, progressionTypeId, completed (boolean), completedAt (nullable)
3. Enum `ProgressionCategory`: DOFUS_QUEST, DUNGEON, WANTED
4. Index composite sur (characterId, progressionTypeId) pour performance
5. Migration générée et appliquée
6. Seed script avec données de progression types :
- 10 quêtes Dofus (Turquoise, Pourpre, Émeraude, Glaces, Abyssal, Nébuleux, Domakuro, Dorigami, Tacheté, Vulbis)
- Donjons par paliers (1-50, 51-100, 101-150, 151-190, 191-200)
- Recherchés par région (Astrub, Amakna, Frigost I/II/III, etc.)
### Story 4.2: Character Progression View
**As a** user,
**I want** to see and edit a character's progressions on their detail page,
**so that** I can track what each character has completed.
**Acceptance Criteria:**
1. Section "Progressions" sur la page `/characters/:id`
2. Onglets par catégorie : Quêtes Dofus | Donjons | Recherchés
3. Liste des items avec checkbox pour marquer fait/pas fait
4. Date de complétion affichée si complété
5. Clic sur checkbox toggle l'état et sauvegarde immédiatement
6. Compteur de progression par catégorie (ex: "7/10 Dofus")
7. Filtres : Tous | Faits | Non faits
8. Items triés par nom ou par ordre logique (niveau pour donjons)
### Story 4.3: Bulk Progression Update
**As a** user,
**I want** to update progressions for multiple characters at once,
**so that** I can quickly mark a dungeon done for my whole team.
**Acceptance Criteria:**
1. Page `/progressions/bulk` accessible depuis le menu
2. Sélecteur de personnages (multi-select avec filtres)
3. Sélection possible par team entière (bouton "Sélectionner team X")
4. Sélecteur de progression type à mettre à jour
5. Action : "Marquer comme fait" ou "Marquer comme non fait"
6. Confirmation avant exécution avec récapitulatif (X personnages, progression Y)
7. Toast de succès avec nombre de mises à jour effectuées
8. Retour à la page précédente après action
### Story 4.4: Team Progression Status
**As a** user,
**I want** to see the progression status of my team for a specific objective,
**so that** I can see who still needs to complete it.
**Acceptance Criteria:**
1. Sur `/teams/:id`, nouvelle section "Statut des progressions"
2. Sélecteur de progression type (ex: "Dofus Turquoise")
3. Tableau : membres de la team avec statut (fait/pas fait) pour cette progression
4. Pourcentage global affiché (ex: "6/8 = 75%")
5. Indicateur visuel clair (vert = fait, rouge = pas fait)
6. Bouton "Marquer fait pour tous" pour bulk update depuis cette vue
7. Filtrable par catégorie de progression
### Story 4.5: Progression Filters in Character List
**As a** user,
**I want** to filter characters by progression status,
**so that** I can find who hasn't completed a specific objective.
**Acceptance Criteria:**
1. Nouvelle section dans la sidebar des filtres : "Progression"
2. Sélecteur de progression type
3. Options : "A fait" / "N'a pas fait"
4. Combinable avec les autres filtres existants
5. Exemple d'usage : "Montrer tous les Cra qui n'ont pas fait le Dofus Turquoise"
6. Compteur de résultats mis à jour
7. Filtre stocké dans l'URL
---
## Epic 5: Currencies & Aggregations
**Goal:** Implémenter le tracking des monnaies par personnage (Doplons, Orichor, etc.) et afficher les totaux agrégés au niveau compte et global. L'utilisateur peut rapidement voir combien de chaque monnaie il possède au total.
### Story 5.1: Currency Database Schema
**As a** developer,
**I want** a schema for tracking currencies per character,
**so that** currency amounts can be stored and aggregated.
**Acceptance Criteria:**
1. Model `CurrencyType`: id, name, icon (nullable), createdAt
2. Model `CharacterCurrency`: characterId, currencyTypeId, amount (integer), updatedAt
3. Contrainte unique sur (characterId, currencyTypeId)
4. Migration générée et appliquée
5. Seed script avec les 8 monnaies identifiées :
- Doplons, Almatons, Orichor, Kamas de glace
- Perles des profondeurs, Alitons, Trukdivins, Pages calendrier
6. Index sur characterId pour requêtes d'agrégation
### Story 5.2: Character Currency View
**As a** user,
**I want** to see and edit a character's currencies on their detail page,
**so that** I can track each character's wealth.
**Acceptance Criteria:**
1. Section "Monnaies" sur la page `/characters/:id`
2. Liste des monnaies avec champ input numérique pour chaque
3. Modification inline avec sauvegarde au blur ou sur Enter
4. Indicateur de sauvegarde (loading spinner pendant save)
5. Validation : montant >= 0, entier uniquement
6. Affichage de l'icône/nom de chaque monnaie
7. Dernière mise à jour affichée par monnaie
### Story 5.3: Bulk Currency Update
**As a** user,
**I want** to update a currency for multiple characters at once,
**so that** I can quickly update after a group activity.
**Acceptance Criteria:**
1. Page `/currencies/bulk` accessible depuis le menu
2. Sélecteur de personnages (multi-select avec filtres, sélection par team)
3. Sélecteur de monnaie à mettre à jour
4. Mode d'opération : "Définir à" (valeur absolue) ou "Ajouter/Soustraire" (delta)
5. Champ pour la valeur
6. Confirmation avant exécution
7. Toast de succès avec récapitulatif
8. Historique des bulk updates (optionnel, pour audit)
### Story 5.4: Account Currency Totals
**As a** user,
**I want** to see the total currencies for each account,
**so that** I can see my wealth per account.
**Acceptance Criteria:**
1. Sur `/accounts/:id`, section "Total des monnaies"
2. Tableau avec chaque monnaie et le total pour ce compte
3. Total = somme des monnaies de tous les personnages du compte
4. Mise à jour automatique quand les données changent
5. Affichage compact (icône + montant)
6. Zéro affiché si aucun personnage n'a cette monnaie
### Story 5.5: Global Currency Dashboard
**As a** user,
**I want** to see my total currencies across all characters,
**so that** I have a global view of my in-game wealth.
**Acceptance Criteria:**
1. Widget sur le Dashboard (page d'accueil) : "Mes monnaies"
2. Liste de toutes les monnaies avec total global
3. Total global = somme sur tous les personnages
4. Possibilité de cliquer pour voir le détail par compte
5. Drill-down : compte → personnages avec leurs montants
6. Données mises en cache pour performance (invalidation au changement)
### Story 5.6: Currency Management (Admin)
**As a** user,
**I want** to add or remove currency types,
**so that** I can adapt to game updates adding new currencies.
**Acceptance Criteria:**
1. Page `/settings/currencies` pour gérer les types de monnaies
2. Liste des monnaies existantes
3. Formulaire d'ajout : nom, icône (optionnel)
4. Suppression possible si aucun personnage n'a cette monnaie
5. Avertissement si suppression avec données existantes
6. Ordre d'affichage modifiable (drag & drop ou champ order)
---
## Epic 6: DofusDB Integration
**Goal:** Intégrer l'API DofusDB pour importer automatiquement les données de référence du jeu (quêtes, donjons, succès, recherchés). L'utilisateur n'a plus besoin de saisir manuellement ces informations.
### Story 6.1: DofusDB API Client
**As a** developer,
**I want** a typed HTTP client for the DofusDB API,
**so that** I can fetch game reference data reliably.
**Acceptance Criteria:**
1. Module `lib/dofusdb.ts` avec client HTTP typé
2. Types TypeScript pour les réponses API (quêtes, donjons, succès, etc.)
3. Gestion des erreurs API (timeout, rate limit, 404)
4. Configuration via variables d'environnement (API URL, éventuels tokens)
5. Retry automatique en cas d'échec temporaire (max 3 retries)
6. Logging des appels API pour debug
7. Tests unitaires avec mocks des réponses API
### Story 6.2: Dungeon Data Import
**As a** user,
**I want** to import the list of dungeons from DofusDB,
**so that** I don't have to add them manually.
**Acceptance Criteria:**
1. Endpoint ou script pour importer les donjons depuis DofusDB
2. Mapping des données DofusDB vers le model `ProgressionType` (category: DUNGEON)
3. Import des métadonnées : nom, niveau requis, zone/région
4. Gestion des doublons : mise à jour si existant, création sinon
5. Rapport d'import : X créés, Y mis à jour, Z erreurs
6. Bouton "Importer donjons" dans `/settings/data`
7. Indicateur de dernière synchronisation
### Story 6.3: Quest Data Import
**As a** user,
**I want** to import Dofus quest chains from DofusDB,
**so that** I can track my progress on main quests.
**Acceptance Criteria:**
1. Import des quêtes Dofus (les 10 quêtes principales identifiées)
2. Mapping vers `ProgressionType` (category: DOFUS_QUEST)
3. Import des métadonnées : nom, Dofus associé
4. Option de filtrer quelles quêtes importer (sélection manuelle ou toutes)
5. Gestion des doublons
6. Bouton "Importer quêtes" dans `/settings/data`
7. Rapport d'import
### Story 6.4: Wanted Posters Import
**As a** user,
**I want** to import wanted poster data from DofusDB,
**so that** I can track bounties by region.
**Acceptance Criteria:**
1. Import des recherchés par région depuis DofusDB
2. Mapping vers `ProgressionType` (category: WANTED)
3. Métadonnées : nom, région associée
4. Regroupement par région (Astrub, Amakna, Frigost I/II/III, etc.)
5. Gestion des doublons
6. Bouton "Importer recherchés" dans `/settings/data`
7. Rapport d'import
### Story 6.5: Sync Settings & Automation
**As a** user,
**I want** to configure automatic synchronization with DofusDB,
**so that** my reference data stays up to date.
**Acceptance Criteria:**
1. Page `/settings/data` avec configuration de sync
2. Option sync manuelle (boutons par type de données)
3. Option sync automatique périodique (daily, weekly, disabled)
4. Cron job ou scheduled task pour sync auto
5. Notification (toast ou log) après sync automatique
6. Historique des syncs (date, type, résultat)
7. Option de réinitialiser toutes les données de référence
### Story 6.6: Data Conflict Resolution
**As a** developer,
**I want** a strategy for handling conflicts between local and API data,
**so that** user modifications aren't lost during sync.
**Acceptance Criteria:**
1. Les `ProgressionType` importés ont un flag `source: API | MANUAL`
2. Sync API ne modifie que les entrées `source: API`
3. Entrées `source: MANUAL` préservées lors du sync
4. Option de forcer l'écrasement (avec confirmation)
5. Détection des entrées supprimées de l'API (soft delete ou warning)
6. Log des conflits détectés pour review
---
## Checklist Results Report
### Executive Summary
| Metric | Value |
|--------|-------|
| **Overall PRD Completeness** | 95% |
| **MVP Scope Appropriateness** | Just Right |
| **Readiness for Architecture** | Ready |
| **DofusDB API** | ✅ Validée et documentée |
### Category Analysis
| Category | Status | Notes |
|----------|--------|-------|
| 1. Problem Definition & Context | PASS | Problème clairement articulé, utilisateur cible défini |
| 2. MVP Scope Definition | PASS | 6 epics bien délimités, scope MVP réaliste |
| 3. User Experience Requirements | PASS | Flows documentés, paradigmes d'interaction définis |
| 4. Functional Requirements | PASS | 13 FR + 8 NFR, tous testables |
| 5. Non-Functional Requirements | PARTIAL | Performance OK, sécurité minimale (mono-user) |
| 6. Epic & Story Structure | PASS | 6 epics séquentiels, 27 stories avec AC détaillés |
| 7. Technical Guidance | PASS | Stack définie, architecture monolith documentée |
| 8. Cross-Functional Requirements | PASS | Intégration DofusDB, schéma DB complet |
| 9. Clarity & Communication | PASS | Document structuré, terminologie cohérente |
### Issues Identified
| Priority | Issue | Status |
|----------|-------|--------|
| ~~HIGH~~ | ~~API DofusDB non validée~~ | ✅ Résolu — Documentation ajoutée |
| MEDIUM | Métriques de succès non formalisées | À définir post-MVP |
| MEDIUM | Stratégie backup non détaillée | À documenter dans architecture |
| LOW | Seed data à compléter | À préciser lors de l'implémentation |
### Final Decision
**✅ READY FOR ARCHITECT** — Le PRD est complet et prêt pour la phase d'architecture.
---
## Next Steps
### UX Expert Prompt
```
Je travaille sur Dofus Manager, une application web de gestion de personnages pour le MMORPG Dofus.
Contexte : L'application remplace un tableur Excel pour gérer 60+ personnages sur plusieurs comptes. Les fonctionnalités clés sont :
- CRUD pour Serveurs, Comptes, Personnages, Teams
- Filtrage multicritères et recherche
- Tracking des progressions (quêtes, donjons, recherchés)
- Gestion des monnaies avec agrégations
- Validation de contrainte : pas 2 persos du même compte dans une team active
Design goals :
- Desktop-first, responsive tablette
- Dense en informations, inspiré outils pro
- Filtres sidebar façon e-commerce
- Multi-select et bulk actions façon Gmail
- shadcn/ui comme design system
Peux-tu créer les wireframes ou maquettes pour les écrans principaux :
1. Liste des personnages avec filtres
2. Fiche personnage (infos + progressions + monnaies)
3. Gestion des teams avec validation contrainte
Le PRD complet est disponible dans docs/prd.md
```
### Architect Prompt
```
Je travaille sur Dofus Manager, une application web full-stack pour gérer des personnages de MMORPG.
Stack technique validée :
- Framework : TanStack Start (React full-stack, TypeScript)
- ORM : Prisma avec PostgreSQL 16
- UI : shadcn/ui + TanStack Table
- Infra : Docker, Traefik, GitLab CI
Contexte métier :
- 60+ personnages, dizaines de comptes, plusieurs serveurs
- Teams avec contrainte : pas 2 persos du même compte simultanément
- Progressions (quêtes, donjons, recherchés) et monnaies à tracker
- Intégration API DofusDB pour données de référence
Besoins architecture :
1. Schéma Prisma complet pour les entités (Server, Account, Character, Team, ProgressionType, CurrencyType, etc.)
2. Structure du projet TanStack Start
3. Patterns pour server functions et data fetching
4. Stratégie de cache pour agrégations
5. Configuration Docker + GitLab CI
Le PRD complet avec les 6 epics et 27 stories est disponible dans docs/prd.md.
Peux-tu initier le mode architecture et proposer une conception technique ?
```

View File

@@ -0,0 +1,39 @@
# Checklist Results Report
## Executive Summary
| Metric | Value |
|--------|-------|
| **Overall PRD Completeness** | 95% |
| **MVP Scope Appropriateness** | Just Right |
| **Readiness for Architecture** | Ready |
| **DofusDB API** | ✅ Validée et documentée |
## Category Analysis
| Category | Status | Notes |
|----------|--------|-------|
| 1. Problem Definition & Context | PASS | Problème clairement articulé, utilisateur cible défini |
| 2. MVP Scope Definition | PASS | 6 epics bien délimités, scope MVP réaliste |
| 3. User Experience Requirements | PASS | Flows documentés, paradigmes d'interaction définis |
| 4. Functional Requirements | PASS | 13 FR + 8 NFR, tous testables |
| 5. Non-Functional Requirements | PARTIAL | Performance OK, sécurité minimale (mono-user) |
| 6. Epic & Story Structure | PASS | 6 epics séquentiels, 27 stories avec AC détaillés |
| 7. Technical Guidance | PASS | Stack définie, architecture monolith documentée |
| 8. Cross-Functional Requirements | PASS | Intégration DofusDB, schéma DB complet |
| 9. Clarity & Communication | PASS | Document structuré, terminologie cohérente |
## Issues Identified
| Priority | Issue | Status |
|----------|-------|--------|
| ~~HIGH~~ | ~~API DofusDB non validée~~ | ✅ Résolu — Documentation ajoutée |
| MEDIUM | Métriques de succès non formalisées | À définir post-MVP |
| MEDIUM | Stratégie backup non détaillée | À documenter dans architecture |
| LOW | Seed data à compléter | À préciser lors de l'implémentation |
## Final Decision
**✅ READY FOR ARCHITECT** — Le PRD est complet et prêt pour la phase d'architecture.
---

View File

@@ -0,0 +1,77 @@
# DofusDB API Reference
Documentation de l'API externe utilisée pour l'Epic 6.
## Base URL
`https://api.dofusdb.fr/`
## Caractéristiques techniques
- **Framework:** FeathersJS (REST API)
- **Pagination:** `$limit`, `$skip` (défaut: limit=10)
- **Filtrage:** Style MongoDB (`$regex`, `$in`, `$gt`, etc.)
- **Multilingue:** `name.fr`, `name.en`, `name.de`, `name.es`, `name.pt`
- **Authentification:** Aucune (API publique)
## Endpoints disponibles
| Endpoint | Total | Champs clés |
|----------|-------|-------------|
| `/dungeons` | 187 | id, name, optimalPlayerLevel, monsters[], subarea |
| `/quests` | 1978 | id, name, categoryId, levelMin, levelMax, steps[], rewards[] |
| `/achievements` | 2788 | id, name, description, level, points, categoryId, rewards[] |
| `/monsters` | 5093 | id, name, level, isBoss, stats, drops[], subareas[] |
| `/items` | — | id, name, typeId (23 = Dofus trophées) |
| `/quest-categories` | 43+ | id, name (régions, types de quêtes) |
| `/achievement-categories` | 129 | id, name, parentId |
## Mapping pour le PRD
| Besoin PRD | Endpoint DofusDB | Query |
|------------|------------------|-------|
| **Donjons** | `/dungeons` | `?$limit=200` |
| **Recherchés** | `/quests` | `?categoryId=6` |
| **Items Dofus** | `/items` | `?typeId=23&name.fr[$regex]=Dofus` |
| **Succès donjons** | `/achievements` | `?categoryId=3` |
## Dofus identifiés
| ID Item | Nom |
|---------|-----|
| 739 | Dofus Turquoise |
| 694 | Dofus Pourpre |
| 737 | Dofus Émeraude |
| 7043 | Dofus des Glaces |
| 18043 | Dofus Abyssal |
| 8698 | Dofus Nébuleux |
| 7112 | Dofus Tacheté |
| 6980 | Dofus Vulbis |
| 7754 | Dofus Ocre |
| 7114 | Dofus Ébène |
| 7115 | Dofus Ivoire |
## Exemples de requêtes
```bash
# Tous les donjons
curl "https://api.dofusdb.fr/dungeons?$limit=200"
# Quêtes de recherchés (Avis de recherche)
curl "https://api.dofusdb.fr/quests?categoryId=6"
# Items Dofus
curl "https://api.dofusdb.fr/items?typeId=23&name.fr[\$regex]=Dofus"
# Monstres boss
curl "https://api.dofusdb.fr/monsters?isBoss=true&$limit=50"
```
## Notes d'implémentation
- Les quêtes Dofus ne sont pas directement liées aux items Dofus dans l'API → nécessite un mapping manuel
- Les recherchés sont sous `categoryId=6` dans `/quests`
- Les noms sont multilingues : utiliser `name.fr` pour le français
- Pagination recommandée pour les gros volumes (achievements, monsters)
---

View File

@@ -0,0 +1,100 @@
# Epic 1: Foundation & Core Entities
**Goal:** Établir les fondations du projet (setup, Docker, Prisma, CI/CD) et implémenter le CRUD complet pour les entités de base : Serveurs, Comptes et Personnages. À la fin de cet epic, l'utilisateur peut créer, consulter, modifier et supprimer des serveurs, comptes et personnages.
## Story 1.1: Project Setup & Infrastructure
**As a** developer,
**I want** a fully configured TanStack Start project with Docker and GitLab CI,
**so that** I can start development with a working local environment and deployment pipeline.
**Acceptance Criteria:**
1. TanStack Start project initialized with TypeScript strict mode
2. Docker Compose configuration with app service and PostgreSQL 16
3. Prisma configured and connected to PostgreSQL
4. shadcn/ui installed with base components (Button, Input, Card, Table)
5. ESLint + Prettier configured with recommended rules
6. GitLab CI pipeline: build, lint, test stages
7. Dockerfile multi-stage pour production build
8. README avec instructions de setup local
9. Application démarre et affiche une page d'accueil "Dofus Manager"
## Story 1.2: Database Schema - Core Entities
**As a** developer,
**I want** a Prisma schema with Server, Account, and Character models,
**so that** the data structure is defined and migrations are ready.
**Acceptance Criteria:**
1. Model `Server`: id, name, createdAt, updatedAt
2. Model `Account`: id, name, ogrines (integer), createdAt, updatedAt
3. Model `Character`: id, name, class (enum 17 classes), level (1-200), serverId (FK), accountId (FK), createdAt, updatedAt
4. Enum `CharacterClass` avec les 17 classes Dofus
5. Relations définies : Character → Server (N:1), Character → Account (N:1)
6. Migration initiale générée et appliquée
7. Seed script avec données de test (2 serveurs, 3 comptes, 10 personnages)
## Story 1.3: Server CRUD
**As a** user,
**I want** to manage servers (create, view, edit, delete),
**so that** I can add the Dofus servers I play on.
**Acceptance Criteria:**
1. Page `/servers` affiche la liste des serveurs en tableau
2. Bouton "Ajouter" ouvre un formulaire modal de création
3. Formulaire avec champ nom (requis, unique)
4. Actions Edit/Delete sur chaque ligne (icônes au hover)
5. Confirmation avant suppression
6. Toast de confirmation après chaque action
7. Validation : nom non vide, unicité vérifiée côté serveur
8. Serveurs triés par nom alphabétique
## Story 1.4: Account CRUD
**As a** user,
**I want** to manage my Dofus accounts (create, view, edit, delete),
**so that** I can organize my characters by account.
**Acceptance Criteria:**
1. Page `/accounts` affiche la liste des comptes en tableau (nom, ogrines, nb personnages)
2. Bouton "Ajouter" ouvre un formulaire modal de création
3. Formulaire avec champs : nom (requis), ogrines (optionnel, défaut 0)
4. Actions Edit/Delete sur chaque ligne
5. Clic sur un compte navigue vers `/accounts/:id` (fiche détail)
6. Page détail affiche infos compte + liste des personnages associés
7. Suppression compte impossible si personnages associés (message d'erreur)
8. Toast de confirmation après chaque action
## Story 1.5: Character CRUD
**As a** user,
**I want** to manage my characters (create, view, edit, delete),
**so that** I can track all my Dofus characters.
**Acceptance Criteria:**
1. Page `/characters` affiche la liste des personnages en tableau (nom, classe, niveau, serveur, compte)
2. Bouton "Ajouter" ouvre un formulaire modal de création
3. Formulaire avec champs : nom (requis), classe (select), niveau (1-200), serveur (select), compte (select)
4. Actions Edit/Delete sur chaque ligne
5. Clic sur un personnage navigue vers `/characters/:id` (fiche détail)
6. Page détail affiche toutes les infos du personnage
7. Icônes de classe affichées (optionnel: images ou emojis)
8. Tableau paginé (20 items par page)
9. Toast de confirmation après chaque action
## Story 1.6: Navigation & Layout
**As a** user,
**I want** a consistent navigation layout,
**so that** I can easily move between sections of the app.
**Acceptance Criteria:**
1. Sidebar de navigation avec liens : Dashboard, Personnages, Comptes, Serveurs
2. Layout responsive : sidebar collapse sur mobile
3. Breadcrumb sur les pages de détail
4. Page active mise en évidence dans la sidebar
5. Header avec titre de l'application
6. Dark mode toggle (état persisté en localStorage)
---

View File

@@ -0,0 +1,78 @@
# Epic 2: Teams & Constraints
**Goal:** Implémenter la gestion complète des Teams avec la règle métier fondamentale : impossible d'avoir 2 personnages du même compte dans une team active. L'utilisateur peut créer des teams, y ajouter des personnages, et voir le statut de complétion.
## Story 2.1: Team Database Schema
**As a** developer,
**I want** a Prisma schema for Teams with many-to-many relation to Characters,
**so that** teams can be created and managed.
**Acceptance Criteria:**
1. Model `Team`: id, name, type (enum: MAIN, SUCCESS, PL, CUSTOM), isActive (boolean), createdAt, updatedAt
2. Relation many-to-many Team ↔ Character via table de jonction `TeamMember`
3. Model `TeamMember`: teamId, characterId, joinedAt
4. Enum `TeamType` avec les types identifiés (Main, Succès, PL, Custom)
5. Migration générée et appliquée
6. Seed script mis à jour avec 2-3 teams de test
## Story 2.2: Team CRUD - Basic
**As a** user,
**I want** to create, view, edit and delete teams,
**so that** I can organize my characters into groups.
**Acceptance Criteria:**
1. Page `/teams` affiche la liste des teams en tableau (nom, type, nb membres, statut actif)
2. Bouton "Ajouter" ouvre un formulaire modal de création
3. Formulaire avec champs : nom (requis), type (select), isActive (checkbox)
4. Actions Edit/Delete sur chaque ligne
5. Clic sur une team navigue vers `/teams/:id` (fiche détail)
6. Suppression team supprime aussi les TeamMember associés
7. Badge visuel pour teams actives vs inactives
8. Toast de confirmation après chaque action
## Story 2.3: Team Member Management
**As a** user,
**I want** to add and remove characters from a team,
**so that** I can compose my teams.
**Acceptance Criteria:**
1. Page `/teams/:id` affiche la liste des membres actuels
2. Bouton "Ajouter membre" ouvre un sélecteur de personnages
3. Sélecteur filtrable par nom, classe, compte, serveur
4. Multi-select possible pour ajouter plusieurs personnages à la fois
5. Bouton "Retirer" sur chaque membre pour le supprimer de la team
6. Affichage du compte de chaque personnage dans la liste des membres
7. Ordre des membres modifiable (drag & drop optionnel, sinon ordre d'ajout)
## Story 2.4: Account Constraint Validation
**As a** user,
**I want** the system to prevent adding two characters from the same account to an active team,
**so that** I respect the game's simultaneous play restriction.
**Acceptance Criteria:**
1. Lors de l'ajout d'un membre, vérification que son compte n'est pas déjà dans la team
2. Si conflit détecté : message d'erreur clair indiquant le personnage en conflit
3. Validation côté serveur (impossible de contourner)
4. Validation côté client pour feedback immédiat
5. La contrainte ne s'applique qu'aux teams **actives** (isActive = true)
6. Teams inactives peuvent avoir plusieurs persos du même compte (pour planification)
7. Lors du passage d'une team inactive → active : vérification des conflits
## Story 2.5: Team Status Overview
**As a** user,
**I want** to see a summary of each team's composition,
**so that** I can quickly assess my teams.
**Acceptance Criteria:**
1. Sur `/teams`, colonnes : nom, type, membres (count), statut, classes représentées
2. Sur `/teams/:id`, section récapitulative : nb membres, comptes utilisés, classes
3. Indicateur visuel si team incomplète (< 8 membres pour type MAIN)
4. Liste des comptes utilisés dans la team (pour éviter conflits lors de multi-boxing)
5. Affichage des classes sous forme d'icônes compactes
---

View File

@@ -0,0 +1,85 @@
# Epic 3: Filtering & Search
**Goal:** Ajouter un système de filtrage multicritères et de recherche textuelle sur la liste des personnages. L'utilisateur peut rapidement trouver les personnages qui correspondent à ses critères (classe, serveur, compte, team, etc.).
## Story 3.1: Filter Sidebar Component
**As a** user,
**I want** a sidebar with filter options on the characters list,
**so that** I can narrow down the displayed characters.
**Acceptance Criteria:**
1. Sidebar à gauche de la liste des personnages
2. Section "Classe" : checkboxes pour chaque classe (17 classes)
3. Section "Serveur" : checkboxes pour chaque serveur existant
4. Section "Compte" : checkboxes pour chaque compte existant
5. Section "Team" : checkboxes pour chaque team existante
6. Section "Niveau" : slider ou inputs min/max (1-200)
7. Bouton "Réinitialiser les filtres"
8. Sidebar collapsible sur mobile (bouton toggle)
9. Compteur de résultats mis à jour en temps réel
## Story 3.2: Filter Logic Implementation
**As a** developer,
**I want** server-side filtering with URL state,
**so that** filters are shareable and persist on refresh.
**Acceptance Criteria:**
1. Filtres stockés dans les query params de l'URL (ex: `?class=CRA,IOP&server=1`)
2. API endpoint accepte les paramètres de filtre
3. Requête Prisma optimisée avec WHERE dynamique
4. Filtres combinés en AND (classe ET serveur ET compte...)
5. Au sein d'un même filtre, valeurs combinées en OR (Cra OU Iop)
6. État des filtres synchronisé avec l'URL au changement
7. Chargement initial lit les filtres depuis l'URL
8. Debounce sur les changements pour éviter trop de requêtes
## Story 3.3: Text Search
**As a** user,
**I want** to search characters by name,
**so that** I can quickly find a specific character.
**Acceptance Criteria:**
1. Champ de recherche au-dessus du tableau
2. Recherche sur le nom du personnage (insensible à la casse)
3. Recherche également sur le nom du compte
4. Résultats filtrés en temps réel (debounce 300ms)
5. Recherche combinable avec les filtres sidebar
6. Icône "clear" pour vider la recherche
7. Placeholder : "Rechercher un personnage..."
8. Recherche stockée dans l'URL (`?q=...`)
## Story 3.4: Column Sorting
**As a** user,
**I want** to sort the characters table by clicking column headers,
**so that** I can organize the data as needed.
**Acceptance Criteria:**
1. Colonnes triables : nom, classe, niveau, serveur, compte
2. Clic sur header = tri ascendant, second clic = descendant, troisième = reset
3. Indicateur visuel de la colonne triée (flèche up/down)
4. Tri côté serveur pour performance
5. Tri par défaut : niveau descendant (200 en premier)
6. Tri stocké dans l'URL (`?sort=level&order=desc`)
7. Un seul tri actif à la fois
## Story 3.5: Saved Filter Presets
**As a** user,
**I want** to save and reuse filter combinations,
**so that** I don't have to reconfigure common filters.
**Acceptance Criteria:**
1. Bouton "Sauvegarder ce filtre" quand filtres actifs
2. Modal pour nommer le preset
3. Liste des presets sauvegardés dans la sidebar (section "Mes filtres")
4. Clic sur preset applique tous ses filtres
5. Bouton supprimer sur chaque preset
6. Presets stockés en base de données (model `FilterPreset`)
7. Limite de 10 presets maximum
8. Presets spécifiques à l'utilisateur (pour futur multi-user)
---

View File

@@ -0,0 +1,84 @@
# Epic 4: Progression Tracking
**Goal:** Implémenter le tracking des progressions par personnage : quêtes Dofus, donjons par paliers, et recherchés par région. L'utilisateur peut marquer les progressions comme complétées et voir les statistiques par team.
## Story 4.1: Progression Database Schema
**As a** developer,
**I want** a flexible schema for tracking character progressions,
**so that** different types of progressions can be managed uniformly.
**Acceptance Criteria:**
1. Model `ProgressionType`: id, category (enum: DOFUS_QUEST, DUNGEON, WANTED), name, region (nullable), levelRange (nullable), createdAt
2. Model `CharacterProgression`: characterId, progressionTypeId, completed (boolean), completedAt (nullable)
3. Enum `ProgressionCategory`: DOFUS_QUEST, DUNGEON, WANTED
4. Index composite sur (characterId, progressionTypeId) pour performance
5. Migration générée et appliquée
6. Seed script avec données de progression types :
- 10 quêtes Dofus (Turquoise, Pourpre, Émeraude, Glaces, Abyssal, Nébuleux, Domakuro, Dorigami, Tacheté, Vulbis)
- Donjons par paliers (1-50, 51-100, 101-150, 151-190, 191-200)
- Recherchés par région (Astrub, Amakna, Frigost I/II/III, etc.)
## Story 4.2: Character Progression View
**As a** user,
**I want** to see and edit a character's progressions on their detail page,
**so that** I can track what each character has completed.
**Acceptance Criteria:**
1. Section "Progressions" sur la page `/characters/:id`
2. Onglets par catégorie : Quêtes Dofus | Donjons | Recherchés
3. Liste des items avec checkbox pour marquer fait/pas fait
4. Date de complétion affichée si complété
5. Clic sur checkbox toggle l'état et sauvegarde immédiatement
6. Compteur de progression par catégorie (ex: "7/10 Dofus")
7. Filtres : Tous | Faits | Non faits
8. Items triés par nom ou par ordre logique (niveau pour donjons)
## Story 4.3: Bulk Progression Update
**As a** user,
**I want** to update progressions for multiple characters at once,
**so that** I can quickly mark a dungeon done for my whole team.
**Acceptance Criteria:**
1. Page `/progressions/bulk` accessible depuis le menu
2. Sélecteur de personnages (multi-select avec filtres)
3. Sélection possible par team entière (bouton "Sélectionner team X")
4. Sélecteur de progression type à mettre à jour
5. Action : "Marquer comme fait" ou "Marquer comme non fait"
6. Confirmation avant exécution avec récapitulatif (X personnages, progression Y)
7. Toast de succès avec nombre de mises à jour effectuées
8. Retour à la page précédente après action
## Story 4.4: Team Progression Status
**As a** user,
**I want** to see the progression status of my team for a specific objective,
**so that** I can see who still needs to complete it.
**Acceptance Criteria:**
1. Sur `/teams/:id`, nouvelle section "Statut des progressions"
2. Sélecteur de progression type (ex: "Dofus Turquoise")
3. Tableau : membres de la team avec statut (fait/pas fait) pour cette progression
4. Pourcentage global affiché (ex: "6/8 = 75%")
5. Indicateur visuel clair (vert = fait, rouge = pas fait)
6. Bouton "Marquer fait pour tous" pour bulk update depuis cette vue
7. Filtrable par catégorie de progression
## Story 4.5: Progression Filters in Character List
**As a** user,
**I want** to filter characters by progression status,
**so that** I can find who hasn't completed a specific objective.
**Acceptance Criteria:**
1. Nouvelle section dans la sidebar des filtres : "Progression"
2. Sélecteur de progression type
3. Options : "A fait" / "N'a pas fait"
4. Combinable avec les autres filtres existants
5. Exemple d'usage : "Montrer tous les Cra qui n'ont pas fait le Dofus Turquoise"
6. Compteur de résultats mis à jour
7. Filtre stocké dans l'URL
---

View File

@@ -0,0 +1,94 @@
# Epic 5: Currencies & Aggregations
**Goal:** Implémenter le tracking des monnaies par personnage (Doplons, Orichor, etc.) et afficher les totaux agrégés au niveau compte et global. L'utilisateur peut rapidement voir combien de chaque monnaie il possède au total.
## Story 5.1: Currency Database Schema
**As a** developer,
**I want** a schema for tracking currencies per character,
**so that** currency amounts can be stored and aggregated.
**Acceptance Criteria:**
1. Model `CurrencyType`: id, name, icon (nullable), createdAt
2. Model `CharacterCurrency`: characterId, currencyTypeId, amount (integer), updatedAt
3. Contrainte unique sur (characterId, currencyTypeId)
4. Migration générée et appliquée
5. Seed script avec les 8 monnaies identifiées :
- Doplons, Almatons, Orichor, Kamas de glace
- Perles des profondeurs, Alitons, Trukdivins, Pages calendrier
6. Index sur characterId pour requêtes d'agrégation
## Story 5.2: Character Currency View
**As a** user,
**I want** to see and edit a character's currencies on their detail page,
**so that** I can track each character's wealth.
**Acceptance Criteria:**
1. Section "Monnaies" sur la page `/characters/:id`
2. Liste des monnaies avec champ input numérique pour chaque
3. Modification inline avec sauvegarde au blur ou sur Enter
4. Indicateur de sauvegarde (loading spinner pendant save)
5. Validation : montant >= 0, entier uniquement
6. Affichage de l'icône/nom de chaque monnaie
7. Dernière mise à jour affichée par monnaie
## Story 5.3: Bulk Currency Update
**As a** user,
**I want** to update a currency for multiple characters at once,
**so that** I can quickly update after a group activity.
**Acceptance Criteria:**
1. Page `/currencies/bulk` accessible depuis le menu
2. Sélecteur de personnages (multi-select avec filtres, sélection par team)
3. Sélecteur de monnaie à mettre à jour
4. Mode d'opération : "Définir à" (valeur absolue) ou "Ajouter/Soustraire" (delta)
5. Champ pour la valeur
6. Confirmation avant exécution
7. Toast de succès avec récapitulatif
8. Historique des bulk updates (optionnel, pour audit)
## Story 5.4: Account Currency Totals
**As a** user,
**I want** to see the total currencies for each account,
**so that** I can see my wealth per account.
**Acceptance Criteria:**
1. Sur `/accounts/:id`, section "Total des monnaies"
2. Tableau avec chaque monnaie et le total pour ce compte
3. Total = somme des monnaies de tous les personnages du compte
4. Mise à jour automatique quand les données changent
5. Affichage compact (icône + montant)
6. Zéro affiché si aucun personnage n'a cette monnaie
## Story 5.5: Global Currency Dashboard
**As a** user,
**I want** to see my total currencies across all characters,
**so that** I have a global view of my in-game wealth.
**Acceptance Criteria:**
1. Widget sur le Dashboard (page d'accueil) : "Mes monnaies"
2. Liste de toutes les monnaies avec total global
3. Total global = somme sur tous les personnages
4. Possibilité de cliquer pour voir le détail par compte
5. Drill-down : compte → personnages avec leurs montants
6. Données mises en cache pour performance (invalidation au changement)
## Story 5.6: Currency Management (Admin)
**As a** user,
**I want** to add or remove currency types,
**so that** I can adapt to game updates adding new currencies.
**Acceptance Criteria:**
1. Page `/settings/currencies` pour gérer les types de monnaies
2. Liste des monnaies existantes
3. Formulaire d'ajout : nom, icône (optionnel)
4. Suppression possible si aucun personnage n'a cette monnaie
5. Avertissement si suppression avec données existantes
6. Ordre d'affichage modifiable (drag & drop ou champ order)
---

View File

@@ -0,0 +1,94 @@
# Epic 6: DofusDB Integration
**Goal:** Intégrer l'API DofusDB pour importer automatiquement les données de référence du jeu (quêtes, donjons, succès, recherchés). L'utilisateur n'a plus besoin de saisir manuellement ces informations.
## Story 6.1: DofusDB API Client
**As a** developer,
**I want** a typed HTTP client for the DofusDB API,
**so that** I can fetch game reference data reliably.
**Acceptance Criteria:**
1. Module `lib/dofusdb.ts` avec client HTTP typé
2. Types TypeScript pour les réponses API (quêtes, donjons, succès, etc.)
3. Gestion des erreurs API (timeout, rate limit, 404)
4. Configuration via variables d'environnement (API URL, éventuels tokens)
5. Retry automatique en cas d'échec temporaire (max 3 retries)
6. Logging des appels API pour debug
7. Tests unitaires avec mocks des réponses API
## Story 6.2: Dungeon Data Import
**As a** user,
**I want** to import the list of dungeons from DofusDB,
**so that** I don't have to add them manually.
**Acceptance Criteria:**
1. Endpoint ou script pour importer les donjons depuis DofusDB
2. Mapping des données DofusDB vers le model `ProgressionType` (category: DUNGEON)
3. Import des métadonnées : nom, niveau requis, zone/région
4. Gestion des doublons : mise à jour si existant, création sinon
5. Rapport d'import : X créés, Y mis à jour, Z erreurs
6. Bouton "Importer donjons" dans `/settings/data`
7. Indicateur de dernière synchronisation
## Story 6.3: Quest Data Import
**As a** user,
**I want** to import Dofus quest chains from DofusDB,
**so that** I can track my progress on main quests.
**Acceptance Criteria:**
1. Import des quêtes Dofus (les 10 quêtes principales identifiées)
2. Mapping vers `ProgressionType` (category: DOFUS_QUEST)
3. Import des métadonnées : nom, Dofus associé
4. Option de filtrer quelles quêtes importer (sélection manuelle ou toutes)
5. Gestion des doublons
6. Bouton "Importer quêtes" dans `/settings/data`
7. Rapport d'import
## Story 6.4: Wanted Posters Import
**As a** user,
**I want** to import wanted poster data from DofusDB,
**so that** I can track bounties by region.
**Acceptance Criteria:**
1. Import des recherchés par région depuis DofusDB
2. Mapping vers `ProgressionType` (category: WANTED)
3. Métadonnées : nom, région associée
4. Regroupement par région (Astrub, Amakna, Frigost I/II/III, etc.)
5. Gestion des doublons
6. Bouton "Importer recherchés" dans `/settings/data`
7. Rapport d'import
## Story 6.5: Sync Settings & Automation
**As a** user,
**I want** to configure automatic synchronization with DofusDB,
**so that** my reference data stays up to date.
**Acceptance Criteria:**
1. Page `/settings/data` avec configuration de sync
2. Option sync manuelle (boutons par type de données)
3. Option sync automatique périodique (daily, weekly, disabled)
4. Cron job ou scheduled task pour sync auto
5. Notification (toast ou log) après sync automatique
6. Historique des syncs (date, type, résultat)
7. Option de réinitialiser toutes les données de référence
## Story 6.6: Data Conflict Resolution
**As a** developer,
**I want** a strategy for handling conflicts between local and API data,
**so that** user modifications aren't lost during sync.
**Acceptance Criteria:**
1. Les `ProgressionType` importés ont un flag `source: API | MANUAL`
2. Sync API ne modifie que les entrées `source: API`
3. Entrées `source: MANUAL` préservées lors du sync
4. Option de forcer l'écrasement (avec confirmation)
5. Détection des entrées supprimées de l'API (soft delete ou warning)
6. Log des conflits détectés pour review
---

12
docs/prd/epic-list.md Normal file
View File

@@ -0,0 +1,12 @@
# Epic List
| # | Epic | Objectif |
|---|------|----------|
| **1** | **Foundation & Core Entities** | Établir le projet, le schéma DB, et le CRUD de base pour Serveurs, Comptes et Personnages |
| **2** | **Teams & Constraints** | Implémenter la gestion des Teams avec validation de la contrainte compte |
| **3** | **Filtering & Search** | Ajouter les filtres multicritères et la recherche textuelle sur la liste des personnages |
| **4** | **Progression Tracking** | Tracker les progressions (quêtes Dofus, donjons, recherchés) par personnage |
| **5** | **Currencies & Aggregations** | Gérer les monnaies par personnage et afficher les totaux agrégés |
| **6** | **DofusDB Integration** | Intégrer l'API DofusDB pour les données de référence |
---

View File

@@ -0,0 +1,25 @@
# Goals and Background Context
## Goals
- **Remplacer le tableur Excel** de gestion de 60+ personnages Dofus par une application web moderne et maintenable
- **Offrir une vue d'ensemble claire** de tous les personnages avec filtrage multicritères et recherche instantanée
- **Automatiser la gestion des données** via intégration avec l'API DofusDB (quêtes, donjons, succès)
- **Faciliter les mises à jour groupées** (bulk update) pour réduire drastiquement le temps de maintenance
- **Valider automatiquement les contraintes de compte** (pas 2 personnages du même compte simultanément dans une team)
- **Tracker les progressions** (quêtes Dofus, donjons, recherchés, monnaies) par personnage et par team
## Background Context
Theo est un joueur de Dofus gérant **60+ personnages niveau 200** répartis sur plusieurs dizaines de comptes sur plusieurs serveurs (principalement Imagiro). Actuellement, cette gestion est faite via un tableur Excel avec les personnages en colonnes horizontales, ce qui rend la visualisation impossible sans scroll excessif, les modifications fragiles (risque de casser le formatage), et la règle métier fondamentale du jeu ("pas 2 persos du même compte simultanément") gérée uniquement mentalement.
L'application remplacera ce tableur par un système web permettant la gestion CRUD des comptes, personnages, serveurs et teams, avec des filtres avancés façon e-commerce, des actions groupées, et une intégration avec DofusDB pour éliminer la saisie manuelle des données de référence (quêtes, donjons, succès).
## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2026-01-17 | 0.1 | Création initiale du PRD | John (PM) |
| 2026-01-17 | 0.2 | Ajout documentation API DofusDB (endpoints validés) | John (PM) |
---

80
docs/prd/index.md Normal file
View File

@@ -0,0 +1,80 @@
# Dofus Manager - Product Requirements Document (PRD)
## Table of Contents
- [Dofus Manager - Product Requirements Document (PRD)](#table-of-contents)
- [Goals and Background Context](./goals-and-background-context.md)
- [Goals](./goals-and-background-context.md#goals)
- [Background Context](./goals-and-background-context.md#background-context)
- [Change Log](./goals-and-background-context.md#change-log)
- [Requirements](./requirements.md)
- [Functional Requirements](./requirements.md#functional-requirements)
- [Non-Functional Requirements](./requirements.md#non-functional-requirements)
- [User Interface Design Goals](./user-interface-design-goals.md)
- [Overall UX Vision](./user-interface-design-goals.md#overall-ux-vision)
- [Key Interaction Paradigms](./user-interface-design-goals.md#key-interaction-paradigms)
- [Core Screens and Views](./user-interface-design-goals.md#core-screens-and-views)
- [Accessibility](./user-interface-design-goals.md#accessibility)
- [Branding](./user-interface-design-goals.md#branding)
- [Target Device and Platforms](./user-interface-design-goals.md#target-device-and-platforms)
- [Technical Assumptions](./technical-assumptions.md)
- [Repository Structure: Monorepo](./technical-assumptions.md#repository-structure-monorepo)
- [Service Architecture: Monolith Full-Stack](./technical-assumptions.md#service-architecture-monolith-full-stack)
- [Testing Requirements: Unit + Integration](./technical-assumptions.md#testing-requirements-unit-integration)
- [Additional Technical Assumptions and Requests](./technical-assumptions.md#additional-technical-assumptions-and-requests)
- [DofusDB API Reference](./dofusdb-api-reference.md)
- [Base URL](./dofusdb-api-reference.md#base-url)
- [Caractéristiques techniques](./dofusdb-api-reference.md#caractristiques-techniques)
- [Endpoints disponibles](./dofusdb-api-reference.md#endpoints-disponibles)
- [Mapping pour le PRD](./dofusdb-api-reference.md#mapping-pour-le-prd)
- [Dofus identifiés](./dofusdb-api-reference.md#dofus-identifis)
- [Exemples de requêtes](./dofusdb-api-reference.md#exemples-de-requtes)
- [Notes d'implémentation](./dofusdb-api-reference.md#notes-dimplmentation)
- [Epic List](./epic-list.md)
- [Epic 1: Foundation & Core Entities](./epic-1-foundation-core-entities.md)
- [Story 1.1: Project Setup & Infrastructure](./epic-1-foundation-core-entities.md#story-11-project-setup-infrastructure)
- [Story 1.2: Database Schema - Core Entities](./epic-1-foundation-core-entities.md#story-12-database-schema-core-entities)
- [Story 1.3: Server CRUD](./epic-1-foundation-core-entities.md#story-13-server-crud)
- [Story 1.4: Account CRUD](./epic-1-foundation-core-entities.md#story-14-account-crud)
- [Story 1.5: Character CRUD](./epic-1-foundation-core-entities.md#story-15-character-crud)
- [Story 1.6: Navigation & Layout](./epic-1-foundation-core-entities.md#story-16-navigation-layout)
- [Epic 2: Teams & Constraints](./epic-2-teams-constraints.md)
- [Story 2.1: Team Database Schema](./epic-2-teams-constraints.md#story-21-team-database-schema)
- [Story 2.2: Team CRUD - Basic](./epic-2-teams-constraints.md#story-22-team-crud-basic)
- [Story 2.3: Team Member Management](./epic-2-teams-constraints.md#story-23-team-member-management)
- [Story 2.4: Account Constraint Validation](./epic-2-teams-constraints.md#story-24-account-constraint-validation)
- [Story 2.5: Team Status Overview](./epic-2-teams-constraints.md#story-25-team-status-overview)
- [Epic 3: Filtering & Search](./epic-3-filtering-search.md)
- [Story 3.1: Filter Sidebar Component](./epic-3-filtering-search.md#story-31-filter-sidebar-component)
- [Story 3.2: Filter Logic Implementation](./epic-3-filtering-search.md#story-32-filter-logic-implementation)
- [Story 3.3: Text Search](./epic-3-filtering-search.md#story-33-text-search)
- [Story 3.4: Column Sorting](./epic-3-filtering-search.md#story-34-column-sorting)
- [Story 3.5: Saved Filter Presets](./epic-3-filtering-search.md#story-35-saved-filter-presets)
- [Epic 4: Progression Tracking](./epic-4-progression-tracking.md)
- [Story 4.1: Progression Database Schema](./epic-4-progression-tracking.md#story-41-progression-database-schema)
- [Story 4.2: Character Progression View](./epic-4-progression-tracking.md#story-42-character-progression-view)
- [Story 4.3: Bulk Progression Update](./epic-4-progression-tracking.md#story-43-bulk-progression-update)
- [Story 4.4: Team Progression Status](./epic-4-progression-tracking.md#story-44-team-progression-status)
- [Story 4.5: Progression Filters in Character List](./epic-4-progression-tracking.md#story-45-progression-filters-in-character-list)
- [Epic 5: Currencies & Aggregations](./epic-5-currencies-aggregations.md)
- [Story 5.1: Currency Database Schema](./epic-5-currencies-aggregations.md#story-51-currency-database-schema)
- [Story 5.2: Character Currency View](./epic-5-currencies-aggregations.md#story-52-character-currency-view)
- [Story 5.3: Bulk Currency Update](./epic-5-currencies-aggregations.md#story-53-bulk-currency-update)
- [Story 5.4: Account Currency Totals](./epic-5-currencies-aggregations.md#story-54-account-currency-totals)
- [Story 5.5: Global Currency Dashboard](./epic-5-currencies-aggregations.md#story-55-global-currency-dashboard)
- [Story 5.6: Currency Management (Admin)](./epic-5-currencies-aggregations.md#story-56-currency-management-admin)
- [Epic 6: DofusDB Integration](./epic-6-dofusdb-integration.md)
- [Story 6.1: DofusDB API Client](./epic-6-dofusdb-integration.md#story-61-dofusdb-api-client)
- [Story 6.2: Dungeon Data Import](./epic-6-dofusdb-integration.md#story-62-dungeon-data-import)
- [Story 6.3: Quest Data Import](./epic-6-dofusdb-integration.md#story-63-quest-data-import)
- [Story 6.4: Wanted Posters Import](./epic-6-dofusdb-integration.md#story-64-wanted-posters-import)
- [Story 6.5: Sync Settings & Automation](./epic-6-dofusdb-integration.md#story-65-sync-settings-automation)
- [Story 6.6: Data Conflict Resolution](./epic-6-dofusdb-integration.md#story-66-data-conflict-resolution)
- [Checklist Results Report](./checklist-results-report.md)
- [Executive Summary](./checklist-results-report.md#executive-summary)
- [Category Analysis](./checklist-results-report.md#category-analysis)
- [Issues Identified](./checklist-results-report.md#issues-identified)
- [Final Decision](./checklist-results-report.md#final-decision)
- [Next Steps](./next-steps.md)
- [UX Expert Prompt](./next-steps.md#ux-expert-prompt)
- [Architect Prompt](./next-steps.md#architect-prompt)

57
docs/prd/next-steps.md Normal file
View File

@@ -0,0 +1,57 @@
# Next Steps
## UX Expert Prompt
```
Je travaille sur Dofus Manager, une application web de gestion de personnages pour le MMORPG Dofus.
Contexte : L'application remplace un tableur Excel pour gérer 60+ personnages sur plusieurs comptes. Les fonctionnalités clés sont :
- CRUD pour Serveurs, Comptes, Personnages, Teams
- Filtrage multicritères et recherche
- Tracking des progressions (quêtes, donjons, recherchés)
- Gestion des monnaies avec agrégations
- Validation de contrainte : pas 2 persos du même compte dans une team active
Design goals :
- Desktop-first, responsive tablette
- Dense en informations, inspiré outils pro
- Filtres sidebar façon e-commerce
- Multi-select et bulk actions façon Gmail
- shadcn/ui comme design system
Peux-tu créer les wireframes ou maquettes pour les écrans principaux :
1. Liste des personnages avec filtres
2. Fiche personnage (infos + progressions + monnaies)
3. Gestion des teams avec validation contrainte
Le PRD complet est disponible dans docs/prd.md
```
## Architect Prompt
```
Je travaille sur Dofus Manager, une application web full-stack pour gérer des personnages de MMORPG.
Stack technique validée :
- Framework : TanStack Start (React full-stack, TypeScript)
- ORM : Prisma avec PostgreSQL 16
- UI : shadcn/ui + TanStack Table
- Infra : Docker, Traefik, GitLab CI
Contexte métier :
- 60+ personnages, dizaines de comptes, plusieurs serveurs
- Teams avec contrainte : pas 2 persos du même compte simultanément
- Progressions (quêtes, donjons, recherchés) et monnaies à tracker
- Intégration API DofusDB pour données de référence
Besoins architecture :
1. Schéma Prisma complet pour les entités (Server, Account, Character, Team, ProgressionType, CurrencyType, etc.)
2. Structure du projet TanStack Start
3. Patterns pour server functions et data fetching
4. Stratégie de cache pour agrégations
5. Configuration Docker + GitLab CI
Le PRD complet avec les 6 epics et 27 stories est disponible dans docs/prd.md.
Peux-tu initier le mode architecture et proposer une conception technique ?
```

49
docs/prd/requirements.md Normal file
View File

@@ -0,0 +1,49 @@
# Requirements
## Functional Requirements
- **FR1:** Le système doit permettre la création, lecture, modification et suppression (CRUD) des **comptes** avec les attributs : nom, ogrines, récompenses succès débloquées (Dofus, ressources).
- **FR2:** Le système doit permettre la gestion CRUD des **personnages** avec les attributs : pseudo, classe (17 classes Dofus), niveau, serveur associé, compte associé.
- **FR3:** Le système doit permettre la gestion CRUD des **teams** avec validation automatique de la contrainte "pas 2 personnages du même compte dans une team active".
- **FR4:** Le système doit offrir un **filtrage multicritères** des personnages par : classe, niveau, compte, team, serveur, statut de progression (quêtes, donjons, recherchés).
- **FR5:** Le système doit permettre la **recherche textuelle** sur les noms de personnages, comptes et teams.
- **FR6:** Le système doit permettre les **mises à jour groupées (bulk update)** : cocher/décocher plusieurs progressions pour une sélection de personnages ou une team entière.
- **FR7:** Le système doit tracker les **progressions par personnage** : quêtes Dofus (Turquoise, Pourpre, Émeraude, etc.), donjons par paliers avec types de succès, recherchés par région.
- **FR8:** Le système doit tracker les **monnaies par personnage** : Doplons, Almatons, Orichor, Kamas de glace, Perles des profondeurs, Alitons, Trukdivins, Pages calendrier.
- **FR9:** Le système doit afficher les **totaux agrégés des monnaies** au niveau compte et global.
- **FR10:** Le système doit s'intégrer avec **l'API DofusDB** pour importer les données de référence (liste des quêtes, donjons, succès, recherchés).
- **FR11:** Le système doit afficher une **vue statut team** avec pourcentage de complétion par objectif (ex: "Dofus Turquoise: 6/8 persos = 75%").
- **FR12:** Le système doit gérer les **métiers par couple compte+serveur** (et non par personnage) avec niveau de maîtrise.
- **FR13:** Le système doit permettre la gestion CRUD des **serveurs** (ex: Imagiro, Jahash, Draconiros) avec possibilité d'en ajouter de nouveaux.
## Non-Functional Requirements
- **NFR1:** L'application doit être **responsive** et utilisable sur desktop et tablette (usage sur second écran pendant le jeu).
- **NFR2:** L'application doit offrir une **latence de réponse < 500ms** pour les opérations courantes (filtrage, CRUD).
- **NFR3:** L'application doit supporter **100+ personnages** sans dégradation notable des performances.
- **NFR4:** L'application doit être **auto-hébergeable** sur un serveur dédié personnel via Docker.
- **NFR5:** L'application doit utiliser **PostgreSQL** comme base de données pour la persistance.
- **NFR6:** L'application doit être développée avec **React + TanStack Start** (full-stack TypeScript).
- **NFR7:** Les données doivent être **sauvegardables et restaurables** facilement (backup PostgreSQL).
- **NFR8:** L'application doit fonctionner en **mode mono-utilisateur** (pas d'authentification multi-users dans le MVP).
---

View File

@@ -0,0 +1,62 @@
# Technical Assumptions
## Repository Structure: Monorepo
Projet organisé en **monorepo** :
```
/
├── src/
│ ├── routes/ # Pages et API routes (TanStack Start)
│ ├── components/ # Composants React réutilisables
│ ├── lib/ # Utilitaires, clients API, helpers
│ └── server/ # Server functions, services
├── prisma/ # Schéma et migrations Prisma
├── docker/ # Configuration Docker
└── docs/ # Documentation projet
```
## Service Architecture: Monolith Full-Stack
**Architecture monolithique** avec TanStack Start :
- **Frontend** : React avec TanStack Router (file-based routing)
- **Backend** : Server functions intégrées à TanStack Start
- **Base de données** : PostgreSQL avec Prisma ORM
## Testing Requirements: Unit + Integration
| Type | Scope | Outils |
|------|-------|--------|
| **Unit** | Logique métier, validations, helpers | Vitest |
| **Integration** | API routes, queries DB | Vitest + testcontainers |
| **E2E** | Non prioritaire MVP | (Playwright en V2) |
## Additional Technical Assumptions and Requests
**Stack technique :**
- **Framework** : TanStack Start (React full-stack)
- **ORM** : Prisma (type-safe, migrations robustes, écosystème mature)
- **UI Components** : shadcn/ui (composants copiés, personnalisables)
- **Tables** : TanStack Table (tri, filtres, pagination)
- **Database** : PostgreSQL 16+
- **Container** : Docker + Docker Compose
**Infrastructure :**
- **Reverse proxy** : Traefik (existant sur le serveur)
- **CI/CD** : GitLab personnel (pipelines de build et déploiement)
- **Hébergement** : Serveur dédié personnel
**Intégration externe :**
- **DofusDB API** : Client HTTP pour récupérer les données de référence
- Sync manuelle ou cron pour mise à jour des données de jeu
**Conventions de code :**
- TypeScript strict mode
- ESLint + Prettier
- Conventional commits (feat:, fix:, chore:, etc.)
**Déploiement :**
- Docker Compose (app + postgres)
- Pipeline GitLab CI pour build et push des images
- Labels Traefik pour routing automatique
---

View File

@@ -0,0 +1,51 @@
# User Interface Design Goals
## Overall UX Vision
L'application doit offrir une expérience **efficace et dense en informations**, inspirée des outils de gestion de données professionnels. L'objectif est de permettre à l'utilisateur de :
- Trouver rapidement l'information cherchée (quel perso n'a pas fait X ?)
- Effectuer des modifications en masse sans friction
- Avoir une vue d'ensemble claire malgré le volume de données (60+ personnages)
Le design privilégie la **fonctionnalité sur l'esthétique** : interface sobre, contrastes clairs, densité d'information élevée, navigation rapide.
## Key Interaction Paradigms
- **Filtres sidebar façon e-commerce** — Panel latéral avec facettes cliquables (classe, serveur, team, compte, statut)
- **Multi-select façon Gmail** — Checkboxes pour sélection multiple + barre d'actions groupées
- **Tables interactives** — Tri, resize colonnes, pagination, colonnes masquables
- **Actions au survol** — Boutons edit/delete apparaissent au hover pour réduire le bruit visuel
- **Drill-down progressif** — Liste → Fiche détaillée → Sous-sections (progressions, monnaies)
- **Feedback immédiat** — Toasts pour confirmations, indicateurs de chargement, états vides informatifs
## Core Screens and Views
1. **Dashboard** — Vue d'accueil avec KPIs (total persos, teams, progression globale)
2. **Liste Personnages** — Vue principale avec filtres, recherche, tableau paginé
3. **Fiche Personnage** — Détails complets : infos, progressions, monnaies, teams
4. **Liste Comptes** — Gestion des comptes avec leurs personnages associés
5. **Fiche Compte** — Détails compte : ogrines, métiers (par serveur), récompenses
6. **Liste Teams** — Toutes les teams avec statut de complétion
7. **Fiche Team** — Membres, validation contraintes, % progression par objectif
8. **Gestion Serveurs** — CRUD des serveurs disponibles
9. **Données de référence** — Gestion des quêtes/donjons/recherchés (sync DofusDB)
## Accessibility
**Niveau cible : Aucun (pas de conformité WCAG requise)**
Application à usage personnel. Bonnes pratiques de base respectées : contrastes suffisants, navigation clavier, labels sur formulaires.
## Branding
**Aucun branding spécifique.** Design system sobre et moderne (shadcn/ui ou similaire), palette neutre, pas de thématique Dofus (éviter copyright), focus sur lisibilité.
## Target Device and Platforms
**Web Responsive (Desktop-first)**
- **Priorité 1 : Desktop** — Usage principal sur grand écran pendant les sessions de jeu
- **Priorité 2 : Tablette** — Consultation occasionnelle
- **Priorité 3 : Mobile** — Consultation basique acceptable
---