From 63792b449fb0cfb4d9944c22d82bd72b4e58c5b3 Mon Sep 17 00:00:00 2001 From: veypi Date: Tue, 17 Feb 2026 20:59:52 +0800 Subject: [PATCH] docs: Add CLAUDE.md for Claude Code guidance - Add project overview with tech stack (Go 1.24+, Vigo framework, GORM) - Document common commands (make run, db operations, tests) - Describe onion model request flow and middleware stages - Explain RBAC permission system format and usage - Document multi-tenancy patterns (B2C/B2B/Platform) - Add API response format and error code conventions - Include Vigo handler pattern with parameter binding - Document vhtml frontend structure --- CLAUDE.md | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2b53784 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,164 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +VBase is a Go-based identity authentication and permission management framework built on the [Vigo](https://github.com/veypi/vigo) web framework (onion-model middleware architecture). It provides user management, organization (multi-tenant), RBAC permissions, and OAuth2 authentication services. + +- **Language**: Go 1.24+ +- **Framework**: Vigo (onion-model middleware) +- **ORM**: GORM (MySQL, PostgreSQL, SQLite supported) +- **Authentication**: JWT + OAuth2 +- **Frontend**: vhtml (embedded HTML-based UI at `/vb/`) + +## Common Commands + +```bash +# Run development server (default port 4001) +make run + +# Database operations +go run ./cli/main.go db migrate +go run ./cli/main.go db drop + +# Run integration tests +go test -v ./tests/... +``` + +Tests in `tests/` use an in-memory SQLite database with mock Redis. The `ensureUsers(t)` helper sets up test users (admin, user1, user2) with tokens stored in globals (`AdminToken`, `User1Token`, etc.). + +## Architecture + +### Onion Model Request Flow + +``` +Request -> [Global Before Middlewares] -> [Router] -> [Handler] -> [Service] -> [Model] -> Database + | +Response <- [Global After Middleware] <--------+ +``` + +Key middleware stages: + +- **Before**: Authentication, preprocessing, context injection (parent hooks run before child hooks) +- **Handler**: Business logic, returns data (does not write response directly) +- **After**: Response formatting (parent hooks run after child hooks) + +### Directory Structure + +``` +├── api/ # REST API handlers and routing +│ ├── auth/ # Login, register, refresh token, SMS +│ ├── oauth/ # OAuth2 provider endpoints +│ ├── org/ # Organization/tenant management +│ ├── role/ # Role management +│ ├── user/ # User management +│ └── init.go # Router aggregation +├── auth/ # Core RBAC permission system +│ ├── auth.go # Permission checking implementation +│ └── middleware.go # Auth middleware +├── cfg/ # Configuration (DB, Redis, JWT settings) +├── models/ # GORM data models +│ ├── auth.go # Role, Policy, UserRole models +│ ├── user.go # User, Identity, Session models +│ ├── org.go # Org, OrgMember models +│ └── init.go # Model registration and migrations +├── libs/ # Utilities (cache, crypto, jwt, sms, email) +├── ui/ # Frontend admin interface (vhtml framework) +├── cli/ # Application entry point +└── tests/ # Go integration tests +``` + +### Permission System (RBAC) + +Permission format: `resource:action` or `app:resource:action` + +Examples: `user:read`, `org:create`, `oauth-client:delete` + +**Important**: Resource identifiers must NOT contain colons (use kebab-case or snake_case). + +Permission middleware usage: + +```go +// Basic permission +Router.Post("/articles", AppAuth.Perm("article:create"), createArticle) + +// Owner check - allows if user is resource owner +Router.Patch("/articles/{id}", AppAuth.PermWithOwner("article:update", "id"), updateArticle) + +// Wildcard support +AppAuth.AddRole("admin", "Admin", "*:*") // All permissions +``` + +### Multi-Tenancy (Org) + +Organizations provide data isolation. Three usage patterns: + +1. **B2C (Single Tenant)**: Ignore Org, bind roles to global (`org_id=""`) +2. **B2B SaaS (Multi-Tenant)**: Require `X-Org-ID` header on all business APIs +3. **Platform (Hybrid)**: Merchant side uses Org, consumer side is global + +The `AuthMiddleware` extracts `X-Org-ID` header and loads user's roles for that org context. + +### API Response Format + +All responses are JSON formatted by `common.JsonResponse` middleware: + +**Success:** + +```json +{"code": 200, "data": { ... }} +``` + +**Error:** + +```json +{ "code": 40001, "message": "Error description" } +``` + +Error codes combine HTTP status (3 digits) + scenario (2 digits), e.g., `40001` = Bad Request + invalid argument. + +### Configuration + +Configuration is loaded from: + +1. Config file (`-f ./cfg/dev.yml`) +2. Environment variables (uppercase with underscores, e.g., `DB_DSN`, `JWT_SECRET`) + +Key config in `cfg/cfg.go`: + +- `DB`: Database connection (type: mysql/postgres/sqlite) +- `Redis`: Use `memory` for development +- `Key`: System encryption key (32+ chars recommended) +- `JWT`: Token expiry settings +- `InitAdmin`: Auto-create admin on first run (empty password = first registered user becomes admin) + +### Handler Pattern (Vigo Framework) + +Handlers use generics with automatic parameter binding: + +```go +type CreateReq struct { + Name string `json:"name" src:"json"` // Required + Email *string `json:"email" src:"json"` // Optional (pointer) + Page int `src:"query" default:"1"` // Query param with default +} + +func CreateUser(x *vigo.X, req *CreateReq) (*User, error) { + // Business logic + return user, nil // Framework handles JSON response +} +``` + +Parameter sources: `path`, `query`, `header`, `json`, `form`. Non-pointer fields are required by default. + +### Frontend (vhtml) + +The admin UI is in `ui/` using the vhtml framework: + +- Pages in `ui/page/` (e.g., `user_list.html` → route `/user_list`) +- Components as HTML files, referenced with hyphens (e.g., `` for `/ui/form/user_create.html`) +- Routes defined in `ui/routes.js` +- Access UI at `/vb/` path when server is running + +Full API documentation is available at `/_api.json` when the server is running.