Backend microservices platform for GoApps built with Go, gRPC, and Clean Architecture principles.
- Overview
- Architecture
- Technology Stack
- Repository Structure
- Quick Start
- Services
- Development
- Testing
- CI/CD Pipeline
- Deployment
- API Documentation
- Troubleshooting
- Related Documentation
This repository contains backend microservices for the GoApps platform. Each service follows Clean Architecture principles and exposes both gRPC and REST APIs.
goapps/
├── goapps-backend/ # 🖥️ Backend microservices (this repo)
├── goapps-infra/ # 🔧 Infrastructure as Code
├── goapps-frontend/ # 🌐 Frontend application (Next.js)
└── goapps-shared-proto/ # 📝 Protocol Buffer definitions
| Repository | Description | Tech Stack |
|---|---|---|
goapps-backend |
Microservices APIs | Go 1.24, gRPC, PostgreSQL, Redis |
goapps-infra |
Infrastructure as Code | Kubernetes, Kustomize, Helm, ArgoCD |
goapps-frontend |
Web Application | Next.js 15, React, TypeScript |
goapps-shared-proto |
API Contracts | Protocol Buffers, Buf |
┌──────────────────────────────────────────────────────────────────────────────┐
│ GoApps Backend │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ EXTERNAL CLIENTS │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Next.js │ │ Mobile │ │ External │ │ │
│ │ │ Frontend │ │ Apps │ │ Services │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │
│ └─────────┼────────────────┼────────────────┼───────────────────────────┘ │
│ │ │ │ │
│ │ gRPC-Web │ gRPC │ REST/gRPC │
│ ▼ ▼ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ INGRESS / LOAD BALANCER │ │
│ │ (NGINX Ingress Controller) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ MICROSERVICES │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ Finance Service │ │ IAM Service │ │ Other Services │ │ │
│ │ │ (gRPC+REST) │ │ (gRPC+REST) │ │ (gRPC+REST) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ Port 50051 │ │ Port 50052 │ │ Port 5005x │ │ │
│ │ │ Port 8080 │ │ Port 8081 │ │ Port 808x │ │ │
│ │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │
│ └───────────┼────────────────────┼────────────────────┼─────────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ DATA LAYER │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ PostgreSQL │ │ Redis │ │ RabbitMQ │ │ Oracle │ │ │
│ │ │ (Primary) │ │ (Cache) │ │ (Queue) │ │ (Legacy) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ OBSERVABILITY │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Prometheus │ │ Jaeger │ │ Loki │ │ │
│ │ │ (Metrics) │ │ (Tracing) │ │ (Logs) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘
Each service follows Clean Architecture with 4 layers:
graph TB
subgraph "Service Architecture"
subgraph "Delivery Layer"
GRPC[gRPC Handlers]
HTTP[HTTP Gateway]
end
subgraph "Application Layer"
UC[Use Cases]
DTO[DTOs/Mappers]
end
subgraph "Domain Layer"
ENT[Entities]
VO[Value Objects]
REPO[Repository Interfaces]
ERR[Domain Errors]
end
subgraph "Infrastructure Layer"
PG[PostgreSQL Repo]
REDIS[Redis Cache]
CFG[Config]
TRACE[Tracing]
end
end
GRPC --> UC
HTTP --> UC
UC --> ENT
UC --> REPO
PG -.-> REPO
REDIS -.-> REPO
┌─────────────────────────────────────────────────────────────────────────────┐
│ DEPENDENCY DIRECTION │
│ │
│ External World │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Delivery │ ← Handles HTTP/gRPC requests │
│ │ (grpc, http) │ ← Depends on Application layer │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Application │ ← Contains business logic (use cases) │
│ │ (use cases) │ ← Depends on Domain layer │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Domain │ ← Core business entities and rules │
│ │(entities, repos)│ ← NO external dependencies │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Infrastructure │ ← Implements domain interfaces │
│ │(postgres, redis)│ ← Can depend on external packages │
│ └─────────────────┘ │
│ │
│ KEY: Inner layers MUST NOT depend on outer layers │
└─────────────────────────────────────────────────────────────────────────────┘
| Component | Version | Description |
|---|---|---|
| Go | 1.24 | Programming language |
| gRPC | 1.78.0 | RPC framework |
| gRPC-Gateway | 2.27.7 | REST API from gRPC |
| Protocol Buffers | 3.x | Interface definition |
| Buf | v2 | Protobuf management |
| Component | Version | Description |
|---|---|---|
| PostgreSQL | 18 | Primary database |
| pgx | 5.8.0 | PostgreSQL driver |
| Redis | 7 | Caching layer |
| go-redis | 9.17.3 | Redis client |
| Component | Description |
|---|---|
| zerolog | Structured logging |
| OpenTelemetry | Distributed tracing |
| Prometheus client | Metrics exposure |
| Tool | Version | Description |
|---|---|---|
| golangci-lint | v2.3.0 | Code linting (20+ linters) |
| golang-migrate | v4.18.1 | Database migrations |
| testify | 1.11.1 | Testing assertions |
| excelize | 2.8.1 | Excel file processing |
goapps-backend/
│
├── 📁 services/ # Microservices
│ └── finance/ # Finance service
│ ├── cmd/ # Entry points
│ │ └── server/ # Main server
│ │ └── main.go
│ ├── internal/ # Private code
│ │ ├── domain/ # Domain layer
│ │ │ └── uom/ # UOM domain
│ │ │ ├── entity.go # Domain entity
│ │ │ ├── value_object.go # Value objects
│ │ │ ├── repository.go # Repository interface
│ │ │ └── errors.go # Domain errors
│ │ ├── application/ # Application layer
│ │ │ └── uom/ # UOM use cases
│ │ │ ├── service.go # Business logic
│ │ │ ├── dto.go # Data transfer objects
│ │ │ └── mapper.go # Entity ↔ DTO mapping
│ │ ├── infrastructure/ # Infrastructure layer
│ │ │ ├── config/ # Configuration
│ │ │ ├── postgres/ # PostgreSQL implementation
│ │ │ ├── redis/ # Redis caching
│ │ │ ├── tracing/ # OpenTelemetry setup
│ │ │ └── audit/ # Audit logging
│ │ └── delivery/ # Delivery layer
│ │ ├── grpc/ # gRPC handlers
│ │ └── httpdelivery/ # HTTP gateway
│ ├── pkg/ # Shared utilities
│ │ ├── logger/ # Logging helpers
│ │ ├── circuitbreaker/ # Circuit breaker
│ │ ├── response/ # Response helpers
│ │ └── safeconv/ # Safe type conversions
│ ├── migrations/ # Database migrations
│ │ └── postgres/
│ ├── deployments/ # Deployment configs
│ │ ├── docker-compose.yaml
│ │ └── kubernetes/
│ ├── tests/ # Tests
│ │ ├── e2e/ # End-to-end tests
│ │ └── loadtest/ # Load tests
│ ├── docs/ # Service docs
│ ├── Dockerfile # Multi-stage build
│ ├── Makefile # Service-specific targets
│ ├── config.yaml # Default config
│ ├── go.mod
│ └── go.sum
│
├── 📁 gen/ # Generated code
│ ├── common/v1/ # Common proto types
│ ├── finance/v1/ # Finance proto types
│ ├── openapi/ # OpenAPI specs
│ ├── go.mod
│ └── go.sum
│
├── 📁 deploy/ # Deployment assets
│
├── 📁 .github/ # GitHub Actions
│ ├── workflows/
│ │ ├── finance-service.yml # Finance CI/CD
│ │ └── release-please.yml # Release automation
│ ├── ISSUE_TEMPLATE/
│ └── PULL_REQUEST_TEMPLATE.md
│
├── .golangci.yml # Linter configuration
├── .gitignore
├── Makefile # Root Makefile
├── README.md # This file
├── RULES.md # Development rules
├── CONTRIBUTING.md # Contribution guide
└── LICENSE # Proprietary license
- Go 1.24+ - Download
- Docker & Docker Compose - For local development
- Buf CLI - Protocol buffer management
- golangci-lint - Code linting
- golang-migrate - Database migrations
# Install Buf CLI
# See: https://buf.build/docs/installation
# Install golangci-lint
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.3.0
# Install golang-migrate
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest# 1. Clone repository
git clone https://github.com/mutugading/goapps-backend.git
cd goapps-backend
# 2. Generate proto code (if needed)
make proto
# 3. Start infrastructure
cd services/finance
docker compose -f deployments/docker-compose.yaml up -d postgres redis
# 4. Run migrations
export DATABASE_URL="postgres://finance:finance123@localhost:5434/finance_db?sslmode=disable"
make finance-migrate
# 5. Run service
make finance-run# Check gRPC endpoint
grpcurl -plaintext localhost:50051 list
# Check HTTP endpoint
curl http://localhost:8080/healthz
# Check metrics
curl http://localhost:8080/metricsThe Finance Service manages financial data including Units of Measure (UOM).
| Property | Value |
|---|---|
| Path | services/finance |
| gRPC Port | 50051 |
| HTTP Port | 8080 |
| Metrics | /metrics on HTTP port |
| Health | /healthz on HTTP port |
gRPC Services:
UOMService.CreateUOM- Create new unit of measureUOMService.GetUOM- Get UOM by IDUOMService.ListUOMs- List all UOMs with filteringUOMService.UpdateUOM- Update existing UOMUOMService.DeleteUOM- Soft delete UOMUOMService.ImportUOMs- Bulk import from ExcelUOMService.ExportUOMs- Export to Excel
REST Endpoints (via gRPC-Gateway):
POST /api/v1/finance/uom
GET /api/v1/finance/uom/{id}
GET /api/v1/finance/uom
PUT /api/v1/finance/uom/{id}
DELETE /api/v1/finance/uom/{id}
POST /api/v1/finance/uom/import
GET /api/v1/finance/uom/export
Environment variables override config.yaml:
| Variable | Default | Description |
|---|---|---|
APP_ENV |
development | Environment (development/staging/production) |
DATABASE_HOST |
localhost | PostgreSQL host |
DATABASE_PORT |
5434 | PostgreSQL port |
DATABASE_USER |
finance | Database user |
DATABASE_PASSWORD |
- | Database password |
DATABASE_NAME |
finance_db | Database name |
REDIS_HOST |
localhost | Redis host |
REDIS_PORT |
6379 | Redis port |
TRACING_ENABLED |
true | Enable OpenTelemetry |
JAEGER_ENDPOINT |
localhost:4317 | Jaeger collector |
Root Makefile:
make help # Show all targets
make proto # Generate proto code
make lint # Run golangci-lint
make lint-fix # Auto-fix lint issues
make test # Run all tests
make test-coverage # Run tests with coverage
make clean # Clean build artifactsFinance Service:
make finance-run # Run service locally
make finance-build # Build binary
make finance-migrate # Run DB migrations
make finance-seed # Run seeders
make finance-docker # Build Docker imageProto files are in goapps-shared-proto. To regenerate:
# From goapps-backend root
make proto
# Or from goapps-shared-proto
cd ../goapps-shared-proto
./scripts/gen-go.shGenerated code is placed in gen/ directory.
# Create new migration
migrate create -ext sql -dir services/finance/migrations/postgres -seq add_new_table
# Run migrations
export DATABASE_URL="postgres://user:pass@host:port/db?sslmode=disable"
migrate -path services/finance/migrations/postgres -database "$DATABASE_URL" up
# Rollback last migration
migrate -path services/finance/migrations/postgres -database "$DATABASE_URL" down 1| Type | Directory | Command | Description |
|---|---|---|---|
| Unit | internal/ |
go test -short ./internal/... |
Isolated component tests |
| Integration | internal/infrastructure/ |
go test ./internal/infrastructure/... |
Database/Redis tests |
| E2E | tests/e2e/ |
go test ./tests/e2e/... |
Full API tests |
| Load | tests/loadtest/ |
Custom | Performance tests |
# Unit tests only
go test -v -race -short ./...
# All tests (requires running PostgreSQL/Redis)
go test -v -race ./...
# With coverage
go test -v -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
# Specific package
go test -v ./internal/domain/uom/...Integration tests require PostgreSQL and Redis:
# Start test infrastructure
docker compose -f deployments/docker-compose.yaml up -d postgres redis
# Run migrations
migrate -path migrations/postgres \
-database "postgres://finance:finance123@localhost:5434/finance_db_test?sslmode=disable" \
up
# Run integration tests
INTEGRATION_TEST=true go test -v ./internal/infrastructure/...graph LR
subgraph "CI Pipeline"
A[Push/PR] --> B[Lint]
A --> C[Test]
B --> D{Pass?}
C --> D
D -->|Yes| E[Build]
D -->|No| F[Fail]
E --> G[Docker Build]
end
subgraph "CD Pipeline"
G --> H[E2E Tests]
H --> I[Deploy Staging]
I --> J[Deploy Production]
end
| Job | Trigger | Description |
|---|---|---|
lint |
Push/PR | golangci-lint validation |
test |
Push/PR | Unit + integration tests |
build |
After lint+test | Compile binary |
docker |
Push to main | Build & push to GHCR |
e2e |
After docker | End-to-end tests |
deploy-staging |
After e2e | Auto-deploy via ArgoCD |
deploy-production |
After staging | Manual approval required |
Deployments use self-hosted runners in VPS:
runs-on: [self-hosted, staging, goapps-runner]Images are pushed to GitHub Container Registry:
ghcr.io/mutugading/finance-service:latest
ghcr.io/mutugading/finance-service:<sha>
ghcr.io/mutugading/finance-service:main
Kubernetes manifests are in goapps-infra repository:
goapps-infra/services/finance-service/
├── base/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── hpa.yaml
└── overlays/
├── staging/
└── production/
Services are auto-synced via ArgoCD:
- Push to
maintriggers Docker build - New image pushed to GHCR
- ArgoCD detects new image tag
- Auto-sync deploys to staging
- Manual sync deploys to production
OpenAPI specs are generated from proto files:
gen/openapi/
├── finance/v1/uom.swagger.json
└── common/v1/common.swagger.json
Source proto files in goapps-shared-proto:
// finance/v1/uom.proto
service UOMService {
rpc CreateUOM(CreateUOMRequest) returns (CreateUOMResponse);
rpc GetUOM(GetUOMRequest) returns (GetUOMResponse);
rpc ListUOMs(ListUOMsRequest) returns (ListUOMsResponse);
rpc UpdateUOM(UpdateUOMRequest) returns (UpdateUOMResponse);
rpc DeleteUOM(DeleteUOMRequest) returns (DeleteUOMResponse);
}gRPC reflection is enabled. Use grpcurl to explore:
# List services
grpcurl -plaintext localhost:50051 list
# Describe service
grpcurl -plaintext localhost:50051 describe finance.v1.UOMService
# Call method
grpcurl -plaintext -d '{"code": "KG", "name": "Kilogram"}' \
localhost:50051 finance.v1.UOMService/CreateUOM# Check PostgreSQL is running
docker ps | grep postgres
# Test connection
psql -h localhost -p 5434 -U finance -d finance_db
# Check logs
docker logs <postgres-container-id># Check service is running
lsof -i :50051
# Check logs
tail -f /path/to/service.log
# Test with grpcurl
grpcurl -plaintext localhost:50051 list# Check migration status
migrate -path migrations/postgres -database "$DATABASE_URL" version
# Force version (use with caution)
migrate -path migrations/postgres -database "$DATABASE_URL" force <version>
# Check migration files
ls -la migrations/postgres/# Run with verbose output
golangci-lint run -v ./...
# Fix auto-fixable issues
golangci-lint run --fix ./...
# Check specific linter
golangci-lint run --enable=errcheck ./...# Check service health
curl http://localhost:8080/healthz
# View metrics
curl http://localhost:8080/metrics | grep go_
# Tail logs (with zerolog pretty print)
go run cmd/server/main.go 2>&1 | jq
# Profile CPU
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30
# Profile memory
go tool pprof http://localhost:8080/debug/pprof/heap| Document | Path | Description |
|---|---|---|
| Development Rules | RULES.md | Coding conventions |
| Contributing Guide | CONTRIBUTING.md | How to contribute |
| License | LICENSE | Proprietary license |
| Template | Description |
|---|---|
| 🐛 Bug Report | Report bugs or issues |
| ✨ Feature Request | Request new features |
| 🚀 New Service | Request new microservice |
- Team: GoApps Backend
- Organization: PT Mutu Gading Tekstil
- Repository Issues: GitHub Issues
This project is proprietary software. See the LICENSE file for details.
© 2024-2026 PT Mutu Gading Tekstil. All Rights Reserved.