From 9e55c5c562c71e5127df7be1acb779934c3bf12f Mon Sep 17 00:00:00 2001 From: Ramiro Paz Date: Wed, 11 Mar 2026 11:04:53 -0300 Subject: [PATCH] changes --- AGENTS.md | 2 +- CLAUDE.md | 496 ------------------------------------------ tools/build.sh | 2 +- tools/generate-jwt.sh | 2 +- tools/restart | 2 +- 5 files changed, 4 insertions(+), 500 deletions(-) delete mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md index 0ae0e5d..9ecd1b9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,7 +12,7 @@ The service boots from `main.go`, and all Go packages live under `src`. Use `src - `make deploy e=` – pushes a build using the target defined in `build/deploy.sh`. ## Coding Style & Naming Conventions -Run `make fmt` to apply gofumpt, gci, and goimports; Go’s formatter enforces tab indentation and canonical spacing. Follow idiomatic naming—PascalCase for exported symbols, camelCase for internals, lowercase filenames—and keep package paths under `quantex.com/skeleton/`. Group imports as standard library, third-party, then `quantex.com`, and avoid formatting-only commits. +Run `make fmt` to apply gofumpt, gci, and goimports; Go’s formatter enforces tab indentation and canonical spacing. Follow idiomatic naming—PascalCase for exported symbols, camelCase for internals, lowercase filenames—and keep package paths under `quantex.com/qfixpt/`. Group imports as standard library, third-party, then `quantex.com`, and avoid formatting-only commits. ## Testing Guidelines Keep `*_test.go` files beside the code and prefer table-driven cases. Guard integration tests with `QUANTEX_ENVIRONMENT` so they hit the intended backend, and regenerate Swagger with `make swag` whenever REST contracts change. Spot-check concurrency with `go test -race ./src/` and store fixtures under package-level `testdata/` directories. diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 78711b2..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,496 +0,0 @@ -# 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 diff --git a/tools/build.sh b/tools/build.sh index 766da5f..187a478 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -42,7 +42,7 @@ if COMMIT_MSG=$(QUANTEX_ENVIRONMENT=$ENV "${OUT_PATH}/qfixpt" -v 2>/dev/null); t echo "$COMMIT_MSG" else echo "---------------------------------" - echo "Skeleton" + echo "QFIXPT" echo "Built at: ${BUILT_TIME}" echo "Branch: ${BUILD_BRANCH}" echo "SHA: ${BUILD_HASH}" diff --git a/tools/generate-jwt.sh b/tools/generate-jwt.sh index 2ae449e..dfb2004 100755 --- a/tools/generate-jwt.sh +++ b/tools/generate-jwt.sh @@ -3,7 +3,7 @@ set -e read -r -p "Issuer: " ISSUER -read -r -p "Service (e.g. SKELETON): " SERVICE +read -r -p "Service (e.g. QFIXPT): " SERVICE read -r -p "Token: " TOKEN read -r -p "Expire (e.g. 24h) [none]: " EXPIRY diff --git a/tools/restart b/tools/restart index 052ecf0..1a03842 100644 --- a/tools/restart +++ b/tools/restart @@ -1,4 +1,4 @@ #!/bin/bash systemctl daemon-reload -systemctl restart skeleton.service \ No newline at end of file +systemctl restart qfixpt.service \ No newline at end of file