crud-handler-http

crud-handler-http is a skill for Claude Code, Codex from ArtisanCloud/PowerX. It costs 23 tokens per session (2,304 once invoked), scanned A, original, Apache-2.0.

PowerX HTTP Handler 规则(绑定校验、统一回包、无 DB IO)。.

Skill for Claude CodeCodex

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add skills/artisancloud/powerx/handler-http
Any agent
npx skills add ArtisanCloud/PowerX --skill handler-http
Clone the repo
git clone --depth 1 https://github.com/ArtisanCloud/PowerX

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for crud-handler-http

README.md
[![agentmods](https://agentmods.dev/badge/skills/artisancloud/powerx/handler-http.svg)](https://agentmods.dev/skills/artisancloud/powerx/handler-http)
Your own site
<a href="https://agentmods.dev/skills/artisancloud/powerx/handler-http"><img src="https://agentmods.dev/badge/skills/artisancloud/powerx/handler-http.svg" alt="Measured on agentmods" height="20"></a>
Per session 23 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 2,304 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00023 $0.02304
Opus 5 $0.00012 $0.01152
Sonnet 5 $0.00005 $0.00461
Haiku 4.5 $0.00002 $0.00230

Measured today against content hash f15954fa42e9, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

crud-handler-http scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured today.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.codex/skills/crud/handler-http/SKILL.md · 233 lines

How it starts

The opening of the file, as written. The whole thing — 233 lines — stays where its author put it; the contents beside it link to each section on GitHub.

PowerX CRUD Handler HTTP

步骤

  1. 打开 本文件内嵌规则
  2. 按规则执行实现/校对。
  3. 完成后按核对清单验收。

核对点

  • 与 PowerX 当前代码结构、路径与命名一致。
  • 仅在传输层/契约层做职责内改动,不跨层越界。

规则(内嵌)

handler_http.yaml

kind: ruleset
name: crud_handler_http
version: 1.0.0
owner: powerx
status: stable

meta:
  intent: >
    规范 HTTP Handler 的目录、职责与调用形态:参数绑定/校验 → 调用 Service → 统一回包/错误桥接,
    禁止业务与 DB/外部 IO;分页、错误、SSE 事件与 REST 契约/DTO 对齐。
  references:
    - dev_crud_http_guides.md
    - constitution.md

scope:
  applies_to:
    - "internal/transport/http/**/**_handler.go"
    - "internal/transport/http/**/api.go"

principles:
  - Handler 只做 绑定/校验 → 调 Service → 回包;禁止写业务、DB 或外部 IO。   # 指南·Handler职责
  - DTO 独立于模型;参数绑定使用统一函数,错误使用 AppError 桥接返回。      # 指南·DTO/错误桥接
  - 路由注册独立在 api.go;前缀使用 /api/v1/{admin|open|web}。               # 指南·路由与版本
  - 多租户上下文来自中间件;缺失租户返回 400 语义,鉴权在 Service 落实。       # 宪章·多租户

checks:

  # 目录 & 入口
  - id: http.dir.shape
    level: error
    when:
      glob: "internal/transport/http/**/api.go"
    assert:
      - must_define: "func Register*Routes(*gin.RouterGroup, *shared.Deps)"
      - must_prefix_route_one_of: ["/api/v1/admin", "/api/v1/open", "/api/v1/web"]

  # Handler 职责边界
  - id: handler.no_db_or_io
    level: error
    when:
      glob: "internal/transport/http/**/**_handler.go"
    assert:
      - must_not_import: ["database/sql","gorm.io/gorm","net/http"] # 允许 gin 但禁止直接 http client
      - must_not_call: ["sql.DB","gorm.DB","http.DefaultClient.Do","os.Remove","ioutil.ReadAll"]
      - must_define_like: "type *Handler struct { svc *service.* }" # 依赖仅指向 Service

  - id: handler.ctor
    level: error
    when:
      glob: "internal/transport/http/**/**_handler.go"
    assert:
      - must_define_like: "func New*Handler(*service.*) *"
      - must_not_define: "func New*Handler(*gorm.DB)"               # 禁止直注 DB

  # 租户上下文与校验/绑定
  - id: handler.binding_and_tenant
    level: error
    when:
      glob: "internal/transport/http/**/**_handler.go"
    assert:
      - must_call_one_of: ["ValidateRequestWithContext(","ValidateAndBindWithContext("]
      - must_call: ["reqctx.From(c)"]       # 从中间件注入的上下文取 tenant/request_id
      - on_missing_tenant_http: 400

  # 统一回包与错误桥接
  - id: handler.response_envelope
    level: error
    when:
      glob: "internal/transport/http/**/**_handler.go"
    assert:
      - must_use_one_of: ["ResponseSuccess(","RespondOK(","RespondErrorFrom("]
      - http_status_in: [200,201,204,400,401,403,404,409,429,500]

  # 分页语义统一
  - id: handler.pagination_contract
    level: error
    when:
      glob: "internal/transport/http/**/**_handler.go"
    assert:
      - must_bind_dto: ["PaginationRequest"]
      - must_return: ["ResponseList","PaginationResponse"]

  # SSE/WS(若涉及)
  - id: handler.sse_events
    level: warn
    when:
      contains: "WriteToSSE("
    assert:
      - must_use_events:
          ["start","intent","plan","token","data","action","final","end","error","heartbeat"]

  # 契约一致性(与 REST 资源路由)
  - id: handler.crud_shape
    level: error
    when:
      glob: "internal/transport/http/**/api.go"
    assert:
      - must_register_methods:
          - 'POST ""'
          - 'GET ""'
          - 'GET "/:id"'
          - 'PATCH "/:id"'
          - 'DELETE "/:id"'

  # 依赖注入(Deps)
  - id: handler.deps_injection
    level: error
    when:
      glob: "internal/transport/http/**/**_handler.go"
    assert:
      - must_reference: "*shared.Deps"   # Handler 通过 Deps 链路拿到 svc(在 api.go 中)
      - must_not_new_external_clients: true

acceptance:
  checklist:
    - "[ ] api.go 只做路由注册,使用 /api/v1/{admin|open|web} 前缀"
    - "[ ] Handler 仅做绑定/校验/调用 Service/回包,不含 DB 与外部 IO"
    - "[ ] 使用 ValidateRequestWithContext/RespondErrorFrom/ResponseSuccess 等统一工具"
    - "[ ] 分页使用 PaginationRequest/PaginationResponse,列表用 ResponseList"
    - "[ ] SSE 事件(若有)使用统一事件名"
    - "[ ] 租户上下文来自中间件,缺失返回 400;鉴权/审计在 Service 层"
    - "[ ] Handler 构造函数存在,依赖通过 *shared.Deps 提供 svc"

templates:

  handler_go: |
    package {{domain}}

    import (
      "github.com/gin-gonic/gin"
      "github.com/ArtisanCloud/PowerX/internal/app/shared"
      "github.com/ArtisanCloud/PowerX/internal/service/{{domain}}"
      dto "{{module_path}}/internal/transport/http/{{layer}}/{{domain}}/dto"
      "github.com/ArtisanCloud/PowerX/pkg/corex/iam/reqctx"
    )

    type {{Entity}}Handler struct {
      svc *{{domain}}.{{Entity}}Service
    }

    func New{{Entity}}Handler(s *{{domain}}.{{Entity}}Service) *{{Entity}}Handler {
      return &{{Entity}}Handler{svc: s}
    }

    // POST /{{domain}}/{{resource}}
    func (h *{{Entity}}Handler) Create(c *gin.Context) {
      ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}CreateReq{})
      if err != nil { RespondErrorFrom(c, err); return }
      out, err := h.svc.Create(ctx, rc.TenantID, rc.ActorID, rc.RequestID, rc.TraceID, rc.Payload)
      if err != nil { RespondErrorFrom(c, err); return }
      ResponseSuccess(c, out)
    }

    // GET /{{domain}}/{{resource}}
    func (h *{{Entity}}Handler) List(c *gin.Context) {
      ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}ListReq{})
      if err != nil { RespondErrorFrom(c, err); return }
      items, pg, err := h.svc.List(ctx, rc.TenantID, rc.Pagination, rc.Filters)
      if err != nil { RespondErrorFrom(c, err); return }
      ResponseSuccess(c, ResponseList{Items: items, Pagination: pg})
    }

    // GET /{{domain}}/{{resource}}/:id
    func (h *{{Entity}}Handler) Get(c *gin.Context) {
      ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}GetReq{})
      if err != nil { RespondErrorFrom(c, err); return }
      out, err := h.svc.Get(ctx, rc.TenantID, rc.ID)
      if err != nil { RespondErrorFrom(c, err); return }
      ResponseSuccess(c, out)
    }

    // PATCH /{{domain}}/{{resource}}/:id
    func (h *{{Entity}}Handler) Update(c *gin.Context) {
      ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}UpdateReq{})
      if err != nil { RespondErrorFrom(c, err); return }
      out, err := h.svc.Update(ctx, rc.TenantID, rc.ID, rc.Payload, rc.IfMatch) // 支持 If-Match/ETag(可选)
      if err != nil { RespondErrorFrom(c, err); return }
      ResponseSuccess(c, out)
    }

    // DELETE /{{domain}}/{{resource}}/:id
    func (h *{{Entity}}Handler) Delete(c *gin.Context) {
      ctx, rc, err := ValidateRequestWithContext(c, &dto.{{Entity}}DeleteReq{})
      if err != nil { RespondErrorFrom(c, err); return }
      err = h.svc.Delete(ctx, rc.TenantID, rc.ID, rc.Force) // 默认为软删;Force 需权限
      if err != nil { RespondErrorFrom(c, err); return }
      ResponseSuccess(c, ResponseSuccess{OK: true})
    }

  api_go: |
    package {{domain}}

    import (
      "github.com/gin-gonic/gin"
      "github.com/ArtisanCloud/PowerX/internal/app/shared"
    )

    func Register{{Domain}}Routes(rg *gin.RouterGroup, deps *shared.Deps) {
      h := New{{Entity}}Handler(deps.{{Entity}}Service)
      g := rg.Group("/{{domain}}/{{resource}}")
      {
        g.POST("", h.Create)
        g.GET("", h.List)
        g.GET("/:id", h.Get)
        g.PATCH("/:id", h.Update)
        g.DELETE("/:id", h.Delete)
      }
    }

