Development Guide

June 14, 2026 ยท View on GitHub


Architecture Design

AxonHub implements a bidirectional data transformation pipeline that ensures seamless communication between clients and AI providers.

AxonHub Transformation Flow

Pipeline Components

ComponentPurposeKey Features
ClientApplication layerWeb apps, mobile apps, API clients
Inbound TransformerRequest preprocessingParse, validate, normalize input
Unified RequestCore processingRoute selection, load balancing, failover
Outbound TransformerProvider adaptationFormat conversion, protocol mapping
ProviderAI servicesOpenAI, Anthropic, DeepSeek, etc.

This architecture ensures:

  • โšก Low Latency: Optimized processing pipeline
  • ๐Ÿ”„ Auto Failover: Seamless provider switching
  • ๐Ÿ“Š Real-time Monitoring: Complete request tracing
  • ๐Ÿ›ก๏ธ Security & Validation: Input sanitization and output verification

Technology Stack

Backend Technology Stack

  • Go 1.26+
  • Gin
  • Ent ORM
  • gqlgen
  • JWT

Frontend Technology Stack

  • React 19
  • TypeScript
  • Tailwind CSS
  • TanStack Router
  • Zustand

Development Environment Setup

Prerequisites

  • Go 1.26 or higher
  • Node.js 18+ and pnpm
  • Git

Clone the Project

git clone https://github.com/looplj/axonhub.git
cd axonhub

Start Backend

# Option 1: Build and run directly
make build-backend
./axonhub

# Option 2: Use air for hot reload (recommended for development)
go install github.com/air-verse/air@latest
air

The backend server will start at http://localhost:8090.

Start Frontend

In a new terminal window:

cd frontend
pnpm install
pnpm dev

The frontend development server will start at http://localhost:5173.

Building the Project

Build Complete Project

make build

This will build both backend and frontend, and embed frontend assets into the backend binary.

Build Backend Only

make build-backend

Build Frontend Only

cd frontend
pnpm build

Code Generation

When changing Ent schema or GraphQL schema, regenerate generated code:

make generate

Testing

Run Backend Tests

go test ./...

Run E2E Tests

bash ./scripts/e2e/e2e-test.sh

Code Quality

Run Go Linter

golangci-lint run -v

Run Frontend Lint/Format

cd frontend
pnpm lint
pnpm format:check

Transactions (Ent)

When to use transactions

  • Multiple writes must succeed or fail together.
  • You need to ensure reads and writes are consistent within one logical operation.

RunInTransaction will:

  • Reuse the existing transaction if ctx already carries one.
  • Otherwise start a new transaction, attach the tx-bound *ent.Client to ctx, and commit/rollback automatically.
func (s *SomeService) doWork(ctx context.Context) error {
    return s.RunInTransaction(ctx, func(ctx context.Context) error {
        // ctx now carries:
        // - ent.TxFromContext(ctx) (the current tx)
        // - ent.FromContext(ctx)   (tx-bound *ent.Client)
        //
        // You can call other services and they will pick up the same tx via ctx.
        return nil
    })
}

Notes

  • A transaction client is not safe to share across goroutines.
  • Prefer keeping the transaction scope as small as possible.

Adding a Channel

When introducing a new provider channel, keep backend and frontend changes aligned:

  1. Extend the channel enum in the Ent schema

  2. Map default endpoints

  3. Wire the outbound transformer

    • Add a case to the switch in ChannelService.buildChannelWithTransformer (internal/server/biz/channel_llm.go)
    • If a new credential variant, add validation above the switch
    • If adding a new transformer under llm/transformer/, import it and build config with getAPIKeyProvider(ch)
  4. Sync the frontend schema and config

  5. Add internationalization