Files
PageManager/CLAUDE.md
T
2026-03-15 22:31:31 +02:00

5.4 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Repository Structure

Mono-repo with two projects:

  • PageManager.Api/ — .NET 10 Web API (solution root contains PageManager.Api.slnx)
    • PageManager.Api/PageManager.Api/ — the actual C# project
    • PageManager.Api/PageManager.Api.Tests/ — xunit test project
  • PageManager.Web/ — React 19 + Vite + TypeScript SPA
  • compose.yaml — root-level Docker Compose orchestrating both services

Development Commands

API (PageManager.Api/)

cd PageManager.Api
dotnet run --project PageManager.Api        # runs on http://localhost:5278
dotnet build
dotnet test                                  # all tests
dotnet test --filter "FullyQualifiedName~Unit"         # unit only (no Docker needed)
dotnet test --filter "FullyQualifiedName~Integration"  # integration only (Docker required)

Migrations (PageManager.Api/)

EF Core tooling targets the PageManager.Api project. All commands run from PageManager.Api/.

# Create a migration after changing Data/Models
dotnet ef migrations add <MigrationName> --project PageManager.Api

# Apply pending migrations to the database
dotnet ef database update --project PageManager.Api

# Roll back to a specific migration
dotnet ef database update <MigrationName> --project PageManager.Api

# Generate SQL script for a migration (useful for production deploys)
dotnet ef migrations script --project PageManager.Api

Install the EF global tool if not present: dotnet tool install --global dotnet-ef

Web (PageManager.Web/)

cd PageManager.Web
npm install
npm run dev          # http://localhost:5173
npm run build
npm run preview      # preview production build locally
npm test             # single pass (CI)
npm run test:watch   # interactive watch (development)
npm run test:coverage

Docker (both services)

docker compose up --build   # web → :8080, api → :5278

Architecture

API → Web connection

Dev: Vite dev server proxies /api/* to http://localhost:5278 (configured in PageManager.Web/vite.config.ts). The API enables CORS for http://localhost:5173 in Program.cs — only in the Development environment.

Production (Docker): nginx (PageManager.Web/nginx.conf) proxies /api/* to http://pagemanager.api:8080 (the compose service name). All other routes fall back to index.html for SPA routing.

Conventions

  • Controllers are thin — logic lives in Services
  • EF Core models in Data/Models, DTOs in Api/Dtos
  • React components in PascalCase, files match component name
  • API calls go through src/api/*.ts typed wrappers, never raw fetch in components
  • Design reference: src/Leafreader.Web/design-reference.html

Testing

Rule: every code change must be followed by running the relevant tests and fixing any failures before the task is considered done.

After API changes

cd PageManager.Api
dotnet test --filter "FullyQualifiedName~Unit"   # always run; no Docker needed
# If integration-relevant (endpoint, EF query, DB schema): also run:
dotnet test --filter "FullyQualifiedName~Integration"   # requires Docker

After Web changes

cd PageManager.Web
npm test

Test locations

Layer Location Tool
API unit PageManager.Api.Tests/Unit/Services/ xunit + NSubstitute + FluentAssertions
API integration PageManager.Api.Tests/Integration/ xunit + Testcontainers (postgres:17-alpine) + WebApplicationFactory
Web unit src/**/__tests__/ Vitest + Testing Library

What to test and when

  • New service method or DTO mapping → add unit test in Unit/Services/
  • New or changed endpoint → add integration test in Integration/BooksControllerTests.cs (or a new *ControllerTests.cs)
  • New utility function (utils.ts) → add unit test in a sibling __tests__/ folder
  • New React component with logic → add component test in __tests__/
  • Private logic inside a component → extract to utils.ts first, then test the exported function

What does NOT get tested

  • BooksRepository — pure EF Include chains, covered by integration tests
  • BooksController — too thin, covered by integration tests
  • CSS Modules, Sidebar (static nav), App.tsx routing
  • importQueue.ts — currently mock stubs; add tests when real HTTP is introduced

Decision rules

  • Unit test: any service method, utility function, or DTO mapping with conditional logic or data transformation
  • Integration test: any new endpoint, EF Core query change, or PostgreSQL-specific feature
  • Don't duplicate: if unit tests own mapping correctness, integration tests own HTTP contract + DB round-trip
  • Extract before testing: private logic inside a component must move to utils.ts before writing tests

Infrastructure notes

  • Integration tests use [Collection("Postgres")] — one container shared across all integration test classes
  • Each integration test class truncates tables in InitializeAsync to ensure isolation
  • Book.Formats and Book.Genres are text[] (PostgreSQL-specific) — always use real Postgres for integration tests, never InMemory
  • TestWebAppFactory sets UseEnvironment("Testing") — CORS and OpenAPI middleware are skipped