一键导入
storm-api
Implement a C# backend using the Storm.Api framework. Use when writing business logic, logging, extension methods, or general Storm.Api patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Implement a C# backend using the Storm.Api framework. Use when writing business logic, logging, extension methods, or general Storm.Api patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Implement authentication using the Storm.Api framework with JWT, API key, custom authenticators, and refresh tokens. Use when adding auth to endpoints.
Write a database migration using the Storm.Api framework with BaseMigration and OrmLite. Use when creating or modifying database tables, columns, or seed data.
Implement database entities and repositories using the Storm.Api framework with ServiceStack.OrmLite. Use when creating entities, repositories, or database queries.
Implement email sending using the Storm.Api framework with Resend provider and temporary email detection. Use when sending emails or validating email addresses.
Implement a C# endpoint using the Storm.Api framework with CQRS actions, controllers, source generators, exceptions, and response DTOs.
Initialize a new Storm.Api project with NuGet packages, Program.cs, Startup.cs, and code style configuration. Use when setting up a new project from scratch.
| name | storm-api |
| description | Implement a C# backend using the Storm.Api framework. Use when writing business logic, logging, extension methods, or general Storm.Api patterns. |
| user-invocable | true |
| disable-model-invocation | false |
You are helping implement a C# backend using the Storm.Api framework. Follow all patterns and constraints below exactly — they are non-negotiable.
The user's request: $ARGUMENTS
Storm.Api is an opinionated ASP.NET Core framework built on CQRS. Business logic lives in Action classes, never in controllers. Controllers are thin, source-generated glue. Three NuGet packages:
Storm.Api — core framework (net10.0)Storm.Api.Dtos — response types, shared with clients (netstandard2.0)Storm.Api.SourceGenerators — Roslyn generator for [WithAction<T>] (netstandard2.0)For specific patterns, use the focused skills:
/storm-api-init — new project setup (NuGet packages, Program.cs, Startup.cs, code style)/storm-api-endpoint — actions, controllers, exceptions, response DTOs, OpenAPI documentation attributes ([Summary], [Description], [ErrorCode], [HttpError], [MediaType], [SuccessCode], [InternalActionCall<>])/storm-api-auth — IActionAuthenticator, JWT, API key, custom authenticators, refresh tokens/storm-api-database — entities, OrmLite queries, repositories/storm-api-database-migrations — writing and registering migrations/storm-api-email — email sending with Resend, temporary email detection/storm-api-workers — background tasks, periodic/scheduled hosted services, retry strategies/storm-api-redis — Redis caching, key-value storage, pub/sub messaging/storm-api-queues — in-memory queues, buffered/throttled batching, queue workersNever use ILogger<T> or Microsoft.Extensions.Logging. Use ILogService exclusively.
// Resolve inside an action or service
var log = Resolve<ILogService>();
// Log with structured properties
log.Log(LogLevel.Warning, x => x
.WriteProperty("message", "Something went wrong")
.WriteProperty("userId", userId)
.WriteException(ex));
// Convenience extension methods
log.Information(x => x.WriteProperty("event", "user_created").WriteProperty("id", id));
log.Warning(x => x.WriteProperty("message", "Rate limit hit"));
log.Error(x => x.WriteProperty("message", "Unexpected failure").WriteException(ex));
Register in Startup.ConfigureServices:
RegisterConsoleLogger(services, LogLevel.Debug);
// or
RegisterSerilogLogger(services, "Serilog");
// or
RegisterElasticSearchLogger(services, "ElasticSearch");
// or (background queue)
RegisterElasticSearchHostedLogger(services, "ElasticSearch");
// Instead of Task.FromResult()
return myValue.AsTask();
return null.AsTaskNullable<int>();
// String helpers
str.IsNullOrEmpty() // bool
str.IsNotNullOrEmpty() // bool
str.ValueIfNullOrEmpty("fallback")
str.NullIfEmpty() // returns null if empty
str.OrEmpty() // coalesce to ""
// Execute action outside controller context
await services.ExecuteAction<MyAction, MyParam, MyOutput>(param);
await services.ExecuteWithScope(async sp => { ... });
// Service resolution inside actions/services
var svc = Resolve<IMyService>();
var keyed = ResolveKeyed<IMyService>("key");
| ❌ Wrong | ✅ Correct |
|---|---|
Task.FromResult(value) | value.AsTask() |
| Constructor-inject services | Resolve<T>() inside methods |
ILogger<T> | ILogService |
| Entity Framework / Dapper | ServiceStack.OrmLite |
| Logic in controller | Logic in Action class |
DateTime.Now / DateTime.UtcNow / DateTimeOffset.UtcNow | Resolve<TimeProvider>().GetUtcNow().UtcDateTime (or inject TimeProvider via constructor in non-Resolve classes) |