docs: Update architecture and template documentation for GoodGo Platform

- Revised the architecture documentation to include detailed diagrams and descriptions for the GoodGo Microservices Platform, enhancing clarity on system components and interactions.
- Updated the .NET template documentation to reflect new naming conventions and project structures, ensuring consistency across services.
- Added real-world examples and practical setup instructions for local development, including Traefik routing and environment variable configurations.
- Enhanced the guide documentation with verification checklists and troubleshooting steps to support developers in deploying and managing services effectively.
This commit is contained in:
Ho Ngoc Hai
2026-01-14 12:21:51 +07:00
parent 6996e12ff0
commit 02e1053eb5
7 changed files with 722 additions and 217 deletions

View File

@@ -41,16 +41,36 @@ Giải thích chi tiết bằng tiếng Việt về kiến trúc, bao gồm:
```mermaid
C4Context
title System Context Diagram for [System Name]
title System Context Diagram for GoodGo Microservices Platform
Person(user, "User", "System user")
System(system, "System Name", "System description")
System_Ext(external, "External System", "External dependency")
Person(user, "End User", "Platform users")
Person(admin, "Administrator", "System administrators")
Rel(user, system, "Uses")
Rel(system, external, "Calls", "HTTPS")
System_Boundary(platform, "GoodGo Platform") {
System(gateway, "Traefik Gateway", "API Gateway, routing, load balancing")
System(services, "Microservices", "IAM, Storage, Chat, Membership, etc.")
System(rabbitmq, "RabbitMQ", "Message broker for async events")
}
System_Ext(neon, "Neon PostgreSQL", "Serverless database")
System_Ext(redis, "Redis", "Cache and session store")
System_Ext(minio, "MinIO/Aliyun OSS", "Object storage")
System_Ext(monitoring, "Observability Stack", "Prometheus + Grafana + Loki + Jaeger")
Rel(user, gateway, "Uses", "HTTPS")
Rel(admin, gateway, "Manages", "HTTPS")
Rel(gateway, services, "Routes to", "HTTP")
Rel(services, neon, "Stores data", "PostgreSQL")
Rel(services, redis, "Caches data", "Redis Protocol")
Rel(services, rabbitmq, "Pub/Sub events", "AMQP")
Rel(services, minio, "Stores files", "S3 API")
Rel(services, monitoring, "Sends telemetry", "HTTP/gRPC")
```
**EN**: The GoodGo Platform uses microservices architecture where all client requests go through Traefik API Gateway. Services communicate synchronously via REST/HTTP and asynchronously via RabbitMQ events. Each service has its own database schema in Neon PostgreSQL and uses Redis for caching.
**VI**: Nền tảng GoodGo sử dụng kiến trúc microservices nơi tất cả requests từ client đi qua Traefik API Gateway. Các services giao tiếp đồng bộ qua REST/HTTP và bất đồng bộ qua RabbitMQ events. Mỗi service có database schema riêng trong Neon PostgreSQL và sử dụng Redis cho caching.
## Components / Thành phần
### Component A / Thành phần A
@@ -81,9 +101,71 @@ const componentA = new ComponentA({
**File Location**: [`component-a.ts`](file:///path/to/component-a.ts)
### Component B / Thành phần B
---
(Repeat structure for each major component)
### Real-World Example: Storage Service / Ví dụ Thực tế: Storage Service
**EN**: File storage management service supporting multiple cloud providers (MinIO, Aliyun OSS).
**VI**: Service quản lý lưu trữ file hỗ trợ nhiều cloud providers (MinIO, Aliyun OSS).
**Key Features / Tính năng chính**:
- Multi-provider pattern (MinIO/Aliyun OSS)
- Pre-signed URL generation for secure uploads/downloads
- User quota management
- File sharing với time-limited tokens
- Direct client upload pattern
**Technologies Used / Công nghệ sử dụng**:
- .NET 10, Entity Framework Core
- MinIO Client, Aliyun OSS SDK
- Redis (caching)
- PostgreSQL (Neon)
**Architecture Pattern**:
```csharp
// Provider abstraction
public interface IStorageProvider
{
Task<string> UploadFileAsync(Stream fileStream, string fileName, CancellationToken ct);
Task<string> GeneratePresignedUrlAsync(string objectKey, int expiryMinutes, CancellationToken ct);
}
// Concrete implementations
public class MinioStorageProvider : IStorageProvider { }
public class AliyunOssStorageProvider : IStorageProvider { }
// Factory pattern for provider selection
public class StorageProviderFactory
{
public IStorageProvider CreateProvider(string providerName) { }
}
```
**File Location**: [`services/storage-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/storage-service-net)
---
### Real-World Example: IAM Service / Ví dụ Thực tế: IAM Service
**EN**: Identity and Access Management service handling authentication, authorization, and RBAC.
**VI**: Service quản lý định danh và truy cập xử lý xác thực, phân quyền và RBAC.
**Key Features / Tính năng chính**:
- JWT authentication (RS256)
- Role-Based Access Control (RBAC)
- MFA support (TOTP)
- Session management
- Permission caching
**Technologies Used / Công nghệ sử dụng**:
- .NET 10, Duende IdentityServer
- Entity Framework Core
- Redis (caching)
- PostgreSQL (Neon)
**File Location**: [`services/iam-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/iam-service-net)
## Data Flow / Luồng Dữ liệu
@@ -158,15 +240,28 @@ erDiagram
## Performance Characteristics / Đặc điểm Hiệu suất
**EN**: Description of performance expectations and optimizations
**EN**: Description of performance expectations and optimizations based on GoodGo Platform standards.
**VI**: Mô tả kỳ vọng hiệu suất và tối ưu hóa
**VI**: Mô tả kỳ vọng hiệu suất và tối ưu hóa dựa trên chuẩn GoodGo Platform.
| Metric / Chỉ số | Target / Mục tiêu | Notes / Ghi chú |
|------------------|-------------------|-----------------|
| Response Time / Thời gian phản hồi | < 100ms | P95 |
| Throughput / Thông lượng | 1000 req/s | Peak load |
| Memory Usage / Sử dụng RAM | < 512MB | Per instance |
| API Response Time (P95) / Thời gian phản hồi API | < 200ms | Excluding external API calls |
| API Response Time (P99) / Thời gian phản hồi API | < 500ms | Peak load scenarios |
| Throughput / Thông lượng | 1000 req/s | Per service instance |
| Database Query Time (P95) / Truy vấn Database | < 50ms | Simple queries with indexes |
| Cache Hit Rate (L1) / Tỷ lệ cache hit | > 40% | In-memory cache |
| Cache Hit Rate (L2) / Tỷ lệ cache hit | > 80% | Redis cache |
| Service Availability / Tính khả dụng | > 99.9% | Monthly uptime target |
| Error Rate / Tỷ lệ lỗi | < 1% | 4xx + 5xx errors |
**Optimization Strategies / Chiến lược Tối ưu**:
- **Multi-layer caching**: L1 (Memory) + L2 (Redis)
- **Connection pooling**: For PostgreSQL connections
- **Pagination**: Max 100 items per page for list endpoints
- **Database indexes**: On frequently queried fields
- **Async events**: Fire-and-forget với RabbitMQ
- **CDN**: For static assets (Next.js)
## Security Considerations / Cân nhắc Bảo mật
@@ -179,23 +274,55 @@ erDiagram
## Deployment / Triển khai
**EN**: How this architecture is deployed and scaled
**EN**: How this architecture is deployed and scaled in GoodGo Platform.
**VI**: Cách kiến trúc này được triển khai và mở rộng
**VI**: Cách kiến trúc này được triển khai và mở rộng trong GoodGo Platform.
### Traefik API Gateway Routing
```yaml
# docker-compose.yml
services:
storage-service-net:
labels:
- "traefik.enable=true"
- "traefik.http.routers.storage-service.rule=PathPrefix(`/api/v1/storage`)"
- "traefik.http.services.storage-service.loadbalancer.server.port=8080"
- "traefik.http.routers.storage-service.middlewares=strip-prefix@docker"
```
### Kubernetes Deployment
```mermaid
graph LR
LB[Load Balancer] --> A[Instance 1]
LB --> B[Instance 2]
LB --> C[Instance 3]
A --> DB[(Database)]
LB[Load Balancer] --> Traefik[Traefik Gateway<br/>2-3 replicas]
Traefik --> A[Service A<br/>2-10 replicas HPA]
Traefik --> B[Service B<br/>2-10 replicas HPA]
Traefik --> C[Service C<br/>2-10 replicas HPA]
A --> DB[(Neon PostgreSQL<br/>Serverless)]
B --> DB
C --> DB
A --> Cache[(Redis)]
A --> Cache[(Redis Cluster<br/>3 nodes)]
B --> Cache
C --> Cache
style LB fill:#1565c0,stroke:#fff,stroke-width:2px,color:#fff
style Traefik fill:#0f4c81,stroke:#fff,stroke-width:2px,color:#fff
style A fill:#283593,stroke:#fff,stroke-width:2px,color:#fff
style B fill:#4527a0,stroke:#fff,stroke-width:2px,color:#fff
style C fill:#4527a0,stroke:#fff,stroke-width:2px,color:#fff
style DB fill:#5e35b1,stroke:#fff,stroke-width:2px,color:#fff
style Cache fill:#ef6c00,stroke:#fff,stroke-width:2px,color:#fff
```
**Resource Allocation / Phân bổ Tài nguyên**:
| Service | Requests | Limits |
|---------|----------|--------|
| **Microservices** | 256Mi RAM, 250m CPU | 512Mi RAM, 500m CPU |
| **Traefik** | 512Mi RAM, 500m CPU | 1Gi RAM, 1000m CPU |
| **Redis** | 2Gi RAM, 1 CPU | 4Gi RAM, 2 CPU |
## Monitoring & Observability / Giám sát & Khả năng quan sát
**EN**: How to monitor this architecture, key metrics, alerts
@@ -212,9 +339,20 @@ graph LR
## Related Documentation / Tài liệu Liên quan
- [Related Arch Doc 1](../architecture/related-doc-1.md) - EN: Description / VI: Mô tả
- [Related Guide](../guides/related-guide.md) - EN: Description / VI: Mô tả
- [Related Skill](../skills/related-skill.md) - EN: Description / VI: Mô tả
### Architecture Documents
- [System Design](../architecture/system-design.md) - EN: Overall platform architecture / VI: Kiến trúc tổng thể platform
- [Microservices Communication](../architecture/microservices-communication.md) - EN: Service communication patterns / VI: Patterns giao tiếp services
- [Caching Architecture](../architecture/caching-architecture.md) - EN: Redis caching strategies / VI: Chiến lược Redis caching
- [Event-Driven Architecture](../architecture/event-driven-architecture.md) - EN: RabbitMQ event patterns / VI: Patterns RabbitMQ events
### Skills Reference
- [CQRS with MediatR](../skills/cqrs-mediatr.md) - EN: CQRS pattern / VI: Pattern CQRS
- [Repository Pattern](../skills/repository-pattern.md) - EN: EF Core repository / VI: Repository EF Core
- [Domain-Driven Design](../skills/domain-driven-design.md) - EN: DDD patterns / VI: Patterns DDD
### Guides
- [Local Development](../guides/local-development.md) - EN: Setup dev environment / VI: Setup môi trường dev
- [Deployment](../guides/deployment.md) - EN: Kubernetes deployment / VI: Triển khai Kubernetes
## References / Tham khảo

View File

@@ -29,14 +29,22 @@ Template này cung cấp cấu trúc sẵn sàng production cho microservices .N
```bash
# Sao chép template sang service mới
cp -r services/_template_dot_net services/your-service-name
cd services/your-service-name
cp -r services/_template_dot_net services/your-service-name-net
cd services/your-service-name-net
# Đổi tên tất cả "MyService" thành "YourService"
# Ví dụ: MyService → StorageService, UserService, PaymentService
find . -type f -name "*.cs" -exec sed -i '' 's/MyService/YourService/g' {} +
find . -type f -name "*.csproj" -exec sed -i '' 's/MyService/YourService/g' {} +
find . -type f -name "*.sln" -exec sed -i '' 's/MyService/YourService/g' {} +
```
**Naming Convention**:
- Service folder: `{service-name}-net` (ví dụ: `storage-service-net`, `iam-service-net`)
- Projects: `{ServiceName}.API`, `{ServiceName}.Domain`, `{ServiceName}.Infrastructure`
- DbContext: `{ServiceName}Context` (ví dụ: `StorageServiceContext`)
- Namespace: `GoodGo.Services.{ServiceName}` (ví dụ: `GoodGo.Services.StorageService`)
### 2. Cấu Hình Môi Trường
```bash
@@ -62,36 +70,54 @@ dotnet run --project src/MyService.API
## Cấu Trúc Dự Án
```
_template_dot_net/
{service-name}-net/ # Ví dụ: storage-service-net
├── src/
│ ├── MyService.API/ # Lớp Presentation (Controllers, CQRS)
│ ├── {ServiceName}.API/ # Lớp Presentation (Controllers, CQRS)
│ │ ├── Controllers/ # Các API endpoints
│ │ ├── Application/ # Triển khai CQRS
│ │ │ ├── Commands/ # Thao tác ghi (MediatR)
│ │ │ ├── Queries/ # Thao tác đọc
│ │ │ ├── Behaviors/ # MediatR pipeline behaviors
│ │ │ └── Validations/ # FluentValidation validators
│ │ ├── Middlewares/ # Custom middlewares
│ │ └── Program.cs # Điểm vào ứng dụng
│ │
│ ├── MyService.Domain/ # Lớp Domain (Business logic thuần túy)
│ ├── {ServiceName}.Domain/ # Lớp Domain (Business logic thuần túy)
│ │ ├── AggregatesModel/ # Aggregate roots và entities
│ │ ├── Events/ # Domain events
│ │ ├── Exceptions/ # Domain exceptions
│ │ └── SeedWork/ # Base classes
│ │ └── SeedWork/ # Base classes (Entity, IAggregateRoot)
│ │
│ └── MyService.Infrastructure/ # Lớp Infrastructure
│ ├── EntityConfigurations/ # Cấu hình EF Core
│ └── {ServiceName}.Infrastructure/ # Lớp Infrastructure
│ ├── EntityConfigurations/ # Cấu hình EF Core (Fluent API)
│ ├── Repositories/ # Triển khai repositories
── MyServiceContext.cs # DbContext với Unit of Work
── Providers/ # External service providers (nếu có)
│ ├── Services/ # Infrastructure services
│ ├── Migrations/ # EF Core migrations
│ └── {ServiceName}Context.cs # DbContext với Unit of Work
├── tests/
│ ├── MyService.UnitTests/ # Unit tests
│ └── MyService.FunctionalTests/ # Integration tests
│ ├── {ServiceName}.UnitTests/ # Unit tests
│ └── {ServiceName}.FunctionalTests/ # Integration tests
├── docs/
│ ├── en/ # English documentation
│ │ ├── README.md
│ │ └── ARCHITECTURE.md
│ └── vi/ # Vietnamese documentation
│ ├── README.md
│ └── ARCHITECTURE.md
├── Dockerfile # Multi-stage Docker build
── docker-compose.yml # Thiết lập phát triển local
── docker-compose.yml # Thiết lập phát triển local
└── README.md # Service overview (bilingual)
```
**Examples thực tế**:
- Storage Service: [`services/storage-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/storage-service-net)
- IAM Service: [`services/iam-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/iam-service-net)
- Chat Service: [`services/chat-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/chat-service-net)
## Kiến Trúc
```mermaid
@@ -204,12 +230,43 @@ Request → LoggingBehavior → ValidatorBehavior → TransactionBehavior → Ha
## Biến Môi Trường
### Required / Bắt buộc
| Biến | Mô Tả | Mặc định |
|------|-------|----------|
| `ASPNETCORE_ENVIRONMENT` | Tên môi trường | `Development` |
| `DATABASE_URL` | Kết nối PostgreSQL | - |
| `REDIS_URL` | Kết nối Redis | - |
| `JWT_SECRET` | Secret ký JWT | - |
| `DATABASE_URL` | Kết nối Neon PostgreSQL | - |
| `ConnectionStrings__DefaultConnection` | Connection string format chuẩn | - |
### Optional / Tùy chọn
| Biến | Mô Tả | Mặc định |
|------|-------|----------|
| `REDIS_URL` | Kết nối Redis (cache) | - |
| `RabbitMQ__Host` | RabbitMQ hostname | `localhost` |
| `RabbitMQ__Port` | RabbitMQ port | `5672` |
| `RabbitMQ__Username` | RabbitMQ username | `guest` |
| `RabbitMQ__Password` | RabbitMQ password | `guest` |
### Inter-Service Communication
| Biến | Mô Tả | Mặc định |
|------|-------|----------|
| `IamService__BaseUrl` | IAM Service URL | `http://iam-service-net:5001` |
| `Services__InternalApiKey` | Shared secret cho service-to-service auth | - |
### Multi-Provider Pattern (Example: Storage Service)
| Biến | Mô Tả | Mặc định |
|------|-------|----------|
| `Storage__Provider` | Provider: `minio` hoặc `aliyun` | `minio` |
| `Storage__DefaultBucket` | Default bucket name | `storage` |
| `Storage__MinIO__Endpoint` | MinIO endpoint | `localhost:9000` |
| `Storage__MinIO__AccessKey` | MinIO access key | - |
| `Storage__MinIO__SecretKey` | MinIO secret key | - |
| `Storage__AliyunOSS__Endpoint` | Aliyun OSS endpoint | - |
| `Storage__AliyunOSS__AccessKeyId` | Aliyun access key | - |
| `Storage__AliyunOSS__AccessKeySecret` | Aliyun secret key | - |
## Kiểm Thử
@@ -257,23 +314,223 @@ spec:
port: 8080
```
## Patterns Nâng cao
### Multi-Provider Pattern
**Sử dụng khi**: Service cần hỗ trợ nhiều external providers (storage, payment, SMS)
**Example**: Storage Service với MinIO và Aliyun OSS
```csharp
// Domain - Interface
public interface IStorageProvider
{
Task<string> UploadFileAsync(Stream fileStream, string fileName, CancellationToken ct);
Task<Stream> DownloadFileAsync(string objectKey, CancellationToken ct);
Task DeleteFileAsync(string objectKey, CancellationToken ct);
Task<string> GeneratePresignedUrlAsync(string objectKey, int expiryMinutes, CancellationToken ct);
}
// Infrastructure - MinIO Implementation
public class MinioStorageProvider : IStorageProvider
{
private readonly MinioClient _client;
// Implementation...
}
// Infrastructure - Aliyun OSS Implementation
public class AliyunOssStorageProvider : IStorageProvider
{
private readonly OssClient _client;
// Implementation...
}
// API - Provider Factory
public class StorageProviderFactory
{
public IStorageProvider CreateProvider(IConfiguration config)
{
var provider = config["Storage:Provider"];
return provider?.ToLower() switch
{
"minio" => new MinioStorageProvider(config),
"aliyun" => new AliyunOssStorageProvider(config),
_ => throw new InvalidOperationException($"Unknown provider: {provider}")
};
}
}
```
**File Reference**: [`StorageService.Infrastructure/Providers/`](file:///Users/velikho/Desktop/WORKING/Base/services/storage-service-net/src/StorageService.Infrastructure/Providers)
---
### Inter-Service Authentication Pattern
**Sử dụng khi**: Service cần validate JWT tokens với IAM Service
```csharp
// Infrastructure - IAM Service Client
public class IamServiceClient
{
private readonly HttpClient _httpClient;
private readonly IConfiguration _config;
public IamServiceClient(HttpClient httpClient, IConfiguration config)
{
_httpClient = httpClient;
_config = config;
_httpClient.BaseAddress = new Uri(_config["IamService:BaseUrl"]);
}
public async Task<UserInfo> ValidateTokenAsync(string token, CancellationToken ct)
{
var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/auth/validate")
{
Headers = { { "Authorization", $"Bearer {token}" } }
};
var response = await _httpClient.SendAsync(request, ct);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<UserInfo>(ct);
}
}
// API - Middleware
public class JwtValidationMiddleware
{
private readonly RequestDelegate _next;
private readonly IamServiceClient _iamClient;
public async Task InvokeAsync(HttpContext context)
{
var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
if (!string.IsNullOrEmpty(token))
{
var userInfo = await _iamClient.ValidateTokenAsync(token, context.RequestAborted);
context.Items["UserId"] = userInfo.UserId;
}
await _next(context);
}
}
```
---
## Có Gì Mới Trong .NET 10
- Tính năng ngôn ngữ **C# 14**
- Hỗ trợ **Native AOT** được cải thiện
- Hiệu suất **async/await** tốt hơn
- **JSON serialization** được nâng cao
- **JSON serialization** được nâng cao (System.Text.Json)
- Hỗ trợ **LTS** 3 năm (đến tháng 11/2028)
- **Entity Framework Core 10** với performance improvements
## Tích hợp với Platform
### Traefik Routing
Thêm labels vào `docker-compose.yml`:
```yaml
services:
your-service-net:
build:
context: ../..
dockerfile: services/your-service-net/Dockerfile
labels:
- "traefik.enable=true"
- "traefik.http.routers.your-service.rule=PathPrefix(`/api/v1/your-service`)"
- "traefik.http.services.your-service.loadbalancer.server.port=8080"
- "traefik.http.routers.your-service.middlewares=strip-prefix@docker"
```
### Neon PostgreSQL Configuration
```json
{
"ConnectionStrings": {
"DefaultConnection": "Host=ep-xxx.neon.tech;Database=your_service;Username=xxx;Password=xxx;SSL Mode=Require;Trust Server Certificate=true"
}
}
```
**Best Practices**:
- Sử dụng connection pooling: `Pooling=true;Maximum Pool Size=100`
- Enable SSL: `SSL Mode=Require`
- Set command timeout: `Command Timeout=30`
### RabbitMQ Integration (thay vì Kafka)
```csharp
// Domain Event
public record FileUploadedEvent(string FileId, string UserId, long FileSize) : IDomainEvent;
// Infrastructure - Event Publisher
public class RabbitMqEventPublisher : IEventPublisher
{
private readonly IConnection _connection;
private readonly IModel _channel;
public async Task PublishAsync<T>(T @event, CancellationToken ct) where T : IDomainEvent
{
var message = JsonSerializer.Serialize(@event);
var body = Encoding.UTF8.GetBytes(message);
_channel.BasicPublish(
exchange: "domain_events",
routingKey: typeof(T).Name,
body: body
);
}
}
```
---
## Tài Liệu Liên Quan
- [Chi Tiết Kiến Trúc](../architecture/microservices-communication.md)
- [DDD Patterns](../architecture/system-design.md)
- [Hướng Dẫn Triển Khai](../guides/deployment.md)
### Architecture
- [System Design](../architecture/system-design.md) - Kiến trúc tổng thể GoodGo Platform
- [Microservices Communication](../architecture/microservices-communication.md) - Patterns giao tiếp
- [Caching Architecture](../architecture/caching-architecture.md) - Chiến lược Redis caching
## Tài Nguyên
### Skills
- [CQRS with MediatR](../skills/cqrs-mediatr.md) - CQRS pattern implementation
- [Repository Pattern](../skills/repository-pattern.md) - EF Core repository pattern
- [Domain-Driven Design](../skills/domain-driven-design.md) - DDD tactical patterns
- [Error Handling](../skills/error-handling-patterns.md) - Exception handling patterns
- [eShopOnContainers](https://github.com/dotnet-architecture/eShopOnContainers)
- [Tài liệu .NET 10](https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10)
- [MediatR](https://github.com/jbogard/MediatR)
- [FluentValidation](https://docs.fluentvalidation.net/)
### Guides
- [Local Development](../guides/local-development.md) - Setup môi trường dev
- [Deployment](../guides/deployment.md) - Deploy lên Kubernetes
## Tài Nguyên Bổ sung
### Microsoft Official
- [.NET 10 Documentation](https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10)
- [Entity Framework Core 10](https://docs.microsoft.com/en-us/ef/core/)
- [ASP.NET Core 10](https://docs.microsoft.com/en-us/aspnet/core/)
### Architecture References
- [eShopOnContainers](https://github.com/dotnet-architecture/eShopOnContainers) - Microservices reference architecture
- [.NET Microservices Architecture Book](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/)
### Libraries
- [MediatR](https://github.com/jbogard/MediatR) - CQRS implementation
- [FluentValidation](https://docs.fluentvalidation.net/) - Validation library
- [Polly](https://github.com/App-vNext/Polly) - Resilience and transient-fault-handling
### Tools
- [EF Core Tools](https://docs.microsoft.com/en-us/ef/core/cli/dotnet) - Migrations và scaffolding
- [Neon PostgreSQL](https://neon.tech/docs) - Serverless Postgres documentation
---
**Last Updated**: 2026-01-14
**Template Version**: 2.0
**Maintained By**: GoodGo Architecture Team

View File

@@ -45,6 +45,25 @@ Trước khi bắt đầu hướng dẫn này, hãy đảm bảo bạn có:
# EN: Verify prerequisites / VI: Xác minh yêu cầu
node --version # Should be 20 or higher / Phải là 20 hoặc cao hơn
docker --version # Should be installed / Phải được cài đặt
dotnet --version # Should be 10.0+ for .NET services / Phải là 10.0+ cho .NET services
```
**Example: Local Development Setup for Storage Service**
```bash
# Clone repository
cd /Users/velikho/Desktop/WORKING/Base
# Install dependencies (.NET)
cd services/storage-service-net
dotnet restore
# Setup infrastructure
cd ../../deployments/local
docker-compose up -d postgres redis minio
# Run migrations
cd ../../services/storage-service-net
dotnet ef database update --project src/StorageService.Infrastructure --startup-project src/StorageService.API
```
## Overview / Tổng quan
@@ -96,11 +115,53 @@ touch .env.local
**Example Content / Nội dung ví dụ**:
```env
# EN: Environment variables / VI: Biến môi trường
PORT=5000
NODE_ENV=development
ASPNETCORE_ENVIRONMENT=Development
DATABASE_URL=postgresql://localhost:5432/mydb
REDIS_URL=redis://localhost:6379
Storage__Provider=minio
Storage__MinIO__Endpoint=localhost:9000
Storage__MinIO__AccessKey=minioadmin
Storage__MinIO__SecretKey=minioadmin
```
### Real-World Example / Ví dụ Thực tế: Traefik Routing Setup
**EN**: How to configure Traefik routing for a new service.
**VI**: Cách cấu hình Traefik routing cho service mới.
```yaml
# docker-compose.yml
services:
your-service-net:
build:
context: ../..
dockerfile: services/your-service-net/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- DATABASE_URL=${DATABASE_URL}
labels:
# Enable Traefik
- "traefik.enable=true"
# Define routing rule
- "traefik.http.routers.your-service.rule=PathPrefix(`/api/v1/your-service`)"
# Specify service port
- "traefik.http.services.your-service.loadbalancer.server.port=8080"
# Strip prefix middleware
- "traefik.http.routers.your-service.middlewares=strip-prefix@docker"
networks:
- goodgo-network
networks:
goodgo-network:
external: true
```
**Expected Result / Kết quả mong đợi**:
- ✅ Service accessible at `http://localhost/api/v1/your-service`
- ✅ Traefik dashboard shows the service at `http://localhost:8080`
- ✅ Health check endpoint works: `http://localhost/api/v1/your-service/health`
### Step 2 / Bước 2: [Action Title]
**EN**: Continue with next step explanation...
@@ -142,9 +203,35 @@ curl http://localhost:5000/health
### Verification Checklist / Danh sách kiểm tra
- [ ] Check 1 / Kiểm tra 1: Description / Mô tả
- [ ] Check 2 / Kiểm tra 2: Description / Mô tả
- [ ] Check 3 / Kiểm tra 3: Description / Mô tả
**For .NET Services**:
- [ ] Check 1: Service builds successfully / Service build thành công
```bash
dotnet build
```
- [ ] Check 2: Database migrations applied / Migrations đã apply
```bash
dotnet ef database update --project src/{ServiceName}.Infrastructure --startup-project src/{ServiceName}.API
```
- [ ] Check 3: Service responds to health checks / Service phản hồi health checks
```bash
curl http://localhost:8080/health
# Expected: {"status":"Healthy"}
```
- [ ] Check 4: Swagger UI accessible / Swagger UI truy cập được
```bash
open http://localhost:8080/swagger
```
**For Traefik Integration**:
- [ ] Check 5: Service registered in Traefik / Service đăng ký trong Traefik
```bash
curl http://localhost:8080/api/http/routers
# Should see your-service router
```
- [ ] Check 6: API accessible via gateway / API truy cập được qua gateway
```bash
curl http://localhost/api/v1/your-service/health
```
## Common Issues / Vấn đề Thường gặp
@@ -176,19 +263,26 @@ step-2
```mermaid
flowchart TD
Problem[Problem Occurs] --> Check1{Check 1:<br/>Condition?}
Check1 -->|Yes| Solution1[Solution 1]
Check1 -->|No| Check2{Check 2:<br/>Condition?}
Check2 -->|Yes| Solution2[Solution 2]
Check2 -->|No| Check3{Check 3:<br/>Condition?}
Check3 -->|Yes| Solution3[Solution 3]
Check3 -->|No| Support[Contact Support]
Problem[Service not accessible] --> Check1{Traefik<br/>running?}
Check1 -->|No| Solution1[Start Traefik:<br/>docker-compose up traefik]
Check1 -->|Yes| Check2{Service<br/>container running?}
Check2 -->|No| Solution2[Start service:<br/>docker-compose up your-service]
Check2 -->|Yes| Check3{Database<br/>connection OK?}
Check3 -->|No| Solution3[Check DATABASE_URL<br/>Run migrations]
Check3 -->|Yes| Logs[Check service logs:<br/>docker-compose logs -f]
Solution1 --> Resolved{Resolved?}
Solution2 --> Resolved
Solution3 --> Resolved
Resolved -->|No| Support
Logs --> Resolved
Resolved -->|No| Support[Check documentation:<br/>docs/vi/guides/troubleshooting.md]
Resolved -->|Yes| Success([Success])
style Problem fill:#f8d7da,stroke:#721c24,stroke-width:2px
style Success fill:#d4edda,stroke:#155724,stroke-width:2px
style Check1 fill:#fff3cd,stroke:#856404,stroke-width:2px
style Check2 fill:#fff3cd,stroke:#856404,stroke-width:2px
style Check3 fill:#fff3cd,stroke:#856404,stroke-width:2px
```
## Advanced Options / Tùy chọn Nâng cao
@@ -214,9 +308,16 @@ advanced-command --option
**VI**: Làm gì sau khi hoàn thành hướng dẫn này.
- [ ] Next step 1 / Bước tiếp theo 1: [Related Guide](../guides/related-guide.md)
- [ ] Next step 2 / Bước tiếp theo 2: [Another Guide](../guides/another-guide.md)
- [ ] Next step 3 / Bước tiếp theo 3: [Deep Dive](../skills/deep-dive.md)
**For .NET Services**:
- [ ] Next step 1: [Implement CQRS Commands](../skills/cqrs-mediatr.md)
- [ ] Next step 2: [Add Repository Pattern](../skills/repository-pattern.md)
- [ ] Next step 3: [Setup Redis Caching](../skills/redis-caching.md)
- [ ] Next step 4: [Configure Observability](../guides/observability.md)
**For Deployment**:
- [ ] Next step 1: [Kubernetes Deployment](../guides/deployment.md)
- [ ] Next step 2: [Configure CI/CD Pipeline](../guides/ci-cd.md)
- [ ] Next step 3: [Setup Monitoring](../guides/observability.md)
## Additional Resources / Tài nguyên Bổ sung

View File

@@ -17,7 +17,10 @@
- Security considerations
- Deployment strategy
**Ví dụ**: [`system-design.md`](../architecture/system-design.md)
**Ví dụ**:
- Storage Service Architecture: [`storage-architecture.md`](../architecture/storage-architecture.md)
- IAM Architecture: [`iam-proposal.md`](../architecture/iam-proposal.md)
- System Design: [`system-design.md`](../architecture/system-design.md)
### 2. Guide Template - [`guide.md`](./guide.md)
@@ -31,7 +34,10 @@
- Common issues & troubleshooting
- FAQ section
**Ví dụ**: Hướng dẫn deployment, local development
**Ví dụ**:
- Local Development: [`local-development.md`](../guides/local-development.md)
- Deployment to Kubernetes: [`deployment.md`](../guides/deployment.md)
- IAM Authentication Guide: [`iam-authentication.md`](../guides/iam-authentication.md)
### 3. Skill/Pattern Template - [`skill-pattern.md`](./skill-pattern.md)
@@ -46,7 +52,11 @@
- Common mistakes
- Testing examples
**Ví dụ**: Repository pattern, RBAC pattern
**Ví dụ**:
- CQRS with MediatR: [`cqrs-mediatr.md`](../skills/cqrs-mediatr.md)
- Repository Pattern: [`repository-pattern.md`](../skills/repository-pattern.md)
- Redis Caching: [`redis-caching.md`](../skills/redis-caching.md)
- Domain-Driven Design: [`domain-driven-design.md`](../skills/domain-driven-design.md)
## Quick Start
@@ -61,7 +71,13 @@ Xác định loại tài liệu bạn cần tạo:
```bash
# Ví dụ: Tạo architecture document mới
cp docs/vi/templates/architecture.md docs/vi/architecture/ten-kien-truc-moi.md
cp docs/vi/templates/architecture.md docs/vi/architecture/new-architecture-name.md
# Ví dụ: Tạo guide document mới
cp docs/vi/templates/guide.md docs/vi/guides/new-guide-name.md
# Ví dụ: Tạo skill document mới
cp docs/vi/templates/skill-pattern.md docs/vi/skills/new-skill-name.md
```
### Bước 3: Thay thế Placeholders

View File

@@ -6,6 +6,8 @@
Template này cung cấp nền tảng hoàn chỉnh, sẵn sàng production để xây dựng các microservice với:
> **Lưu ý**: Template này dành cho tương lai. Hiện tại dự án GoodGo chủ yếu sử dụng .NET services. Xem [dotnet-template.md](./dotnet-template.md) cho template đang sử dụng.
- **Framework**: Express.js với TypeScript
- **Database**: Prisma ORM với PostgreSQL
- **Validation**: Zod cho validation biến môi trường và đầu vào

View File

@@ -138,60 +138,44 @@ export class ExamplePattern {
```
**File Location / Vị trí File**:
- **Template**: [`_template/src/modules/example/example.pattern.ts`](file:///Users/velikho/Desktop/WORKING/Base/services/_template/src/modules/example/example.pattern.ts)
- **Production**: [`iam-service/src/modules/example/example.pattern.ts`](file:///Users/velikho/Desktop/WORKING/Base/services/iam-service/src/modules/example/example.pattern.ts)
- **Skill Template**: [`.agent/skills/skill-authoring/SKILL.md`](file:///Users/velikho/Desktop/WORKING/Base/.agent/skills/skill-authoring/SKILL.md)
- **Example Skills**: [`.agent/skills/`](file:///Users/velikho/Desktop/WORKING/Base/.agent/skills)
### Advanced Implementation / Triển khai Nâng cao
**EN**: More complex implementation with additional features.
**EN**: More complex implementation with additional features like caching and error handling.
**VI**: Triển khai phức tạp hơn với các tính năng bổ sung.
**VI**: Triển khai phức tạp hơn với các tính năng bổ sung như caching và xử lý lỗi.
```typescript
// EN: Advanced implementation with caching and error handling
// VI: Triển khai nâng cao với caching và xử lý lỗi
```csharp
// EN: Advanced .NET implementation with caching
// VI: Triển khai .NET nâng cao với caching
export class AdvancedExamplePattern extends ExamplePattern {
constructor(
dependency1: Dependency1,
dependency2: Dependency2,
private cache: CacheService,
private logger: Logger
) {
super(dependency1, dependency2);
}
public class CachedStorageProvider : IStorageProvider
{
private readonly IStorageProvider _innerProvider;
private readonly IDistributedCache _cache;
private readonly ILogger<CachedStorageProvider> _logger;
async execute(input: InputType): Promise<OutputType> {
// EN: Try cache first
// VI: Thử cache trước
const cacheKey = this.getCacheKey(input);
const cached = await this.cache.get<OutputType>(cacheKey);
public async Task<string> UploadFileAsync(Stream fileStream, string fileName, CancellationToken ct)
{
try
{
// EN: Upload file
// VI: Upload file
var result = await _innerProvider.UploadFileAsync(fileStream, fileName, ct);
if (cached) {
this.logger.info('Cache hit', { key: cacheKey });
return cached;
}
try {
// EN: Execute pattern logic
// VI: Thực thi logic pattern
const result = await super.execute(input);
// EN: Cache result
// VI: Cache kết quả
await this.cache.set(cacheKey, result, 300); // 5 minutes
// EN: Invalidate cache
// VI: Vô hiệu hóa cache
await _cache.RemoveAsync($"file:{fileName}", ct);
return result;
} catch (error) {
// EN: Error handling
// VI: Xử lý lỗi
this.logger.error('Pattern execution failed', { error, input });
throw new PatternExecutionError('Execution failed', { cause: error });
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to upload file {FileName}", fileName);
throw;
}
private getCacheKey(input: InputType): string {
return `pattern:example:${JSON.stringify(input)}`;
}
}
```
@@ -255,60 +239,76 @@ sequenceDiagram
## Usage Examples / Ví dụ Sử dụng
### Example 1 / Ví dụ 1: Basic Usage
### Example 1: Multi-Provider Storage Pattern (Real-World)
**EN**: Basic usage scenario with explanation.
**EN**: Real implementation from Storage Service.
**VI**: Tình huống sử dụng cơ bản với giải thích.
**VI**: Triển khai thực tế từ Storage Service.
```typescript
// EN: Setup
// VI: Thiết lập
const dependency1 = new Dependency1();
const dependency2 = new Dependency2();
const pattern = new ExamplePattern(dependency1, dependency2);
```csharp
// Domain interface
public interface IStorageProvider
{
Task<string> UploadFileAsync(Stream fileStream, string fileName, CancellationToken ct);
Task<string> GeneratePresignedUrlAsync(string objectKey, int expiryMinutes, CancellationToken ct);
}
// EN: Execute pattern
// VI: Thực thi pattern
const input: InputType = {
id: '123',
data: 'example',
// Factory pattern
public class StorageProviderFactory
{
public IStorageProvider CreateProvider(string providerName)
{
return providerName?.ToLower() switch
{
"minio" => _serviceProvider.GetRequiredService<MinioStorageProvider>(),
"aliyun" => _serviceProvider.GetRequiredService<AliyunOssStorageProvider>(),
_ => throw new InvalidOperationException($"Unknown provider: {providerName}")
};
const result = await pattern.execute(input);
console.log(result);
// EN: Output / VI: Kết quả:
// { success: true, data: { ... } }
}
}
```
### Example 2 / Ví dụ 2: Advanced Usage with Caching
**File Reference**: [`services/storage-service-net/src/StorageService.Infrastructure/Providers/`](file:///Users/velikho/Desktop/WORKING/Base/services/storage-service-net/src/StorageService.Infrastructure/Providers)
**EN**: Advanced usage with caching enabled.
---
**VI**: Sử dụng nâng cao với caching được bật.
### Example 2: CQRS with MediatR (Real-World)
```typescript
// EN: Setup with additional dependencies
// VI: Thiết lập với các dependencies bổ sung
const cache = new CacheService();
const logger = new Logger();
const pattern = new AdvancedExamplePattern(
dependency1,
dependency2,
cache,
logger
**EN**: Command handler pattern from actual services.
**VI**: Pattern command handler từ các services thực tế.
```csharp
// Command
public record CreateFileCommand(string FileName, Stream FileStream, string UserId)
: IRequest<CreateFileCommandResult>;
// Handler
public class CreateFileCommandHandler : IRequestHandler<CreateFileCommand, CreateFileCommandResult>
{
private readonly IStorageProvider _storageProvider;
private readonly IFileRepository _fileRepository;
public async Task<CreateFileCommandResult> Handle(CreateFileCommand request, CancellationToken ct)
{
// Upload to storage
var objectKey = await _storageProvider.UploadFileAsync(
request.FileStream,
request.FileName,
ct
);
// EN: First call (cache miss)
// VI: Lần gọi đầu tiên (cache miss)
const result1 = await pattern.execute(input);
// Save metadata
var file = new File(request.FileName, objectKey, request.UserId);
await _fileRepository.AddAsync(file, ct);
// EN: Second call (cache hit)
// VI: Lần gọi thứ hai (cache hit)
const result2 = await pattern.execute(input); // Returns cached result
return new CreateFileCommandResult(file.Id);
}
}
```
**File Reference**: See [CQRS with MediatR Skill](../skills/cqrs-mediatr.md)
## Best Practices / Thực hành Tốt nhất
### EN: Recommended Practices
@@ -372,81 +372,79 @@ if (input) {
## Testing / Kiểm thử
### Unit Test Example / Ví dụ Unit Test
### Unit Test Example for .NET / Ví dụ Unit Test cho .NET
```typescript
// EN: Unit test for the pattern
// VI: Unit test cho pattern
```csharp
// EN: Unit test for CQRS command handler
// VI: Unit test cho CQRS command handler
describe('ExamplePattern', () => {
let pattern: ExamplePattern;
let mockDep1: jest.Mocked<Dependency1>;
let mockDep2: jest.Mocked<Dependency2>;
using Xunit;
using NSubstitute;
beforeEach(() => {
mockDep1 = {
transform: jest.fn(),
} as any;
mockDep2 = {} as any;
public class CreateFileCommandHandlerTests
{
private readonly IStorageProvider _storageProvider;
private readonly IFileRepository _fileRepository;
private readonly CreateFileCommandHandler _handler;
pattern = new ExamplePattern(mockDep1, mockDep2);
});
public CreateFileCommandHandlerTests()
{
_storageProvider = Substitute.For<IStorageProvider>();
_fileRepository = Substitute.For<IFileRepository>();
_handler = new CreateFileCommandHandler(_storageProvider, _fileRepository);
}
it('should execute successfully', async () => {
// EN: Arrange
// VI: Chuẩn bị
const input = { id: '123', data: 'test' };
const expectedProcessed = { transformed: true };
mockDep1.transform.mockResolvedValue(expectedProcessed);
[Fact]
public async Task Handle_ValidCommand_CreatesFileSuccessfully()
{
// Arrange
var command = new CreateFileCommand("test.txt", Stream.Null, "user-123");
_storageProvider.UploadFileAsync(Arg.Any<Stream>(), Arg.Any<string>(), Arg.Any<CancellationToken>())
.Returns("object-key-123");
// EN: Act
// VI: Thực thi
const result = await pattern.execute(input);
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// EN: Assert
// VI: Kiểm tra
expect(result.success).toBe(true);
expect(result.data).toEqual(expectedProcessed);
expect(mockDep1.transform).toHaveBeenCalledWith(input);
});
it('should throw error for invalid input', async () => {
// EN: Expect error for null input
// VI: Mong đợi lỗi cho đầu vào null
await expect(pattern.execute(null as any))
.rejects
.toThrow('Input is required');
});
});
// Assert
Assert.NotNull(result);
Assert.NotEmpty(result.FileId);
await _fileRepository.Received(1).AddAsync(Arg.Any<File>(), Arg.Any<CancellationToken>());
}
}
```
**Reference**: See [Testing Patterns Skill](../skills/testing-patterns.md)
## Related Patterns / Patterns Liên quan
**EN**: Other patterns that complement or relate to this one.
**VI**: Các patterns khác bổ sung hoặc liên quan đến pattern này.
- [Related Pattern 1](./related-pattern-1.md) - EN: How it relates / VI: Cách nó liên quan
- [Related Pattern 2](./related-pattern-2.md) - EN: Comparison / VI: So sánh
- [Alternative Pattern](./alternative-pattern.md) - EN: When to use instead / VI: Khi nào sử dụng thay thế
**GoodGo Skills**:
- [CQRS with MediatR](../skills/cqrs-mediatr.md) - EN: Command/Query separation / VI: Tách biệt Command/Query
- [Repository Pattern](../skills/repository-pattern.md) - EN: Data access abstraction / VI: Trừa tượng hóa truy cập dữ liệu
- [Domain-Driven Design](../skills/domain-driven-design.md) - EN: DDD tactical patterns / VI: Patterns chiến thuật DDD
- [Redis Caching](../skills/redis-caching.md) - EN: Distributed caching / VI: Caching phân tán
- [Error Handling](../skills/error-handling-patterns.md) - EN: Exception patterns / VI: Patterns exception
## Real-World Examples / Ví dụ Thực tế
**EN**: Examples of this pattern used in the codebase.
**EN**: Examples of this pattern used in the GoodGo codebase.
**VI**: Ví dụ về pattern này được sử dụng trong codebase.
**VI**: Ví dụ về pattern này được sử dụng trong codebase GoodGo.
### Example from IAM Service
### Storage Service - Multi-Provider Pattern
**File**: [`iam-service/src/modules/rbac/rbac.service.ts`](file:///Users/velikho/Desktop/WORKING/Base/services/iam-service/src/modules/rbac/rbac.service.ts)
**File**: [`services/storage-service-net/src/StorageService.Infrastructure/Providers/`](file:///Users/velikho/Desktop/WORKING/Base/services/storage-service-net/src/StorageService.Infrastructure/Providers)
```typescript
// EN: Real implementation from IAM service
// VI: Triển khai thực tế từ IAM service
export class RBACService implements ExamplePattern {
// ... implementation
}
```
**Pattern**: Factory pattern for switching between MinIO and Aliyun OSS providers.
### IAM Service - RBAC Pattern
**File**: [`services/iam-service-net/`](file:///Users/velikho/Desktop/WORKING/Base/services/iam-service-net)
**Pattern**: Role-Based Access Control implementation with permission caching.
## Additional Resources / Tài nguyên Bổ sung

View File

@@ -1,10 +1,3 @@
Test Account
Tài khoản: hongochai10@icloud.com
Mật Khẩu: Velik@2026
📊 Mức Độ Ưu Tiên
Ưu Tiên Skills Lý Do
Cao testing-patterns, repository-pattern, error-handling-patterns Core development patterns
Trung bình cqrs-mediatr, docker-traefik, observability Infrastructure & architecture
Thấp redis-caching, inter-service-communication, domain-driven-design, deployment-kubernetes Advanced patterns
Bạn muốn tôi tạo skill nào trước? Hay cần tôi tạo implementation plan chi tiết cho tất cả các skills đề xuất?