Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
5324c19
refactor(identity,auditing): apply code review improvements to Groups…
Feb 21, 2026
dfe8ae9
fix(identity): add Produces(204/401/403) to all delete endpoints to f…
Feb 21, 2026
087b3e5
chore(blazor): regenerate NSwag client to fix 204 NoContent handling …
Feb 21, 2026
56b694d
Revert "chore(blazor): regenerate NSwag client to fix 204 NoContent h…
Feb 21, 2026
b20407a
fix(blazor): patch Generated.cs delete methods to accept HTTP 204 NoC…
Feb 21, 2026
79e7481
fix(identity,blazor): revert DeleteGroup and RemoveUserFromGroup to O…
Feb 22, 2026
49bee9c
fix(identity): standardize all delete endpoints to Ok() with TODO for…
Feb 22, 2026
e50d66c
fix(blazor): restore Generated.cs delete methods to original status_=…
Feb 22, 2026
e48e3df
fix(identity): fix EF Core translation error in CreateGroupCommandHan…
Feb 23, 2026
48c1606
feat(auditing): standardize auditing endpoints with TypedResults and …
cesarcastrocuba Feb 24, 2026
c7b1a55
feat(multitenancy): standardize multitenancy endpoints with TypedResu…
cesarcastrocuba Feb 24, 2026
b71ed74
refactor(identity): restore granular permissions for session manageme…
cesarcastrocuba Feb 24, 2026
0ba8e18
feat(identity): standardize roles and groups endpoints with TypedResu…
cesarcastrocuba Feb 24, 2026
0e94787
feat(identity): standardize users endpoints, refine permissions, and …
cesarcastrocuba Feb 24, 2026
f8c01ce
fix(identity): use parsedAccessToken.Subject for more reliable subjec…
cesarcastrocuba Feb 24, 2026
27451be
chore: update vscode settings
cesarcastrocuba Feb 24, 2026
372a997
chore: add antigravity/gemini agent configuration and documentation
cesarcastrocuba Feb 24, 2026
4d8fd68
chore(openapi): fix generation script and regenerate clients
cesarcastrocuba Feb 25, 2026
96e7bd9
feat(identity): standardize endpoints with TypedResults (201/204)
cesarcastrocuba Feb 25, 2026
b9bef6d
feat(multitenancy): standardize tenant endpoint with TypedResults (201)
cesarcastrocuba Feb 25, 2026
ffa72f1
fix: address code review findings in endpoint standardization
Feb 26, 2026
a85f0a7
perf: optimize logging by wrapping calls in IsEnabled checks to resol…
cesarcastrocuba Feb 26, 2026
4dd146d
fix(security): remove ConnectionString from startup log to prevent cr…
Feb 26, 2026
4cd3cdf
fix(identity): align Group entity with FSH BaseEntity<Guid> pattern a…
Feb 26, 2026
92c597c
perf: wrap log calls with IsEnabled guards in Identity and Multitenan…
Feb 26, 2026
6b92443
perf: wrap log calls with IsEnabled guards in BuildingBlocks and Play…
Feb 26, 2026
1408ebf
refactor(domain): align remaining entities with BaseEntity<Guid> and …
Feb 28, 2026
7cefd23
chore: add .aspire/ to .gitignore to prevent local dashboard settings…
Feb 28, 2026
4da9a43
perf: migrate Endpoints and Services to ValueTask to reduce allocations
cesarcastrocuba Feb 26, 2026
dd8faa9
fix(identity): protect default framework roles from deletion
Feb 28, 2026
9a6e78d
style: fix indentation and spacing in CreateUserDialog.razor
Feb 28, 2026
5ef38dc
Revert "style: fix indentation and spacing in CreateUserDialog.razor"
Feb 28, 2026
616cf52
style: restore tabular formatting for MudTextField components
Feb 28, 2026
f102d9e
chore(docs): sync AI documentation and replace Moq with NSubstitute
cesarcastrocuba Mar 6, 2026
ccb4307
chore(sdd): implement generic spec-driven development workflow
cesarcastrocuba Mar 6, 2026
4025153
feat(sdd): add automated branch creation to spec coordinator
cesarcastrocuba Mar 6, 2026
d0e9aba
chore(workflows): Formalize SDD Phase 5 and unify agent structure
cesarcastrocuba Mar 7, 2026
8b38455
chore(workflows): Formalize SDD Phase 6 Walkthrough and unify agent s…
cesarcastrocuba Mar 7, 2026
200457f
docs(ai): update claude testing rules to reflect NSubstitute over Moq
cesarcastrocuba Mar 6, 2026
ba35f90
chore(sdd): implement generic spec-driven development workflow
cesarcastrocuba Mar 6, 2026
0a1db79
feat(sdd): add automated branch creation to spec coordinator
cesarcastrocuba Mar 6, 2026
6036da9
chore(workflows): Formalize SDD Phase 5 and unify agent structure
cesarcastrocuba Mar 7, 2026
176b2d2
chore(workflows): Formalize SDD Phase 6 Walkthrough and unify agent s…
cesarcastrocuba Mar 7, 2026
c35fd60
feat(sdd): add automated branch creation to spec coordinator
cesarcastrocuba Mar 6, 2026
4cbbf0a
chore(workflows): Formalize SDD Phase 5 and unify agent structure
cesarcastrocuba Mar 7, 2026
a221836
chore(workflows): Formalize SDD Phase 6 Walkthrough and unify agent s…
cesarcastrocuba Mar 7, 2026
53542f4
fix(multitenancy): BUG-1 & BUG-2 - Remove duplicate ITenantService re…
cesarcastrocuba Mar 7, 2026
553d11d
fix(multitenancy): BUG-3 & PERF-1 - atomic check in DeactivateAsync, …
cesarcastrocuba Mar 7, 2026
91e107c
fix(multitenancy): BUG-4 - Thread cancellation token in TenantProvisi…
cesarcastrocuba Mar 7, 2026
a82a32c
fix(multitenancy): CACHE-2 - Invalidate theme:default cache on ResetT…
cesarcastrocuba Mar 7, 2026
f14ee68
fix(identity): CACHE-1, IDENTITY-1, IDENTITY-2 - tenant isolate permi…
cesarcastrocuba Mar 7, 2026
dd17e3a
fix(eventing): EVENTING-1, EVENTING-2 - Restore tenant context in out…
cesarcastrocuba Mar 7, 2026
042cb97
fix(auditing,storage): AUDITING-1, STORAGE-1 - Apply soft-delete filt…
cesarcastrocuba Mar 7, 2026
4c05013
test(multitenancy): BUG-1 - Verify single DI registration for ITenant…
cesarcastrocuba Mar 7, 2026
f234fa8
test(multitenancy): BUG-4 - Verify TenantProvisioningJob threads canc…
cesarcastrocuba Mar 7, 2026
09f1f28
test(multitenancy,storage): CACHE-2, STORAGE-1 - Unit tests for theme…
cesarcastrocuba Mar 7, 2026
0b41888
test(multitenancy,storage): CACHE-2, STORAGE-1 - Unit tests for theme…
cesarcastrocuba Mar 7, 2026
3fbb729
test(auditing,eventing,storage): Verify AUDITING-1, EVENTING-1, EVENT…
cesarcastrocuba Mar 7, 2026
de52c7d
fix(tenancy): Include missing project and test modifications
cesarcastrocuba Mar 7, 2026
45b2a9d
docs(sdd): Add final walkthrough as 6-walkthrough.md
cesarcastrocuba Mar 7, 2026
e805774
docs(sdd): Include implementation report and spec artifacts
cesarcastrocuba Mar 7, 2026
c43e7dd
fix(identity): Revert IsMultiTenant configurations breaking login wit…
cesarcastrocuba Mar 7, 2026
a4bc137
docs(sdd): Add final walkthrough as 6-walkthrough.md
cesarcastrocuba Mar 7, 2026
340fdab
docs(sdd): Include implementation report and spec artifacts
cesarcastrocuba Mar 7, 2026
348113e
fix(identity): Revert IsMultiTenant configurations breaking login wit…
cesarcastrocuba Mar 7, 2026
e6f3db3
Merge branch 'pr/update-ai-testing-docs' into develop
cesarcastrocuba Mar 7, 2026
da23e88
Merge branch 'pr/setup-sdd-workflow' into develop
cesarcastrocuba Mar 7, 2026
f4b71e4
Merge branch 'pr/tenancy-isolation-nomigration' into develop
cesarcastrocuba Mar 7, 2026
2431d5d
feat: implement testing architecture redesign (Resolves #23)
Mar 7, 2026
efd59a2
fix(identity): re-apply multitenancy configurations for groups and fi…
Mar 8, 2026
ae19b5a
Merge branch 'pr/tenancy-isolation-nomigration' into develop
Mar 8, 2026
9f35163
chore: resolve merge conflicts after integrating official tenancy fixes
Mar 8, 2026
d0c88c9
docs: complete implementation and walkthrough for testing architectur…
Mar 8, 2026
7105775
docs: add implementation detail for testing architecture redesign
Mar 8, 2026
a151845
docs: finalize testing architecture documentation and polish function…
Mar 8, 2026
9a17f1b
fix: resolve IdentityDbContext constructor crash and document [ERR] l…
Mar 8, 2026
90de4bb
fix: restore original TenantInfo property pattern and layout in Ident…
Mar 8, 2026
98d38f1
test(architecture,identity): fix pre-existing failing tests inherited…
Mar 8, 2026
60b351e
Merge branch 'pr/tenancy-isolation-nomigration' into develop
Mar 8, 2026
a8dea3d
Merge branch 'pr/tenancy-isolation-nomigration' into pr/testing-archi…
Mar 8, 2026
33c8f12
docs: finalize redesign walkthrough with pg fix description
cesarcastrocuba Mar 9, 2026
b3e6c0f
fix(auditing): adjust AuditRecord TenantId length to match pg schema
Mar 14, 2026
082979f
fix(eventing): graceful degradation for outbox dispatcher during test…
Mar 14, 2026
574d2bd
fix(auditing): suppress OperationCanceledException during background …
Mar 14, 2026
287d01f
fix: resolve remaining compiler, sonarqube, and nuget vulnerability w…
Mar 14, 2026
9604596
fix: ignore Shared.Tests project during test execution
Mar 14, 2026
7b441ac
docs: restore module-specific tests to guide and add new tests
Mar 14, 2026
90286c2
fix(feat): remove problematic unit tests but keep documentation resto…
Mar 14, 2026
96246ea
chore: restore tenancy tests for future migration
Mar 15, 2026
75dc098
docs: explicitly formalize NSubstitute over Moq in testing guide
Mar 15, 2026
ab48aae
docs: sync agents testing guide with claude testing guide
Mar 15, 2026
1f79302
fix(web): include tenantId and userId in GlobalExceptionHandler logs …
Mar 15, 2026
bf0cf55
fix(identity): align JWT claim mapping and add UserId fallbacks [I-14]
Mar 15, 2026
f84d873
feat(persistence): add AuditableEntitySaveChangesInterceptor with rec…
Mar 16, 2026
b9d812f
feat(audit): implement IgnoreAuditTrail attribute and apply to infra …
Mar 16, 2026
42b8dde
feat(jobs): propagate CorrelationId from web requests to background jobs
Mar 16, 2026
98a99e3
Merge branch 'fix/web-tenantid-error-logs' into develop (resolved con…
Mar 18, 2026
6f1c466
Merge branch 'fix/blazor-currentuser-claim' into develop
Mar 18, 2026
cc771d8
Merge branch 'fix/identity-dbcontext-interceptor-loop' into develop
Mar 18, 2026
b243cc1
Merge branch 'fix/ignore-audit-trail-attribute' into develop (resolve…
Mar 18, 2026
740145a
Merge branch 'feat/jobs-correlationid' into develop
Mar 18, 2026
2bb72a5
Merge branch 'feat/testing-architecture-redesign' into develop
Mar 18, 2026
04352da
feat(docs): reorganize SDD specs into type/date/slug structure
Mar 18, 2026
93367f5
feat(config): include docs folder in version control
Mar 18, 2026
0a980a0
feat: standardize timestamps to DateTimeOffset and OnUtc suffix acros…
Mar 20, 2026
b0635ab
Fix all 26 build warnings and standardize migrations
Mar 21, 2026
2a2c12c
Merge fix/tenancy-migration-standardization: Fix 26 build warnings an…
Mar 21, 2026
727056e
Fix final 3 build warnings (S2696 and S4487)
Mar 21, 2026
18ad2cd
fix(web): sync CorrelationId with HttpContext.TraceIdentifier for job…
Mar 21, 2026
1d1caf3
Merge branch 'feat/jobs-correlationid' into develop
Mar 21, 2026
3e87fc5
security: pin Scriban to 6.6.0 to resolve transitive vulnerabilities
Mar 21, 2026
fd0a189
fix(multitenancy): standardize tenant pattern, resolve missing migrat…
Mar 22, 2026
723c26c
docs(specs): complete SDD phases 5 and 6 for tenant pattern unification
Mar 22, 2026
c4e280a
fix(identity): remove redundant example hangfire outbox dispatcher
Mar 22, 2026
a2a70ec
Merge branch 'fix/tenant-pattern-unification' into develop: resolve i…
Mar 22, 2026
93c65f5
feat(caching): add ITenantCacheService structural guardrail (Issue #9)
Mar 23, 2026
195c945
Merge fix/tenant-cache-service: ITenantCacheService structural guardr…
Mar 23, 2026
f10ea3c
fix: pre-create database on first Aspire startup (issue #16)
Mar 23, 2026
aca2b83
docs: complete SDD documentation for fix #16
Mar 23, 2026
08aa296
Add MSSQL support with migrations and test infra updates
Mar 24, 2026
389ec52
Merge branch 'develop' into feat/mssql-dbprovider-support
Mar 24, 2026
2e8ae78
Standardize timestamps and tenancy across all modules
Mar 25, 2026
448d128
Remove **/wwwroot/uploads/* from .gitignore. This path is needed to s…
Mar 25, 2026
b934aa7
Revert "Remove **/wwwroot/uploads/* from .gitignore. This path is nee…
Mar 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
65 changes: 65 additions & 0 deletions .agents/rules/api-conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
paths:
- "src/Modules/**/Features/**/*"
- "src/Modules/**/*Endpoint*.cs"
---

# API Conventions

Rules for API endpoints in FSH.

## Endpoint Requirements

Every endpoint MUST have:

```csharp
endpoints.MapPost("/", handler)
.WithName(nameof(CommandOrQuery)) // Required: Unique name
.WithSummary("Description") // Required: OpenAPI description
.RequirePermission(Permission) // Required: Or .AllowAnonymous()
```

## HTTP Method Mapping

| Operation | Method | Return |
|-----------|--------|--------|
| Create | `MapPost` | `TypedResults.Created(...)` |
| Read single | `MapGet` | `TypedResults.Ok(...)` |
| Read list | `MapGet` | `TypedResults.Ok(...)` |
| Update | `MapPut` | `TypedResults.Ok(...)` or `NoContent()` |
| Delete | `MapDelete` | `TypedResults.NoContent()` |

## Route Patterns

```
/api/v1/{module}/{entities} # Collection
/api/v1/{module}/{entities}/{id} # Single item
/api/v1/{module}/{entities}/{id}/sub # Sub-resource
```

## Response Types

Always use `TypedResults`:
- `TypedResults.Ok(data)`
- `TypedResults.Created($"/path/{id}", data)`
- `TypedResults.NoContent()`
- `TypedResults.NotFound()`
- `TypedResults.BadRequest(errors)`

Never return raw objects or use `Results.Ok()`.

## Permission Format

```csharp
.RequirePermission({Module}Permissions.{Entity}.{Action})
```

Actions: `View`, `Create`, `Update`, `Delete`

## Query Parameters

Use `[AsParameters]` for complex queries:

```csharp
endpoints.MapGet("/", async ([AsParameters] GetProductsQuery query, ...) => ...)
```
247 changes: 247 additions & 0 deletions .agents/rules/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
---
paths:
- "src/**"
---

# Architecture Rules

FSH is a **Modular Monolith** — NOT microservices, NOT a traditional layered architecture.

## Core Principles

### 1. Modular Monolith

```
Single deployment unit
Multiple bounded contexts (modules)
Each module is self-contained
Communication via Contracts (interfaces/DTOs)
```

**Modules:**
- Identity (users, roles, permissions)
- Multitenancy (tenants, subscriptions)
- Auditing (audit trails)
- Your business modules (e.g., Catalog, Orders)

**Rules:**
- Modules CANNOT reference other module internals
- Modules CAN reference other module Contracts
- Modules share BuildingBlocks (framework code)

### 2. CQRS (Mediator Library)

**Commands** (write operations):
```csharp
public record CreateUserCommand(string Email) : ICommand<Guid>;

public class CreateUserHandler : ICommandHandler<CreateUserCommand, Guid>
{
public async ValueTask<Guid> Handle(CreateUserCommand cmd, CancellationToken ct)
{
// Write to database
return user.Id;
}
}
```

**Queries** (read operations):
```csharp
public record GetUserQuery(Guid Id) : IQuery<UserDto>;

public class GetUserHandler : IQueryHandler<GetUserQuery, UserDto>
{
public async ValueTask<UserDto> Handle(GetUserQuery query, CancellationToken ct)
{
// Read from database
return userDto;
}
}
```

⚠️ **NOT MediatR:** FSH uses `Mediator` library (different interfaces!)

### 3. Domain-Driven Design

**Entities** inherit `BaseEntity`:
```csharp
public class Product : BaseEntity, IAuditable
{
public string Name { get; private set; } = default!;
public Money Price { get; private set; } = default!;

public static Product Create(string name, Money price)
{
// Factory method, enforce invariants
return new Product { Name = name, Price = price };
}
}
```

**Value Objects** (immutable):
```csharp
public record Money(decimal Amount, string Currency);
```

**Aggregates:**
- Root entity controls access to child entities
- Enforce business rules
- Transaction boundary

### 4. Multi-Tenancy

**Finbuckle.MultiTenant:**
- Shared database, tenant isolation via TenantId
- Automatic query filtering
- Tenant resolution from HTTP header or claim

```csharp
// Tenant-aware entity
public class Order : BaseEntity, IMustHaveTenant
{
public Guid TenantId { get; set; } // Auto-filtered
}
```

**Tenant Resolution Order:**
1. HTTP header: `X-Tenant`
2. JWT claim: `tenant`
3. Host/route strategy (optional)

### 5. Vertical Slice Architecture

Each feature = complete slice (command/handler/validator/endpoint in one folder).

```
Features/v1/CreateProduct/
├── CreateProductCommand.cs
├── CreateProductHandler.cs
├── CreateProductValidator.cs
└── CreateProductEndpoint.cs
```

**Benefits:**
- High cohesion (related code together)
- Low coupling (features don't depend on each other)
- Easy to find/modify

### 6. BuildingBlocks (Shared Kernel)

11 packages providing cross-cutting concerns:

| Package | Purpose |
|---------|---------|
| Core | Base entities, interfaces, exceptions |
| Persistence | EF Core, repositories, specifications |
| Caching | Redis/memory caching |
| Mailing | Email templates, MailKit integration |
| Jobs | Hangfire background jobs |
| Storage | File storage (AWS S3, local) |
| Web | API conventions, filters, middleware |
| Eventing | Domain events, message bus |
| Blazor.UI | UI components (optional) |
| Shared | DTOs, constants |
| Eventing.Abstractions | Event contracts |

**Protected:** BuildingBlocks should NOT be modified without approval. See `.agents/rules/buildingblocks-protection.md`.

### 7. Dependency Flow

```
API Layer (Minimal APIs)
Application Layer (Commands/Queries/Handlers)
Domain Layer (Entities/Value Objects)
Infrastructure Layer (Persistence/External Services)
```

**Rules:**
- Domain CANNOT depend on infrastructure
- Application CANNOT depend on infrastructure directly
- Infrastructure implements domain interfaces

### 8. Persistence Strategy

**DbContext per Module:**
- IdentityDbContext
- MultitenancyDbContext
- AuditingDbContext
- Your module DbContexts

**Repository Pattern:**
```csharp
public interface IRepository<T> where T : BaseEntity
{
Task<T?> GetByIdAsync(Guid id, CancellationToken ct);
Task<List<T>> ListAsync(Specification<T> spec, CancellationToken ct);
Task<T> AddAsync(T entity, CancellationToken ct);
Task UpdateAsync(T entity, CancellationToken ct);
Task DeleteAsync(T entity, CancellationToken ct);
}
```

**Specification Pattern** (queries):
```csharp
public class ActiveProductsSpec : Specification<Product>
{
public ActiveProductsSpec()
{
Query.Where(p => !p.IsDeleted && p.IsActive);
}
}
```

## Architectural Tests

`Architecture.Tests` project enforces rules:

```csharp
[Fact]
public void Modules_Should_Not_Reference_Other_Modules()
{
// Fails if Module A references Module B directly
}

[Fact]
public void Domain_Should_Not_Depend_On_Infrastructure()
{
// Fails if domain entities reference EF Core
}
```

## Technology Stack

- **.NET 10** (latest LTS)
- **EF Core 10** (PostgreSQL provider)
- **Mediator** (CQRS)
- **FluentValidation** (input validation)
- **Mapster** (object mapping)
- **Hangfire** (background jobs)
- **Finbuckle.MultiTenant** (multi-tenancy)
- **MailKit** (email)
- **Scalar** (OpenAPI docs)
- **Serilog** (logging)
- **OpenTelemetry** (observability)
- **Aspire** (orchestration)

## Key Takeaways

1. **Modular Monolith** ≠ Microservices. Modules share process, database, infrastructure.
2. **CQRS** separates reads/writes. Use `ICommand`/`IQuery`, not `IRequest`.
3. **DDD** enforces business rules in domain. Entities control their state.
4. **Multi-Tenancy** is built-in. Every entity is either tenant-aware or shared.
5. **Vertical Slices** keep features independent. No shared "services" layer.
6. **BuildingBlocks** provide infrastructure. Don't reinvent, reuse.
7. **Tests enforce architecture**. Violate rules → build fails.

---

For implementation details, see:
- `ARCHITECTURE_ANALYSIS.md` (deep dive)
- `.agents/rules/modules.md` (module patterns)
- `.agents/rules/persistence.md` (data access patterns)
36 changes: 36 additions & 0 deletions .agents/rules/buildingblocks-protection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
paths:
- "src/BuildingBlocks/**/*"
---

# ⚠️ BuildingBlocks Protection

**STOP. You are modifying BuildingBlocks.**

Changes to BuildingBlocks affect ALL modules across the entire framework. These are core abstractions that many projects depend on.

## Before Proceeding

1. **Confirm explicit approval** - Has the user specifically approved this change?
2. **Consider alternatives** - Can this be done in the module instead?
3. **Assess impact** - What modules will this affect?

## If Approved

- Make minimal, focused changes
- Ensure backward compatibility
- Update all affected modules
- Run full test suite: `dotnet test src/FSH.Framework.slnx`
- Document the change

## Alternatives to Consider

| Instead of... | Consider... |
|---------------|-------------|
| Modifying Core | Extension method in module |
| Changing Persistence | Custom repository in module |
| Updating Web | Module-specific middleware |

## If Not Approved

Do not proceed. Suggest alternatives that don't require BuildingBlocks modifications.
Loading