Portfolio Management Tool
Gaivota (Portuguese for "seagull") is a comprehensive portfolio management API written in Go. It's designed to help users track and manage their investment portfolios across multiple wallets and exchanges.
- Multi-Wallet Support: Track assets across different wallets and exchanges
- Investment Tracking: Monitor positions with average prices and automatic profit/loss calculations
- Order Management: Record buy/sell orders with support for limit and market orders
- Multi-User: Support for multiple users with individual portfolios
- Real-time Health Checks: Built-in health monitoring endpoints
- Soft Deletes: Data integrity with soft delete functionality
- Backend: Go 1.16 with custom HTTP router
- Database: PostgreSQL 13 with migrations
- Containerization: Docker with docker-compose
- Database Driver: pgx/v4 for PostgreSQL connectivity
The system follows a well-structured domain model with these core entities:
- Users - Account holders of the system
- Portfolios - Logical groupings of investments per user
- Wallets - Physical or digital storage locations with addresses
- Investments - Specific tokens/assets within portfolios
- Positions - Investment amounts with average prices and profit tracking
- Holdings - Relationships between positions and wallets (where assets are stored)
- Orders - Buy/sell transactions with exchange information
├── cmd/gaivota/ # Application entry point
├── handlers/ # HTTP request handlers
├── internal/config/ # Configuration management
├── log/ # Custom logging
├── mux/ # HTTP routing and endpoints
├── postgres/ # Database layer implementations
├── migrations/ # Database schema migrations
└── gaivota.go # Core domain types and interfaces
- Docker and Docker Compose
- Go 1.16+ (for local development)
-
Create configuration file
cp config.exemple.json config.json
-
Start the services
docker compose up -d
This will start:
- API server on port 8888
- PostgreSQL database on port 5555
The application uses a JSON configuration file with the following structure:
{
"Port": 9090,
"DatabaseConnString": "postgres://gaivota:secretpassword@db:5432/gaivota"
}The application uses PostgreSQL with automated migrations. The database schema includes:
- users: User account information
- portfolios: Investment portfolio groupings
- wallets: Asset storage locations
- investments: Tracked tokens/assets
- positions: Investment amounts and pricing
- holdings: Position-wallet relationships
- orders: Transaction history
All tables include automatic timestamp tracking and soft delete functionality.
1. REST API Server
- Health checks (
/health) - Portfolio management endpoints
- User management endpoints
- Investment tracking endpoints
- Order processing endpoints
2. Command Line Interface (CLI)
- Direct database access for all entities
- User-friendly commands for data management
- Perfect for administration and testing
The project follows Go's standard cmd/ pattern with multiple entry points:
# Build API server
go build -o bin/gaivota ./cmd/gaivota
# Build CLI tool
go build -o bin/gaivota-cli ./cmd/gaivota-cli
# Or build both
go build -o bin/ ./cmd/...-
Install dependencies
go mod download
-
Setup configuration
cp config.example.json config.json
-
Start database
docker compose up -d db
-
Run database migrations
# Configure tern.conf based on tern.example.conf tern migrate -
Start the API server
go run cmd/gaivota/main.go # or ./bin/gaivota -
Use the CLI tool
go run cmd/gaivota-cli/main.go --help # or ./bin/gaivota-cli --help
# Check database connection
./gaivota-cli health
# List all users
./gaivota-cli users list
# Create a new user
./gaivota-cli users create "[email protected]" "John" "Doe"
# List portfolios for a user
./gaivota-cli portfolios list-by-user 1
# Create a portfolio
./gaivota-cli portfolios create 1 "My Crypto Portfolio"
# List all wallets
./gaivota-cli wallets list
# Get specific investment details
./gaivota-cli investments get 1The system uses PostgreSQL with the following key relationships:
- Users → Portfolios (1:many)
- Users → Wallets (1:many)
- Portfolios → Investments (1:many)
- Investments → Positions (1:many)
- Positions → Orders (1:many)
- Positions ↔ Wallets (many:many through Holdings)
The project follows Go best practices with:
- Interface-based design for testability
- Clean separation of concerns
- Dependency injection
- Graceful shutdown handling
- Comprehensive error handling and logging
See LICENSE file for details.