From 3003a0ff0bfc8479f210ae43cef51a0816449554 Mon Sep 17 00:00:00 2001 From: Te amo Date: Mon, 9 Mar 2026 16:51:44 +0700 Subject: [PATCH] source: Add rules for AI Coding --- Dockerfile | 20 +- MyNewProjectName.AdminAPI/appsettings.json | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 239 +++++++++ .../MyNewProjectName.WebAPI.csproj | 1 + MyNewProjectName.WebAPI/Program.cs | 122 +++-- MyNewProjectName.WebAPI/appsettings.json | 2 +- base/.agent/rules/GitBranch.md | 334 +++++++++++++ base/.agent/rules/GitCommit.md | 468 ++++++++++++++++++ base/.agent/rules/Redis.md | 394 +++++++++++++++ .../CI-CD/GenerateGitHubActions.md | 126 +++++ .../GenerateNewFeature/GenerateCQRSFeature.md | 34 ++ .../GenerateNTierFeature.md | 40 ++ .../GenerateTest/ArchitectureTest.md | 49 ++ .../GenerateTest/IntegrationTest.md | 34 ++ .../custom-skills/GenerateTest/UnitTest.md | 32 ++ base/.agent/skills/ui-ux-pro-max | 1 + .../01. Documents/meeting-script.txt | 19 + .../05. Architecture/C4_Code.md | 48 ++ .../05. Architecture/C4_Component.md | 61 +++ .../05. Architecture/C4_Container.md | 54 ++ .../05. Architecture/C4_Context.md | 58 +++ .../05. Architecture/README.md | 24 + .../01. HighLevelDesign/HighLevelDesign.md | 0 .../02. LowLevelDesign/LowLevelDesign.md | 0 .../rename-project.ps1 | 4 +- .../rename-project.sh | 4 +- rename-project/rename.md | 3 + 27 files changed, 2103 insertions(+), 70 deletions(-) create mode 100644 MyNewProjectName.WebAPI/Extensions/ServiceCollectionExtensions.cs create mode 100644 base/.agent/rules/GitBranch.md create mode 100644 base/.agent/rules/GitCommit.md create mode 100644 base/.agent/rules/Redis.md create mode 100644 base/.agent/skills/custom-skills/CI-CD/GenerateGitHubActions.md create mode 100644 base/.agent/skills/custom-skills/GenerateNewFeature/GenerateCQRSFeature.md create mode 100644 base/.agent/skills/custom-skills/GenerateNewFeature/GenerateNTierFeature.md create mode 100644 base/.agent/skills/custom-skills/GenerateTest/ArchitectureTest.md create mode 100644 base/.agent/skills/custom-skills/GenerateTest/IntegrationTest.md create mode 100644 base/.agent/skills/custom-skills/GenerateTest/UnitTest.md create mode 120000 base/.agent/skills/ui-ux-pro-max create mode 100644 base/01. Project Management/01. Documents/meeting-script.txt create mode 100644 base/02. Requirements/05. Architecture/C4_Code.md create mode 100644 base/02. Requirements/05. Architecture/C4_Component.md create mode 100644 base/02. Requirements/05. Architecture/C4_Container.md create mode 100644 base/02. Requirements/05. Architecture/C4_Context.md create mode 100644 base/02. Requirements/05. Architecture/README.md create mode 100644 base/03. Design/01. HighLevelDesign/HighLevelDesign.md create mode 100644 base/03. Design/02. LowLevelDesign/LowLevelDesign.md rename rename-project.ps1 => rename-project/rename-project.ps1 (95%) rename rename-project.sh => rename-project/rename-project.sh (96%) create mode 100644 rename-project/rename.md diff --git a/Dockerfile b/Dockerfile index e10dba4..968edb3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,22 +3,22 @@ FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build WORKDIR /src # Copy csproj files and restore -COPY ["iYHCT360.Domain/iYHCT360.Domain.csproj", "iYHCT360.Domain/"] -COPY ["iYHCT360.Contracts/iYHCT360.Contracts.csproj", "iYHCT360.Contracts/"] -COPY ["iYHCT360.Application/iYHCT360.Application.csproj", "iYHCT360.Application/"] -COPY ["iYHCT360.Infrastructure/iYHCT360.Infrastructure.csproj", "iYHCT360.Infrastructure/"] -COPY ["iYHCT360.WebAPI/iYHCT360.WebAPI.csproj", "iYHCT360.WebAPI/"] +COPY ["MyNewProjectName.Domain/MyNewProjectName.Domain.csproj", "MyNewProjectName.Domain/"] +COPY ["MyNewProjectName.Contracts/MyNewProjectName.Contracts.csproj", "MyNewProjectName.Contracts/"] +COPY ["MyNewProjectName.Application/MyNewProjectName.Application.csproj", "MyNewProjectName.Application/"] +COPY ["MyNewProjectName.Infrastructure/MyNewProjectName.Infrastructure.csproj", "MyNewProjectName.Infrastructure/"] +COPY ["MyNewProjectName.WebAPI/MyNewProjectName.WebAPI.csproj", "MyNewProjectName.WebAPI/"] -RUN dotnet restore "iYHCT360.WebAPI/iYHCT360.WebAPI.csproj" +RUN dotnet restore "MyNewProjectName.WebAPI/MyNewProjectName.WebAPI.csproj" # Copy everything else and build COPY . . -WORKDIR "/src/iYHCT360.WebAPI" -RUN dotnet build "iYHCT360.WebAPI.csproj" -c Release -o /app/build +WORKDIR "/src/MyNewProjectName.WebAPI" +RUN dotnet build "MyNewProjectName.WebAPI.csproj" -c Release -o /app/build # Publish stage FROM build AS publish -RUN dotnet publish "iYHCT360.WebAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false +RUN dotnet publish "MyNewProjectName.WebAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false # Final stage FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS final @@ -27,4 +27,4 @@ EXPOSE 8080 EXPOSE 8081 COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "iYHCT360.WebAPI.dll"] +ENTRYPOINT ["dotnet", "MyNewProjectName.WebAPI.dll"] diff --git a/MyNewProjectName.AdminAPI/appsettings.json b/MyNewProjectName.AdminAPI/appsettings.json index 2aa297e..9a99411 100644 --- a/MyNewProjectName.AdminAPI/appsettings.json +++ b/MyNewProjectName.AdminAPI/appsettings.json @@ -40,4 +40,4 @@ "EnableResponseLogging": false }, "AllowedHosts": "*" -} +} \ No newline at end of file diff --git a/MyNewProjectName.WebAPI/Extensions/ServiceCollectionExtensions.cs b/MyNewProjectName.WebAPI/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..be5babe --- /dev/null +++ b/MyNewProjectName.WebAPI/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,239 @@ +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Configuration; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; +using System.Reflection; +using System.Text; +using System.Text.Json; +using MyNewProjectName.Infrastructure.Options; +using MyNewProjectName.Contracts.Common; + +namespace MyNewProjectName.WebAPI.Extensions; + +/// +/// Extension methods for configuring services in the dependency injection container +/// +public static class ServiceCollectionExtensions +{ + /// + /// Configures Swagger/OpenAPI documentation with JWT Bearer authentication support + /// + public static IServiceCollection AddCustomSwagger(this IServiceCollection services) + { + services.AddSwaggerGen(c => + { + c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyNewProjectName API", Version = "v1" }); + + var securityScheme = new OpenApiSecurityScheme + { + Name = "Authorization", + Description = "Enter JWT Bearer token", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + Scheme = "bearer", + BearerFormat = "JWT" + }; + c.AddSecurityDefinition("Bearer", securityScheme); + + var securityRequirement = new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "Bearer" + } + }, + new string[] {} + } + }; + c.AddSecurityRequirement(securityRequirement); + + // Set the comments path for the Swagger JSON and UI (only if XML file exists) + var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; + var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); + if (File.Exists(xmlPath)) + { + c.IncludeXmlComments(xmlPath); + } + }); + + return services; + } + + /// + /// Configures JWT Bearer authentication with custom token validation and error handling + /// + public static IServiceCollection AddJwtAuthentication(this IServiceCollection services, IConfiguration configuration) + { + var jwtOptionsSection = configuration.GetSection(JwtOptions.SectionName); + var jwtOptions = jwtOptionsSection.Get() + ?? throw new InvalidOperationException("JwtOptions configuration is missing"); + + services + .AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddJwtBearer(options => + { + options.RequireHttpsMetadata = false; + options.SaveToken = true; + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidateAudience = true, + ValidateIssuerSigningKey = true, + ValidateLifetime = true, + ValidIssuer = jwtOptions.Issuer, + ValidAudience = jwtOptions.Audience, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.Secret)), + ClockSkew = TimeSpan.Zero + }; + + // Log token & claims for debugging + options.Events = new JwtBearerEvents + { + OnMessageReceived = context => + { + var logger = context.HttpContext.RequestServices + .GetRequiredService() + .CreateLogger("JwtBearer"); + + // Có thể bật lại nếu cần debug Authorization header + // logger.LogInformation("JWT received. Authorization header: {Header}", context.Request.Headers["Authorization"].ToString()); + return Task.CompletedTask; + }, + OnTokenValidated = context => + { + var logger = context.HttpContext.RequestServices + .GetRequiredService() + .CreateLogger("JwtBearer"); + + var claims = context.Principal?.Claims + .Select(c => $"{c.Type}={c.Value}") + .ToList() ?? new List(); + + // logger.LogInformation("JWT validated. Claims: {Claims}", string.Join(", ", claims)); + return Task.CompletedTask; + }, + OnAuthenticationFailed = context => + { + var logger = context.HttpContext.RequestServices + .GetRequiredService() + .CreateLogger("JwtBearer"); + + logger.LogWarning(context.Exception, "JWT authentication failed"); + return Task.CompletedTask; + }, + OnChallenge = async context => + { + // Ngăn không cho middleware mặc định ghi response lần nữa + context.HandleResponse(); + + var logger = context.HttpContext.RequestServices + .GetRequiredService() + .CreateLogger("JwtBearer"); + + if (context.Response.HasStarted) + { + logger.LogWarning("The response has already started, the JWT challenge middleware will not be executed."); + return; + } + + var correlationId = context.HttpContext.Request.Headers["X-Correlation-ID"].FirstOrDefault() ?? "unknown"; + + var isExpired = context.AuthenticateFailure is SecurityTokenExpiredException; + var message = isExpired + ? "Token expired" + : "Unauthorized"; + + logger.LogInformation("JWT challenge. Expired: {Expired}, Error: {Error}, Description: {Description}, CorrelationId: {CorrelationId}", + isExpired, context.Error, context.ErrorDescription, correlationId); + + context.Response.StatusCode = StatusCodes.Status401Unauthorized; + context.Response.ContentType = "application/json"; + + var response = new ServiceResponse + { + Success = false, + Message = message, + Errors = null + }; + + var json = JsonSerializer.Serialize(response, new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }); + + await context.Response.WriteAsync(json); + }, + OnForbidden = async context => + { + var logger = context.HttpContext.RequestServices + .GetRequiredService() + .CreateLogger("JwtBearer"); + + logger.LogWarning("User is authenticated but does not have access to the requested resource (403 Forbidden)."); + + context.Response.StatusCode = StatusCodes.Status403Forbidden; + context.Response.ContentType = "application/json"; + + var response = new ServiceResponse + { + Success = false, + Message = "You do not have permission to perform this action.", + Errors = null + }; + + var json = JsonSerializer.Serialize(response, new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }); + + await context.Response.WriteAsync(json); + } + }; + }); + + return services; + } + + // /// + // /// Configures authorization policies based on user type and roles. + // /// + // public static IServiceCollection AddCustomAuthorization(this IServiceCollection services) + // { + // services.AddAuthorization(options => + // { + // // 1. Policy chỉ dành cho SuperAdmin + // options.AddPolicy("RequireSuperAdmin", policy => + // policy.RequireClaim("userType", "SuperAdmin")); + + // // 2. Policy cho TenantAdmin (TenantMember + Role = TenantAdmin) + // options.AddPolicy("RequireTenantAdmin", policy => + // policy.RequireClaim("userType", "TenantMember") + // .RequireRole("TenantAdmin")); + + // // 3. Policy cho TenantMember (TenantMember + Role = Doctor) + // options.AddPolicy("RequireTenantMember", policy => + // policy.RequireClaim("userType", "TenantMember") + // ); + // // 4. Policy SuperAdmin hoặc TenantAdmin + // options.AddPolicy("RequireSuperAdminOrTenantAdmin", policy => + // policy.RequireAssertion(context => + // // Điều kiện 1: Là SuperAdmin + // context.User.HasClaim("userType", "SuperAdmin") + // || + // // HOẶC Điều kiện 2: Là Nhân viên VÀ có Role là TenantAdmin + // (context.User.HasClaim("userType", "TenantMember") && context.User.IsInRole("TenantAdmin")) + // )); + // }); + + // return services; + // } +} diff --git a/MyNewProjectName.WebAPI/MyNewProjectName.WebAPI.csproj b/MyNewProjectName.WebAPI/MyNewProjectName.WebAPI.csproj index 4441521..e5d13f8 100644 --- a/MyNewProjectName.WebAPI/MyNewProjectName.WebAPI.csproj +++ b/MyNewProjectName.WebAPI/MyNewProjectName.WebAPI.csproj @@ -6,6 +6,7 @@ + diff --git a/MyNewProjectName.WebAPI/Program.cs b/MyNewProjectName.WebAPI/Program.cs index e6aa956..c0b49ba 100644 --- a/MyNewProjectName.WebAPI/Program.cs +++ b/MyNewProjectName.WebAPI/Program.cs @@ -1,75 +1,89 @@ -using Microsoft.Extensions.Hosting; using MyNewProjectName.Application; using MyNewProjectName.Infrastructure; -using MyNewProjectName.Infrastructure.Extensions; using MyNewProjectName.WebAPI.Middleware; -using Serilog; +using MyNewProjectName.WebAPI.Extensions; +using MyNewProjectName.Application.Interfaces; +using MyNewProjectName.WebAPI.Services; var builder = WebApplication.CreateBuilder(args); -// Configure Serilog -builder.Host.UseSerilogLogging(builder.Configuration); - -// Add OpenTelemetry distributed tracing -builder.Services.AddOpenTelemetryTracing("MyNewProjectName.WebAPI"); - -// Add services to the container. -builder.Services.AddControllers(); - -// Add Application Layer -builder.Services.AddApplication(); - -// Add Infrastructure Layer -builder.Services.AddInfrastructure(builder.Configuration); - -// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi -builder.Services.AddOpenApi(); - -// Add Swagger +// ========================================== +// 1. ADD SERVICES TO CONTAINER +// ========================================== +builder.Services.AddControllers() + .AddJsonOptions(options => + { + // Configure enum serialization to use string representation + options.JsonSerializerOptions.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter()); + }); builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddMemoryCache(); +builder.Services.AddLogging(); +// Extension Methods: Swagger, JWT Authentication & Authorization +builder.Services.AddCustomSwagger(); +builder.Services.AddJwtAuthentication(builder.Configuration); +builder.Services.AddCustomAuthorization(); + +// Layers Registration +builder.Services.AddApplication(); +builder.Services.AddInfrastructure(builder.Configuration); +builder.Services.AddHttpContextAccessor(); +builder.Services.AddScoped(); + +// CORS Configuration +builder.Services.AddCors(option => +{ + option.AddPolicy(name: "CorsPolicy", + configurePolicy: builder => builder + .SetIsOriginAllowed((host) => true) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials()); +}); + + +builder.WebHost.UseUrls("http://0.0.0.0:5044"); var app = builder.Build(); -// Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { - app.MapOpenApi(); + app.UseSwagger(); + app.UseSwaggerUI(option => + { + option.SwaggerEndpoint("/swagger/v1/swagger.json", "iYHCT360 API"); + option.RoutePrefix = "swagger"; // UI tại /swagger + option.DisplayRequestDuration(); + option.EnableFilter(); + option.EnableValidator(); + option.EnableTryItOutByDefault(); + }); } -// Middleware pipeline order is critical: -// 1. CorrelationIdMiddleware - Must be first to track all requests + +// Middleware Pipeline - Order is important! +// 1. CorrelationIdMiddleware: Generate correlation ID for request tracking (must be first) app.UseMiddleware(); -// 2. RequestResponseLoggingMiddleware - Optional, enable only when needed -// WARNING: This can generate large log files. Enable only for specific environments. -// Configure in appsettings.json: "Logging:EnableRequestLogging" and "Logging:EnableResponseLogging" -app.UseMiddleware(); - -app.UseHttpsRedirection(); - -// 3. Authentication (built-in) -app.UseAuthentication(); - -// 4. Authorization (built-in) -app.UseAuthorization(); - -// 6. ExceptionHandlingMiddleware - Must be last to catch all exceptions +// 2. ExceptionHandlingMiddleware: Global exception handler (must be early to catch all exceptions) app.UseMiddleware(); +// 3. Routing & Static Files +app.UseRouting(); +app.UseStaticFiles(); + +// 4. CORS (must be before UseAuthentication/UseAuthorization) +app.UseCors("CorsPolicy"); + +// 5. Authentication & Authorization +app.UseAuthentication(); +app.UseAuthorization(); + +// 6. RequestResponseLoggingMiddleware: Log request/response (after routing and auth to avoid interfering with response) +app.UseMiddleware(); + +// 7. Map Controllers app.MapControllers(); -try -{ - Log.Information("Starting MyNewProjectName.WebAPI"); - app.Run(); -} -catch (Exception ex) -{ - Log.Fatal(ex, "Application terminated unexpectedly"); - throw; -} -finally -{ - Log.CloseAndFlush(); -} +app.Run(); diff --git a/MyNewProjectName.WebAPI/appsettings.json b/MyNewProjectName.WebAPI/appsettings.json index 2aa297e..9a99411 100644 --- a/MyNewProjectName.WebAPI/appsettings.json +++ b/MyNewProjectName.WebAPI/appsettings.json @@ -40,4 +40,4 @@ "EnableResponseLogging": false }, "AllowedHosts": "*" -} +} \ No newline at end of file diff --git a/base/.agent/rules/GitBranch.md b/base/.agent/rules/GitBranch.md new file mode 100644 index 0000000..be8f369 --- /dev/null +++ b/base/.agent/rules/GitBranch.md @@ -0,0 +1,334 @@ +# Huong Dan Dat Ten Git Branch Trong Du An + +> **Tham khao:** [Git Branch Naming Conventions - Codiga](https://codiga.io/blog/git-branch-naming-conventions) + +--- + +## Muc Luc + +1. [Nguyen Tac Chung](#1-nguyen-tac-chung) +2. [Cau Truc Ten Branch](#2-cau-truc-ten-branch) +3. [Cac Loai Branch (Branch Types)](#3-cac-loai-branch-branch-types) +4. [Bang Mau Ten Branch Theo Chuc Nang](#4-bang-mau-ten-branch-theo-chuc-nang) +5. [Quy Tac Dat Ten (Good Practices)](#5-quy-tac-dat-ten-good-practices) +6. [Mo Hinh Git Flow](#6-mo-hinh-git-flow) +7. [Vi Du Thuc Te Trong Du An](#7-vi-du-thuc-te-trong-du-an) +8. [Checklist Truoc Khi Tao Branch](#8-checklist-truoc-khi-tao-branch) + +--- + +## 1. Nguyen Tac Chung + +Theo bai viet tu Codiga, mot quy uoc dat ten branch tot giup: + +| # | Loi ich | Mo ta | +|---|---------|-------| +| 1 | **Truy vet tac gia** | Biet ai da tao branch (developer nao) | +| 2 | **Lien ket voi issue tracker** | De dang trace branch voi task/ticket tren JIRA, Trello, GitHub Issues... | +| 3 | **Hieu muc dich branch** | Nhanh chong biet branch la bugfix, feature, hay hotfix | +| 4 | **To chuc workflow** | Giu cho quy trinh lam viec co trat tu va hieu qua | + +--- + +## 2. Cau Truc Ten Branch + +### Format chung + +``` +/- +``` + +Trong do: + +| Thanh phan | Bat buoc | Mo ta | Vi du | +|-----------|----------|-------|-------| +| `type` | Co | Loai branch (feature, bugfix, hotfix...) | `feature` | +| `ticket-id` | Co (neu co) | Ma ticket/issue tu issue tracker | `PROJ-1234` | +| `short-description` | Co | Mo ta ngan 3-6 tu, phan cach bang dau `-` | `add-user-authentication` | + +### Vi du day du + +``` +feature/PROJ-1234-add-user-authentication +bugfix/PROJ-5678-fix-login-redirect +hotfix/PROJ-9012-patch-security-vulnerability +``` + +### Format mo rong (co ten tac gia) + +Neu team co nhieu nguoi lam chung mot ticket, them ten tac gia: + +``` +//- +``` + +Vi du: + +``` +julien/feature/1234-new-dashboard +david/feature/1234-new-dashboard +``` + +Dieu nay giup phan biet ro rang code cua tung developer cho cung mot task. + +--- + +## 3. Cac Loai Branch (Branch Types) + +### Branch chinh (Long-lived branches) + +| Branch | Muc dich | Duoc merge tu | Ghi chu | +|--------|---------|---------------|---------| +| `main` (hoac `master`) | Code production, luon o trang thai stable | `release`, `hotfix` | Khong bao gio commit truc tiep | +| `develop` | Code moi nhat cho phien ban tiep theo | `feature`, `bugfix` | Nhanh tich hop chinh | +| `staging` | Moi truong test truoc khi len production | `develop` | Tuy chon, tuy du an | + +### Branch tam thoi (Short-lived branches) + +| Prefix | Muc dich | Tao tu | Merge vao | Vi du | +|--------|---------|--------|----------|-------| +| `feature/` | Tinh nang moi | `develop` | `develop` | `feature/PROJ-101-add-login-page` | +| `bugfix/` | Sua loi trong qua trinh phat trien | `develop` | `develop` | `bugfix/PROJ-202-fix-null-reference` | +| `hotfix/` | Sua loi khan cap tren production | `main` | `main` va `develop` | `hotfix/PROJ-303-fix-payment-crash` | +| `release/` | Chuan bi phien ban moi | `develop` | `main` va `develop` | `release/v1.2.0` | +| `chore/` | Cong viec bao tri, refactor, CI/CD | `develop` | `develop` | `chore/update-dependencies` | +| `docs/` | Cap nhat tai lieu | `develop` | `develop` | `docs/update-api-documentation` | +| `test/` | Viet test hoac cai thien test | `develop` | `develop` | `test/add-unit-tests-user-service` | +| `refactor/` | Tai cau truc code, khong thay doi chuc nang | `develop` | `develop` | `refactor/clean-up-user-repository` | + +--- + +## 4. Bang Mau Ten Branch Theo Chuc Nang + +### Authentication & Authorization + +``` +feature/PROJ-101-add-jwt-authentication +feature/PROJ-102-implement-refresh-token +feature/PROJ-103-add-role-based-access +bugfix/PROJ-104-fix-token-expiration +hotfix/PROJ-105-patch-auth-bypass +``` + +### CRUD Entity + +``` +feature/PROJ-201-create-product-entity +feature/PROJ-202-add-product-api-endpoints +feature/PROJ-203-implement-product-search +bugfix/PROJ-204-fix-product-update-validation +``` + +### Infrastructure & DevOps + +``` +chore/PROJ-301-setup-docker-compose +chore/PROJ-302-configure-ci-cd-pipeline +chore/PROJ-303-add-redis-caching +chore/PROJ-304-setup-logging-serilog +``` + +### Database & Migration + +``` +feature/PROJ-401-add-migration-user-table +feature/PROJ-402-seed-initial-data +bugfix/PROJ-403-fix-migration-conflict +``` + +### Documentation + +``` +docs/PROJ-501-update-readme +docs/PROJ-502-add-api-swagger-docs +docs/PROJ-503-create-deployment-guide +``` + +--- + +## 5. Quy Tac Dat Ten (Good Practices) + +### Nen lam + +| Quy tac | Chi tiet | Vi du | +|---------|---------|-------| +| **Dung ten mo ta** | Ten branch phai phan anh ro noi dung thay doi | `feature/PROJ-101-add-user-authentication` | +| **Giu ngan gon** | Chi 3-6 tu khoa, phan cach bang dau `-` | `bugfix/PROJ-202-fix-null-ref` | +| **Viet thuong toan bo** | Khong viet hoa | `feature/add-login` | +| **Dung dau `-` phan cach tu** | Khong dung dau cach, underscore, hoac camelCase | `fix-login-redirect` | +| **Bat dau bang type prefix** | Luon co prefix xac dinh loai branch | `feature/`, `bugfix/`, `hotfix/` | +| **Lien ket ticket ID** | Giup trace nguon goc thay doi | `PROJ-1234-...` | + +### Khong nen lam + +| Quy tac | Vi du sai | Vi du dung | +|---------|----------|-----------| +| **Khong dung ky tu dac biet** | `feature/add@user#auth` | `feature/add-user-auth` | +| **Khong dung dau cach** | `feature/add user auth` | `feature/add-user-auth` | +| **Khong viet hoa** | `Feature/Add-User-Auth` | `feature/add-user-auth` | +| **Khong dat ten chung chung** | `feature/new-stuff` | `feature/PROJ-101-add-payment-gateway` | +| **Khong dat ten qua dai** | `feature/PROJ-101-add-new-user-authentication-with-jwt-and-refresh-token-support-for-all-roles` | `feature/PROJ-101-add-jwt-auth` | +| **Khong dung so thuong** | `feature/123` | `feature/PROJ-123-add-login` | +| **Khong commit truc tiep vao main/develop** | — | Luon tao branch rieng | + +--- + +## 6. Mo Hinh Git Flow + +### So do tong quat + +``` +main (production) + | + |--- hotfix/PROJ-xxx-fix-critical-bug + | | + | v + | (merge vao main VA develop) + | + |--- release/v1.2.0 + | | + | v + | (merge vao main VA develop) + | +develop (integration) + | + |--- feature/PROJ-xxx-new-feature + | | + | v + | (merge vao develop qua Pull Request) + | + |--- bugfix/PROJ-xxx-fix-bug + | | + | v + | (merge vao develop qua Pull Request) + | + |--- chore/update-packages + | + v + (merge vao develop qua Pull Request) +``` + +### Quy trinh lam viec + +1. **Tao branch** tu `develop` (hoac `main` cho hotfix) +2. **Commit** thuong xuyen voi message ro rang +3. **Push** branch len remote +4. **Tao Pull Request** (PR) de review code +5. **Review & Approve** boi it nhat 1 thanh vien khac +6. **Merge** vao branch dich (squash merge hoac merge commit) +7. **Xoa branch** sau khi merge thanh cong + +### Lenh Git mau + +```bash +# Tao branch feature moi tu develop +git checkout develop +git pull origin develop +git checkout -b feature/PROJ-101-add-login-page + +# Lam viec va commit +git add . +git commit -m "feat(PROJ-101): add login page UI" + +# Push len remote +git push origin feature/PROJ-101-add-login-page + +# Sau khi merge PR, xoa branch local +git checkout develop +git pull origin develop +git branch -d feature/PROJ-101-add-login-page +``` + +--- + +## 7. Vi Du Thuc Te Trong Du An + +### Ap dung cho du an Clean Architecture (MyNewProjectName) + +#### Sprint 1: Khoi tao du an + +```bash +# Cau hinh co ban +chore/PROJ-001-setup-clean-architecture +chore/PROJ-002-configure-dependency-injection +chore/PROJ-003-setup-ef-core-database +chore/PROJ-004-add-serilog-logging +chore/PROJ-005-setup-docker-compose +``` + +#### Sprint 2: Authentication + +```bash +# Tinh nang xac thuc +feature/PROJ-010-add-user-entity +feature/PROJ-011-implement-jwt-authentication +feature/PROJ-012-add-refresh-token-flow +feature/PROJ-013-implement-role-authorization +bugfix/PROJ-014-fix-token-validation-error +``` + +#### Sprint 3: CRUD cho SampleEntity + +```bash +# Tinh nang CRUD +feature/PROJ-020-add-sample-entity-crud +feature/PROJ-021-add-pagination-support +feature/PROJ-022-implement-search-filter +bugfix/PROJ-023-fix-sample-delete-cascade +``` + +#### Hotfix khan cap + +```bash +# Sua loi tren production +hotfix/PROJ-099-fix-sql-injection-vulnerability +hotfix/PROJ-100-patch-cors-configuration +``` + +### Quy uoc Commit Message (di kem voi branch) + +De dong bo voi quy uoc branch, nen dung [Conventional Commits](https://www.conventionalcommits.org/): + +``` +(): +``` + +| Type | Muc dich | Vi du | +|------|---------|-------| +| `feat` | Tinh nang moi | `feat(PROJ-101): add login page` | +| `fix` | Sua loi | `fix(PROJ-202): resolve null reference in UserService` | +| `chore` | Bao tri | `chore: update NuGet packages` | +| `docs` | Tai lieu | `docs: update API documentation` | +| `refactor` | Tai cau truc | `refactor: simplify UserRepository queries` | +| `test` | Them/sua test | `test: add unit tests for AuthService` | +| `style` | Format code | `style: apply editorconfig rules` | +| `ci` | CI/CD | `ci: add GitHub Actions workflow` | + +--- + +## 8. Checklist Truoc Khi Tao Branch + +- [ ] Ten branch co bat dau bang type prefix khong? (`feature/`, `bugfix/`, `hotfix/`...) +- [ ] Ten branch co chua ticket/issue ID khong? (`PROJ-1234`) +- [ ] Mo ta co ngan gon va ro rang khong? (3-6 tu) +- [ ] Chi dung chu thuong, so, dau `-` va dau `/`? +- [ ] Khong co ky tu dac biet, dau cach, hoac chu viet hoa? +- [ ] Branch duoc tao tu dung branch nguon? (`develop` hoac `main`) +- [ ] Da pull code moi nhat tu branch nguon truoc khi tao? + +--- + +## Tom Tat Nhanh + +``` +Format: /- +Vi du: feature/PROJ-101-add-user-authentication + +Type: feature | bugfix | hotfix | release | chore | docs | test | refactor +Chu y: - Viet thuong toan bo + - Dung dau `-` phan cach tu + - Giu ngan gon (3-6 tu) + - Khong ky tu dac biet + - Lien ket ticket ID + - Xoa branch sau khi merge +``` diff --git a/base/.agent/rules/GitCommit.md b/base/.agent/rules/GitCommit.md new file mode 100644 index 0000000..37d01dd --- /dev/null +++ b/base/.agent/rules/GitCommit.md @@ -0,0 +1,468 @@ +# Huong Dan Viet Git Commit Message Trong Du An + +> **Tham khao:** [Conventional Commits](https://www.conventionalcommits.org/) + +--- + +## Muc Luc + +1. [Nguyen Tac Chung](#1-nguyen-tac-chung) +2. [Cau Truc Commit Message](#2-cau-truc-commit-message) +3. [Cac Loai Type](#3-cac-loai-type) +4. [Scope - Pham Vi Thay Doi](#4-scope---pham-vi-thay-doi) +5. [Quy Tac Viet Description](#5-quy-tac-viet-description) +6. [Commit Message Voi Body Va Footer](#6-commit-message-voi-body-va-footer) +7. [Bang Vi Du Day Du](#7-bang-vi-du-day-du) +8. [Vi Du Thuc Te Trong Du An](#8-vi-du-thuc-te-trong-du-an) +9. [Nhung Loi Thuong Gap](#9-nhung-loi-thuong-gap) +10. [Checklist Truoc Khi Commit](#10-checklist-truoc-khi-commit) + +--- + +## 1. Nguyen Tac Chung + +Viet commit message chuan giup: + +| # | Loi ich | Mo ta | +|---|---------|-------| +| 1 | **Doc lich su de dang** | Nhin vao git log biet ngay thay doi gi | +| 2 | **Tu dong tao changelog** | Cac tool co the tu dong tao changelog tu commit message | +| 3 | **Lien ket voi issue tracker** | De dang trace commit voi task/ticket | +| 4 | **Review code hieu qua** | Nguoi review hieu nhanh muc dich cua commit | +| 5 | **Tu dong versioning** | Xac dinh phien ban tu dong (semantic versioning) dua tren type | + +--- + +## 2. Cau Truc Commit Message + +### Format chung + +``` +(): +``` + +Trong do: + +| Thanh phan | Bat buoc | Mo ta | Vi du | +|-----------|----------|-------|-------| +| `type` | Co | Loai thay doi (feat, fix, chore...) | `feat` | +| `scope` | Khong | Pham vi/module bi anh huong | `auth`, `api`, `user` | +| `description` | Co | Mo ta ngan, duoi 50 ky tu, viet hoa dau cau, khong dau cham cuoi | `add Google login` | + +### Format day du (voi body va footer) + +``` +(): + + + +