Compare commits
2 Commits
0c3a54c62c
...
2669fb9865
| Author | SHA1 | Date | |
|---|---|---|---|
| 2669fb9865 | |||
| fcbd9d0533 |
@@ -19,16 +19,14 @@
|
|||||||
|
|
||||||
### ⚡ Problèmes de Performance
|
### ⚡ Problèmes de Performance
|
||||||
|
|
||||||
#### 🔴 Critique - N+1 API Calls dans getLibraries
|
|
||||||
**Impact:** Fort | **Fichiers:** `src/lib/services/library.service.ts:22-46`
|
|
||||||
|
|
||||||
Les appels pour récupérer le count des livres sont parallèles (Promise.all), mais on pourrait utiliser l'endpoint Komga `expand=booksCount` si disponible.
|
|
||||||
|
|
||||||
#### 🟡 Cache préférences (IMPACT: MOYEN)
|
#### 🟡 Cache préférences (IMPACT: MOYEN)
|
||||||
**Symptôme:** Chaque lecture de préférences = 1 query DB
|
**Symptôme:** Chaque lecture de préférences = 1 query DB
|
||||||
|
|
||||||
**Fichier:** `src/lib/services/preferences.service.ts`
|
**Fichier:** `src/lib/services/preferences.service.ts`
|
||||||
|
|
||||||
|
#### 🟢 N+1 API Calls - résolu avec cache
|
||||||
|
Les appels pour récupérer le count des livres sont parallèles (Promise.all) + cache Next.js (0-2ms). Plus critique qu'avant.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 🔒 Problemes de Securite
|
### 🔒 Problemes de Securite
|
||||||
@@ -48,21 +46,18 @@ const authHeader: string = Buffer.from(`${data.username}:${data.password}`).toSt
|
|||||||
|
|
||||||
**Solution:** Ajouter `rate-limiter-flexible` pour limiter les requêtes par IP/user
|
**Solution:** Ajouter `rate-limiter-flexible` pour limiter les requêtes par IP/user
|
||||||
|
|
||||||
#### 🟡 Pas de sanitization des inputs
|
|
||||||
**Impact:** MEDIUM | **Fichiers:** `library.service.ts`, `series.service.ts`
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ⚠️ Autres Problemes
|
### ⚠️ Autres Problemes
|
||||||
|
|
||||||
|
#### 🟡 Appels doublons (architecture Next.js)
|
||||||
|
**Impact:** Moyen | **Fichier:** `layout.tsx`
|
||||||
|
|
||||||
|
Le layout + les pages font des appels séparés → appels doublons. Résolu en partie par le cache.
|
||||||
|
|
||||||
#### Service Worker double-cache (IMPACT: FAIBLE)
|
#### Service Worker double-cache (IMPACT: FAIBLE)
|
||||||
**Symptôme:** Conflit entre cache SW et navigateur
|
**Symptôme:** Conflit entre cache SW et navigateur
|
||||||
|
|
||||||
**Fichier:** `public/sw.js` (ligne 528-536)
|
|
||||||
|
|
||||||
#### RequestDeduplicationService non utilise
|
|
||||||
**Impact:** Moyen | **Fichier:** `src/lib/services/request-deduplication.service.ts`
|
|
||||||
|
|
||||||
#### getHomeData echoue completement si une requete echoue
|
#### getHomeData echoue completement si une requete echoue
|
||||||
**Impact:** Fort | **Fichier:** `src/app/api/komga/home/route.ts`
|
**Impact:** Fort | **Fichier:** `src/app/api/komga/home/route.ts`
|
||||||
|
|
||||||
@@ -73,13 +68,13 @@ const authHeader: string = Buffer.from(`${data.username}:${data.password}`).toSt
|
|||||||
### ✅ Phase 2: Performance (COMPLETEE)
|
### ✅ Phase 2: Performance (COMPLETEE)
|
||||||
- **Cache serveur API via fetchFromApi avec option `revalidate`**
|
- **Cache serveur API via fetchFromApi avec option `revalidate`**
|
||||||
- Fichiers modifiés:
|
- Fichiers modifiés:
|
||||||
- `src/lib/services/base-api.service.ts` - ajout option `revalidate` dans fetch
|
- `src/lib/services/base-api.service.ts` - ajout option `revalidate` dans fetch + CACHE_DEBUG
|
||||||
- `src/lib/services/library.service.ts` - CACHE_TTL = 300s (5 min)
|
- `src/lib/services/library.service.ts` - CACHE_TTL = 300s (5 min)
|
||||||
- `src/lib/services/home.service.ts` - CACHE_TTL = 120s (2 min)
|
- `src/lib/services/home.service.ts` - CACHE_TTL = 120s (2 min)
|
||||||
- `src/lib/services/series.service.ts` - CACHE_TTL = 120s (2 min)
|
- `src/lib/services/series.service.ts` - CACHE_TTL = 120s (2 min)
|
||||||
- `src/lib/services/book.service.ts` - CACHE_TTL = 60s (1 min)
|
- `src/lib/services/book.service.ts` - CACHE_TTL = 60s (1 min)
|
||||||
|
|
||||||
### Phase 1: Securite (Priorite HAUTE)
|
### Phase 1: Securite (PRIORITE SUIVANTE)
|
||||||
|
|
||||||
1. **Chiffrer les identifiants Komga**
|
1. **Chiffrer les identifiants Komga**
|
||||||
```typescript
|
```typescript
|
||||||
|
|||||||
18
package.json
18
package.json
@@ -37,14 +37,14 @@
|
|||||||
"i18next-browser-languagedetector": "^8.0.4",
|
"i18next-browser-languagedetector": "^8.0.4",
|
||||||
"lucide-react": "^0.487.0",
|
"lucide-react": "^0.487.0",
|
||||||
"mongodb": "^6.20.0",
|
"mongodb": "^6.20.0",
|
||||||
"next": "^15.5.9",
|
"next": "^16.1.6",
|
||||||
"next-auth": "^5.0.0-beta.30",
|
"next-auth": "^5.0.0-beta.30",
|
||||||
"next-themes": "0.2.1",
|
"next-themes": "0.2.1",
|
||||||
"photoswipe": "^5.4.4",
|
"photoswipe": "^5.4.4",
|
||||||
"pino": "^10.1.0",
|
"pino": "^10.1.0",
|
||||||
"pino-pretty": "^13.1.2",
|
"pino-pretty": "^13.1.2",
|
||||||
"react": "19.2.0",
|
"react": "19.2.4",
|
||||||
"react-dom": "19.2.0",
|
"react-dom": "19.2.4",
|
||||||
"react-i18next": "^15.4.1",
|
"react-i18next": "^15.4.1",
|
||||||
"sharp": "0.33.2",
|
"sharp": "0.33.2",
|
||||||
"tailwind-merge": "^3.0.2",
|
"tailwind-merge": "^3.0.2",
|
||||||
@@ -54,13 +54,13 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "24.7.2",
|
"@types/node": "24.7.2",
|
||||||
"@types/react": "19.2.2",
|
"@types/react": "19.2.14",
|
||||||
"@types/react-dom": "19.2.2",
|
"@types/react-dom": "19.2.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.24.0",
|
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
||||||
"@typescript-eslint/parser": "6.21.0",
|
"@typescript-eslint/parser": "8.56.1",
|
||||||
"autoprefixer": "10.4.17",
|
"autoprefixer": "10.4.17",
|
||||||
"eslint": "8.56.0",
|
"eslint": "9.39.3",
|
||||||
"eslint-config-next": "15.2.0",
|
"eslint-config-next": "16.1.6",
|
||||||
"eslint-config-prettier": "10.0.1",
|
"eslint-config-prettier": "10.0.1",
|
||||||
"eslint-plugin-typescript-sort-keys": "^3.3.0",
|
"eslint-plugin-typescript-sort-keys": "^3.3.0",
|
||||||
"eslint-plugin-unused-imports": "^4.1.4",
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
|
|||||||
1841
pnpm-lock.yaml
generated
1841
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -51,10 +51,4 @@ const logger = pino({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Prevent memory leaks in development (Node.js runtime only)
|
|
||||||
if (!isProduction && typeof process.stdout !== "undefined") {
|
|
||||||
process.stdout.setMaxListeners?.(20);
|
|
||||||
process.stderr.setMaxListeners?.(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default logger;
|
export default logger;
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
@@ -11,7 +15,7 @@
|
|||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "react-jsx",
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
@@ -19,9 +23,20 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": [
|
||||||
|
"./src/*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
"include": [
|
||||||
"exclude": ["node_modules", "temp"]
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts",
|
||||||
|
".next/dev/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"temp"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user