# 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.