本文へ移動
cccskills
無料GitHub で公開

crud-grpc-ruleset

PowerX CRUD gRPC 顶层 ruleset 约束。

インストール方法を見る

含まれるファイル(1)

  • SKILL.md7.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

PowerX CRUD gRPC Ruleset

步骤

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

核对点

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

规则(内嵌)

crud_grpc.yaml

kind: ruleset
name: crud_grpc
version: 1.1.0
owner: powerx
status: stable

meta:
  intent: >
    规定 CRUD 的 gRPC 契约与消息形态(proto 结构、分页/错误/鉴权/多租户语义及命名规范),
    保证与 REST/Service 层语义等价,可双向对照;并校验 go_package 与 buf.gen.yaml 前缀一致。
  references:
    - constitution.md
    - crud_api_rest.yaml
    - crud_service.yaml
    - crud_repository.yaml
    - proto_gen.yaml
    - docs/grpc/readme.md

scope:
  applies_to:
    - "api/grpc/**/*.proto"

principles:
  - 使用 proto3;每个 proto 必须声明 go_package。
  - 包与命名:package 用 `<org>.<product>.<domain>`;Service 命名 `{{Entity}}Service`。
  - RPC 五件套:Create/List/Get/Update/Delete;批量操作以 Batch 作为后缀。
  - 分页:与 REST 对齐字段(page,page_size,total,pages),允许扩展 cursor_token。
  - 错误语义:业务错误优先封装在 `common.v1.ResponseMeta`,仅在传输/系统异常时返回标准 gRPC status。
  - 多租户/鉴权:tenant/actor 从 metadata 推导,不作为业务字段传入;request_id/trace_id 透传。
  - 流式场景:仅在必要时使用 server streaming;事件名与 REST SSE 对齐。

checks:

  # ---- 基础 proto 规范 ----
  proto.basics:
    - id: proto.syntax
      level: error
      when: { glob: "api/grpc/**/*.proto" }
      assert:
        - must_contain: 'syntax = "proto3";'
        - must_contain_regex: 'option\\s+go_package\\s*=\\s*"[^\"]+";'
    - id: proto.package.naming
      level: error
      when: { glob: "api/grpc/**/*.proto" }
      assert:
        - must_contain_regex: "package [a-z0-9]+(\\.[a-z0-9_]+)+;"

  # ---- Service + RPC 五件套形态(按资源原型做匹配)----
  service_and_rpcs:
    - id: svc.crud.methods
      level: error
      when: { glob: "api/grpc/**/{{resource}}.proto" }
      assert:
        - must_contain_regex: "service\\s+{{Entity}}Service\\s*{"
        - must_contain: "rpc Create{{Entity}}(Create{{Entity}}Request) returns ({{Entity}}Response);"
        - must_contain: "rpc List{{Entity}}(List{{Entity}}Request) returns (List{{Entity}}Response);"
        - must_contain: "rpc Get{{Entity}}(Get{{Entity}}Request) returns ({{Entity}}Response);"
        - must_contain: "rpc Update{{Entity}}(Update{{Entity}}Request) returns ({{Entity}}Response);"
        - must_contain: "rpc Delete{{Entity}}(Delete{{Entity}}Request) returns (google.protobuf.Empty);"

  # ---- 消息与分页形态 ----
  messages_and_pagination:
    - id: msg.pagination.shape
      level: error
      when: { glob: "api/grpc/**/{{resource}}.proto" }
      assert:
        - must_contain: "message Pagination { int64 total = 1; int32 page = 2; int32 page_size = 3; int32 pages = 4; }"
        - must_contain_regex: "message List{{Entity}}Response\\s*{\\s*repeated {{Entity}} items = 1;\\s*Pagination pagination = 2;"

  # ---- 多租户/鉴权提示(作为规范注释)----
  auth_and_tenant:
    - id: comments.tenant.auth
      level: warn
      when: { glob: "api/grpc/**/{{resource}}.proto" }
      assert:
        - should_contain: "// NOTE: tenant/actor 从 metadata 推导,不作为业务字段传入"

  # ---- go_package 与 buf.gen.yaml 的 go_package_prefix 一致性 ----
  go_package_prefix:
    - id: proto.go_package_prefix.config.exists
      level: error
      when: { file: "api/grpc/contract/buf.gen.yaml" }
      assert:
        - must_contain: "go_package_prefix:"
        - must_contain: "default: github.com/ArtisanCloud/PowerX/api/grpc/gen"
    - id: proto.go_package_prefix.match
      level: error
      when: { glob: "api/grpc/**/*.proto" }
      assert:
        - must_contain_regex: 'option\\s+go_package\\s*=\\s*"github\\.com/ArtisanCloud/PowerX/api/grpc/gen[^"]*;[a-zA-Z0-9_]+";'
      message: "proto 的 go_package 必须以 github.com/ArtisanCloud/PowerX/api/grpc/gen 起始,并以 ;<包名> 结尾"
    - id: proto.go_package_prefix.output.dir
      level: error
      when: { file: "api/grpc/contract/buf.gen.yaml" }
      assert:
        - must_contain_regex: "out:\\s*api/grpc/gen"
        - must_contain: "opt:\n          - paths=source_relative"

