Files
qfixpt/CLAUDE.md
2026-03-11 10:54:11 -03:00

14 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a Go microservice skeleton/template for Quantex projects. It implements a Hexagonal Architecture (Ports & Adapters) pattern with clear separation between domain logic, application orchestration, and infrastructure concerns. The skeleton supports multiple execution modes (REST API service, MQTT async messaging, external API integration examples) through a runner-based system.

Development Commands

Building and Running

# Run the REST API service (text logs)
QUANTEX_ENVIRONMENT="dev" go run main.go -c -run service

# Run the REST API service (JSON logs)
QUANTEX_ENVIRONMENT="dev" go run main.go -run service

# Run with debug mode and specific log format
QUANTEX_ENVIRONMENT="dev" go run main.go -d -f tint1 -run service

# Build for current platform
make build

# Build for Linux (production)
make linux-build

Available Runners

The application supports multiple execution modes via the -run flag:

  • service - Main REST API server (Gin framework)
  • async - MQTT messaging example
  • external - QApix external API integration example
  • tracerr - Error handling demonstration
  • logger - Logging format demonstration

Log Formats

Use -f or -logs-format flag:

  • json - Structured JSON logs (default, for production)
  • text - Plain text logs
  • tint1 - Single-line colored logs (best for local development)
  • tint2 - Two-line colored logs

Testing and Linting

# Run all tests
make test

# Run tests for specific package
go test ./src/client/api/rest/...

# Run single test
go test ./src/... -run TestFunctionName

# Run checks and linters
make check

# Format code (gofumpt, gci, goimports)
make fmt

# Full CI pipeline (format, tidy, checks)
make ci

# Regenerate Swagger docs
make swag

# Run development workflow (checklist + check)
make dev

Branch Management

# Create new branch with naming convention
make branch t=feature u=jdoe n=39 m="add new endpoint"
# Creates: feature/jdoe/SKL-39/add_new_endpoint

# Valid types: feature, hotfix, refactor, improvement, doc, fix

Deployment

# Deploy to environment (requires SSH alias in ~/.ssh/config)
make deploy e=dev
make deploy e=prod

# First-time deployment
make first-deploy e=dev

Architecture

Layer Structure

The codebase follows Hexagonal Architecture with four distinct layers:

main.go (entry point)
    ↓
src/cmd/ (Command/Runner layer - bootstrap & execution modes)
    ↓
src/app/ (Application layer - configuration & wiring)
    ↓
src/client/ (Infrastructure layer - external integrations)
    ↓
src/domain/ (Domain layer - business logic & contracts)
    ↓
src/common/ (Cross-cutting concerns)

Directory Organization

  • src/domain/ - Core business models and interfaces (Asyncer, Notifier, UserDataProvider). Pure domain logic with no dependencies on infrastructure.

  • src/app/ - Application-level configuration structures, version information, and global settings. Bridges domain and infrastructure.

  • src/client/ - All infrastructure implementations:

    • api/rest/ - Gin HTTP server, controllers, routes, middleware (auth, CORS)
    • api/async/ - MQTT client for async messaging
    • config/ - TOML configuration loading
    • data/ - Data provider implementations
    • store/ - Database (MultiDB) and external API clients (QApix)
    • notify/ - Notification services (Google Chat, Slack)
    • res/ - Embedded resources
  • src/cmd/ - Runners for different execution modes:

    • service/ - Main REST API service runner
    • example/ - Example runners (async, external, tracerr, logger)
    • base.go - Runner abstraction and factory
  • src/common/ - Shared utilities:

    • logger/ - Multi-format logging (JSON, text, tint) with Gin middleware
    • tracerr/ - Error handling with stack trace capture
    • securetoken/ - JWT token encryption/validation

REST API Architecture

The REST API uses Gin framework with the following patterns:

Authentication Strategies:

  1. Cookie-based - HTTP-only secure cookie with Redis-backed session (20-minute TTL)
  2. Bearer token - Format: Bearer email:token
  3. JWT token - Service-to-service auth with permission validation

Middleware Chain:

Request → Options (CORS) → AuthRequired → Role Check → Handler

Available middlewares in src/client/api/rest/midlewares.go:

  • Options() - CORS preflight handler
  • AuthRequired() - Validates cookie or Authorization header
  • TokenAuth() - Bearer token validation
  • JWTTokenAuth() - JWT service token validation
  • CookieAuth() - Session cookie validation
  • Role-based: SuperUser(), BackOfficeUser(), PartyAdmin(), etc.

