feat: perf optimisation
Some checks failed
Deploy with Docker Compose / deploy (push) Failing after 2s
Some checks failed
Deploy with Docker Compose / deploy (push) Failing after 2s
This commit is contained in:
65
project-intelligence/business-domain.md
Normal file
65
project-intelligence/business-domain.md
Normal file
@@ -0,0 +1,65 @@
|
||||
<!-- Context: project-intelligence/business | Priority: high | Version: 1.0 | Updated: 2026-02-27 -->
|
||||
|
||||
# Business Domain
|
||||
|
||||
**Purpose**: Business context, problems solved, and value created for the comic/manga reader app.
|
||||
**Last Updated**: 2026-02-27
|
||||
|
||||
## Quick Reference
|
||||
- **Update When**: Business direction changes, new features shipped
|
||||
- **Audience**: Developers needing context, stakeholders
|
||||
|
||||
## Project Identity
|
||||
```
|
||||
Project Name: Stripstream
|
||||
Tagline: Modern web reader for digital comics and manga
|
||||
Problem: Need a responsive, feature-rich web interface for reading comics from Komga servers
|
||||
Solution: Next.js PWA that syncs with Komga API, supports offline reading, multiple reading modes
|
||||
```
|
||||
|
||||
## Target Users
|
||||
| Segment | Who | Needs | Pain Points |
|
||||
|---------|-----|-------|--------------|
|
||||
| Comic/Manga Readers | Users with Komga servers | Read comics in browser | Komga web UI is limited |
|
||||
| Mobile Readers | iPad/Android users | Offline reading, touch gestures | No native mobile app |
|
||||
| Library Organizers | Users with large collections | Search, filter, track progress | Hard to manage |
|
||||
|
||||
## Value Proposition
|
||||
**For Users**:
|
||||
- Read comics anywhere via responsive PWA
|
||||
- Offline reading with local storage
|
||||
- Multiple viewing modes (single/double page, RTL, scroll)
|
||||
- Progress sync with Komga server
|
||||
- Light/Dark mode, language support (EN/FR)
|
||||
|
||||
**For Business**:
|
||||
- Open source showcase
|
||||
- Demonstrates Next.js + Komga integration patterns
|
||||
|
||||
## Key Features
|
||||
- **Sync**: Read progress, series/books lists with Komga
|
||||
- **Reader**: RTL, double/single page, zoom, thumbnails, fullscreen
|
||||
- **Offline**: PWA with local book downloads
|
||||
- **UI**: Dark/light, responsive, loading/error states
|
||||
- **Lists**: Pagination, search, mark read/unread, favorites
|
||||
- **Settings**: Cache TTL, Komga config, display preferences
|
||||
|
||||
## Tech Stack Context
|
||||
- Integrates with **Komga** (comic server API)
|
||||
- Uses **MongoDB** for local caching/preferences
|
||||
- **NextAuth** for authentication (session-based)
|
||||
|
||||
## Success Metrics
|
||||
| Metric | Target |
|
||||
|--------|--------|
|
||||
| Page load | <2s |
|
||||
| Reader responsiveness | 60fps |
|
||||
| PWA install rate | Track via analytics |
|
||||
|
||||
## Constraints
|
||||
- Requires Komga server (not standalone)
|
||||
- Mobile storage limits for offline books
|
||||
|
||||
## Related Files
|
||||
- `technical-domain.md` - Tech stack and code patterns
|
||||
- `business-tech-bridge.md` - Business-technical mapping
|
||||
65
project-intelligence/business-tech-bridge.md
Normal file
65
project-intelligence/business-tech-bridge.md
Normal file
@@ -0,0 +1,65 @@
|
||||
<!-- Context: project-intelligence/bridge | Priority: medium | Version: 1.0 | Updated: 2026-02-27 -->
|
||||
|
||||
# Business-Tech Bridge
|
||||
|
||||
**Purpose**: Map business concepts to technical implementation.
|
||||
**Last Updated**: 2026-02-27
|
||||
|
||||
## Quick Reference
|
||||
- **Update When**: New features that bridge business and tech
|
||||
- **Audience**: Developers, product
|
||||
|
||||
---
|
||||
|
||||
## Business → Technical Mapping
|
||||
|
||||
| Business Concept | Technical Implementation |
|
||||
|-----------------|------------------------|
|
||||
| Read comics | `BookService.getBook()`, PhotoswipeReader component |
|
||||
| Sync progress | Komga API calls in `ReadProgressService` |
|
||||
| Offline reading | Service Worker + IndexedDB via `ClientOfflineBookService` |
|
||||
| User preferences | MongoDB + `PreferencesService` |
|
||||
| Library management | `LibraryService`, `SeriesService` |
|
||||
| Authentication | NextAuth v5 + `AuthServerService` |
|
||||
|
||||
---
|
||||
|
||||
## User Flows → API Routes
|
||||
|
||||
| User Action | API Route | Service |
|
||||
|-------------|-----------|---------|
|
||||
| View home | `GET /api/komga/home` | `HomeService` |
|
||||
| Browse series | `GET /api/komga/libraries/:id/series` | `SeriesService` |
|
||||
| Read book | `GET /api/komga/books/:id` | `BookService` |
|
||||
| Update progress | `POST /api/komga/books/:id/read-progress` | `BookService` |
|
||||
| Download book | `GET /api/komga/images/books/:id/pages/:n` | `ImageService` |
|
||||
|
||||
---
|
||||
|
||||
## Components → Services
|
||||
|
||||
| UI Component | Service Layer |
|
||||
|--------------|---------------|
|
||||
| HomeContent | HomeService |
|
||||
| SeriesGrid | SeriesService |
|
||||
| BookCover | BookService |
|
||||
| PhotoswipeReader | ImageService |
|
||||
| FavoritesButton | FavoriteService |
|
||||
| SettingsPanel | PreferencesService |
|
||||
|
||||
---
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
User Request → API Route → Service → Komga API / MongoDB → Response
|
||||
↓
|
||||
Logger (Pino)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Files
|
||||
- `technical-domain.md` - Tech stack and code patterns
|
||||
- `business-domain.md` - Business context
|
||||
- `decisions-log.md` - Architecture decisions
|
||||
130
project-intelligence/decisions-log.md
Normal file
130
project-intelligence/decisions-log.md
Normal file
@@ -0,0 +1,130 @@
|
||||
<!-- Context: project-intelligence/decisions | Priority: medium | Version: 1.0 | Updated: 2026-02-27 -->
|
||||
|
||||
# Decisions Log
|
||||
|
||||
**Purpose**: Record architecture decisions with context and rationale.
|
||||
**Last Updated**: 2026-02-27
|
||||
|
||||
## Quick Reference
|
||||
- **Update When**: New architecture decisions
|
||||
- **Audience**: Developers, architects
|
||||
|
||||
---
|
||||
|
||||
## ADR-001: Use Prisma with MongoDB
|
||||
|
||||
**Date**: 2024
|
||||
**Status**: Accepted
|
||||
|
||||
**Context**: Need database for caching Komga responses and storing user preferences.
|
||||
|
||||
**Decision**: Use Prisma ORM with MongoDB adapter.
|
||||
|
||||
**Rationale**:
|
||||
- Type-safe queries across the app
|
||||
- Schema migration support
|
||||
- Works well with MongoDB's flexible schema
|
||||
|
||||
**Alternatives Considered**:
|
||||
- Mongoose: Less type-safe, manual schema management
|
||||
- Raw MongoDB driver: No type safety, verbose
|
||||
|
||||
---
|
||||
|
||||
## ADR-002: Service Layer Pattern
|
||||
|
||||
**Date**: 2024
|
||||
**Status**: Accepted
|
||||
|
||||
**Context**: API routes need business logic separated from HTTP handling.
|
||||
|
||||
**Decision**: Create service classes in `src/lib/services/` (BookService, SeriesService, etc.)
|
||||
|
||||
**Rationale**:
|
||||
- Separation of concerns
|
||||
- Testable business logic
|
||||
- Reusable across API routes
|
||||
|
||||
**Example**:
|
||||
```typescript
|
||||
// API route (thin)
|
||||
export async function GET(request: NextRequest, { params }) {
|
||||
const book = await BookService.getBook(bookId);
|
||||
return NextResponse.json(book);
|
||||
}
|
||||
|
||||
// Service (business logic)
|
||||
class BookService {
|
||||
static async getBook(bookId: string) { ... }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ADR-003: Custom AppError with Error Codes
|
||||
|
||||
**Date**: 2024
|
||||
**Status**: Accepted
|
||||
|
||||
**Context**: Need consistent error handling across API.
|
||||
|
||||
**Decision**: Custom `AppError` class with error codes from `ERROR_CODES` constant.
|
||||
|
||||
**Rationale**:
|
||||
- Consistent error format: `{ error: { code, name, message } }`
|
||||
- Typed error codes for client handling
|
||||
- Centralized error messages via `getErrorMessage()`
|
||||
|
||||
---
|
||||
|
||||
## ADR-004: Radix UI + Tailwind for Components
|
||||
|
||||
**Date**: 2024
|
||||
**Status**: Accepted
|
||||
|
||||
**Context**: Need accessible UI components without fighting a component library.
|
||||
|
||||
**Decision**: Use Radix UI primitives with custom Tailwind styling.
|
||||
|
||||
**Rationale**:
|
||||
- Radix provides accessible primitives
|
||||
- Full control over styling via Tailwind
|
||||
- Shadcn-like pattern (cva + cn)
|
||||
|
||||
---
|
||||
|
||||
## ADR-005: Client-Side Request Deduplication
|
||||
|
||||
**Date**: 2024
|
||||
**Status**: Accepted
|
||||
|
||||
**Context**: Multiple components may request same data (e.g., home page with series, books, continue reading).
|
||||
|
||||
**Decision**: `RequestDeduplicationService` with React query-like deduplication.
|
||||
|
||||
**Rationale**:
|
||||
- Reduces Komga API calls
|
||||
- Consistent data across components
|
||||
- Configurable TTL
|
||||
|
||||
---
|
||||
|
||||
## ADR-006: PWA with Offline Book Storage
|
||||
|
||||
**Date**: 2024
|
||||
**Status**: Accepted
|
||||
|
||||
**Context**: Users want to read offline, especially on mobile.
|
||||
|
||||
**Decision**: Next PWA + Service Worker + IndexedDB for storing book blobs.
|
||||
|
||||
**Rationale**:
|
||||
- Full offline capability
|
||||
- Background sync when online
|
||||
- Local storage limits on mobile
|
||||
|
||||
---
|
||||
|
||||
## Related Files
|
||||
- `technical-domain.md` - Tech stack details
|
||||
- `business-domain.md` - Business context
|
||||
64
project-intelligence/living-notes.md
Normal file
64
project-intelligence/living-notes.md
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- Context: project-intelligence/living-notes | Priority: low | Version: 1.0 | Updated: 2026-02-27 -->
|
||||
|
||||
# Living Notes
|
||||
|
||||
**Purpose**: Development notes, TODOs, and temporary information.
|
||||
**Last Updated**: 2026-02-27
|
||||
|
||||
## Quick Reference
|
||||
- **Update When**: Adding dev notes, tracking issues
|
||||
- **Audience**: Developers
|
||||
|
||||
---
|
||||
|
||||
## Current Focus
|
||||
|
||||
- Performance optimization (see PLAN_OPTIMISATION_PERFORMANCES.md)
|
||||
- Reducing bundle size
|
||||
- Image optimization
|
||||
|
||||
---
|
||||
|
||||
## Development Notes
|
||||
|
||||
### Service Layer
|
||||
All business logic lives in `src/lib/services/`. API routes are thin wrappers.
|
||||
|
||||
### API Error Handling
|
||||
Use `AppError` class from `@/utils/errors`. Always include error code from `ERROR_CODES`.
|
||||
|
||||
### Component Patterns
|
||||
- UI components: `src/components/ui/` (Radix + Tailwind)
|
||||
- Feature components: `src/components/*/` (by feature)
|
||||
- Use `cva` for variant props
|
||||
- Use `cn` from `@/lib/utils` for class merging
|
||||
|
||||
### Types
|
||||
- Komga types: `src/types/komga/`
|
||||
- App types: `src/types/`
|
||||
|
||||
### Database
|
||||
- Prisma schema: `prisma/schema.prisma`
|
||||
- MongoDB connection: `src/lib/prisma.ts`
|
||||
|
||||
---
|
||||
|
||||
## Known Issues
|
||||
|
||||
- Large libraries may be slow to load (pagination helps)
|
||||
- Offline storage limited by device space
|
||||
|
||||
---
|
||||
|
||||
## Future Ideas
|
||||
|
||||
- [ ] Add more reader modes
|
||||
- [ ] User collections/tags
|
||||
- [ ] Reading statistics
|
||||
- [ ] Better caching strategy
|
||||
|
||||
---
|
||||
|
||||
## Related Files
|
||||
- `technical-domain.md` - Code patterns
|
||||
- `decisions-log.md` - Architecture decisions
|
||||
23
project-intelligence/navigation.md
Normal file
23
project-intelligence/navigation.md
Normal file
@@ -0,0 +1,23 @@
|
||||
<!-- Context: project-intelligence/navigation | Priority: critical | Version: 1.0 | Updated: 2026-02-27 -->
|
||||
|
||||
# Project Intelligence
|
||||
|
||||
Quick overview of project patterns and context files.
|
||||
|
||||
## Quick Routes
|
||||
|
||||
| File | Description | Priority |
|
||||
|------|-------------|----------|
|
||||
| [technical-domain.md](./technical-domain.md) | Tech stack, architecture, patterns | critical |
|
||||
| [business-domain.md](./business-domain.md) | Business logic, domain model | high |
|
||||
| [decisions-log.md](./decisions-log.md) | Architecture decisions | medium |
|
||||
| [living-notes.md](./living-notes.md) | Development notes | low |
|
||||
| [business-tech-bridge.md](./business-tech-bridge.md) | Business-technical mapping | medium |
|
||||
|
||||
## All Files Complete |
|
||||
|
||||
## Usage
|
||||
|
||||
- **AI Agents**: Read technical-domain.md for code patterns
|
||||
- **New Developers**: Start with technical-domain.md + business-domain.md
|
||||
- **Architecture**: Check decisions-log.md for rationale
|
||||
154
project-intelligence/technical-domain.md
Normal file
154
project-intelligence/technical-domain.md
Normal file
@@ -0,0 +1,154 @@
|
||||
<!-- Context: project-intelligence/technical | Priority: critical | Version: 1.0 | Updated: 2026-02-27 -->
|
||||
|
||||
# Technical Domain
|
||||
|
||||
**Purpose**: Tech stack, architecture, development patterns for this project.
|
||||
**Last Updated**: 2026-02-27
|
||||
|
||||
## Quick Reference
|
||||
**Update Triggers**: Tech stack changes | New patterns | Architecture decisions
|
||||
**Audience**: Developers, AI agents
|
||||
|
||||
## Primary Stack
|
||||
| Layer | Technology | Version | Rationale |
|
||||
|-------|-----------|---------|-----------|
|
||||
| Framework | Next.js | 15.5.9 | App Router, Server Components |
|
||||
| Language | TypeScript | 5.3.3 | Type safety |
|
||||
| Database | MongoDB | - | Flexible schema for media metadata |
|
||||
| ORM | Prisma | 6.17.1 | Type-safe DB queries |
|
||||
| Styling | Tailwind CSS | 3.4.1 | Utility-first |
|
||||
| UI Library | Radix UI | - | Accessible components |
|
||||
| Animation | Framer Motion | 12.x | Declarative animations |
|
||||
| Auth | NextAuth | v5 | Session management |
|
||||
| Validation | Zod | 3.22.4 | Schema validation |
|
||||
| Logger | Pino | 10.x | Structured logging |
|
||||
|
||||
## Project Structure
|
||||
```
|
||||
src/
|
||||
├── app/ # Next.js App Router pages
|
||||
├── components/ # React components (ui/, features/)
|
||||
├── lib/ # Services, utils, config
|
||||
│ └── services/ # Business logic (BookService, etc.)
|
||||
├── hooks/ # Custom React hooks
|
||||
├── types/ # TypeScript type definitions
|
||||
├── utils/ # Helper functions
|
||||
├── contexts/ # React contexts
|
||||
├── constants/ # App constants
|
||||
└── i18n/ # Internationalization
|
||||
```
|
||||
|
||||
## Code Patterns
|
||||
### API Endpoint
|
||||
```typescript
|
||||
import { NextResponse } from "next/server";
|
||||
import { BookService } from "@/lib/services/book.service";
|
||||
import { ERROR_CODES } from "@/constants/errorCodes";
|
||||
import { getErrorMessage } from "@/utils/errors";
|
||||
import { AppError } from "@/utils/errors";
|
||||
import logger from "@/lib/logger";
|
||||
|
||||
export async function GET(request: NextRequest, { params }: { params: Promise<{ bookId: string }> }) {
|
||||
try {
|
||||
const bookId: string = (await params).bookId;
|
||||
const data = await BookService.getBook(bookId);
|
||||
return NextResponse.json(data);
|
||||
} catch (error) {
|
||||
logger.error({ err: error }, "API Books - Erreur:");
|
||||
if (error instanceof AppError) {
|
||||
const isNotFound = error.code === ERROR_CODES.BOOK.NOT_FOUND;
|
||||
return NextResponse.json(
|
||||
{ error: { code: error.code, name: "Error", message: getErrorMessage(error.code) } },
|
||||
{ status: isNotFound ? 404 : 500 }
|
||||
);
|
||||
}
|
||||
return NextResponse.json(
|
||||
{ error: { code: ERROR_CODES.BOOK.NOT_FOUND, name: "Error", message: "Internal error" } },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Component with Variants
|
||||
```typescript
|
||||
import * as React from "react";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const buttonVariants = cva("inline-flex items-center justify-center...", {
|
||||
variants: {
|
||||
variant: { default: "...", destructive: "...", outline: "..." },
|
||||
size: { default: "...", sm: "...", lg: "..." },
|
||||
},
|
||||
defaultVariants: { variant: "default", size: "default" },
|
||||
});
|
||||
|
||||
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
||||
asChild?: boolean;
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonProps, ButtonProps>(({ className, variant, size, asChild, ...props }, ref) => {
|
||||
const Comp = asChild ? Slot : "button";
|
||||
return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;
|
||||
});
|
||||
Button.displayName = "Button";
|
||||
|
||||
export { Button, buttonVariants };
|
||||
```
|
||||
|
||||
### Feature Component
|
||||
```typescript
|
||||
import type { KomgaBook } from "@/types/komga";
|
||||
|
||||
interface HomeContentProps {
|
||||
data: HomeData;
|
||||
}
|
||||
|
||||
export function HomeContent({ data }: HomeContentProps) {
|
||||
return (
|
||||
<div className="space-y-12">
|
||||
{data.ongoing && <MediaRow titleKey="home.sections.continue" items={data.ongoing} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Naming Conventions
|
||||
| Type | Convention | Example |
|
||||
|------|-----------|---------|
|
||||
| Files | kebab-case | book-cover.tsx |
|
||||
| Components | PascalCase | BookCover |
|
||||
| Functions | camelCase | getBookById |
|
||||
| Types | PascalCase | KomgaBook |
|
||||
| Database | snake_case | read_progress |
|
||||
| API Routes | kebab-case | /api/komga/books |
|
||||
|
||||
## Code Standards
|
||||
- TypeScript strict mode enabled
|
||||
- Zod for request/response validation
|
||||
- Prisma for all database queries (type-safe)
|
||||
- Server Components by default, Client Components when needed
|
||||
- Custom AppError class with error codes
|
||||
- Structured logging with Pino
|
||||
- Error responses: `{ error: { code, name, message } }`
|
||||
|
||||
## Security Requirements
|
||||
- Validate all user input with Zod
|
||||
- Parameterized queries via Prisma (prevents SQL injection)
|
||||
- Sanitize before rendering (React handles this)
|
||||
- HTTPS only in production
|
||||
- Auth via NextAuth v5
|
||||
- Role-based access control (admin, user)
|
||||
- API routes protected with session checks
|
||||
|
||||
## 📂 Codebase References
|
||||
**API Routes**: `src/app/api/**/route.ts` - All API endpoints
|
||||
**Services**: `src/lib/services/*.service.ts` - Business logic layer
|
||||
**Components**: `src/components/ui/`, `src/components/*/` - UI and feature components
|
||||
**Types**: `src/types/**` - TypeScript definitions
|
||||
**Config**: package.json, tsconfig.json, prisma/schema.prisma
|
||||
|
||||
## Related Files
|
||||
- business-domain.md - Business logic and domain model
|
||||
- decisions-log.md - Architecture decisions
|
||||
Reference in New Issue
Block a user