acceptance:
  checklist:
    - "[ ] 使用 proto3,且每个 proto 设置 go_package"
    - "[ ] {{Entity}}Service 含 Create/List/Get/Update/Delete RPC"
    - "[ ] 列表响应包含 items + Pagination(total/page/page_size/pages)"
    - "[ ] 错误响应通过 ResponseMeta 对齐 HTTP(仅系统异常返回 gRPC status)"
    - "[ ] 多租户/鉴权通过 metadata 推导(非业务字段)"
    - "[ ] go_package 与 buf.gen.yaml 的 go_package_prefix.default 一致"
    - "[ ] 生成输出到 api/grpc/gen,并使用 paths=source_relative"

templates:
  proto_snippet: |
    syntax = "proto3";
    package powerx.media;

    option go_package = "github.com/ArtisanCloud/PowerX/api/grpc/gen/media;media";

    import "google/protobuf/empty.proto";
    import "google/protobuf/timestamp.proto";

    // NOTE: tenant/actor 从 metadata 推导,不作为业务字段传入
    message Pagination {
      int64 total = 1;
      int32 page = 2;
      int32 page_size = 3;
      int32 pages = 4;
    }

    message MediaAsset {
      string id = 1;                   // ULID/UUID
      uint64 tenant_id = 2;            // 服务端填充
      string name = 3;
      string code = 4;
      string meta_json = 5;
      int32 status = 6;
      google.protobuf.Timestamp created_at = 7;
      google.protobuf.Timestamp updated_at = 8;
    }

    message CreateMediaAssetRequest {
      string name = 1;
      string code = 2;
      string meta_json = 3;
      int32 status = 4;
    }
    message UpdateMediaAssetRequest {
      string id = 1;
      string name = 2;
      string meta_json = 3;
      int32 status = 4;
    }
    message GetMediaAssetRequest { string id = 1; }
    message DeleteMediaAssetRequest { string id = 1; }

    message ListMediaAssetRequest {
      int32 page = 1;
      int32 page_size = 2;
      string sort_by = 3;     // created_at/updated_at/id
      string sort_order = 4;  // asc/desc
      string q = 5;
      map<string,string> filters = 6;
    }

    message MediaAssetResponse { MediaAsset data = 1; }
    message ListMediaAssetResponse {
      repeated MediaAsset items = 1;
      Pagination pagination = 2;
    }

    service MediaAssetService {
      rpc CreateMediaAsset(CreateMediaAssetRequest) returns (MediaAssetResponse);
      rpc ListMediaAsset(ListMediaAssetRequest) returns (ListMediaAssetResponse);
      rpc GetMediaAsset(GetMediaAssetRequest) returns (MediaAssetResponse);
      rpc UpdateMediaAsset(UpdateMediaAssetRequest) returns (MediaAssetResponse);
      rpc DeleteMediaAsset(DeleteMediaAssetRequest) returns (google.protobuf.Empty);
    }
  handler_go: |
    func (s *FooServer) GetFoo(ctx context.Context, req *foov1.GetFooRequest) (*foov1.GetFooResponse, error) {
      tid := tenantIDFrom(ctx, req.GetCtx())
      if tid == 0 {
        return &foov1.GetFooResponse{Meta: badMeta(ctx, 400, "tenant_id required", req.GetCtx().GetRequestId())}, nil
      }
      foo, err := s.fooSvc.GetFoo(ctx, uint64(tid), req.GetId())
      if err != nil {
        if errors.Is(err, service.ErrFooNotFound) {
          return &foov1.GetFooResponse{Meta: badMeta(ctx, 404, "foo not found", req.GetCtx().GetRequestId())}, nil
        }
        return nil, status.Errorf(codes.Internal, "get foo: %v", err)
      }
      return &foov1.GetFooResponse{
        Meta: okMeta(ctx, req.GetCtx().GetRequestId()),
        Data: &foov1.GetFooData{Foo: toPBFoo(foo)},
      }, nil
    }

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

PowerX API 命名与访问规范(/api/v1、/admin、/internal 边界)。

日本語の概要は準備中です。原文の説明を表示しています。

ArtisanCloud/PowerX3812026年10月11日 更新

PowerX 底座 Capability 治理与发布准入规则。用于审计 REST/OpenAPI/gRPC/Gin 生成的能力候选、正式 platform_capabilities 目录、Capability Registry 登记、agent_usable/permission_code/risk_level 元数据、ignore 清单和缺失能力;当用户要求“重新识别能力”“能力是否能发布”“补齐能力登记”“检查 capability-gen/audit/check”“底座接口暴露给插件/agent”时使用。

日本語の概要は準備中です。原文の説明を表示しています。

ArtisanCloud/PowerX3812026年10月11日 更新

PowerX REST 契约规则(资源命名、分页、错误、版本化)。

日本語の概要は準備中です。原文の説明を表示しています。

ArtisanCloud/PowerX3812026年10月11日 更新

crud-di

無料

PowerX CRUD 依赖注入规则(Deps 单入口、构造注入、跨传输复用)。

日本語の概要は準備中です。原文の説明を表示しています。

ArtisanCloud/PowerX3812026年10月11日 更新

crud-dto

無料

PowerX CRUD DTO 规则(输入输出分离、分页、校验)。

日本語の概要は準備中です。原文の説明を表示しています。

ArtisanCloud/PowerX3812026年10月11日 更新

crud-grpc

無料

PowerX CRUD gRPC 开发规范(proto、server、拦截器、错误映射)。

日本語の概要は準備中です。原文の説明を表示しています。

ArtisanCloud/PowerX3812026年10月11日 更新

ArtisanCloud のスキルをすべて見る

このスキルの問題を報告する