Skip to content

Quick Start

Get Promenade running in 5 minutes - from zero to first API call.


Prerequisites

Before you begin, ensure you have:

  • Go 1.24+ installed
  • Docker & Docker Compose (for PostgreSQL)
  • Make (comes with macOS/Linux)
  • Git (to clone the repository)

1. Clone & Start Infrastructure

bash
# Clone repository
git clone https://github.com/basilex/promenade.git
cd promenade

# Start PostgreSQL (localhost:5432)
make docker-up

# Wait for PostgreSQL to be ready (3 seconds)

PostgreSQL is now running on localhost:5432


2. Run Migrations

bash
# Migrations run automatically on app startup
# Or manually:
make migrate

This creates all tables in correct order:

  • Core (UUID v7 extensions, auth, RBAC)
  • Shared (Countries, Currencies, Languages, Timezones)
  • Identity (Users, Contacts, Profiles, Roles, Permissions)
  • Customer Management (Customers)

3. Start API Server

bash
# Full dev environment (Docker + migrations + API)
make dev

# Or build and run separately
make build
./bin/promenade

Server starts on http://localhost:8081


4. Health Check

bash
curl http://localhost:8081/health

Expected Response:

json
{
  "status": "healthy",
  "timestamp": "2025-12-29T12:00:00Z"
}

5. Your First API Calls

Register a User

bash
curl -X POST http://localhost:8081/api/v1/identity/users/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "name": "John Doe",
    "password": "SecurePass123"
  }'

Response:

json
{
  "status": "success",
  "data": {
    "id": "01JGABC1234567890DEFGHIJK",
    "email": "john@example.com",
    "name": "John Doe",
    "status": "active",
    "created_at": "2025-12-29T12:00:00Z"
  }
}

Login

bash
curl -X POST http://localhost:8081/api/v1/identity/users/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "password": "SecurePass123"
  }'

Response:

json
{
  "status": "success",
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expires_at": "2025-12-29T12:15:00Z",
    "token_type": "Bearer",
    "user": {
      "id": "01JGABC1234567890DEFGHIJK",
      "email": "john@example.com",
      "name": "John Doe"
    }
  }
}

Copy the access_token - you'll need it for protected endpoints!

Create Profile (Protected)

bash
# Replace YOUR_ACCESS_TOKEN with token from login response
curl -X POST http://localhost:8081/api/v1/identity/profiles \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "display_name": "John D.",
    "first_name": "John",
    "last_name": "Doe",
    "bio": "Software developer and DDD enthusiast",
    "timezone": "Europe/Kyiv",
    "language": "uk",
    "country": "UA"
  }'

Response:

json
{
  "status": "success",
  "data": {
    "id": "01JGABC9876543210ZYXWVUTS",
    "user_id": "01JGABC1234567890DEFGHIJK",
    "display_name": "John D.",
    "first_name": "John",
    "last_name": "Doe",
    "bio": "Software developer and DDD enthusiast",
    "timezone": "Europe/Kyiv",
    "language": "uk",
    "country": "UA",
    "is_public": false
  }
}

Add Email Contact

bash
curl -X POST http://localhost:8081/api/v1/identity/contacts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "type": "email",
    "email": "john.work@company.com",
    "label": "Work",
    "is_primary": false
  }'

Response:

json
{
  "status": "success",
  "data": {
    "id": "01JGABCXYZ1234567890ABCDE",
    "user_id": "01JGABC1234567890DEFGHIJK",
    "type": "email",
    "label": "Work",
    "email": "john.work@company.com",
    "is_primary": false,
    "is_verified": false,
    "is_public": false
  }
}

Get Reference Data

bash
# Get all countries
curl http://localhost:8081/api/v1/shared/countries

# Get all currencies
curl http://localhost:8081/api/v1/shared/currencies

# Get all languages
curl http://localhost:8081/api/v1/shared/languages

# Get all timezones
curl http://localhost:8081/api/v1/shared/timezones

6. Common Workflows

Complete User Setup

bash
# 1. Register
TOKEN=$(curl -s -X POST http://localhost:8081/api/v1/identity/users/register \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com","name":"Alice","password":"Pass123!"}' | \
  jq -r '.data.access_token')

# 2. Create Profile
curl -X POST http://localhost:8081/api/v1/identity/profiles \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"display_name":"Alice","timezone":"Europe/London","language":"en","country":"GB"}'

# 3. Add Work Email
curl -X POST http://localhost:8081/api/v1/identity/contacts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"email","email":"alice.work@company.com","label":"Work","is_primary":true}'

# 4. Add Phone
curl -X POST http://localhost:8081/api/v1/identity/contacts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"phone","phone":"+441234567890","label":"Mobile"}'