Key files:

  • server.go - Server initialization, Redis pool setup, trusted proxies
  • controller.go - HTTP handlers (Login, Refresh, GetUser)
  • routes.go - Route definitions with middleware chains
  • model.go - Request/response DTOs
  • validator.go - Input validation
  • traslator.go - Response formatting

Async/MQTT Architecture

Located in src/client/api/async/, uses Eclipse Paho MQTT client:

  • JWT-based authentication (token generated with service name and expiry)
  • Auto-reconnect with keep-alive
  • Topic structure: {subdomain}/quantex/{topic}
  • Error notifications integrated
  • Implements domain.Asyncer interface

Configuration System

Configuration uses TOML files with two-level structure:

  1. Global config (../global_conf.toml) - Shared settings across services
  2. Service config (conf.toml) - Service-specific settings

Key configuration sections:

  • [MQTT] - Async messaging settings
  • [Gin] - HTTP server configuration
  • [Notify] - Notification channels (Google, Slack)
  • [ExtAuth] - External authentication providers

Environment variable QUANTEX_ENVIRONMENT (required) determines runtime behavior:

  • dev - Development mode, debug logging, relaxed CORS
  • demo, open-demo - Demo environments
  • prod - Production mode, release logging, strict security

Dependency Injection Pattern

Dependencies flow from main.go → runners → infrastructure:

// Example from service runner
api := rest.New(userData, appStore, restConfig, notify)
// Dependencies: UserDataProvider, Store, Config, Notifier

All dependencies are interface-based for testability and loose coupling.

Error Handling

Use src/common/tracerr/ for errors that need stack traces:

import "quantex.com/skeleton/src/common/tracerr"

// Instead of fmt.Errorf:
return tracerr.Errorf("failed to process: %w", err)

// Errors automatically include stack traces
// Critical errors trigger notification via domain.Notifier

Logging

Access via standard library log/slog:

import "log/slog"

slog.Info("message", "key", value)
slog.Error("error occurred", "error", err)
slog.Debug("debug info") // Only visible with -d flag

Logger integrates with Gin middleware for request logging and sends error-level logs to notifier.

Common Development Patterns

