Files
pos-system/microservices/.agent/skills/development-lifecycle/SKILL.md
Ho Ngoc Hai 76d75c753b Migrate
2026-05-23 18:37:02 +07:00

14 KiB

name, description, compatibility, metadata
name description compatibility metadata
development-lifecycle Development lifecycle workflow - Code → Build → Test → Fix → Deploy. Use for understanding complete development process, debugging build errors, fixing test failures, and continuous improvement cycles in GoodGo microservices. .NET 10+, Docker 24+, docker-compose 2.x
author version
Velik Ho 1.0

Development Lifecycle / Quy Trình Phát Triển

Complete iterative development workflow from code to deployment with focus on troubleshooting and debugging.

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

Use this skill when:

  • Starting development on a new feature / Bắt đầu phát triển feature mới
  • Debugging build or test failures / Debug lỗi build hoặc test
  • Understanding the complete dev cycle / Hiểu quy trình phát triển hoàn chỉnh
  • Setting up local development environment / Setup môi trường local
  • Troubleshooting deployment issues / Khắc phục sự cố deployment

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

Development Cycle / Chu Kỳ Phát Triển

graph LR
    A[① CODE<br/>Write Features] --> B[② BUILD<br/>Compile & Package]
    B --> C[③ TEST<br/>Run Tests]
    C --> D{Pass?}
    D -->|No| E[④ FIX<br/>Debug & Resolve]
    E --> B
    D -->|Yes| F[⑤ DEPLOY<br/>Local/Staging/Prod]
    F --> G{Issues?}
    G -->|Yes| E
    G -->|No| H[✓ Done]

Philosophy / Triết Lý

  1. Fail Fast - Phát hiện lỗi sớm nhất có thể
  2. Iterative - Cải tiến liên tục qua từng cycle
  3. Automated - Tự động hóa các bước lặp lại
  4. Observable - Luôn có visibility vào system state

Phase 1: CODE ✍️

Goal: Viết code sạch, maintainable theo architecture chuẩn

Workflow

Use existing skills cho coding phase:

Best Practices

// ✅ GOOD: Clear intention, follows patterns
public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, OrderResult>
{
    private readonly IOrderRepository _repository;
    
    public async Task<OrderResult> Handle(CreateOrderCommand cmd, CancellationToken ct)
    {
        var order = new Order(cmd.UserId, cmd.ShippingAddress);
        foreach (var item in cmd.Items)
            order.AddItem(item.ProductId, item.Quantity, item.Price);
        
        await _repository.AddAsync(order, ct);
        await _repository.UnitOfWork.SaveChangesAsync(ct);
        
        return new OrderResult(order.Id);
    }
}

// ❌ BAD: Mixed concerns, no separation
[HttpPost]
public async Task<IActionResult> CreateOrder(CreateOrderRequest request)
{
    var order = new Order { UserId = request.UserId };
    _context.Orders.Add(order);
    await _context.SaveChangesAsync();
    return Ok(order.Id);
}

Phase 2: BUILD 🔨

Goal: Compile code và tạo artifacts (DLLs, Docker images)

Local .NET Build

# Restore NuGet packages
dotnet restore

# Build solution
dotnet build

# Build specific project
dotnet build src/MyService.API/

# Release build
dotnet build -c Release

# Verbose output (for debugging)
dotnet build -v detailed

Docker Build

# Build service image
docker build -t my-service:latest -f services/my-service-net/Dockerfile .

# Build via docker-compose
docker-compose -f deployments/local/docker-compose.yml build my-service-net

# No cache (clean build)
docker-compose -f deployments/local/docker-compose.yml build --no-cache my-service-net

# Parallel build multiple services
docker-compose -f deployments/local/docker-compose.yml build --parallel

Common Build Errors

Error Code Cause Solution
CS0246 Missing type/namespace Run dotnet restore, add package reference
CS0103 Name does not exist Add using statement
CS1061 Missing member Check property/method name, NuGet version
NU1101 Unable to find package Check package name, NuGet source
Docker context Wrong build context Verify -f and context path

