Agent Skills › ahaodev/shadmin › shadmin-dev

shadmin-dev

GitHub

指导基于Shadmin架构的全栈功能开发,涵盖Go后端与React前端。涉及CRUD、API路由、权限管理及数据库变更的端到端工作流。

.agent/skills/shadmin-dev/SKILL.md ahaodev/shadmin

Trigger Scenarios

添加或修改业务功能 创建CRUD模块或API接口 修改数据库Schema 开发前端页面或组件

Install

npx skills add ahaodev/shadmin --skill shadmin-dev -g -y
More Options

Non-standard path

npx skills add https://github.com/ahaodev/shadmin/tree/main/.agent/skills/shadmin-dev -g -y

Use without installing

npx skills use ahaodev/shadmin@shadmin-dev

指定 Agent (Claude Code)

npx skills add ahaodev/shadmin --skill shadmin-dev -a claude-code -g -y

安装 repo 全部 skill

npx skills add ahaodev/shadmin --all -g -y

预览 repo 内 skill

npx skills add ahaodev/shadmin --list

SKILL.md

Frontmatter
{
    "name": "shadmin-dev",
    "description": "Apply Shadmin feature-development standards (backend Go\/Gin\/Ent + frontend React\/TS). Use when adding\/modifying features, CRUD modules, API routes\/controllers\/usecases\/repositories, Ent schemas, frontend pages\/routes, React components, TanStack hooks, or any full-stack work in this project. Trigger whenever the user mentions new features, backend changes, frontend changes, database schema changes, permissions, UI pages, tables, forms, or API endpoints — even if they don't explicitly say \"feature development.\""
}

Shadmin Feature Development

Guide full-stack feature development through Shadmin's clean architecture, producing code that compiles, passes lint/tests, and follows established patterns. Most features require both backend and frontend changes — this skill covers the end-to-end workflow.

Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│  Frontend (React 19 + TypeScript + Vite)                            │
│  Route File → Page Component → TanStack Query Hook → API Service   │
│       ↕ Zustand (auth-store) ↕ Permission checks                   │
├─────────────────────────────────────────────────────────────────────┤
│  HTTP (Axios apiClient ← Bearer Token injection)                   │
├─────────────────────────────────────────────────────────────────────┤
│  Backend (Go + Gin + Ent ORM)                                      │
│  Route → [JWT MW → Casbin MW] → Controller → Usecase → Repository  │
│       ↕ Domain (contracts, DTOs, errors) ↕ Ent (DB, migrations)    │
└─────────────────────────────────────────────────────────────────────┘

Backend layers — each has exactly one responsibility:

Layer Directory Responsibility
Domain domain/ Entity structs, DTOs, Repository/UseCase interfaces, errors, response helpers
Schema ent/schema/ DB schema → run go generate ./ent after changes
Repository repository/ Data access via Ent, domain↔ent conversion, pagination
Usecase usecase/ Business logic, validation, context.WithTimeout
Controller api/controller/ HTTP parsing only, Swagger annotations, status code mapping
Route api/route/ Route registration, middleware wiring
Factory api/route/factory.go DI: repo → usecase → controller construction
Bootstrap bootstrap/ App init, DB, Casbin, seeds

Frontend layers:

Layer Directory Responsibility
Types frontend/src/types/ TypeScript interfaces matching backend DTOs
Services frontend/src/services/ Axios API wrappers, date parsing
Features frontend/src/features/ Page components, tables, dialogs, forms, hooks
Routes frontend/src/routes/ TanStack Router file-based routing
Stores frontend/src/stores/ Zustand state (auth, permissions)
Constants frontend/src/constants/ Permission strings, enums

Full-Stack Development Workflow

Step 1: Clarify Scope (before writing code)

State explicitly:

  • What entities/fields are involved
  • API endpoints: path, method, request/response shapes
  • Whether Casbin permission checks are needed
  • Frontend: pages, tables, forms, dialogs
  • Permission strings (e.g., system:project:add)

Step 2: List All Touched Files

Group by layer — this catches missing pieces early:

# Backend (implement in this order)
domain/<resource>.go
ent/schema/<resource>.go
repository/<resource>_repository.go
usecase/<resource>_usecase.go
api/controller/<resource>_controller.go
api/route/<resource>_routes.go (or modify system_routes.go)
api/route/factory.go

