Develop#9
Merged
Merged
Conversation
- configs/config.yaml skeleton
- README with architecture overview"
- Makefile with lint, test, build, run, up, down, migrate, gen targets - tools/tools.go pins dev tool versions in go.mod
- ci.yml: lint -> test -> build chain on every PR - test job spins up real Postgres 16 sidecar container - proto.yml: buf lint and format check on .proto changes - Jobs use needs: to enforce sequential execution - Tests run with -race flag and 120s timeout
- Postgres 16 Alpine with named volume for data persistence - pgAdmin for visual DB inspection at localhost:5050 - .env.example for local configuration (actual .env is gitignored) - Updated Makefile with full set of targets across all phases - make help prints formatted list of all available targets - DB_DSN loaded from .env via include directive
feat: add local dev environment with Docker Compose
- accounts: UUID PK, account_type enum, currency_code, balance cache - transactions: idempotency_key UNIQUE, status enum, JSONB metadata - CHECK: from_account != to_account - CHECK: amount > 0 - entries: immutable double-entry ledger, signed amounts - positive = CREDIT, negative = DEBIT - SUM(amount) across all entries always equals 0 - trigger_set_updated_at() on accounts and transactions - Indexes on all foreign keys and common query patterns - All migrations have corresponding down files for rollback
feat: add database schema and migrations
buf requires directory structure to mirror the proto package name. Package 'ledger.v1' must live in 'ledger/v1' relative to the module root. Updated go_package option to match the new path.
Feature/api contract
CI: - Both workflows now trigger on workflow_dispatch only - internal/store/postgres/store.go: Store struct, New(), Close(), compile-time check - internal/store/postgres/account.go: CreateAccount, GetAccount, GetBalance - internal/store/postgres/transaction.go: stubs - internal/store/postgres/account_test.go: integration tests against real Postgres - pgx/v5: direct driver, no database/sql wrapper - Postgres enum scanned via intermediate string conversion
Generated proto files import grpc-gateway, grpc, protobuf, and genproto packages. These were previously anchored via tools.go which was removed. Added as direct dependencies via go get.
Feature/store interface
…tion Feature/atomic transaction
- ValidationError type: consistent validation errors map to codes.InvalidArgument . - slog: replaced stdlib log.Println with structured JSON logging throughout
Bugfix/fix build and bugs
- Rewrote README with architecture diagram, double-entry bookkeeping explanation, race condition / idempotency deep-dives, API examples, full config reference, error table, and project structure map - Added generated OpenAPI/Swagger spec (api/openapi/ledger.swagger.json) - Updated Makefile gen target to copy swagger.json into transport/http - Fixed indentation in configs/config.example.yaml and added metrics_port - Added METRICS_PORT to .env.example; removed stale inline comments - Promoted golang.org/x/sync to a direct dependency; added koanf, prometheus/client_golang and their transitive deps to go.mod/go.sum
- Create multi-stage Dockerfile with Go builder and distroless runtime - Optimize image size with CGO disabled and stripped binaries - Add ledger service to docker-compose with environment configuration - Configure gRPC (9090), HTTP (8080), and metrics (9091) ports - Set up service dependencies and health checks for PostgreSQL - Remove unnecessary PGADMIN_CONFIG_SERVER_MODE environment variable - Enable containerized local development and deployment workflow
…zation - Add config package with YAML-based configuration loading using koanf - Support environment variable overrides for all configuration values - Replace hardcoded environment variable parsing with structured config in main.go - Add validation for required config values with sensible defaults - Initialize metrics package with Prometheus counters, histograms, and gauges - Add MetricsPort to server configuration for metrics endpoint - Update main.go to load configuration from configs/config.yaml - Set log level from config instead of hardcoded debug level - Log configuration values on startup for observability
- Add transaction_test.go with integration tests for CreateTransaction - Implement setupStore helper and seedWallets utility for test fixtures - Add TestCreateTransaction_Success to verify successful transaction flow - Add TestCreateTransaction_InsufficientFunds to validate balance checks - Add TestCreateTransaction_Idempotency to ensure idempotency key prevents duplicates - Add TestCreateTransaction_CurrencyMismatch to validate currency validation - Add TestCreateTransaction_ConcurrentDeductions to verify SELECT FOR UPDATE prevents race conditions - Add TestCreateTransaction_ConcurrentContention to test concurrent access under resource constraints - Add Ping method to Store for health checks and connection verification - Upgrade logging from standard log to log/slog for structured logging - Improve rollback error handling to ignore already-closed transactions - Reduce log noise by filtering ErrTxClosed during rollback operations
- Add metrics instrumentation to CreateTransaction handler for duration tracking and error classification - Implement classifyError function to categorize transaction errors for better observability - Create LoggingInterceptor to log all gRPC method calls with duration and status codes - Create RecoveryInterceptor to catch and log panics in gRPC handlers - Register interceptors in gRPC server using ChainUnaryInterceptor - Add health check endpoint to HTTP gateway with database connectivity verification - Add /metrics endpoint to expose Prometheus metrics - Update gateway to accept optional ping function for health checks - Improve logging in GetBalance handler with consistent message formatting - Remove unused handler field from Server struct for cleaner initialization
Feature/audit
- Move swaggerUIHTML constant from gateway.go to new swagger_ui.go file - Update Swagger UI CDN from jsdelivr to unpkg with version pinning (@5) - Add responsive styling for Swagger UI container with max-width and centering - Replace SwaggerUIBundle.SwaggerUIStandalonePreset with imported SwaggerUIStandalonePreset - Add window.onload wrapper for improved initialization handling - Enable deepLinking and DownloadUrl plugin for enhanced API documentation experience - Improves code organization by separating concerns between gateway setup and UI presentation
- Enable pull_request and push triggers on develop and main branches - Replace manual workflow_dispatch-only trigger with automated events - Add database migration step using golang-migrate before running tests - Rename DB_DSN to DB_DSN_TEST environment variable for test clarity - Ensure test database schema is up-to-date before test execution
- Replace inline Auditor interface with OutboxStore-based event persistence - Remove NoOp and WebhookAuditor implementations in favor of worker-based delivery - Add Worker type to handle asynchronous audit event processing and retry logic - Introduce AuditOutboxEntry and OutboxStore interface for durable event storage - Remove audit logging from Service.CreateTransaction, delegating to outbox worker - Simplify Service initialization by removing Auditor dependency - Implement polling-based delivery with configurable retry handling and status tracking - Improves reliability and decouples event production from delivery concerns
…ttern - Create audit_outbox table to implement transactional outbox pattern for reliable audit event delivery - Add audit_status ENUM type with states: PENDING, SENT, FAILED, DEAD_LETTERED - Include retry logic with configurable max_retries and retry_count tracking - Add partial index on status='PENDING' for efficient polling of pending events - Store action_type and JSONB payload for flexible audit event representation - Track processing metadata: created_at, processed_at, and last_error for observability - Ensures audit records are created atomically within the same transaction as ledger operations, preventing data loss during webhook failures
- Remove synchronous auditor from service initialization - Add audit outbox worker that polls and processes pending events - Create PollAuditOutbox, MarkAuditEntrySent, and MarkAuditEntryFailed store methods - Insert audit events into outbox table on transaction creation - Add /swagger.json endpoint to serve OpenAPI specification - Extract jsonEncode helper to eliminate repeated error suppression comments - Reorganize imports in gateway module for consistency - Configure worker with 5-second poll interval and retry logic - Enable graceful shutdown of audit worker through error group context
- Add i18n package with multi-language message catalog supporting English and Farsi - Implement language negotiation via Accept-Language header parsing - Create error mapping from domain errors to localized messages - Extract HTTP error response handling into dedicated response.go module - Implement CustomErrorHandler for gRPC-gateway with proper HTTP status code mapping - Add structured error response format with error details and metadata timestamps - Remove swagger.json route handler in favor of centralized response handling - Support locale fallback to English when requested language is unavailable
- Add regex pattern for UUID format validation - Implement validateUUID helper function to validate UUID format and non-empty values - Add UUID validation to GetAccount method - Add UUID validation to GetBalance method - Add UUID validation to CreateTransaction method for both from and to account IDs - Fix whitespace inconsistency in Service struct field alignment - Ensure all account ID parameters are validated before store operations
- Add service_test.go with mockStore implementation for testing ledger operations - Implement test cases for account creation validation (empty name, invalid currency, invalid type) - Implement test cases for transaction creation validation (zero/negative amounts, same account, empty idempotency key) - Implement test cases for wallet history pagination (default limit, limit cap enforcement) - Remove section comment headers from Makefile for cleaner organization - Add nolint directive to i18n/messages.go for intentional Persian typography character (U+200C ZWNJ)
- Add swaggo/http-swagger dependency for Swagger UI integration - Update buf.gen.yaml to output OpenAPI spec to internal/transport/http - Rename merged OpenAPI file from ledger to swagger for clarity - Create swagger.swagger.json with generated OpenAPI specification - Implement swagger_ui.go module to serve Swagger UI endpoints - Update gateway.go HTTP transport layer to include Swagger routes - Add response.go utilities for consistent HTTP response formatting - Update audit worker.go for compatibility with transport changes - Fix Makefile run target with proper go run command syntax - Add go-openapi and related dependencies to support OpenAPI generation - Consolidate API documentation in application rather than separate api/ directory
- Extract error logging into dedicated logHandlerError function for consistent error handling - Differentiate between validation/domain errors (warn level) and unexpected errors (error level) - Add context and slog imports for structured logging with context support - Update CreateWallet handler to use new logHandlerError utility - Improves observability by categorizing errors appropriately and reducing code duplication across handlers
…yError swagger: - //go:embed swagger.json was missing — variable was always empty bytes - Adding directive compiles the 8464-byte spec into the binary classifyError: - ErrAccountNotFound and ErrTransactionNotFound now map to 'not_found'
Feature/swagger ci fix
|
The latest Buf updates on your PR. Results from workflow Proto / lint (pull_request).
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.