CLAUDE.md Configuration
CLAUDE.md files are the primary configuration mechanism for Claude Code. They provide always-on context that the agent loads automatically when it enters a directory. SaaS4Builders ships three CLAUDE.md files at strategic locations, each progressively adding domain-specific context.
The Three Configuration Files
| File | Lines | Scope | Loaded When |
|---|---|---|---|
CLAUDE.md | ~150 | Project-wide | Always (project root) |
backend/CLAUDE.md | ~540 | Laravel backend | Working in backend/ |
frontend/CLAUDE.md | ~320 | Nuxt frontend | Working in frontend/ |
When Claude Code opens the project, it loads the root file. When you cd backend, it loads both root AND backend. When you cd frontend, it loads both root AND frontend. This layering means the agent always has the right level of context for the current work.
Root CLAUDE.md — The Project Map
The root file is the entry point for all AI-assisted work. At ~150 lines, it gives an agent enough context to navigate the full project without overwhelming its context window.
What It Contains
Project identity — Stack declaration (Laravel 13 + Nuxt 4), billing provider (Stripe), tenancy model (single-DB), supported locales (EN/FR/ES/IT).
Project structure — The directory layout an agent needs to find any file:
backend/ → Laravel API (has its own CLAUDE.md)
frontend/ → Nuxt 4 (has its own CLAUDE.md)
.claude/ → Skills, decisions, settings
docs/ → API contracts, milestones, specs
ai-context/ → Project brief, glossary, architecture
Docker commands — The full set of make commands for both stacks, grouped by concern (setup, backend, frontend, quality). Every command is copy-pasteable.
Domain entities — A table defining the nine core entities the agent will encounter:
| Entity | Description |
|--------|-------------|
| **Tenant** | Customer org — all resources scoped by `tenant_id` (UUID) |
| **User** | Individual account, single tenant (int ID, nullable `tenant_id`) |
| **Product** | Logical offering (global catalog) |
| **Plan** | Pricing config: flat-rate / seat-based / usage-based |
| **Feature** | Functional capability gated by entitlements |
| **Entitlement** | Plan ↔ Feature link with limits (boolean or quota) |
| **Subscription** | Tenant ↔ Plan binding. Lifecycle: trialing → active → past_due → canceled |
| **Invoice** | Internal invoice (PDF). Immutable after paid. |
| **Meter/UsageEvent** | Usage tracking counters and events |
Critical conventions — The non-negotiable rules that apply everywhere:
- API rules:
snake_caseJSON keys, ISO-8601 dates,amount_cents+currencyfor money, versioned under/api/v1/ - Multi-tenancy: single DB with
tenant_idscoping,BelongsToTenanttrait, test isolation required - Git: conventional commits (
feat(scope): message), branch prefixes (feature/,fix/, etc.) - Quality gates: PHPStan level 9, TypeScript strict, ESLint, coverage ≥80% on critical paths
Explicit guardrails — A "Do NOT" list that prevents the most dangerous mistakes:
- Never bypass tenant isolation
- Never hardcode secrets or credentials
- Never skip tests for critical features (auth, billing, tenancy)
- Never implement undocumented API endpoints
Skill references — A list of available /skill-name commands, so the agent knows what on-demand context is available.
/skill-name. This progressive disclosure model keeps the base context lean while providing unlimited depth when needed.Backend CLAUDE.md — Laravel Conventions
At ~540 lines, the backend configuration file is the most comprehensive. It is auto-generated by Laravel Boost and provides everything an AI agent needs to write correct Laravel code in this project.
Docker Environment
Container names and command prefixes ensure the agent runs commands in the right place:
# All backend commands run inside the PHP container
docker compose exec php php artisan test --compact
docker compose exec php vendor/bin/pint --dirty
docker compose exec php vendor/bin/phpstan analyse --memory-limit=1G
PHP and Laravel Rules
Foundation conventions that prevent common mistakes:
- PHP 8.4 with constructor property promotion and explicit return types
- Eloquent over raw queries, eager loading to prevent N+1
- Form Request classes for validation with custom messages
config()helper for environment variables (neverenv()directly)- Named routes with the
route()function
Application Architecture
The core of the backend configuration — the modular domain-driven architecture:
app/
├── Application/<Domain>/ # Use cases (Actions, Queries, DTOs)
│ ├── Actions/ # Write operations (mutations)
│ ├── Queries/ # Read operations
│ └── DTO/ # Input Data Transfer Objects
├── Domain/<Domain>/ # Core domain logic
│ ├── Contracts/ # Interfaces for external services
│ ├── DTO/ # Domain Transfer DTOs (provider-agnostic)
│ └── Models/ # Eloquent models (if domain-specific)
├── Infrastructure/<Domain>/ # External implementations
│ ├── Providers/<Provider>/ # Provider-specific implementations
│ └── Mappers/ # External → Domain DTO mappers
└── Http/
├── Controllers/Api/V1/ # Thin controllers (delegation only)
├── Requests/Api/V1/ # Form Requests with toDto()
└── Resources/Api/V1/ # API Resources (snake_case output)
The request flow is explicit:
Request → FormRequest::toDto() → Action/Query → Resource → Response
Where Code Goes
A decision table tells the agent exactly where to put new code:
| I want to... | I create in... |
|---|---|
| Create/update/delete an entity | Application/<Domain>/Actions/ |
| List/filter/paginate | Application/<Domain>/Queries/ |
| Define input data for a use case | Application/<Domain>/DTO/*Data.php |
| Call an external service | Domain/*/Contracts/ + Infrastructure/*/Providers/ |
| Validate HTTP input | Http/Requests/Api/V1/<Context>/ |
| Format API output | Http/Resources/Api/V1/<Context>/ |
Mandatory Rules
Six rules that the agent must never violate:
- Thin Controllers — Controllers delegate only. No business logic, no query building.
- Request → toDto() — Every FormRequest exposes
toDto()mapping HTTP input to an Application DTO. - Actions = Mutations — Wrap in
DB::transaction(). Return Eloquent Model. - Queries = Read-only — No side effects. May use Eloquent or Spatie QueryBuilder.
- Domain Contracts — Actions depend on interfaces, never on providers directly.
- Mappers — Normalize external responses to Domain Transfer DTOs.
Naming Conventions
A detailed table specifying naming patterns for every file type:
| Type | Location | Naming | Notes |
|---|---|---|---|
| Action | Application/<Domain>/Actions/ | CreateX.php | No suffix |
| Query | Application/<Domain>/Queries/ | ListX.php | No suffix |
| Input DTO | Application/<Domain>/DTO/ | CreateXData.php | *Data or *Filters |
| Transfer DTO | Domain/<Domain>/DTO/ | ExternalX.php | Provider-agnostic |
| Contract | Domain/<Domain>/Contracts/ | XGateway.php | Interface only |
| Provider | Infrastructure/<Domain>/Providers/X/ | StripeXGateway.php | Implements Contract |
| Mapper | Infrastructure/<Domain>/Mappers/ | StripeXMapper.php | External → Domain DTO |
| Request | Http/Requests/Api/V1/<Context>/ | CreateXRequest.php | Must have toDto() |
| Resource | Http/Resources/Api/V1/<Context>/ | XResource.php | snake_case keys |
Code Style Rules
- All classes are
finalunless inheritance is explicitly needed - DTOs use
readonly class - Resources output snake_case keys (enforced by API contracts)
- Money fields:
amount_cents(int) +currency(string) — never floats - Dates:
->toIso8601String()format
Additional Sections
The backend configuration also covers:
- Test enforcement — Every change must be tested; run the minimum tests needed
- Internationalization — Four locales (en, fr, es, it), file-per-domain translations
- PR review checklist — Architecture, API contract, and quality checks
Frontend CLAUDE.md — Nuxt Conventions
At ~320 lines, the frontend configuration covers the vertical slice architecture and Nuxt-specific patterns.
Vertical Slice Architecture
The frontend organizes code into three feature layers:
features/
├── foundation/ # Layer 0 — Auth, tenancy, entitlements (auto-imported)
├── core/ # Layer 1 — Business domains: billing, catalog, team
└── product/ # Layer 2 — Product features: onboarding, analytics
common/ # Cross-cutting utilities (auto-imported)
Layer Dependency Rules
Strict import rules enforced by ESLint:
product/ → can import → core/, foundation/, common/
core/ → can import → foundation/, common/
foundation/ → can import → common/ only
common/ → imports NOTHING from features/
Violations the agent must reject: common/ importing from features/*, foundation/ importing from core/, core/ importing from product/, cross-imports between core features (except catalog).
API Call Pattern
The correct pattern for making API calls, enforced by ESLint rules:
// ❌ WRONG
const { data } = useFetch('/api/v1/subscription')
// ✅ CORRECT
const { data } = useAuthenticatedAsyncData(
'billing:subscription',
() => billingApi.getSubscription()
)
The flow: Page → Composable → useXxxApi() → common/api/client.ts
Auth (Sanctum cookies) and tenant context are not available during SSR. Raw useAsyncData without server: false will silently return null during SSR. The useAuthenticatedAsyncData wrapper forces client-side fetching for authenticated routes.
File Structure Per Feature
Every feature follows a consistent structure:
features/core/<feature>/
├── index.ts # Public API (barrel exports) — REQUIRED
├── composables/ # Reactive logic
├── components/ # Vue components
├── api/ # API calls + Zod validation — core/product only
├── types.ts # TypeScript types — REQUIRED
└── schemas.ts # Zod schemas — REQUIRED
Additional Rules
- Zod validation — All API responses must be validated with
.parse() - useAsyncData keys — Namespaced:
billing:subscription,catalog:plans - Composable returns — Return
readonly()refs unless mutation is part of the API - Import rules — Foundation features are auto-imported; core/product use explicit barrel imports
For more on the frontend architecture, see Vertical Slices and Validation.
Progressive Disclosure Model
The configuration system uses a two-tier approach to manage context efficiently:
Why this matters: AI agents have context windows. Loading every convention document, every template, and every domain rule for every task wastes tokens and reduces response quality. Progressive disclosure keeps the base context lean (~150 lines at root level) while providing unlimited depth through the Skills System.
The base CLAUDE.md files answer: "Where does my code go? What are the naming conventions? What rules must I always follow?"
Skills answer: "How does billing work? What are the Stripe webhook patterns? How do I test tenant isolation? What are the currency invariants?"
Customizing for Your Project
When you add new domains to the boilerplate, keep the configuration files up to date.
Adding Domain Entities
When you create a new model, add it to the domain entities table in the root CLAUDE.md:
| **Notification** | Push/email notification with delivery tracking |
This ensures every AI agent session knows about the new entity.
Adding Critical Conventions
If your project has domain-specific rules that should always be loaded, add them to the "Critical Conventions" section:
### Analytics
- All tracking events must include `tenant_id` and `user_id`
- Event names use dot notation: `billing.subscription.created`
- Never track PII in event properties
What to Keep vs. Move to a Skill
| Keep in CLAUDE.md | Move to a Skill |
|---|---|
One-line rules (always snake_case) | Multi-paragraph domain explanations |
| Directory structure and file locations | Step-by-step workflows |
| Command reference | Common mistakes and anti-patterns |
| Entity list (name + one-line description) | Full entity relationships and invariants |
What's Next
- Skills System — On-demand domain expertise loaded via
/skill-name - Workplan Execution — Structured AI-driven feature development
- Architecture Overview — The project architecture these configuration files describe
AI-Assisted Development Overview
How SaaS4Builders is designed for AI coding agents: configuration files, convention documents, and structured execution patterns that keep AI output consistent and correct.
Skills System
What Claude Code skills are, the 15 skills shipped with the boilerplate, skill anatomy, and how to create custom skills for your domain.