# 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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: ```go // 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: ```go 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`: ```go 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: ```go asyncManager.Subscribe("my-topic", func(topic string, msg []byte) { // Handle message }) ``` 2. Publish messages: ```go 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`: ```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: ```bash # Generate enums (run after modifying enum comments) make gogenerate ``` Example enum definition in source files: ```go // ENUM(Test, Web, Panic, Error) type MessageChannel string ``` ### Swagger Documentation Swagger docs are auto-generated from comments: ```go // @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: ```bash # 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): ```bash 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`: ```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. ```markdown ## ℹ️ 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. ```markdown ## 🐛 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️ ``` ## Related Documentation - 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