# 5. Get My Profile
curl http://localhost:8081/api/v1/identity/profiles/me \
  -H "Authorization: Bearer $TOKEN"

Customer Management

bash
# Create Customer
curl -X POST http://localhost:8081/api/v1/customer-mgmt/customers \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corp",
    "email": "contact@acme.com",
    "phone": "+441234567890",
    "segment": "enterprise",
    "status": "active"
  }'

# List Customers
curl http://localhost:8081/api/v1/customer-mgmt/customers \
  -H "Authorization: Bearer $TOKEN"

# Get Customer by ID
curl http://localhost:8081/api/v1/customer-mgmt/customers/01JGABC... \
  -H "Authorization: Bearer $TOKEN"

7. Development Workflow

File Watching (Manual)

bash
# Terminal 1: Watch and restart on changes
fswatch -o internal/ cmd/ pkg/ | xargs -n1 -I{} make run

# Terminal 2: Watch tests
fswatch -o internal/ | xargs -n1 -I{} make test-unit

Database Reset

bash
# Drop and recreate database (WARNING: all data lost!)
make db-reset

# Fresh database with migrations
make db-fresh

# Or full clean restart
make dev-fresh

Run Tests

bash
# All tests (240+ tests, ~40s)
make test

# By type
make test-unit              # Unit tests only (~5s)
make test-smoke             # Smoke tests (~0.4s)
make test-integration       # Integration tests (~6s)

# Specific context
go test ./internal/contexts/identity/... -v

# With coverage
make test-coverage

8. Configuration

Environment Variables

bash
# Development (default)
ENVIRONMENT=dev ./bin/promenade

# Production
ENVIRONMENT=production ./bin/promenade

# Custom database
DB_HOST=localhost DB_PORT=5432 DB_NAME=promenade_custom ./bin/promenade

# Custom JWT secret (production!)
JWT_SECRET=$(openssl rand -base64 32) ./bin/promenade

Configuration Files

  • config/app.postgres-dev.yaml or config/app.sqlite-dev.yaml - Development
  • config/app.postgres-test.yaml or config/app.sqlite-test.yaml - Testing
  • config/app.postgres-prod.yaml or config/app.sqlite-prod.yaml - Production

Example (config/app.postgres-dev.yaml):

yaml
app:
  name: "Promenade Platform"
  environment: "development"
  version: "1.0.0"

server:
  host: "0.0.0.0"
  port: 8081

database:
  postgres:
    host: "localhost"
    port: 5432
    user: "system"
    password: "passw0rd"
    database: "promenade_dev"

bus:
  adapter: "memory"  # fast in-process event bus

9. What's Next?

Learn the Architecture

Explore Contexts

API Reference


Common Issues

PostgreSQL Connection Failed

bash
# Check if PostgreSQL is running
make docker-ps

# Restart PostgreSQL
make docker-down && make docker-up

Port 8081 Already in Use

bash
# Find process using port
lsof -i :8081

# Kill process
kill -9 <PID>

# Or use different port
SERVER_PORT=8082 ./bin/promenade

Migration Errors

bash
# Check migration status
make migrate-status

# Reset database (WARNING: destructive!)
make db-fresh

JWT Token Expired

bash
# Use refresh token to get new access token
curl -X POST http://localhost:8081/api/v1/identity/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{"refresh_token":"YOUR_REFRESH_TOKEN"}'

Make Commands Reference

bash
# Development
make dev               # Full dev environment (Docker + migrations + API)
make dev-fresh         # Fresh start with clean database
make build             # Build binary
make run               # Build and run
make fmt               # Format code
make lint              # Run linters

# Testing
make test              # All tests (~40s)
make test-unit         # Unit tests (~5s)
make test-smoke        # Smoke tests (~0.4s)
make test-integration  # Integration tests (~6s)
make test-coverage     # HTML coverage report

# Database
make docker-up         # Start PostgreSQL
make docker-down       # Stop PostgreSQL
make docker-ps         # Show running containers
make migrate           # Run all migrations
make db-reset          # Drop and recreate database
make db-fresh          # Fresh database with migrations

# Documentation
make swagger-all       # Generate API documentation

Success!

You now have Promenade running locally with:

  • PostgreSQL database with all migrations
  • API server on http://localhost:8081
  • User registration and authentication
  • Profile and contact management
  • Reference data (countries, currencies, etc.)

Next Steps:

  1. Explore the API Reference for all available endpoints
  2. Read the Architecture Guide to understand DDD principles
  3. Check out Testing Strategy to write your own tests
  4. See RBAC Guide for authorization patterns

Happy coding!

Built with Domain-Driven Design and Go