See detailed solutions: references/build-errors.md


Phase 3: TEST 🧪

Goal: Validate correctness through automated tests

Test Pyramid

        ┌──────────────┐
        │  E2E Tests   │  ← ~5% - Slow, brittle
        │   (UI/API)   │
        ├──────────────┤
        │ Integration  │  ← ~15% - Medium speed
        │    Tests     │     Database, HTTP
        ├──────────────┤
        │ Unit Tests   │  ← ~80% - Fast, isolated
        │  (Handlers,  │     Pure logic
        │   Domain)    │
        └──────────────┘

Test Commands

# Run all tests
dotnet test

# Run specific test project
dotnet test tests/MyService.UnitTests/

# Run with filter
dotnet test --filter Category=Unit
dotnet test --filter FullyQualifiedName~CreateOrderHandler

# Watch mode (TDD)
dotnet watch test --project tests/MyService.UnitTests/

# Coverage report
dotnet test /p:CollectCoverage=true /p:CoverageReportFormat=opencover

# Detailed output
dotnet test --logger "console;verbosity=detailed"

Test Structure

Use testing skill: dotnet-senior-tester

// ✅ GOOD: Arrange-Act-Assert, clear mocking
public class CreateOrderCommandHandlerTests
{
    [Fact]
    public async Task Handle_ValidCommand_CreatesOrder()
    {
        // Arrange
        var repository = Substitute.For<IOrderRepository>();
        var unitOfWork = Substitute.For<IUnitOfWork>();
        repository.UnitOfWork.Returns(unitOfWork);
        
        var handler = new CreateOrderCommandHandler(repository);
        var command = new CreateOrderCommand(UserId: Guid.NewGuid(), /* ... */);
        
        // Act
        var result = await handler.Handle(command, CancellationToken.None);
        
        // Assert
        await repository.Received(1).AddAsync(Arg.Any<Order>(), Arg.Any<CancellationToken>());
        await unitOfWork.Received(1).SaveChangesAsync(Arg.Any<CancellationToken>());
        Assert.NotEqual(Guid.Empty, result.OrderId);
    }
}

See test failure patterns: references/test-failures.md


Phase 4: FIX 🔧

Goal: Debug và resolve issues nhanh chóng

Debugging Workflow

graph TD
    A[Error Detected] --> B{Error Type?}
    B -->|Build| C[Check Build Logs]
    B -->|Test| D[Check Test Output]
    B -->|Runtime| E[Check App Logs]
    
    C --> F[Identify Root Cause]
    D --> F
    E --> F
    
    F --> G[Apply Fix]
    G --> H[Verify Fix]
    H --> I{Fixed?}
    I -->|No| F
    I -->|Yes| J[Document Solution]

Debugging Tools

Build Errors:

# Verbose build output
dotnet build -v detailed

# Clean and rebuild
dotnet clean && dotnet build

# Check references
dotnet list package

Test Failures:

# Run single test with details
dotnet test --filter TestMethodName --logger "console;verbosity=detailed"

# Debug test in VS Code
# Set breakpoint, F5 to debug

Runtime Issues:

# Container logs
docker logs -f my-service-net
docker logs --tail 100 my-service-net

# Follow logs
docker-compose -f deployments/local/docker-compose.yml logs -f my-service-net

# Exec into container
docker exec -it my-service-net sh

# Check health endpoint
curl http://localhost/api/v1/my-service/health

Common Fix Patterns

Issue Pattern Example
NullReferenceException Check mock setup repository.Setup(x => x.Get()).Returns(entity)
Async deadlock Use ConfigureAwait(false) await task.ConfigureAwait(false);
Database timeout Check connection string, indexes Add index on frequently queried columns
Container won't start Check environment vars, ports Verify docker-compose.yml config

