You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/CLAUDE.md

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:

  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:

{"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:

  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:

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.