From zenbu-powers
C# IT Stage 4:重構階段。Phase A(測試程式碼)→ 跑測試 → Phase B(生產程式碼)→ 跑測試。 嚴格遵守 /aibdd.auto.csharp.code-quality 規範。
npx claudepluginhub zenbuapps/zenbu-powers --plugin zenbu-powersThis skill uses the workspace's default tool permissions.
在綠燈保護下,以小步驟改善程式碼品質。每一步改動後都必須重跑測試,確保綠燈維持。
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Guides code writing, review, and refactoring with Karpathy-inspired rules to avoid overcomplication, ensure simplicity, surgical changes, and verifiable success criteria.
Share bugs, ideas, or general feedback.
在綠燈保護下,以小步驟改善程式碼品質。每一步改動後都必須重跑測試,確保綠燈維持。
接收目標 feature 路徑,確認綠燈後進入 Phase A → Phase B。
dotnet test --filter "Category!=Ignore"Phase A: 重構測試程式碼(Steps/*.cs, Hooks, Helpers)
↓
跑測試 → dotnet test --filter "Category!=Ignore"
↓(保持綠燈)
Phase B: 重構生產程式碼(Models, Repositories, Services, Controllers, DTOs)
↓
跑測試 → dotnet test --filter "Category!=Ignore"
↓(保持綠燈)
完成
# 重構後每次小改動必跑
dotnet test --filter "Category!=Ignore"
# 特定 feature
dotnet test --filter "FullyQualifiedName~LessonProgress"
# 自動格式化
dotnet format
# 嚴格模式(把 warning 當 error)
dotnet build -warnaserror
或使用 IDE 內建:Rider → Code → Reformat Code / VS → Format Document(Ctrl+K, D)。
Steps/*.cs、Hooks、Helpers 的可讀性與組織。
提取共用邏輯到 Helper
// 重構前:每個 step 都寫一次
var statusMap = new Dictionary<string, string> { ... };
var mapped = statusMap.GetValueOrDefault(status, status);
// 重構後:抽 StatusMapper.cs
var mapped = StatusMapper.Map(status);
移除 TODO 註解(見 /zenbu-powers:aibdd.auto.csharp.code-quality §3)
統一 ScenarioContext 存取模式
// Steps/Helpers/ScenarioContextExtensions.cs
public static class ScenarioContextExtensions
{
public static Dictionary<string, object> Ids(this ScenarioContext ctx)
=> ctx.Get<Dictionary<string, object>>("Ids");
public static HttpClient Client(this ScenarioContext ctx)
=> ctx.Get<HttpClient>("HttpClient");
public static AppDbContext Db(this ScenarioContext ctx)
=> ctx.Get<AppDbContext>("DbContext");
}
// 使用
var userId = _ctx.Ids()[userName].ToString()!;
var client = _ctx.Client();
DataTable 解析抽取為 private method
Step pattern 的中文文字核對(避免空格、標點差異)
Controllers、Services、Repositories、Models 的品質。
// 重構前
public class UpdateVideoProgressRequest
{
public int LessonId { get; set; }
public int Progress { get; set; }
}
// 重構後
public record UpdateVideoProgressRequest(int LessonId, int Progress);
// 重構前
public string MapStatus(string status)
{
if (status == "進行中") return "IN_PROGRESS";
if (status == "已完成") return "COMPLETED";
return status;
}
// 重構後
public static string MapStatus(string status) => status switch
{
"進行中" => "IN_PROGRESS",
"已完成" => "COMPLETED",
"未開始" => "NOT_STARTED",
_ => status
};
// 重構前
var order = _context.Orders.First(o => o.Id == orderId); // 可能拋 InvalidOperationException
// 重構後
var order = _context.Orders.FirstOrDefault(o => o.Id == orderId)
?? throw new OrderNotFoundException(orderId);
// 專案 csproj
<Nullable>enable</Nullable>
// 欄位明確標示
public string Name { get; set; } = null!; // 非 null
public string? Description { get; set; } // 可為 null
// 重構前
public class OrderService
{
private readonly IOrderRepository _orderRepository;
public OrderService(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
}
// 重構後(C# 12 primary constructor)
public class OrderService(IOrderRepository orderRepository) : IOrderService
{
private readonly IOrderRepository _orderRepository = orderRepository;
}
// 重構前
if (obj != null && obj is User)
{
var user = (User)obj;
// ...
}
// 重構後
if (obj is User user)
{
// ...
}
// 1. System.*
using System;
using System.Linq;
// 2. Microsoft.*
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
// 3. Third-party
using FluentAssertions;
// 4. 本地
using ProjectName.Data;
using ProjectName.Models;
[ApiController] 自動處理 ModelState)Ok(...), 失敗用 BadRequest(...))ProblemDetailsFindByUserIdAndLessonId vs Get)AsNoTracking() 做純查詢(效能)Include() 預載關聯OnModelCreating 配置集中於 Configurations/ 子目錄IEntityTypeConfiguration<T> 拆分每個 Entity 的配置public class LessonProgressConfiguration : IEntityTypeConfiguration<LessonProgress>
{
public void Configure(EntityTypeBuilder<LessonProgress> builder)
{
builder.ToTable("lesson_progresses");
builder.HasKey(e => new { e.UserId, e.LessonId });
builder.Property(e => e.Status).HasConversion<string>();
}
}
// AppDbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
}
每次只做一件:
constreadonly 修飾字完整 C# 品質規範見 /zenbu-powers:aibdd.auto.csharp.code-quality。
dotnet test --filter "Category!=Ignore")/zenbu-powers:aibdd.auto.csharp.code-quality 檢查清單dotnet build -warnaserror 無警告(可選)