xpeditis2.0/CLAUDE.md
2026-01-27 19:33:51 +01:00

171 lines
5.8 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
**Xpeditis** is a B2B SaaS maritime freight booking platform. Freight forwarders search and compare real-time shipping rates, book containers, and manage shipments. Built as a monorepo with NestJS backend (Hexagonal Architecture) and Next.js 14 frontend.
## Development Commands
```bash
# Start infrastructure (PostgreSQL + Redis + MinIO)
docker-compose up -d
# Install dependencies
npm install && cd apps/backend && npm install && cd ../frontend && npm install
# Run database migrations
cd apps/backend && npm run migration:run
# Start development servers
npm run backend:dev # http://localhost:4000, Swagger: /api/docs
npm run frontend:dev # http://localhost:3000
```
### Testing
```bash
# Backend (from apps/backend/)
npm test # Unit tests
npm test -- booking.entity.spec.ts # Single file
npm run test:cov # With coverage
npm run test:integration # Integration tests (needs DB/Redis)
npm run test:e2e # E2E tests
# Frontend (from apps/frontend/)
npm test
npx playwright test # E2E tests
```
### Database Migrations
```bash
cd apps/backend
npm run migration:generate -- src/infrastructure/persistence/typeorm/migrations/MigrationName
npm run migration:run
npm run migration:revert
```
### Build
```bash
npm run backend:build # Compiles TS with path alias resolution (tsc-alias)
npm run frontend:build # Next.js production build
```
## Architecture
### Hexagonal Architecture (Backend)
```
apps/backend/src/
├── domain/ # CORE - Pure TypeScript, NO framework imports
│ ├── entities/ # Booking, RateQuote, User (with private props, static create())
│ ├── value-objects/# Money, Email, BookingNumber (immutable, validated)
│ ├── services/ # Domain services
│ ├── ports/
│ │ ├── in/ # Use case interfaces
│ │ └── out/ # Repository interfaces (SPIs)
│ └── exceptions/ # Domain exceptions
├── application/ # Controllers, DTOs, Guards (depends ONLY on domain)
└── infrastructure/ # TypeORM, Redis, Carrier APIs (depends ONLY on domain)
```
**Critical Rules**:
- Domain layer: Zero imports from NestJS, TypeORM, Redis
- Dependencies flow inward: Infrastructure → Application → Domain
- Use path aliases: `@domain/*`, `@application/*`, `@infrastructure/*`
- Domain tests run without NestJS TestingModule
### Frontend (Next.js 14 App Router)
```
apps/frontend/
├── app/ # App Router pages
│ ├── dashboard/ # Protected routes
│ │ ├── bookings/ # Booking management
│ │ ├── admin/ # Admin features (ADMIN role)
│ │ └── settings/ # User/org settings
│ └── carrier/ # Carrier portal (magic link auth)
└── src/
├── components/ # React components (shadcn/ui in ui/)
├── hooks/ # useBookings, useNotifications
├── lib/api/ # API client modules
└── types/ # TypeScript definitions
```
Path aliases: `@/*``./src/*`, `@/components/*`, `@/lib/*`, `@/hooks/*`
## Key Patterns
### Entity Pattern (Domain)
```typescript
export class Booking {
private readonly props: BookingProps;
static create(props: Omit<BookingProps, 'bookingNumber'>): Booking { ... }
updateStatus(newStatus: BookingStatus): Booking { // Returns new instance
return new Booking({ ...this.props, status: newStatus });
}
}
```
### Repository Pattern
- Interface in `domain/ports/out/booking.repository.ts`
- Implementation in `infrastructure/persistence/typeorm/repositories/typeorm-booking.repository.ts`
- Separate mappers for Domain ↔ ORM entity conversions
### Circuit Breaker (External APIs)
- Library: `opossum`, Timeout: 5s
- Used for carrier API calls (Maersk, MSC, CMA CGM)
### Caching
- Redis with 15-min TTL for rate quotes
- Cache key format: `rate:{origin}:{destination}:{containerType}`
## Business Rules
- Booking number format: `WCM-YYYY-XXXXXX`
- Rate quotes expire after 15 minutes
- Multi-currency: USD, EUR
- RBAC Roles: ADMIN, MANAGER, USER, VIEWER, CARRIER
### Carrier Portal Workflow
1. Admin creates CSV booking → assigns carrier
2. Email with magic link sent (1-hour expiry)
3. Carrier auto-login → accept/reject booking
4. Activity logged in `carrier_activities` table
## Tech Stack
**Backend**: NestJS 10, TypeORM 0.3, PostgreSQL 15, Redis 7, Argon2, Pino, Sentry
**Frontend**: Next.js 14, React 18, TanStack Query/Table, React Hook Form + Zod, Tailwind + shadcn/ui, Socket.IO
## Common Pitfalls
- Never import NestJS/TypeORM in domain layer
- Never use `any` type (strict mode enabled)
- Never use `DATABASE_SYNC=true` in production
- Never modify applied migrations - create new ones
- Always validate DTOs with `class-validator`
- Always create mappers for Domain ↔ ORM conversions
## Adding a New Feature
1. **Domain Entity**`domain/entities/*.entity.ts` (pure TS, unit tests)
2. **Value Objects**`domain/value-objects/*.vo.ts` (immutable)
3. **Port Interface**`domain/ports/out/*.repository.ts`
4. **ORM Entity**`infrastructure/persistence/typeorm/entities/*.orm-entity.ts`
5. **Generate Migration**`npm run migration:generate -- ...`
6. **Repository Impl**`infrastructure/persistence/typeorm/repositories/`
7. **DTOs**`application/dto/` (with class-validator decorators)
8. **Controller**`application/controllers/` (with Swagger decorators)
9. **Module** → Register and import in `app.module.ts`
## Documentation
- API Docs: http://localhost:4000/api/docs (Swagger)
- Architecture: `docs/architecture.md`
- Carrier Portal API: `apps/backend/docs/CARRIER_PORTAL_API.md`
- Full docs index: `docs/README.md`