Adding a New REST Endpoint

  1. Add handler method to src/client/api/rest/controller.go
  2. Define request/response models in model.go
  3. Add route in routes.go with appropriate middleware
  4. Update Swagger comments (use // @ annotations)
  5. Run make swag to regenerate docs
  6. Test with make test

Adding a New Async Message Handler

  1. In your runner, subscribe to topic:
asyncManager.Subscribe("my-topic", func(topic string, msg []byte) {
    // Handle message
})
  1. Publish messages:
asyncManager.Publish("my-topic", myMessage)

Adding a New Notifier

  1. Create package in src/client/notify/{provider}/
  2. Implement domain.Notifier interface
  3. Add configuration to src/app/model.go
  4. Wire in main.go or use notify/all/all.go for multi-channel

Extending the Store

Add repository methods to src/client/store/manager.go:

func (s *Store) GetSomething(ctx context.Context, id string) (*domain.Model, error) {
    // Use s.db for database access
}

Module Path Convention

When initializing a new project from this skeleton:

  1. Update go.mod module path (e.g., quantex.com/myservice)
  2. Replace all imports from quantex.com/skeleton to quantex.com/myservice
  3. Update PROJECT and DOMAIN in Makefile.common
  4. Update ISSUE_PREFIX in Makefile.common (e.g., MYPROJ)

Code Generation

Enums

The project uses go-enum for type-safe enums. Files ending in _enum.go are generated:

# Generate enums (run after modifying enum comments)
make gogenerate

Example enum definition in source files:

// ENUM(Test, Web, Panic, Error)
type MessageChannel string

Swagger Documentation

Swagger docs are auto-generated from comments:

// @Summary Get user details
// @Description Retrieves user information by ID
// @Tags users
// @Accept json
// @Produce json
// @Param id path string true "User ID"
// @Success 200 {object} UserResponse
// @Router /users/{id} [get]

Always run make swag after modifying REST API contracts.

Important Conventions

Import Grouping

Imports must be grouped (enforced by gci):

  1. Standard library
  2. Third-party packages
  3. Quantex packages (prefixed with quantex.com)

Run make fmt to auto-format.

Error Handling

  • Always check errors
  • Use tracerr for errors that need debugging context
  • Wrap errors with context: tracerr.Errorf("context: %w", err)
  • Critical errors automatically notify via configured channels

Logging Best Practices

  • Use structured logging with key-value pairs
  • Use appropriate log levels (Debug, Info, Warn, Error)
  • Include relevant context in log messages
  • Avoid logging sensitive information (tokens, passwords)

Testing

  • Place *_test.go files alongside source code
  • Use table-driven tests for multiple cases
  • Integration tests should check QUANTEX_ENVIRONMENT
  • Run with race detector: go test -race ./...

Git Workflow

  • Create branches using make branch command
  • Reference issue numbers in commits (e.g., SKL-123)
  • Run make ci before pushing
  • PRs must pass all checks
  • Keep PRs under 500 lines of diff
  • Follow the checklist in checklist.md

Security Considerations

Authentication

Sessions are stored in Redis with 20-minute TTL. Cookie settings:

  • HttpOnly: true - Prevents JavaScript access
  • Secure: true in production - HTTPS only
  • SameSite: Strict in production - CSRF protection

JWT Tokens

Service-to-service JWT tokens use encryption and permission validation. See src/common/securetoken/ for implementation.

Configuration Secrets

  • Never commit secrets to repository
  • Use environment variables for sensitive data
  • Configuration files in repo should be templates only
  • Production secrets should be managed via deployment pipeline

Troubleshooting

"git state is not clean" Error

The make ci and make push commands check for uncommitted changes. Commit or stash changes before running.

MultiDB Permission Errors

MultiDB creates log folders with restrictive permissions. Either:

# Run with sudo
sudo QUANTEX_ENVIRONMENT="dev" go run main.go -run service

# Or change permissions
sudo chmod 644 multiDB
sudo chmod 644 multiDB/2024_11_22

Swagger Generation Fails

Ensure src/client/api/rest/docs/docs.go exists (even if empty):

mkdir -p src/client/api/rest/docs
echo "package docs" > src/client/api/rest/docs/docs.go
make swag

MQTT Connection Issues

Check configuration in conf.toml:

[MQTT]
Protocol = "wss"
URL = "async-non-prod.quantex.com.ar/mqtt/"
Subdomain = "dev"
Secret = "your-secret-here"

Ensure the secret matches the server configuration.

Templates

Ticket Creation Template:

Important: In the console write the template in markdown format so the user can copy paste it directly.

##  Issue Type

- [ ] feature
- [ ] hotfix
- [ ] refactor
- [ ] improvement
- [ ] doc
- [ ] fix

## ❌ Issue Description

Summary_of_what_is_the_issue_and_include_screenshots_and_links_of_slack_to_follow_the_problem

## ✅ Expected Behaviuor

Explain_little_about_how_it_should_be_working

## 📋 Steps to Reproduce

What_steps_should_someone_take_to_reproduce_the_issue_include_screenshots_and_links

## 🐛 Possible Impacts

What_other_areas_in_our_code_might_be_affected_or_is_it_possible_that_something_else_broke_with_these_changes

Code Review Description Template

Important: In the console write the template in markdown format so the user can copy paste it directly.

## 🐛 Reason to Be

Double_click_to_replace_with_a_brief_summary_of_what_this_MR_does_including_a_summary_of_the_original_issue_and_include_screenshots_and_links_to_designs_if_this_MR_has_a_UI_component

Resolves #Issue_number

Related #Issue_number


## ✅ Expected Behaviuor

Explain_little_about_how_is_it_working_in_the_current_MR


## 📋 How To Test

What_steps_should_someone_take_to_test_these_changes_include_screenshots_and_links_to_mocks_for_any_ui_work


##  ⚠️ Check List

1. [ ]  Title format _**SKL-33: Implement Logging using Qapix Endpoints**_ (PREFIX-Issue#: Message)
2. [ ]  Run `make ci` at your end
3. [ ]  Check the pipeline is **🟢 SUCCESS**
4. [ ]  Set the Assignee and Reviewer
5. [ ]  Create 2 PRs for ⚡ HOTFIX in master and develop
  • README.md - Project initialization steps and examples
  • checklist.md - PR review checklist
  • AGENTS.md - Repository guidelines (if exists)
  • .golangci.yml - Linter configuration
  • tools/check/ - Linter exclusions and settings