This commit is contained in:
Ramiro Paz
2026-03-09 15:09:06 -03:00
parent 8299f8bc96
commit 0e8fe168ef
85 changed files with 14079 additions and 0 deletions

496
CLAUDE.md Normal file
View File

@ -0,0 +1,496 @@
# 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