# Crafted SaaS - Hexagonal Architecture (Web + Mobile)

🏆 **Niveau CRAFTED** - Software Craftsmanship, Web + Mobile

## Configuration

- **Niveau**: Crafted (Software Craftsmanship)
- **Architecture**: Hexagonale (Domain/Application/Infrastructure)
- **Platform**: Web + Mobile (Next.js + React Native/Expo)
- **Équipe**: 10-200+ développeurs
- **Durée**: 5-10+ ans (long-terme)
- **Users**: 10K-1M+ utilisateurs
- **Revenue**: $100K+ MRR

## Architecture Hexagonale

Cette template implémente une **architecture hexagonale** (Ports & Adapters) avec une séparation stricte des responsabilités:

```
packages/
├── domain/              # ⭐ PURE BUSINESS LOGIC (ZERO dependencies)
│   ├── entities/        # User, Product (rich domain models)
│   ├── value-objects/   # Email, Money, Result
│   ├── use-cases/       # CreateUser, GetUserById
│   └── repositories/    # Interfaces only (IUserRepository)
│
├── infrastructure/      # Implémentations externes
│   └── database/
│       └── repositories/
│           └── PrismaUserRepository.ts  # Implémente IUserRepository
│
├── api/                 # Application layer (ultra-thin)
│   └── routers/
│       └── user.ts      # < 10 lignes, orchestration only
│
└── database/            # Prisma + PostgreSQL

apps/
├── web/                 # Next.js 15
└── mobile/              # React Native (Expo)
```

## Principe Fondamental: Domain Agnostic

**Le domain layer est 100% platform-agnostic:**

- ✅ ZERO dépendance externe (pas de Prisma, pas de Next.js, pas de React)
- ✅ Peut tourner sur Node.js, Browser, React Native, Deno, Bun
- ✅ Testable sans infrastructure (100% coverage)
- ✅ Partagé entre web et mobile sans modification

### Exemple: CreateUser Use-Case

```typescript
// packages/domain/src/use-cases/CreateUser.ts
// ✅ Pas d'import de Prisma, Next.js, ou autre framework
export class CreateUser {
  constructor(private userRepository: IUserRepository) {}

  async execute(input: CreateUserInput): Promise<Result<User, DomainError>> {
    const emailResult = Email.create(input.email);
    if (isFailure(emailResult)) return emailResult;

    const userResult = User.create({ id: crypto.randomUUID(), email: emailResult.value, name: input.name });
    if (isFailure(userResult)) return userResult;

    return this.userRepository.save(userResult.value);
  }
}
```

**Le use-case ne sait pas:**
- Comment les données sont stockées (Prisma? MongoDB? InMemory?)
- Sur quelle plateforme il tourne (Web? Mobile? Server?)
- Comment il est appelé (HTTP? GraphQL? Message Queue?)

## Flux de Données

```
Mobile/Web UI
      ↓
   tRPC Router (< 10 lignes)
      ↓
   Use-Case (domain layer)
      ↓
   Repository Interface (IUserRepository)
      ↓
   Infrastructure (PrismaUserRepository)
      ↓
   Database
```

## Shared Code Strategy

### Domain Layer (100% partagé)
- Entities (User, Product)
- Value Objects (Email, Money)
- Use-Cases (CreateUser, GetUserById)
- Repository Interfaces
- Business Rules

### Application Layer (partagé)
- tRPC routers
- API orchestration

### Infrastructure Layer (partagé)
- Database repositories (Prisma)
- Payment clients (Stripe)
- Email services (Resend)

### UI Layer (platform-specific)
- `apps/web/` - Next.js avec shadcn/ui
- `apps/mobile/` - React Native avec NativeWind

## Règles de Code

| Aspect | Règle |
|--------|-------|
| **Max lignes/fonction** | 20 lignes |
| **Parameters** | Max 2 |
| **Duplication** | 0 duplication (CI fail) |
| **Cyclomatic complexity** | < 5 |
| **SOLID** | Full + auditable |
| **Comments** | WHY + ADR ref (NO inline comments) |

## Testing Strategy

### Spec-First (Domain Layer)
1. Comprendre les business rules
2. Générer les tests EN PREMIER (spécification)
3. Implémenter pour satisfaire les tests

### Coverage Targets
- ✅ Domain entities: **100%** (enforced)
- ✅ Use-cases: **100%** (enforced)
- ✅ Infrastructure: **80%** (enforced)
- ✅ E2E complets

```bash
# Run domain tests (100% coverage required)
pnpm --filter @crafted/domain test:coverage

# Run all tests
pnpm test

# E2E tests
pnpm test:e2e
```

## Quick Start

```bash
# Install dependencies
pnpm install

# Setup environment
cp .env.example .env.local
# Edit .env.local with your keys

# Generate Prisma client
pnpm db:generate

# Push database schema
pnpm db:push

# Start web dev server
pnpm --filter web dev

# Start mobile dev server (in another terminal)
pnpm --filter mobile dev
```

