Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .claude/agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Agents

How AI assistants should behave when working with this codebase.

## Identity

You are assisting with **FullStackHero .NET Starter Kit** β€” a production-ready, multi-tenant SaaS framework.

Your role: Help developers build features following established patterns, not invent new ones.

## Before You Start

1. **Understand the request** β€” Is it a feature, fix, or question?
2. **Locate the context** β€” Which module? Which layer?
3. **Check existing patterns** β€” Find similar code to follow
4. **Verify constraints** β€” Review rules before implementing

## Behavior

### Do
- Follow existing patterns exactly β€” consistency over creativity
- Reference actual code in the repo as examples
- Ask clarifying questions before making assumptions
- Verify builds pass with 0 warnings after changes
- Keep changes minimal and focused

### Don't
- Invent new architectural patterns
- Modify BuildingBlocks without explicit approval
- Skip validation on any command
- Return entities directly from endpoints
- Use MediatR patterns (this uses Mediator library)

## Response Style

### For "How do I..." questions
1. Point to existing similar code
2. Show the pattern with repo-specific examples
3. List the files they need to create/modify

### For "Create a..." requests
1. Confirm the module and feature name
2. Generate all required files (Command, Handler, Validator, Endpoint)
3. Show where to wire it up
4. Include the build verification step

### For "Fix..." requests
1. Understand the error/issue first
2. Check if it violates any rules
3. Propose minimal fix following existing patterns
4. Verify the fix doesn't break other things

## Decision Framework

### "Where does this go?"
```
Is it a new API endpoint?
β†’ Modules/{Module}/Features/v1/{Name}/

Is it a shared type for external use?
β†’ Modules.{Module}.Contracts/

Is it a cross-cutting concern?
β†’ BuildingBlocks/ (needs approval)

Is it a new business domain?
β†’ New Modules.{Name}/ project
```

### "Should I create a new module?"
```
Does it have its own domain entities? β†’ Yes = new module
Could it be deployed independently? β†’ Yes = new module
Is it just a feature in existing domain? β†’ No = existing module
```

### "Which pattern do I use?"
```
Changing state? β†’ Command + Handler + Validator + Endpoint
Reading data? β†’ Query + Handler + Endpoint
Domain event? β†’ Implement IDomainEvent, raise from entity
Background work? β†’ Use Hangfire job
```

## Verification Checklist

Before considering any task complete:

- [ ] Code follows vertical slice structure
- [ ] DTOs are in Contracts project
- [ ] Command has a validator
- [ ] Endpoint has `.RequirePermission()` or `.AllowAnonymous()`
- [ ] Endpoint has `.WithName()` and `.WithSummary()`
- [ ] Using Mediator interfaces (not MediatR)
- [ ] `dotnet build src/FSH.Framework.slnx` shows 0 warnings
- [ ] No direct entity exposure in responses

## Common Mistakes to Catch

| If you see... | It's wrong because... | Fix |
|---------------|----------------------|-----|
| `IRequest<T>` | That's MediatR | Use `ICommand<T>` or `IQuery<T>` |
| `IRequestHandler<T,R>` | That's MediatR | Use `ICommandHandler<T,R>` or `IQueryHandler<T,R>` |
| Entity in response | Exposes internals | Create DTO in Contracts |
| No validator | Validation required | Add `AbstractValidator<T>` |
| Manual tenant filter | Framework handles this | Implement `IHasTenant` |
| Code in BuildingBlocks | Affects all modules | Move to module or get approval |
76 changes: 76 additions & 0 deletions .claude/rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Rules

Hard constraints that must always be followed.

## Architecture Rules

1. **Vertical Slices Only**
- Every feature lives in `Modules/{Module}/Features/v1/{FeatureName}/`
- Never scatter feature code across multiple directories
- One folder = one complete feature

2. **Module Boundaries**
- Modules only communicate through Contracts projects
- Never reference internal types across modules
- DTOs always in `Modules.{Name}.Contracts/`

3. **BuildingBlocks Protection**
- Changes to `BuildingBlocks/` require explicit approval
- These affect ALL modules - changes ripple everywhere
- Prefer extension over modification

## Code Rules

4. **Mediator Not MediatR**
- Use `Mediator` source generator library
- Interfaces: `ICommand<T>`, `IQuery<T>`, `ICommandHandler<T,R>`, `IQueryHandler<T,R>`
- Never use `IRequest<T>` or `IRequestHandler<T,R>` (those are MediatR)

5. **Validation Required**
- Every command must have an `AbstractValidator<TCommand>`
- No exceptions - validation is not optional
- Validators auto-register via FluentValidation

6. **No Entity Exposure**
- Never return domain entities from endpoints
- Always map to DTOs from Contracts project
- Entities are internal implementation details

7. **Explicit Authorization**
- Every endpoint needs `.RequirePermission()` or `.AllowAnonymous()`
- Use permission constants from `{Module}PermissionConstants`
- No implicit security

8. **Zero Warnings**
- Build must pass with 0 warnings
- Run `dotnet build src/FSH.Framework.slnx` and verify
- CI enforces this - no exceptions

## Naming Rules

9. **Consistent Naming**
| Type | Pattern |
|------|---------|
| Commands | `{Action}{Entity}Command` |
| Queries | `Get{Entity}Query` or `Get{Entities}Query` |
| Handlers | `{CommandOrQuery}Handler` |
| Validators | `{Command}Validator` |
| Endpoints | `{CommandOrQuery}Endpoint` |
| DTOs | `{Entity}Dto`, `{Entity}Response`, `{Action}{Entity}Request` |

10. **File = Type**
- One public type per file
- Filename matches type name exactly
- `CreateUserCommand.cs` contains `CreateUserCommand`

## Multi-Tenancy Rules

11. **Tenant Isolation**
- Entities with tenant data implement `IHasTenant`
- Framework auto-filters queries by tenant
- Never manually filter by TenantId in queries

12. **No Hardcoded Tenants**
- Never hardcode tenant IDs
- Use `ICurrentUser.TenantId` for current tenant
- Tenant context comes from framework
Loading
Loading