Read the full file on GitHub · 233 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. today First seen · 233 lines · 23 tokens per session scan A f15954fa42e9

Subscribe to this mod's changes

crud-handler-http is a skill published in the GitHub repository ArtisanCloud/PowerX (364 stars, last pushed 3d ago), licensed Apache-2.0. It adds 23 tokens to every session and 2,304 once invoked, about $0.0001 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-04.

Related

Other skills, from other repositories

scalar-docs

Skill for writing and updating scalar.config.json — Scalar Docs configuration reference for users and LLMs.

scalar/scalar · 24 tokens

openapi-glossary

Use consistent OpenAPI terminology and definitions when writing documentation, educational material, and tooling guidance.

scalar/scalar · 24 tokens

wxjava-api-contributor

按 WxJava 的 Maven 多模块、Java 8、公共 API 兼容性和 TestNG 约定,为微信官方接口新增或维护 SDK 支持。适用于新增 Service API、请求响应 Bean、序列化、HTTP 实现、Starter 配置或回归测试时。.

binarywang/WxJava · 68 tokens

datamodel-code-generator

Use this skill when the user wants Python data models, Pydantic models, dataclasses, TypedDicts, msgspec structs, or type-safe Python classes generated from OpenAPI, AsyncAPI, JSON Schema, GraphQL, JSON/YAML/CSV sample data, MCP tool schemas, Protocol Buffers, XML Schema, Apache Avro, or existing Python model objects.…

koxudaxi/datamodel-code-generator · 147 tokens

langbot-deploy

Deploy and configure a LangBot instance — Docker / Docker Compose, Kubernetes, the config.yaml model, the Box sandbox runtime, the plugin runtime, and the global API key. Use when installing, deploying, upgrading, or configuring LangBot in production or self-hosted environments. Triggers on "deploy langbot", "langbot…

langbot-app/LangBot · 104 tokens

om-auto-sec-report-pr

Paranoid OWASP-oriented security analysis for a SINGLE unit of work — one PR, one spec under .ai/specs/, or one branch diff. Hunts non-obvious attack vectors beyond OWASP Top 10, flags same-pattern hotspots elsewhere, and emits "Next steps — go deeper" follow-ups. Writes markdown + HTML under .ai/analysis/; runs…

open-mercato/open-mercato · 93 tokens