Wallets is a microservice for managing electronic wallets written in Go. The service provides a REST API for creating wallets, depositing funds, transferring between wallets, and viewing transaction history.
- Create named wallets
- Deposit funds to wallets
- Transfer funds between wallets
- View transaction history with date filtering
- Export transactions to CSV format
- Go 1.20+
- PostgreSQL 12+
- Docker and Docker Compose (optional)
# Start all services (PostgreSQL + application)
docker-compose up
# Start in background
docker-compose up -d
# 1. Start PostgreSQL
make postgres/up
# 2. Apply database migrations
make migrate/up
# 3. Run the application
make run
# Run unit tests
make test
# Run integration tests
make test/int
# Run tests with coverage
make test/coverage
# Run integration tests with coverage
make test/coverage/int
# Build binary
make build
# Build Docker image
make build/docker
.
├── api/
│ └── v1/
│ └── swagger.yaml # OpenAPI specification
├── cmd/
│ └── main.go # Application entry point
├── docs/
│ └── diagrams/ # Architecture diagrams
├── internal/
│ ├── application/ # Application initialization and startup
│ │ ├── application.go
│ │ └── logger.go
│ ├── config/ # Configuration from env variables
│ │ └── config.go
│ ├── consts/ # Application constants
│ │ └── consts.go
│ ├── csv/ # CSV report generation
│ │ └── operations.go
│ ├── dto/ # Data Transfer Objects
│ │ ├── amount.go
│ │ ├── deposit.go
│ │ ├── operation.go
│ │ ├── transfer.go
│ │ └── wallet.go
│ ├── http/ # HTTP layer
│ │ ├── dependencies.go
│ │ ├── errors.go
│ │ ├── handlers.go
│ │ └── server.go
│ ├── httperr/ # HTTP errors
│ │ └── errors.go
│ ├── repository/ # Database layer
│ │ ├── entities.go
│ │ └── repository.go
│ ├── service/ # Business logic
│ │ ├── dependencies.go
│ │ ├── errors.go
│ │ ├── service.go
│ │ └── service_test.go
│ └── tests/ # Integration tests
│ └── integration_test.go
├── migrations/ # SQL migrations
├── docker-compose.yml
├── Dockerfile
├── go.mod
├── go.sum
├── Makefile
├── README.md # This file (English)
└── README_ru.md # Russian documentation
The application follows a three-layer architecture with clear boundaries between layers:
- HTTP Layer (
internal/http/
) - HTTP request handling, input validation, routing - Service Layer (
internal/service/
) - business logic, transaction management, business rule validation - Repository Layer (
internal/repository/
) - database operations, SQL queries
- Transaction Isolation Level: Uses
sql.LevelSerializable
for all wallet operations, ensuring data consistency in concurrent operations - Money Storage: Amounts are stored as
numeric(18,2)
in the database andfloat64
in Go code - Operation Logging: All monetary operations are recorded in the
operations
table for audit purposes - Validation: Minimum operation amount is 0.01, validated at the HTTP layer
PostgreSQL with two main tables:
- wallets - wallet information (id, name, balance, created_at, updated_at)
- operations - transaction history (id, wallet_id, type, amount, created_at)
The application is configured via environment variables:
Variable | Description | Default Value |
---|---|---|
DB_HOST |
PostgreSQL host | localhost |
DB_PORT |
PostgreSQL port | 5432 |
DB_USER |
Database user | postgres |
DB_PASSWORD |
Database password | postgres |
DB_NAME |
Database name | wallets |
APP_PORT |
HTTP server port | 8080 |
LOG_LEVEL |
Logging level | info |
Create a new wallet
{
"name": "My Wallet"
}
Deposit funds to a wallet
{
"wallet_id": "123e4567-e89b-12d3-a456-426614174000",
"amount": 100.50
}
Transfer funds between wallets
{
"from_wallet_id": "123e4567-e89b-12d3-a456-426614174000",
"to_wallet_id": "987fcdeb-51a2-43d1-9012-345678901234",
"amount": 50.00
}
Get transaction history with optional filters:
wallet_id
- Wallet IDfrom_date
- Start date (RFC3339)to_date
- End date (RFC3339)offset
- Pagination offsetlimit
- Number of records
Detailed API specification is available in api/v1/swagger.yaml.
Command | Description |
---|---|
make build |
Build application binary |
make test |
Run unit tests |
make test/int |
Run integration tests |
make test/coverage |
Run tests with coverage report |
make test/coverage/int |
Run integration tests with coverage |
make run |
Run the application |
make postgres/up |
Start PostgreSQL in Docker container |
make postgres/down |
Stop PostgreSQL container |
make migrate/up |
Apply all migrations |
make migrate/down |
Rollback last migration |
make build/docker |
Build Docker image |
make diagrams |
Generate diagrams from DOT files |
# View package documentation
go doc internal/service
# Generate mocks for testing
go generate ./...
# Check test coverage
go test -cover ./...
# Run specific test
go test -run TestServiceTransfer ./internal/service
- Unit Tests: Use repository mocks to isolate business logic. See example in
internal/service/service_test.go
- Integration Tests: Test the full stack with a real database. See
internal/tests/integration_test.go
- Code Coverage: The project maintains comprehensive test coverage. In PRs, coverage is compared with the master branch to track improvements
- Custom errors are defined in
internal/httperr/
for proper HTTP semantics - Business errors (insufficient funds, wallet not found) return appropriate HTTP status codes
- Structured logging via Zap
- All monetary operations are logged for audit purposes
- Prometheus integration for metrics collection
- Available at
/metrics
endpoint
- README.md - English documentation (this file)
- README_ru.md - Russian documentation
- api/v1/swagger.yaml - OpenAPI specification
This project is distributed under the MIT License. See LICENSE file for details.