shadmin-dev
GitHub指导基于Shadmin架构的全栈功能开发,涵盖Go/Gin/Ent后端与React/TS前端的CRUD、API路由、权限及UI页面实现,确保代码符合规范。
Trigger Scenarios
Install
npx skills add ahaodev/shadmin --skill shadmin-dev -g -y
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 | bootstarp/ |
App init, DB, Casbin, seeds (directory name typo is intentional) |
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 schemaDefaultFunc - Partial updates: pointer fields in
Update*Request(*string) - Pagination: embed
domain.QueryParams, calldomain.ValidateQueryParams() - 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,
%wwrapping, 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
Dateobjects - Query params:
URLSearchParamsconstruction, snake_case to match backend - Table state:
useTableUrlStatehook syncs pagination/filters with URL - Dialog state: string-based via context provider (
open === 'add' | 'edit' | 'delete') - Permissions:
usePermission()hook,PERMISSIONS.SYSTEM.RESOURCE.ACTIONconstants - Toast:
sonnerfor 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:
- Backend auto-scans routes into API resources on startup (
bootstrap.InitApiResources) - API resource IDs are deterministic:
METHOD:/api/v1/path(e.g.,GET:/api/v1/system/project) - Admin assigns menus to roles, each menu binds to API resources
- Frontend fetches permissions from
/api/v1/resourcesand stores in Zustand
To add permissions for a new feature:
- Backend: routes auto-register as API resources on restart
- Frontend: add permission constants in
frontend/src/constants/permissions.ts - Admin panel: create menu entries, bind API resources, assign to roles
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 guidearchitecture.zh.md/architecture.en.md— Architecture deep-divedevelopment.zh.md/development.en.md— Full CRUD walkthrough with exampledeployment.zh.md/deployment.en.md— Production deployment guide
Version History
- 69286ec Current 2026-07-25 09:47