See detailed guide: references/debugging-guide.md


Phase 5: DEPLOY 🚀

Goal: Deploy và verify application in target environment

Local Deployment

# Start service with docker-compose
docker-compose -f deployments/local/docker-compose.yml up -d my-service-net

# Check status
docker-compose -f deployments/local/docker-compose.yml ps

# Health check
curl http://localhost/api/v1/my-service/health

# Swagger UI
open http://localhost/api/v1/my-service/swagger

Health Checks

Every service MUST have /health endpoint:

// Program.cs
builder.Services.AddHealthChecks()
    .AddNpgSql(connectionString, name: "database")
    .AddRedis(redisConnection, name: "redis");

app.MapHealthChecks("/health");

Verification Checklist

  • Service starts without errors
  • /health returns 200 OK
  • Database migrations applied
  • Swagger UI accessible
  • Sample API call works
  • Logs show no errors

Staging/Production

Use deployment skill: deployment-kubernetes

# kubectl commands for K8s
kubectl apply -f deployments/kubernetes/my-service.yaml
kubectl rollout status deployment/my-service
kubectl get pods -l app=my-service

Development Patterns / Các Mẫu Phát Triển

Pattern 1: Test-Driven Development (TDD)

1. ❌ RED    - Write failing test
2. ✅ GREEN  - Write minimal code to pass
3. 🔧 REFACTOR - Improve code quality
4. Repeat

Benefits:

  • Better design (testable code)
  • High confidence in changes
  • Living documentation

Pattern 2: Incremental Development

# Small commits with working state
git commit -m "feat: add CreateOrder command"
git commit -m "test: add CreateOrderHandler tests"
git commit -m "fix: validate order items quantity"

Pattern 3: Hot Reload Development

# .NET hot reload (faster iteration)
dotnet watch run --project src/MyService.API

# Docker with volume mount (for config changes)
docker-compose up --build

Helper Scripts / Scripts Hỗ Trợ

Check Environment

# Verify development environment
./scripts/check-env.sh

Quick Build

# Build single service quickly
./scripts/quick-build.sh my-service-net

Debug Build

# Debug build errors with verbose output
./scripts/debug-build.sh my-service-net

Health Check

# Check all services health
./scripts/health-check.sh

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

1. Skip Tests

Problem: Bugs go to production
Solution: Write tests first (TDD) or immediately after feature

# ❌ BAD: Push without testing
git push origin main

# ✅ GOOD: Always test first
dotnet test && git push origin main

2. Ignore Build Warnings

Problem: Tech debt accumulates, future breaks
Solution: Treat warnings as errors

<!-- MyService.API.csproj -->
<PropertyGroup>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

3. No Logging

Problem: Hard to debug production issues
Solution: Add structured logging

// ✅ GOOD: Structured logging
_logger.LogInformation("Creating order for user {UserId} with {ItemCount} items", 
    command.UserId, command.Items.Count);

4. Skip Health Checks

Problem: Can't verify deployment success
Solution: Always add /health endpoint

app.MapHealthChecks("/health", new HealthCheckOptions
{
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

Quick Reference / Tham Chiếu Nhanh

Development Commands

Task Command
Restore packages dotnet restore
Build dotnet build
Run tests dotnet test
Run locally dotnet run --project src/MyService.API
Watch mode dotnet watch run
Hot reload tests dotnet watch test

Docker Commands

Task Command
Build image docker-compose build my-service-net
Start service docker-compose up -d my-service-net
View logs docker-compose logs -f my-service-net
Restart docker-compose restart my-service-net
Stop docker-compose down
Rebuild & start docker-compose up -d --build my-service-net

Debugging Commands

Task Command
Verbose build dotnet build -v detailed
Clean build dotnet clean && dotnet build
Test with logs dotnet test --logger console
Container logs docker logs -f my-service-net
Exec into container docker exec -it my-service-net sh

Resources / Tài Nguyên

Helper Resources

External Resources