PowerX: Skill for Codex

.codex/skills/crud/service/SKILL.md

crud-service is a skill for Codex from ArtisanCloud/PowerX. It costs 25 tokens per session (2,081 once invoked), scanned A, original, Apache-2.0.

A set of rules for the service layer of a CRUD application, where CRUD means create, read, update, and delete. It defines how services handle permissions, auditing, transactions, duplicate requests, concurrency, and errors.

In plain words
What is it for?
Implementing service methods with repository access, transaction boundaries, tenant and user checks, audit records, idempotency, concurrency controls, and standard error responses.
Why use it?
It keeps business decisions out of HTTP or other transport code and makes behavior consistent across interfaces such as HTTP and gRPC.

Skill for Codex

Written for Codex: installed under .codex/.

This is ArtisanCloud/PowerX's own configuration. It tells Codex how to work on PowerX itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything PowerX configures →

Reuse

Borrowing it

Nothing to install: this file belongs to ArtisanCloud/PowerX. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/ArtisanCloud/PowerX/release/v1.0.0/.codex/skills/crud/service/SKILL.md
Clone the repo
git clone --depth 1 https://github.com/ArtisanCloud/PowerX

Made for: 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-service

README.md
[![agentmods](https://agentmods.dev/badge/skills/artisancloud/powerx/service/github.svg)](https://agentmods.dev/skills/artisancloud/powerx/service)
Your own site
<a href="https://agentmods.dev/skills/artisancloud/powerx/service"><img src="https://agentmods.dev/badge/skills/artisancloud/powerx/service/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for crud-service

Your own site · 80×15
<a href="https://agentmods.dev/skills/artisancloud/powerx/service"><img src="https://agentmods.dev/badge/skills/artisancloud/powerx/service.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 25 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 2,081 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe. Third-party audits
  • NVIDIA SkillSpector pass 7 Sept 2026
How audits are shown
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.1 $0.00025 $0.02081
Opus 5.5 $0.00010 $0.00832
Sonnet 5.5 $0.00005 $0.00416
Haiku 4.5 $0.00003 $0.00208

Measured 1mo ago against content hash 3700d134e647, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade A, and why

crud-service 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 1mo ago.

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/service/SKILL.md · 203 lines

How it starts

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

PowerX CRUD Service

步骤

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

核对点

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

规则(内嵌)

service.yaml

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

meta:
  intent: >
    统一 Service 层职责:鉴权/审计、事务边界、幂等与并发控制、错误翻译(404/409),
    与 Repository/DTO/Handler/DI 对齐,保持传输无关(HTTP/gRPC 共用)。
  references:
    - crud_di.yaml
    - crud_repository.yaml
    - crud_dto.yaml
    - crud_api_rest.yaml
    - constitution.md

scope:
  applies_to:
    - "internal/service/**/**_service.go"

principles:
  - 传输无关:Service 只依赖 Repo 接口与 *shared.Deps,不依赖 gin/http/grpc。
  - 鉴权与审计:在 Service 层落实 RBAC/ABAC 与审计打点(入参需包含 actor/tenant/requestID)。
  - 事务:Service 负责确定事务边界;优先使用 Repo.WithTx 注入 tx。
  - 幂等与并发:Create 支持 Idempotency-Key(可选);Update 支持 If-Match/ETag(可选)。
  - 错误翻译:ErrRecordNotFound → 404;唯一键冲突/重复 → 409;其余 → 500(由上层桥接)。
  - 日志:必要路径要记录关键维度(tenant/actor/id)。
  - 形态约束:Service 默认以结构体 + `New*Service` 构造函数呈现;仅当满足“同一接口需要多种驱动/工厂模式”“为复用/测试提供可替换实现(如 handler、worker、远程代理共用服务)”等场景,或复用已有跨包 interface 规范时,才允许额外定义 interface 壳,并需在评审中说明理由。
  - Repo 生命周期:Service 构造时基于注入的 `*gorm.DB` 创建所需 Repository;禁止在 `shared.Deps` 或 Handler 层先行实例化 Repo 再传入 Service。

checks:

  # 形态:结构体 + 构造函数 + 仅依赖 Deps/Repo
  - id: service.shape
    level: error
    when: { glob: "internal/service/**/**_service.go" }
    assert:
      - must_define_like: "type *Service struct { deps *shared.Deps"
      - must_define_like: "func New*Service(*shared.Deps, *"
      - must_not_import: ["github.com/gin-gonic/gin","net/http","google.golang.org/grpc","gorm.io/gorm"]

  # 方法签名:ctx + tenant/actor/…(根据业务,可放松)
  - id: service.method.signature
    level: warn
    when: { glob: "internal/service/**/**_service.go" }
    assert:
      - should_contain_regex: "func \\(s \\*.*Service\\) .*\\(ctx context\\.Context, .*tenantID .*\\) .*"
      - must_import: ["context"]

  # 事务调用
  - id: service.uses.tx
    level: warn
    when: { glob: "internal/service/**/**_service.go" }
    assert:
      - should_contain_any: ["WithTx(","Transaction("]

  # 错误翻译(记录出现,便于 code review 聚焦)
  - id: service.error.translation
    level: warn
    when: { glob: "internal/service/**/**_service.go" }
    assert:
      - should_contain_any: ["ErrRecordNotFound","409","404","Conflict","NotFound"]

  # 禁止在 Service 中直接 new 外部客户端(统一由 Deps 管理)
  - id: service.no_new_external_clients
    level: error
    when: { glob: "internal/service/**/**_service.go" }
    assert:
      - must_not_call: ["redis.NewClient(","kafka.NewReader(","http.DefaultClient.Do","sql.Open("]

acceptance:
  checklist:
    - "[ ] Service 仅依赖 Repo 接口与 *shared.Deps,不耦合传输层"
    - "[ ] 关键方法包含 ctx/tenant/actor 等上下文,能审计溯源"
    - "[ ] 事务边界清晰:通过 Repo.WithTx/Transaction 控制"
    - "[ ] 错误统一翻译(404/409/500)供上层桥接"
    - "[ ] 可被 HTTP/gRPC 同时复用"

templates:
  service_go: |
    // internal/service/{{domain}}/{{resource}}_service.go
    package {{domain}}svc

    import (
      "context"
      "errors"

      "github.com/ArtisanCloud/PowerX/internal/app/shared"
      {{domain}}repo "{{module_path}}/internal/repository/{{domain}}"
      m "{{module_path}}/pkg/corex/db/persistence/model/{{domain}}"
      "gorm.io/gorm"
    )

    var (
      ErrNotFound = errors.New("{{resource}} not found")
      ErrConflict = errors.New("{{resource}} conflict")
    )

    type {{Entity}}Service struct {
      deps *shared.Deps
      repo {{domain}}repo.{{Entity}}Repo
    }

    func New{{Entity}}Service(d *shared.Deps, r {{domain}}repo.{{Entity}}Repo) *{{Entity}}Service {
      return &{{Entity}}Service{deps: d, repo: r}
    }

    func (s *{{Entity}}Service) Create(ctx context.Context, tenantID uint64, actorID uint64, req any) (*m.{{Entity}}, error) {
      in := &m.{{Entity}}{
        // 从 req 映射;此处略
      }
      // 事务示例
      err := s.repo.WithTx(ctx, s.deps.DB, func(tx *gorm.DB) error {
        return s.repo.Create(ctx, tx, tenantID, in)
      })
      if err != nil {
        // 唯一冲突示例
        if {{domain}}repo.IsUniqueConflict(err) {
          return nil, ErrConflict
        }
        return nil, err
      }
      // 审计/日志(略)
      return in, nil
    }

    func (s *{{Entity}}Service) Get(ctx context.Context, tenantID uint64, id string) (*m.{{Entity}}, error) {
      out, err := s.repo.GetByID(ctx, s.deps.DB, tenantID, id)
      if err != nil {
        if errors.Is(err, gorm.ErrRecordNotFound) {
          return nil, ErrNotFound
        }
        return nil, err
      }
      return out, nil
    }

    func (s *{{Entity}}Service) List(ctx context.Context, tenantID uint64, pg {{domain}}repo.Page, filters map[string]string) ([]*m.{{Entity}}, shared.PaginationResponse, error) {
      items, total, err := s.repo.List(ctx, s.deps.DB, tenantID, pg, filters)
      if err != nil { return nil, shared.PaginationResponse{}, err }
      pr := shared.PaginationResponse{
        Total: total, Page: pg.Page, PageSize: pg.PageSize,
        Pages: (int(total)+pg.PageSize-1)/pg.PageSize,
      }
      return items, pr, nil
    }

    func (s *{{Entity}}Service) Update(ctx context.Context, tenantID uint64, id string, patch any, ifMatch *string) (*m.{{Entity}}, error) {
      cur, err := s.repo.GetByID(ctx, s.deps.DB, tenantID, id)
      if err != nil {
        if errors.Is(err, gorm.ErrRecordNotFound) { return nil, ErrNotFound }
        return nil, err
      }
      // merge patch(略);ETag/If-Match(可选)
      if err := s.repo.Update(ctx, s.deps.DB, tenantID, cur); err != nil {
        return nil, err
      }
      return cur, nil
    }

    func (s *{{Entity}}Service) Delete(ctx context.Context, tenantID uint64, id string, force bool) error {
      // 可加 RBAC 校验(略)
      if err := s.repo.Delete(ctx, s.deps.DB, tenantID, id, force); err != nil {
        if errors.Is(err, gorm.ErrRecordNotFound) { return ErrNotFound }
        return err
      }
      return nil
    }
  repo_err_helpers_go: |
    // internal/repository/{{domain}}/errors.go
    package {{domain}}repo
    import "strings"
    func IsUniqueConflict(err error) bool {
      if err == nil { return false }
      s := err.Error()
      return strings.Contains(s, "duplicate key") || strings.Contains(s, "unique")
    }

Read the full file on GitHub · 203 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. 1mo ago First seen · 203 lines · 25 tokens per session scan A 3700d134e647

Subscribe to this mod's changes

crud-service is a skill published in the GitHub repository ArtisanCloud/PowerX (382 stars, last pushed 2d ago), licensed Apache-2.0. It adds 25 tokens to every session and 2,081 once invoked, about $0.0001 per session on Opus 5.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

fastapi

FastAPI best practices and conventions. Use when working with FastAPI APIs, Pydantic models, dependencies, streaming responses including Server-Sent Events (SSE), and serving frontend apps. Keeps FastAPI code clean and up to date with the latest features and patterns.

fastapi/fastapi · 57 tokens

langbot-eba-adapter-dev

Build, refactor, and test LangBot platform adapters for the Event-Based Agents architecture. Use when adding or migrating Telegram, Discord, or other messaging platform adapters to the EBA adapter layout, validating unified event/message conversion, writing live adapter probes, or using standalone plugin runtime plus…

langbot-app/LangBot · 73 tokens

langbot-dev

Develop, build, and debug the LangBot core backend and web frontend. Use when working inside the LangBot repository — backend (Python/Quart, src/langbot/pkg), the Vite/React web UI, HTTP API controllers/services, Alembic migrations, or the MCP server. Covers the dev environment (uv, pnpm), repo layout, the API auth…

langbot-app/LangBot · 136 tokens

wxjava-module-selector

A decision guide for choosing the correct WxJava Maven module, dependency management file, and example for a WeChat use case. WxJava is a Java software development kit for services such as official accounts, mini programs, and payments.

binarywang/WxJava · 86 tokens

wxjava-api-contributor

A contributor guide for adding or maintaining official WeChat API support in WxJava, a Java software development kit. It covers services, request and response data objects, data conversion, HTTP handling, starter configuration, and regression tests.

binarywang/WxJava · 68 tokens

wxjava-integration-guide

A setup guide for connecting Java, Spring Boot, or Solon applications to WxJava, a Java software development kit for WeChat services. It covers choosing modules, adding dependencies, configuring accounts, and making an initial API call.

binarywang/WxJava · 72 tokens