Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when building or extending a C# service on ASP.NET Core - Minimal APIs or controllers, DI and options, EF Core with Npgsql, ProblemDetails, HttpClientFactory resilience, async and cancellation
日本語の概要は準備中です。原文の説明を表示しています。
インストールする前に、エージェントに与えられる指示の中身を確認できます。
ASP.NET Core is the .NET backend stack: one host for HTTP, DI, configuration, logging and background work. Build in layers so the framework stays at the edges and the domain stays plain C#.
Core principle: the repository's shape wins. Minimal APIs or MVC controllers, EF Core or Dapper, Clean Architecture projects or one project — follow what is there. The patterns below are for new code and for the gaps.
| Layer | Responsibility | ASP.NET Core surface |
|---|---|---|
| Endpoint | HTTP in/out, binding, status codes | MapGroup + MapPost (Minimal APIs) or [ApiController] controllers |
| Application service | Use-case orchestration, business rules | a class registered in DI, constructor-injected, CancellationToken on every async method |
| Domain | Entities, value objects, invariants | plain C#, no ASP.NET or EF attributes driving behaviour |
| Infrastructure | Persistence, outbound HTTP, queues | DbContext, typed HttpClient, BackgroundService |
Dependencies point inward: an endpoint calls a service, a service depends on an interface the infrastructure implements. An endpoint never contains business rules; a service never takes HttpContext.
TargetFramework. A new service targets the current LTS (net10.0); never move a repository to a preview SDK in a feature task. global.json pins the SDK when the repository has one.<Nullable>enable</Nullable>); treat a new nullable warning as a bug, not noise. Respect TreatWarningsAsErrors and .editorconfig analyzers.public sealed class TaskService(ITaskRepository repo, TimeProvider clock). Lifetimes: DbContext scoped, stateless services scoped or singleton, never a scoped dependency captured by a singleton.builder.Services.AddOptions<SmtpOptions>().BindConfiguration("Smtp").ValidateDataAnnotations().ValidateOnStart(); — never read IConfiguration["..."] in a service, never hardcode.builder.Services.AddValidation() (Minimal APIs, .NET 10) or [ApiController] model validation; FluentValidation where the repository already uses it. The domain enforces its own invariants too.builder.Services.AddProblemDetails(), app.UseExceptionHandler() and an IExceptionHandler that maps domain exceptions to 400/404/409. Endpoints return TypedResults (Results<Created<TaskResponse>, ValidationProblem>), not ad-hoc anonymous objects. No stack trace in a response body.await every I/O call and pass the request's CancellationToken down to EF and HttpClient. Never .Result, .Wait() or async void (outside event handlers).AsNoTracking() for reads, projection (Select) to DTOs instead of loading graphs, Include only for what the response needs. Postgres via Npgsql.EntityFrameworkCore.PostgreSQL. Raw SQL only through FromSql/SqlQuery with interpolated parameters (they are parameterized) — never FromSqlRaw with string concatenation.dotnet ef migrations add <Name>, review the generated Up/Down, commit the migration and the model snapshot together. Deploys apply an idempotent script (dotnet ef migrations script --idempotent) or a migration bundle; Database.Migrate() at startup races when several instances start and EnsureCreated() never belongs outside tests. postgres-migrations covers safe DDL.IHttpClientFactory (builder.Services.AddHttpClient<PaymentsClient>()) with AddStandardResilienceHandler() (Microsoft.Extensions.Http.Resilience) for timeouts, retries and circuit breaking. Never new HttpClient() per call.BackgroundService that creates a scope per unit of work (IServiceScopeFactory) and honours stoppingToken.ILogger<T> with message templates (logger.LogInformation("Task {TaskId} created", id)), never string interpolation in a log call; [LoggerMessage] source-generated methods on hot paths. No secrets or PII in a log or a ProblemDetails body.TimeProvider instead of DateTime.UtcNow so tests control the clock; Guid.CreateVersion7() for new time-ordered ids where the repository has no id scheme.builder.Services.AddOpenApi() / app.MapOpenApi() document; keep it in step with api-contract-openapi. New code does not add Swashbuckle.POST /tasks creating a task:
public sealed record CreateTaskRequest([property: Required, StringLength(200)] string Title);
public sealed record TaskResponse(Guid Id, string Title);
public static class TaskEndpoints
{
public static RouteGroupBuilder MapTasks(this IEndpointRouteBuilder app)
{
var group = app.MapGroup("/tasks").RequireAuthorization();
group.MapPost("/", Create);
return group;
}
private static async Task<Created<TaskResponse>> Create(
CreateTaskRequest req, TaskService service, CancellationToken ct)
{
var task = await service.CreateAsync(req.Title, ct);
return TypedResults.Created($"/tasks/{task.Id}", new TaskResponse(task.Id, task.Title));
}
}
public sealed class TaskService(ITaskRepository repo, TimeProvider clock)
{
public async Task<TodoTask> CreateAsync(string title, CancellationToken ct)
{
var task = TodoTask.Create(title, clock.GetUtcNow()); // the domain enforces the 200-character invariant too
await repo.AddAsync(task, ct);
return task;
}
}
The endpoint binds and validates; the service orchestrates; TodoTask.Create rejects an invalid title even when it is called from a job instead of HTTP.
Use the repository's own commands first (list_component_checks, the README, CI). Otherwise: dotnet build (warnings read, not skipped), dotnet format --verify-no-changes when the repository is formatted with it, and dotnet test. For the runtime check build once and run the output — dotnet publish <Api>.csproj -c Release -o /tmp/tt-<task key>/out, then ASPNETCORE_URLS=http://127.0.0.1:18080 dotnet /tmp/tt-<task key>/out/<Api>.dll in the background — rather than dotnet run, whose child process a terminal timeout can orphan.
.Result / .Wait() on a task — thread-pool starvation under load.CancellationToken accepted and never passed on.new HttpClient() in a loop — socket exhaustion; IHttpClientFactory exists for this.using Microsoft.AspNetCore.* inside the domain project.FromSqlRaw($"... {input}") or any SQL assembled from strings.DbContext constructor parameter.catch (Exception) that returns 200.まだレビューはありません。使ってみた感想をお寄せください。
ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。
まだコメントはありません。最初のコメントを書いてみませんか。
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
日本語の概要は準備中です。原文の説明を表示しています。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
日本語の概要は準備中です。原文の説明を表示しています。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
日本語の概要は準備中です。原文の説明を表示しています。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
日本語の概要は準備中です。原文の説明を表示しています。
Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation
日本語の概要は準備中です。原文の説明を表示しています。