- AI chat with SSE streaming (Microsoft Agent Framework + Qwen) - RAG Q&A with hybrid retrieval (vector + keyword RRF fusion) - Knowledge base CRUD with semantic text chunking - Embedding generation via Azure.AI.OpenAI / LM Studio - Document upload with chunked upload support - Redis caching for chat messages - Chunk/vector preview endpoints - gRPC auth service improvements - Removed demo menus, cleaned up seed data
4.9 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Cross-repo rules — see
/Users/wen/project/rag/CLAUDE.mdfor full workspace conventions. Key shared rules:
- File-scoped namespaces, primary constructor DI,
recordfor DTOs/Commands/Queries- Entity:
BaseEntity + IAuditable/ISoftDelete/IFullAuditmarker interfaces- EF Config: snake_case table,
ValueGeneratedNever(),IEntityTypeConfiguration<T>- Endpoint:
FastEndpoint<TReq, TRes>+Permissions("resource:action")- Middleware:
Cors → GlobalException → ApiResponse → Auth → AuthZ → FastEndpoints- Response:
{ code: 0, data, message: "ok" }(auto-wrapped)- JWT shared key:
RagJwtSecretKey2026MustBeAtLeast32CharsLong!- Other repos:
rag-backend(5211),im-system(5212),work-flow,file-system(8080 Go),rag-frontend(5666 Vue)
Build & Run
dotnet build
cd src/RAG.Api && dotnet run # HTTP :5211, gRPC :50051
cd src/RAG.Api && dotnet run -- --seed # Migrate + seed, then exit
cd src/RAG.Infrastructure && dotnet ef migrations add <Name> --startup-project ../RAG.Api
cd src/RAG.Infrastructure && dotnet ef database update --startup-project ../RAG.Api
docker compose up -d # PostgreSQL 17 + pgvector, Redis 7, RabbitMQ 3
Architecture
.NET 10, ABP modular. Four projects: Api → Application → Infrastructure → Domain.
ABP Module Chain
RAGApiModule [DependsOn(RAGApplicationModule, RAGInfrastructureModule)]
→ RAGApplicationModule [DependsOn(RAGInfrastructureModule)]
→ RAGInfrastructureModule [DependsOn(RAGDomainModule)]
DI in ConfigureServices(), middleware in OnApplicationInitialization(). Program.cs bootstraps via builder.AddApplicationAsync<RAGApiModule>().
Middleware Order
Cors → GlobalExceptionMiddleware → ApiResponseMiddleware → Authentication → Authorization → FastEndpoints → SwaggerGen → MapGrpcService
Feature Folder Convention
Application/{Feature}/
Commands/{Action}{Entity}Command.cs — record + Handler(DbContext) in same file
Queries/{Action}{Entity}Query.cs — record + Handler(DbContext) in same file
DTOs/{Entity}DTOs.cs — all DTOs for feature in one file
Validators/{Entity}CommandValidators.cs — FluentValidation rules
Api/Endpoints/{Feature}/
{Action}{Entity}Endpoint.cs — FastEndpoint<TReq, TRes>
gRPC Auth Service
AuthGrpcService (code-first via protobuf-net.Grpc) exposes ValidateToken and CheckPermission. Other services (file-system, work-flow, im-system) call these RPCs.
Seed Data
SeedData.cs creates: 11 permissions, 3 roles (SuperAdmin/Admin/User), admin user (admin/admin123), ~13 demo menus.
Code Patterns
Entity
public class User : BaseEntity, IFullAudit
{
public string Username { get; set; } = default!;
public ICollection<UserRole> UserRoles { get; set; } = [];
// IAuditable, ISoftDelete, IHasOperatorIP fields with = default!
}
Join tables: composite key + IAuditable only (no BaseEntity, no soft delete).
EF Configuration
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.ToTable("users"); // snake_case
builder.HasKey(e => e.Id);
builder.Property(e => e.Id).ValueGeneratedNever(); // Client-generated Guid
builder.HasIndex(e => e.Username).IsUnique();
}
}
Command + Handler (same file)
public record CreateUserCommand(string Username, string Email, string Password) : IRequest<UserDto>;
public class CreateUserCommandHandler(RagDbContext db) : IRequestHandler<CreateUserCommand, UserDto>
{
public async Task<UserDto> Handle(CreateUserCommand request, CancellationToken ct) { ... }
}
Endpoint
public class CreateUserEndpoint(IMediator mediator) : Endpoint<CreateUserRequest, UserDto>
{
public override void Configure() { Post("/users"); Permissions("user:create"); }
public override async Task HandleAsync(CreateUserRequest req, CancellationToken ct) { ... }
}
Validation
public class CreateUserCommandValidator : AbstractValidator<CreateUserCommand>
{
public CreateUserCommandValidator()
{
RuleFor(x => x.Username).NotEmpty().Length(3, 50);
}
}
Auto-registered + ValidationBehavior pipeline. Chinese error messages.
Conventions
- File-scoped namespaces everywhere
- Primary constructors for DI (endpoints, handlers, middleware)
recordfor DTOs/Commands/Queries,classfor entities/handlers/endpoints- Nullable reference types ON,
= default!for required strings TreatWarningsAsErrorsON- Permission codes:
{resource}:{action}(e.g.,user:create) - Response:
{ code: 0, data, message: "ok" }(auto-wrapped) - Route prefix:
/api/