5.5 KiB
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 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
# 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:
// 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:
- B2C (Single Tenant): Ignore Org, bind roles to global (
org_id="") - B2B SaaS (Multi-Tenant): Require
X-Org-IDheader on all business APIs - 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:
{"code": 200, "data": { ... }}
Error:
{ "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:
- Config file (
-f ./cfg/dev.yml) - 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: Usememoryfor developmentKey: System encryption key (32+ chars recommended)JWT: Token expiry settingsInitAdmin: Auto-create admin on first run (empty password = first registered user becomes admin)
Handler Pattern (Vigo Framework)
Handlers use generics with automatic parameter binding:
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.,
<form-user_create>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.