---
name: project-rules
description: GoodGo Platform coding standards and architecture. Use when working with services, apps, packages, or infrastructure.
compatibility: ".NET 10+, ASP.NET Core, MediatR, Entity Framework Core"
metadata:
  author: Velik Ho
  version: "2.0"
---

# GoodGo Project Rules / Quy Tắc Dự Án GoodGo

Coding standards and architecture patterns for GoodGo microservices platform.

## When to Use This Skill / Khi Nào Sử Dụng

Use this skill when:
- Creating new .NET services / Tạo services .NET mới
- Working with project structure / Làm việc với cấu trúc dự án
- Following naming conventions / Tuân thủ quy tắc đặt tên
- Deploying services with Docker/Traefik / Triển khai với Docker/Traefik
- Understanding tech stack / Hiểu tech stack của dự án

## Core Concepts / Khái Niệm Cốt Lõi

### Monorepo Structure / Cấu Trúc Monorepo

```
goodgo/
├── apps/                    # Frontend applications
│   ├── web/                 # Next.js web app
│   └── mobile/              # Flutter mobile app
├── services/                # .NET microservices
│   ├── _template_dot_net/   # Template for new .NET services
│   ├── iam-service-net/     # Identity & Access Management
│   ├── storage-service-net/ # File storage service
│   └── ...
├── packages/                # Shared libraries
├── infra/                   # Infrastructure config
│   ├── traefik/             # API Gateway config
│   └── observability/       # Monitoring stack
└── deployments/             # Deployment configs
    ├── local/               # Docker Compose for local dev
    └── kubernetes/          # K8s manifests
```

### Clean Architecture / Kiến Trúc Clean

```
src/
├── ServiceName.API/           # Presentation layer
│   ├── Controllers/           # API Controllers
│   ├── Application/           # Commands, Queries, Handlers
│   └── Program.cs             # App entry point
├── ServiceName.Domain/        # Business logic
│   ├── AggregatesModel/       # Domain entities
│   ├── Exceptions/            # Domain exceptions
│   └── SeedWork/              # Base classes
└── ServiceName.Infrastructure/ # External concerns
    ├── Data/                  # EF Core DbContext
    ├── Repositories/          # Repository implementations
    └── Services/              # External service clients
```

### Tech Stack / Công Nghệ

| Layer | Technology |
|-------|------------|
| **Backend** | .NET 8, ASP.NET Core, MediatR |
| **Database** | PostgreSQL (Neon), EF Core |
| **Caching** | Redis, StackExchange.Redis |
| **API Gateway** | Traefik |
| **Observability** | Prometheus, Grafana, Loki |
| **Frontend** | Next.js 14+, Flutter 3.x |

## Key Patterns / Mẫu Chính

### Service Template Structure / Cấu Trúc Template

```
services/_template_dot_net/
├── src/
│   ├── MyService.API/
│   ├── MyService.Domain/
│   └── MyService.Infrastructure/
├── tests/
├── docs/
├── Dockerfile
├── docker-compose.yml
└── MyService.slnx
```

### Controller Pattern / Mẫu Controller

```csharp
/// <summary>
/// EN: Controller for user management.
/// VI: Controller quản lý user.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/users")]
[SwaggerTag("User Management")]
public class UsersController : ControllerBase
{
    private readonly IMediator _mediator;

    public UsersController(IMediator mediator)
    {
        _mediator = mediator;
    }

    /// <summary>
    /// EN: Get user by ID.
    /// VI: Lấy user theo ID.
    /// </summary>
    [HttpGet("{userId:guid}")]
    [SwaggerOperation(Summary = "Get user by ID")]
    [SwaggerResponse(200, "Success")]
    [SwaggerResponse(404, "Not found")]
    public async Task<ActionResult<ApiResponse<UserDto>>> GetUser(
        Guid userId,
        CancellationToken ct = default)
    {
        var result = await _mediator.Send(new GetUserQuery(userId), ct);
        
        if (result == null)
            return NotFound(new ApiResponse<UserDto> 
            { 
                Success = false, 
                Error = "User not found" 
            });

        return Ok(new ApiResponse<UserDto> { Success = true, Data = result });
    }
}
```

### API Response Wrapper / Wrapper Response

```csharp
/// <summary>
/// EN: Standard API response wrapper.
/// VI: Wrapper response API chuẩn.
/// </summary>
public class ApiResponse<T>
{
    public bool Success { get; set; }
    public T? Data { get; set; }
    public string? Error { get; set; }
}
```

### Docker Compose with Traefik / Docker Compose với Traefik

```yaml
services:
  my-service-net:
    build:
      context: ../..
      dockerfile: services/my-service-net/Dockerfile
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ConnectionStrings__DefaultConnection=${DATABASE_URL}
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.my-service-net.rule=PathPrefix(`/api/v1/my-service`)"
      - "traefik.http.services.my-service-net.loadbalancer.server.port=8080"
    networks:
      - goodgo-network
```