## Project Structure

```
crafted-web-mobile/
├── apps/
│   ├── web/                    # Next.js 15 app
│   └── mobile/                 # Expo app
│
├── packages/
│   ├── domain/                 # ⭐ Pure business logic (ZERO deps)
│   │   ├── entities/           # User, Product
│   │   ├── value-objects/      # Email, Money, Result
│   │   ├── use-cases/          # CreateUser, GetUserById
│   │   ├── repositories/       # Interfaces only
│   │   └── __tests__/          # 100% coverage
│   │
│   ├── infrastructure/         # External implementations
│   │   └── database/
│   │       └── repositories/   # Prisma implementations
│   │
│   ├── api/                    # tRPC routers (< 10 lines)
│   ├── database/               # Prisma + PostgreSQL
│   ├── validators/             # Zod schemas
│   ├── api-client/             # tRPC client
│   └── storage/                # Platform-agnostic storage
│
├── .craftedrc.json             # Project configuration
└── package.json                # Monorepo root
```

## Features

- ✅ Hexagonal Architecture (Ports & Adapters)
- ✅ Domain-Driven Design
- ✅ 100% Platform-Agnostic Domain Layer
- ✅ Shared Business Logic (Web + Mobile)
- ✅ Result Pattern (no throws in domain)
- ✅ Rich Domain Entities
- ✅ Value Objects
- ✅ Spec-First Testing
- ✅ 100% Domain Coverage
- ✅ Type-safe API (tRPC)
- ✅ Database (Prisma + PostgreSQL)

## Stack

### Web
- **Frontend**: Next.js 15 (App Router), React 19, TypeScript
- **UI**: shadcn/ui
- **Styling**: Tailwind CSS

### Mobile
- **Framework**: React Native + Expo SDK 52+
- **Navigation**: Expo Router
- **Styling**: NativeWind (Tailwind for RN)
- **Storage**: Expo SecureStore

### Shared (Platform-Agnostic)
- **Domain**: Pure TypeScript (ZERO dependencies)
- **Backend**: tRPC 11, Zod validation
- **Database**: Prisma + PostgreSQL
- **Data Fetching**: TanStack Query

## Philosophie

> "Build it right. Architecture-first, sustainable pour 10+ ans."

**Priorités:**
1. Business logic isolée et testable
2. Zero dépendance dans le domain
3. 100% test coverage du domain
4. Architecture qui scale avec l'équipe
5. Code maintenable sur le long terme

## Principes Craft Actifs (16/16 - TOUS)

- ✅ Type Safety (TypeScript strict + Zod)
- ✅ Linting (ESLint strict)
- ✅ Git Hooks
- ✅ Error Handling (Result pattern)
- ✅ Security (OWASP Top 10)
- ✅ Self-Documenting Code
- ✅ Hexagonal Architecture
- ✅ Domain-Driven Design
- ✅ TDD-inspired (spec-first)
- ✅ SOLID strict
- ✅ ADR pour toutes décisions
- ✅ E2E complets
- ✅ 100% Domain Coverage
- ✅ Architecture Tests
- ✅ Performance monitoring
- ✅ Code Review obligatoire

## Documentation

- [Architecture Hexagonale](./ARCHITECTURE.md) - Détails de l'architecture
- [Hexagonal Design](./HEXAGONAL.md) - Guide hexagonal architecture
- [Mobile Integration](./MOBILE.md) - Intégration web + mobile
- [CLAUDE.md](./CLAUDE.md) - Rules pour Claude Code

## Quand utiliser cette template ?

✅ **Utiliser Crafted Web+Mobile si:**
- Équipe ≥ 10 développeurs
- Utilisateurs ≥ 10K
- Revenue ≥ $100K MRR
- Besoin d'architecture hexagonale
- Business logic complexe
- Vision long-terme (5-10+ ans)
- Web ET mobile requis
- Besoin de partager la business logic

❌ **Ne PAS utiliser si:**
- Équipe < 10 personnes → Utiliser **Balanced**
- MVP rapide → Utiliser **Rapid**
- Web uniquement → Utiliser **Crafted Web**
- Business logic simple → Utiliser **Balanced**

## Commands

```bash
# Development
pnpm dev                  # Start all apps
pnpm dev --filter web     # Web only
pnpm dev --filter mobile  # Mobile only

# Testing
pnpm test                 # All tests
pnpm test:coverage        # With coverage
pnpm test:e2e             # E2E tests

# Database
pnpm db:generate          # Generate Prisma client
pnpm db:push              # Push schema changes
pnpm db:migrate           # Create migration
pnpm db:studio            # Open Prisma Studio

# Build
pnpm build                # Build all
pnpm build --filter web   # Web only

# Lint & Type-check
pnpm lint                 # Lint all
pnpm type-check           # Type-check all
```