# Frontend (implement in this order)
frontend/src/types/<resource>.ts
frontend/src/services/<resource>Api.ts
frontend/src/features/<module>/<resource>/components/*-provider.tsx
frontend/src/features/<module>/<resource>/hooks/use-<resource>.ts
frontend/src/features/<module>/<resource>/components/*-columns.tsx
frontend/src/features/<module>/<resource>/components/*-table.tsx
frontend/src/features/<module>/<resource>/components/*-form-dialog.tsx
frontend/src/features/<module>/<resource>/components/*-dialogs.tsx
frontend/src/features/<module>/<resource>/components/*-primary-buttons.tsx
frontend/src/features/<module>/<resource>/data/schema.ts
frontend/src/features/<module>/<resource>/index.tsx
frontend/src/routes/_authenticated/<module>/<resource>.tsx
frontend/src/constants/permissions.ts (add new permission keys)

Step 3: Implement Backend

Follow the layer order strictly — each layer depends on the one above.

Read references/backend.md for complete code templates and patterns.

Quick reference for key conventions:

  • IDs: xid.New().String() in Ent schema DefaultFunc
  • Partial updates: pointer fields in Update*Request (*string)
  • Pagination: embed domain.QueryParams, call qp.Paginate() (returns offset, limit)
  • Response: domain.RespSuccess(data) (code=0) / domain.RespError(msg) (code=1)
  • Usecase: every method starts with context.WithTimeout + defer cancel()
  • Errors: sentinel errors in domain, %w wrapping, map to HTTP status in controller
  • Factory: repo → usecase → controller, dependencies from f.db, f.app, f.timeout
  • Routes: protected system routes use casbinMiddleware.CheckAPIPermission()

Step 4: Implement Frontend

Follow the order: types → service → feature module → route file.

Read references/frontend.md for complete code templates and patterns.

Quick reference for key conventions:

  • API response: response.data.data (outer .data = Axios, inner .data = domain.Response.Data)
  • Date parsing: API service converts string dates to Date objects
  • Query params: URLSearchParams construction, snake_case to match backend
  • Table state: useTableUrlState hook syncs pagination/filters with URL
  • Dialog state: string-based via context provider (open === 'add' | 'edit' | 'delete')
  • Permissions: usePermission() hook, PERMISSIONS.SYSTEM.RESOURCE.ACTION constants
  • Toast: sonner for success/error notifications
  • Forms: React Hook Form + Zod, single hook handles create/edit
  • Route file: Zod schema validates URL search params with .catch() defaults

Step 5: Wire Permissions

Shadmin uses a dual-layer permission model:

Backend (API access):    Casbin checks (userID, path, method)
Frontend (UI visibility): Permission strings like "system:project:add"

These are linked through the Role → Menu → API Resources binding:

  1. Backend auto-scans routes into API resources on startup (bootstrap.InitApiResources)
  2. API resource IDs are deterministic: METHOD:/api/v1/path (e.g., GET:/api/v1/system/project)
  3. Admin assigns menus to roles, each menu binds to API resources
  4. Frontend fetches permissions from /api/v1/resources and stores in Zustand

To add permissions for a new feature:

  1. Backend: routes are scanned into API resources by bootstrap.InitApiResources; route inventory changes advance the authorization generation.
  2. Frontend: add permission constants in frontend/src/constants/permissions.ts.
  3. Admin panel: create menu entries, bind API resources, assign to roles.
  4. For any new write path that changes users, roles, menus, API resources, or their authorization edges, use the repository authorization transaction helper so the DB change and authz_state.generation update commit together. Do not mutate the live Casbin Enforcer directly.

Casbin snapshot lifecycle: Ent authorization relations are the source of truth. Each process builds a complete in-memory Enforcer snapshot and publishes it atomically; a committed authz_states.generation update triggers local synchronization, while AUTHZ_SYNC_POLL_INTERVAL_SECONDS provides low-frequency recovery polling (default one hour) for missed triggers, restarts, and cross-instance changes. Snapshots are not persisted through Casbin AutoSave. If a generation change is detected or cannot be checked, protected Casbin requests fail closed until a fresh snapshot is published. Keep the existing g/p semantics (active users/roles, public resources excluded, admin wildcard) unless a separately reviewed change intentionally changes them.

Step 6: Generate & Verify

# Backend
go generate ./ent           # If schema changed
go fmt ./... && go vet ./... # Format + static analysis
go test ./...                # Run tests
swag init -g main.go --output ./docs  # If Swagger annotations changed

# Frontend (from frontend/)
pnpm lint                   # ESLint
pnpm format:check           # Prettier
pnpm build                  # Recommended if routes/build config changed

Key Response Format

// Success (HTTP 200/201)
type Response struct {
    Code int         `json:"code"`    // 0 = success
    Msg  string      `json:"msg"`     // "OK"
    Data interface{} `json:"data"`    // payload
}

// Error (HTTP 400/404/500)
// Code = 1, Msg = error description, Data = nil

// Paginated response (in Data field)
type PagedResult[T any] struct {
    List       []T `json:"list"`
    Total      int `json:"total"`
    Page       int `json:"page"`
    PageSize   int `json:"page_size"`
    TotalPages int `json:"total_pages"`
}

Boundaries

Things to never do:

  • No business logic in controllers — controllers parse HTTP, call usecase, return response
  • No HTTP/permission logic in repositories — repositories do data access only
  • No bypassing Casbin on protected APIs
  • No new globals — use factory's f.db, f.app, f.timeout
  • No inline API calls in React — all API access goes through services/ wrappers
  • No direct localStorage for auth — use useAuthStore
  • No editing components/ui/ — shadcn-generated primitives
  • No hardcoded menus — menus come from backend /api/v1/resources
  • No unnecessary dependencies — frontend or backend
  • Minimal changes — only touch files relevant to the feature

Reference Files

For detailed code templates and implementation patterns, read these as needed:

  • references/backend.md — Complete Go/Gin/Ent code templates for domain, schema, repository, usecase, controller, routes, and factory. Read when implementing backend features.
  • references/frontend.md — Complete React/TypeScript code templates for types, API services, feature modules, hooks, tables, forms, dialogs, routes, and permissions. Read when implementing frontend features.

Further Documentation

The docs/getting-started/ directory contains comprehensive guides:

  • quickstart.zh.md / quickstart.en.md — Quick start guide
  • architecture.zh.md / architecture.en.md — Architecture deep-dive
  • development.zh.md / development.en.md — Full CRUD walkthrough with example
  • deployment.zh.md / deployment.en.md — Production deployment guide

Version History

  • 9dd35d2 Current 2026-09-28 04:15

    重构Casbin认证逻辑

  • fee1677 2026-09-22 16:56

Same Skill Collection

.agent/skills/cleanup-specialist/SKILL.md
.claude/skills/shadmin-dev/SKILL.md
.github/skills/shadmin-dev/SKILL.md
cli/skill/shadmin-cli/SKILL.md

Metadata

Files
0
Version
9dd35d2
Hash
4cc22464
Indexed
2026-09-22 16:56

ホーム - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-09-30 20:40
浙ICP备14020137号-1