### Dockerfile Pattern / Mẫu Dockerfile

```dockerfile
# EN: Build stage / VI: Stage build
FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o /app

# EN: Runtime stage / VI: Stage runtime
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
WORKDIR /app
COPY --from=build /app .

# EN: Create non-root user / VI: Tạo user không phải root
RUN adduser -D appuser && chown -R appuser /app
USER appuser

EXPOSE 8080
ENTRYPOINT ["dotnet", "MyService.API.dll"]
```

## Naming Conventions / Quy Tắc Đặt Tên

| Type | Convention | Example |
|------|------------|---------|
| **Service folder** | kebab-case + `-net` | `storage-service-net` |
| **Solution file** | PascalCase | `StorageService.slnx` |
| **Project folder** | PascalCase | `StorageService.API` |
| **C# Files** | PascalCase | `FilesController.cs` |
| **Classes** | PascalCase | `StorageFileRepository` |
| **Methods** | PascalCase | `GetFileAsync()` |
| **Variables** | camelCase | `fileContent` |
| **Private fields** | _camelCase | `_mediator` |
| **Constants** | PascalCase | `MaxFileSize` |

## Common Mistakes / Lỗi Thường Gặp

### 1. Wrong Project Structure / Cấu Trúc Sai

```
# ❌ BAD: Flat structure
src/
  Controllers/
  Services/
  Models/

# ✅ GOOD: Clean Architecture
src/
  MyService.API/
  MyService.Domain/
  MyService.Infrastructure/
```

### 2. Missing Bilingual Comments / Thiếu Comment Song Ngữ

```csharp
// ❌ BAD: English only
/// <summary>Get file by ID.</summary>

// ✅ GOOD: Bilingual
/// <summary>
/// EN: Get file by ID.
/// VI: Lấy file theo ID.
/// </summary>
```

### 3. Inconsistent Response Format / Response Không Nhất Quán

```csharp
// ❌ BAD: Direct return
return Ok(file);

// ✅ GOOD: ApiResponse wrapper
return Ok(new ApiResponse<FileDto> { Success = true, Data = file });
```

### 4. Missing API Versioning / Thiếu Versioning

```csharp
// ❌ BAD: No versioning
[Route("api/files")]

// ✅ GOOD: With versioning
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/files")]
```

## Quick Reference / Tham Chiếu Nhanh

### Project Structure

| Component | Location |
|-----------|----------|
| **Service template** | `services/_template_dot_net/` |
| **Controllers** | `src/ServiceName.API/Controllers/` |
| **Commands/Queries** | `src/ServiceName.API/Application/` |
| **Domain entities** | `src/ServiceName.Domain/AggregatesModel/` |
| **Repositories** | `src/ServiceName.Infrastructure/` |
| **Traefik config** | `infra/traefik/` |
| **Docker Compose** | `deployments/local/docker-compose.yml` |

### Common Commands

```bash
# EN: Build solution / VI: Build solution
dotnet build

# EN: Run service / VI: Chạy service
dotnet run --project src/MyService.API

# EN: Run tests / VI: Chạy tests
dotnet test

# EN: Add migration / VI: Thêm migration
dotnet ef migrations add MigrationName --project src/MyService.Infrastructure

# EN: Update database / VI: Cập nhật database
dotnet ef database update --project src/MyService.Infrastructure

# EN: Docker build / VI: Build Docker
docker-compose -f deployments/local/docker-compose.yml build my-service-net

# EN: Docker run / VI: Chạy Docker
docker-compose -f deployments/local/docker-compose.yml up -d my-service-net

# EN: View logs / VI: Xem logs
docker-compose -f deployments/local/docker-compose.yml logs -f my-service-net
```

### Endpoints

| Type | URL Pattern |
|------|-------------|
| **API** | `http://localhost/api/v1/{service-name}` |
| **Health** | `http://localhost/api/v1/{service-name}/health` |
| **Swagger** | `http://localhost/api/v1/{service-name}/swagger` |
| **Traefik Dashboard** | `http://localhost:8080` |

## Resources / Tài Nguyên

- [.NET Microservice Workflow](../dotnet-microservice-workflow/SKILL.md) - 4-phase development workflow
- [API Design](../api-design/SKILL.md) - API patterns
- [Error Handling Patterns](../error-handling-patterns/SKILL.md) - Error handling
- [Repository Pattern](../repository-pattern/SKILL.md) - Data access
- [Testing Patterns](../testing-patterns/SKILL.md) - Testing
- [Deployment Kubernetes](../deployment-kubernetes/SKILL.md) - K8s deployment
- [Skill Authoring](../skill-authoring/SKILL.md) - How to write skills
