A community based topic aggregation platform built on atproto
1.PHONY: help dev-up dev-up-otel dev-down dev-logs dev-status dev-reset test test-all e2e-test clean verify-stack create-test-account mobile-full-setup
2
3# Default target - show help
4.DEFAULT_GOAL := help
5
6# Colors for output
7CYAN := \033[36m
8RESET := \033[0m
9GREEN := \033[32m
10YELLOW := \033[33m
11RED := \033[31m
12
13# Load test database configuration from .env.dev
14include .env.dev
15export
16
17##@ General
18
19help: ## Show this help message
20 @echo ""
21 @echo "$(CYAN)Coves Development Commands$(RESET)"
22 @echo ""
23 @awk 'BEGIN {FS = ":.*##"; printf "Usage: make $(CYAN)<target>$(RESET)\n"} \
24 /^[a-zA-Z_-]+:.*?##/ { printf " $(CYAN)%-15s$(RESET) %s\n", $$1, $$2 } \
25 /^##@/ { printf "\n$(YELLOW)%s$(RESET)\n", substr($$0, 5) }' $(MAKEFILE_LIST)
26 @echo ""
27
28##@ Local Development (All-in-One)
29
30dev-up: ## Start PDS + PostgreSQL + Jetstream + PLC Directory for local development
31 @echo "$(GREEN)Starting Coves development stack...$(RESET)"
32 @docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile jetstream --profile plc up -d postgres postgres-plc plc-directory pds jetstream
33 @echo ""
34 @echo "$(GREEN)✓ Development stack started!$(RESET)"
35 @echo ""
36 @echo "Services available at:"
37 @echo " - PostgreSQL: localhost:5435"
38 @echo " - PDS (XRPC): http://localhost:3001"
39 @echo " - PDS Firehose: ws://localhost:3001/xrpc/com.atproto.sync.subscribeRepos"
40 @echo " - Jetstream: ws://localhost:6008/subscribe $(CYAN)(Read-Forward)$(RESET)"
41 @echo " - Jetstream Metrics: http://localhost:6009/metrics"
42 @echo " - PLC Directory: http://localhost:3002 $(CYAN)(Local DID registry)$(RESET)"
43 @echo ""
44 @echo "$(CYAN)Next steps:$(RESET)"
45 @echo " 1. Run: make run (starts AppView)"
46 @echo " 2. AppView will auto-index users from Jetstream"
47 @echo ""
48 @echo "$(CYAN)Optional:$(RESET) Run 'make dev-up-otel' to add Jaeger for tracing"
49 @echo "$(CYAN)Note:$(RESET) Using local PLC directory - DIDs registered locally (won't pollute plc.directory)"
50 @echo "Run 'make dev-logs' to view logs"
51
52dev-up-otel: ## Start dev stack + Jaeger for OpenTelemetry tracing
53 @echo "$(GREEN)Starting Coves development stack with OpenTelemetry...$(RESET)"
54 @docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile jetstream --profile plc --profile observability up -d postgres postgres-plc plc-directory pds jetstream jaeger
55 @echo ""
56 @echo "$(GREEN)✓ Development stack with tracing started!$(RESET)"
57 @echo ""
58 @echo "Services available at:"
59 @echo " - PostgreSQL: localhost:5435"
60 @echo " - PDS (XRPC): http://localhost:3001"
61 @echo " - Jetstream: ws://localhost:6008/subscribe"
62 @echo " - PLC Directory: http://localhost:3002"
63 @echo " - $(CYAN)Jaeger UI: http://localhost:16686$(RESET) $(CYAN)(Trace viewer)$(RESET)"
64 @echo " - $(CYAN)OTLP Collector: localhost:4317$(RESET) $(CYAN)(gRPC endpoint)$(RESET)"
65 @echo ""
66 @echo "$(CYAN)To enable tracing in AppView:$(RESET)"
67 @echo " export OTEL_ENABLED=true"
68 @echo " export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317"
69 @echo " export OTEL_EXPORTER_OTLP_INSECURE=true"
70 @echo " make run"
71
72dev-down: ## Stop all development services (including Jaeger if running)
73 @echo "$(YELLOW)Stopping Coves development stack...$(RESET)"
74 @docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile jetstream --profile plc --profile observability --profile test down --remove-orphans
75 @docker network rm coves-dev-network 2>/dev/null || true
76 @echo "$(GREEN)✓ Development stack stopped$(RESET)"
77
78dev-logs: ## Tail logs from all development services
79 @docker-compose -f docker-compose.dev.yml --env-file .env.dev logs -f
80
81dev-status: ## Show status of all development containers
82 @echo "$(CYAN)Development Stack Status:$(RESET)"
83 @docker-compose -f docker-compose.dev.yml --env-file .env.dev ps
84
85dev-reset: ## Nuclear option - stop everything and remove all volumes
86 @echo "$(YELLOW)⚠️ WARNING: This will delete ALL data (PostgreSQL + PDS)!$(RESET)"
87 @read -p "Are you sure? (y/N): " confirm && [ "$$confirm" = "y" ] || exit 1
88 @echo "$(YELLOW)Stopping and removing containers and volumes...$(RESET)"
89 @docker-compose -f docker-compose.dev.yml --env-file .env.dev down -v
90 @echo "$(GREEN)✓ Reset complete - all data removed$(RESET)"
91 @echo "Run 'make dev-up' to start fresh"
92
93##@ Database Management
94
95db-shell: ## Open PostgreSQL shell for development database
96 @echo "$(CYAN)Connecting to development database...$(RESET)"
97 @docker exec -it coves-dev-postgres psql -U dev_user -d coves_dev
98
99db-migrate: ## Run database migrations
100 @echo "$(GREEN)Running database migrations...$(RESET)"
101 @goose -dir internal/db/migrations postgres "postgresql://dev_user:dev_password@localhost:5435/coves_dev?sslmode=disable" up
102 @echo "$(GREEN)✓ Migrations complete$(RESET)"
103
104db-migrate-down: ## Rollback last migration
105 @echo "$(YELLOW)Rolling back last migration...$(RESET)"
106 @goose -dir internal/db/migrations postgres "postgresql://dev_user:dev_password@localhost:5435/coves_dev?sslmode=disable" down
107 @echo "$(GREEN)✓ Rollback complete$(RESET)"
108
109db-reset: ## Reset database (delete all data and re-run migrations)
110 @echo "$(YELLOW)⚠️ WARNING: This will delete all database data!$(RESET)"
111 @read -p "Are you sure? (y/N): " confirm && [ "$$confirm" = "y" ] || exit 1
112 @echo "$(YELLOW)Resetting database...$(RESET)"
113 @docker-compose -f docker-compose.dev.yml --env-file .env.dev rm -sf postgres
114 @docker volume rm coves-dev-postgres-data || true
115 @docker-compose -f docker-compose.dev.yml --env-file .env.dev up -d postgres
116 @echo "Waiting for PostgreSQL to be ready..."
117 @sleep 3
118 @make db-migrate
119 @echo "$(GREEN)✓ Database reset complete$(RESET)"
120
121##@ Testing
122
123test: ## Run fast unit/integration tests (skips slow E2E tests)
124 @echo "$(GREEN)Starting test database...$(RESET)"
125 @docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile test up -d postgres-test
126 @echo "Waiting for test database to be ready..."
127 @sleep 3
128 @echo "$(GREEN)Running migrations on test database...$(RESET)"
129 @goose -dir internal/db/migrations postgres "postgresql://$(POSTGRES_TEST_USER):$(POSTGRES_TEST_PASSWORD)@localhost:$(POSTGRES_TEST_PORT)/$(POSTGRES_TEST_DB)?sslmode=disable" up || true
130 @echo "$(GREEN)Running fast tests (use 'make e2e-test' for E2E tests)...$(RESET)"
131 @go test ./cmd/... ./internal/... ./tests/... -short -v
132 @echo "$(GREEN)✓ Tests complete$(RESET)"
133
134e2e-test: ## Run automated E2E tests (requires: make dev-up + make run in another terminal)
135 @echo "$(CYAN)========================================$(RESET)"
136 @echo "$(CYAN) E2E Test: Full User Signup Flow $(RESET)"
137 @echo "$(CYAN)========================================$(RESET)"
138 @echo ""
139 @echo "$(CYAN)Prerequisites:$(RESET)"
140 @echo " 1. Run 'make dev-up' (starts PDS + Jetstream)"
141 @echo " 2. Run 'make run' in another terminal (AppView must be running)"
142 @echo ""
143 @echo "$(GREEN)Running E2E tests...$(RESET)"
144 @go test ./tests/e2e -run TestE2E_UserSignup -v
145 @echo ""
146 @echo "$(GREEN)✓ E2E tests complete!$(RESET)"
147
148e2e-vote-test: ## Run vote E2E tests (requires: make dev-up)
149 @echo "$(CYAN)========================================$(RESET)"
150 @echo "$(CYAN) E2E Test: Vote System $(RESET)"
151 @echo "$(CYAN)========================================$(RESET)"
152 @echo ""
153 @echo "$(CYAN)Prerequisites:$(RESET)"
154 @echo " 1. Run 'make dev-up' (starts PDS + Jetstream + PostgreSQL)"
155 @echo " 2. Test database will be used (port 5434)"
156 @echo ""
157 @echo "$(GREEN)Running vote E2E tests...$(RESET)"
158 @echo ""
159 @echo "$(CYAN)Running simulated E2E test (fast)...$(RESET)"
160 @go test ./tests/integration -run TestVote_E2E_WithJetstream -v
161 @echo ""
162 @echo "$(CYAN)Running live PDS E2E test (requires PDS + Jetstream)...$(RESET)"
163 @go test ./tests/integration -run TestVote_E2E_LivePDS -v || echo "$(YELLOW)Live PDS test skipped (run 'make dev-up' first)$(RESET)"
164 @echo ""
165 @echo "$(GREEN)✓ Vote E2E tests complete!$(RESET)"
166
167test-db-reset: ## Reset test database
168 @echo "$(GREEN)Resetting test database...$(RESET)"
169 @docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile test rm -sf postgres-test
170 @docker volume rm coves-test-postgres-data || true
171 @docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile test up -d postgres-test
172 @echo "Waiting for PostgreSQL to be ready..."
173 @sleep 3
174 @goose -dir internal/db/migrations postgres "postgresql://$(POSTGRES_TEST_USER):$(POSTGRES_TEST_PASSWORD)@localhost:$(POSTGRES_TEST_PORT)/$(POSTGRES_TEST_DB)?sslmode=disable" up || true
175 @echo "$(GREEN)✓ Test database reset$(RESET)"
176
177test-db-stop: ## Stop test database
178 @docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile test stop postgres-test
179 @echo "$(GREEN)✓ Test database stopped$(RESET)"
180
181test-all: ## Run ALL tests with live infrastructure (required before merge)
182 @echo ""
183 @echo "$(CYAN)═══════════════════════════════════════════════════════════════$(RESET)"
184 @echo "$(CYAN) FULL TEST SUITE - All tests with live infrastructure $(RESET)"
185 @echo "$(CYAN)═══════════════════════════════════════════════════════════════$(RESET)"
186 @echo ""
187 @echo "$(YELLOW)▶ Checking infrastructure...$(RESET)"
188 @echo ""
189 @# Check dev stack is running
190 @echo " Checking dev stack (PDS, Jetstream, PLC)..."
191 @docker-compose -f docker-compose.dev.yml --env-file .env.dev ps 2>/dev/null | grep -q "Up" || \
192 (echo "$(RED) ✗ Dev stack not running. Run 'make dev-up' first.$(RESET)" && exit 1)
193 @echo " $(GREEN)✓ Dev stack is running$(RESET)"
194 @# Check AppView is running
195 @echo " Checking AppView (port 8081)..."
196 @curl -sf http://127.0.0.1:8081/xrpc/_health >/dev/null 2>&1 || \
197 curl -sf http://127.0.0.1:8081/ >/dev/null 2>&1 || \
198 (echo "$(RED) ✗ AppView not running. Run 'make run' in another terminal.$(RESET)" && exit 1)
199 @echo " $(GREEN)✓ AppView is running$(RESET)"
200 @# Check test database
201 @echo " Checking test database (port 5434)..."
202 @docker-compose -f docker-compose.dev.yml --env-file .env.dev ps postgres-test 2>/dev/null | grep -q "Up" || \
203 (echo "$(YELLOW) ⚠ Test database not running, starting it...$(RESET)" && \
204 docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile test up -d postgres-test && \
205 sleep 3 && \
206 goose -dir internal/db/migrations postgres "postgresql://$(POSTGRES_TEST_USER):$(POSTGRES_TEST_PASSWORD)@localhost:$(POSTGRES_TEST_PORT)/$(POSTGRES_TEST_DB)?sslmode=disable" up)
207 @echo " $(GREEN)✓ Test database is running$(RESET)"
208 @echo ""
209 @echo "$(GREEN)▶ [1/3] Unit & Package Tests (./cmd/... ./internal/...)$(RESET)"
210 @echo "$(CYAN)───────────────────────────────────────────────────────────────$(RESET)"
211 @LOG_ENABLED=false go test ./cmd/... ./internal/... -timeout 120s
212 @echo ""
213 @echo "$(GREEN)▶ [2/3] Integration Tests (./tests/integration/...)$(RESET)"
214 @echo "$(CYAN)───────────────────────────────────────────────────────────────$(RESET)"
215 @LOG_ENABLED=false go test ./tests/integration/... -timeout 600s
216 @echo ""
217 @echo "$(GREEN)▶ [3/3] E2E Tests (./tests/e2e/...)$(RESET)"
218 @echo "$(CYAN)───────────────────────────────────────────────────────────────$(RESET)"
219 @LOG_ENABLED=false go test ./tests/e2e/... -timeout 180s
220 @echo ""
221 @echo "$(GREEN)═══════════════════════════════════════════════════════════════$(RESET)"
222 @echo "$(GREEN) ✓ ALL TESTS PASSED - Safe to merge $(RESET)"
223 @echo "$(GREEN)═══════════════════════════════════════════════════════════════$(RESET)"
224 @echo ""
225
226##@ Code Quality
227
228fmt: ## Format all Go code with gofmt
229 @echo "$(GREEN)Formatting Go code...$(RESET)"
230 @gofmt -w ./cmd ./internal ./tests
231 @echo "$(GREEN)✓ Formatting complete$(RESET)"
232
233fmt-check: ## Check if Go code is properly formatted
234 @echo "$(GREEN)Checking code formatting...$(RESET)"
235 @unformatted=$$(gofmt -l ./cmd ./internal ./tests); \
236 if [ -n "$$unformatted" ]; then \
237 echo "$(RED)✗ The following files are not formatted:$(RESET)"; \
238 echo "$$unformatted"; \
239 echo "$(YELLOW)Run 'make fmt' to fix$(RESET)"; \
240 exit 1; \
241 fi
242 @echo "$(GREEN)✓ All files are properly formatted$(RESET)"
243
244lint: fmt-check ## Run golangci-lint on the codebase (includes format check)
245 @echo "$(GREEN)Running linter...$(RESET)"
246 @golangci-lint run ./cmd/... ./internal/... ./tests/...
247 @echo "$(GREEN)✓ Linting complete$(RESET)"
248
249lint-fix: ## Run golangci-lint and auto-fix issues
250 @echo "$(GREEN)Running linter with auto-fix...$(RESET)"
251 @golangci-lint run --fix ./cmd/... ./internal/... ./tests/...
252 @gofmt -w ./cmd ./internal ./tests
253 @echo "$(GREEN)✓ Linting complete$(RESET)"
254
255##@ Build & Run
256
257build: ## Build the Coves server (production - no dev code)
258 @echo "$(GREEN)Building Coves server (production)...$(RESET)"
259 @go build -o server ./cmd/server
260 @echo "$(GREEN)✓ Build complete: ./server$(RESET)"
261
262build-dev: ## Build the Coves server with dev mode (includes localhost OAuth resolvers)
263 @echo "$(GREEN)Building Coves server (dev mode)...$(RESET)"
264 @go build -tags dev -o server ./cmd/server
265 @echo "$(GREEN)✓ Build complete: ./server (with dev tags)$(RESET)"
266
267run: ## Run the Coves server with dev environment (requires database running)
268 @make db-migrate
269 @./scripts/dev-run.sh
270
271##@ Cleanup
272
273clean: ## Clean build artifacts and temporary files
274 @echo "$(YELLOW)Cleaning build artifacts...$(RESET)"
275 @rm -f server main validate-lexicon
276 @go clean
277 @echo "$(GREEN)✓ Clean complete$(RESET)"
278
279clean-all: clean ## Clean everything including Docker volumes (DESTRUCTIVE)
280 @echo "$(YELLOW)⚠️ WARNING: This will remove ALL Docker volumes!$(RESET)"
281 @read -p "Are you sure? (y/N): " confirm && [ "$$confirm" = "y" ] || exit 1
282 @make dev-reset
283 @echo "$(GREEN)✓ All clean$(RESET)"
284
285##@ Workflows (Common Tasks)
286
287fresh-start: ## Complete fresh start (reset everything, start clean)
288 @echo "$(CYAN)Starting fresh development environment...$(RESET)"
289 @make dev-reset || true
290 @sleep 2
291 @make dev-up
292 @sleep 3
293 @make db-migrate
294 @echo ""
295 @echo "$(GREEN)✓ Fresh environment ready!$(RESET)"
296 @make dev-status
297
298quick-restart: ## Quick restart of development stack (keeps data)
299 @make dev-down
300 @make dev-up
301
302##@ Mobile Testing
303
304mobile-setup: ## Setup Android port forwarding for USB-connected devices (recommended)
305 @echo "$(CYAN)Setting up Android mobile testing environment...$(RESET)"
306 @./scripts/setup-mobile-ports.sh
307
308mobile-reset: ## Remove all Android port forwarding
309 @echo "$(YELLOW)Removing Android port forwarding...$(RESET)"
310 @adb reverse --remove-all || echo "$(YELLOW)No device connected$(RESET)"
311 @echo "$(GREEN)✓ Port forwarding removed$(RESET)"
312
313verify-stack: ## Verify local development stack (PLC, PDS, configs)
314 @./scripts/verify-local-stack.sh
315
316create-test-account: ## Create a test account on local PDS for OAuth testing
317 @./scripts/create-test-account.sh
318
319mobile-full-setup: verify-stack create-test-account mobile-setup ## Full mobile setup: verify stack, create account, setup ports
320 @echo ""
321 @echo "$(GREEN)═══════════════════════════════════════════════════════════$(RESET)"
322 @echo "$(GREEN) Mobile development environment ready! $(RESET)"
323 @echo "$(GREEN)═══════════════════════════════════════════════════════════$(RESET)"
324 @echo ""
325 @echo "$(CYAN)Run the Flutter app with:$(RESET)"
326 @echo " $(YELLOW)cd /home/bretton/Code/coves-mobile$(RESET)"
327 @echo " $(YELLOW)flutter run --dart-define=ENVIRONMENT=local$(RESET)"
328 @echo ""
329
330ngrok-up: ## Start ngrok tunnels (for iOS or WiFi testing - requires paid plan for 3 tunnels)
331 @echo "$(GREEN)Starting ngrok tunnels for mobile testing...$(RESET)"
332 @./scripts/start-ngrok.sh
333
334ngrok-down: ## Stop all ngrok tunnels
335 @./scripts/stop-ngrok.sh
336
337##@ Web Frontend Development
338
339run-web: ## Run Coves backend configured for web frontend dev (OAuth via :8080 proxy)
340 @make db-migrate
341 @./scripts/web-dev-run.sh
342
343web-proxy: ## Start Caddy reverse proxy for web frontend dev (combines Vite + Coves on :8080)
344 @echo "$(CYAN)Starting web development proxy...$(RESET)"
345 @echo ""
346 @echo "$(YELLOW)Prerequisites:$(RESET)"
347 @echo " 1. Coves backend running on :8081 (make run)"
348 @echo " 2. Vite frontend running on :5173 (cd frontend && npm run dev)"
349 @echo ""
350 @command -v caddy >/dev/null 2>&1 || { echo "$(RED)Error: Caddy not installed. Install with:$(RESET)"; \
351 echo " Ubuntu/Debian: sudo apt install caddy"; \
352 echo " macOS: brew install caddy"; \
353 echo " Or see: https://caddyserver.com/docs/install"; \
354 exit 1; }
355 @echo "$(GREEN)Starting Caddy on http://localhost:8080$(RESET)"
356 @echo " Backend routes (/oauth/*, /xrpc/*, /api/*) -> 127.0.0.1:8081"
357 @echo " Frontend routes (everything else) -> localhost:5173"
358 @echo ""
359 @echo "$(CYAN)Access your app at: http://localhost:8080$(RESET)"
360 @echo "$(CYAN)Press Ctrl+C to stop$(RESET)"
361 @echo ""
362 @caddy run --config Caddyfile.dev
363
364web-proxy-bg: ## Start Caddy proxy in background
365 @command -v caddy >/dev/null 2>&1 || { echo "$(RED)Error: Caddy not installed$(RESET)"; exit 1; }
366 @caddy start --config Caddyfile.dev
367 @echo "$(GREEN)✓ Caddy proxy started in background on http://localhost:8080$(RESET)"
368
369web-proxy-stop: ## Stop background Caddy proxy
370 @caddy stop 2>/dev/null || echo "$(YELLOW)Caddy not running$(RESET)"
371 @echo "$(GREEN)✓ Caddy proxy stopped$(RESET)"
372
373##@ Utilities
374
375validate-lexicon: ## Validate all Lexicon schemas
376 @echo "$(GREEN)Validating Lexicon schemas...$(RESET)"
377 @./validate-lexicon
378 @echo "$(GREEN)✓ Lexicon validation complete$(RESET)"
379
380##@ Documentation
381
382docs: ## Open project documentation
383 @echo "$(CYAN)Project Documentation:$(RESET)"
384 @echo " - Setup Guide: docs/LOCAL_DEVELOPMENT.md"
385 @echo " - Project Structure: PROJECT_STRUCTURE.md"
386 @echo " - Build Guide: CLAUDE.md"
387 @echo " - atProto Guide: ATPROTO_GUIDE.md"
388 @echo " - PRD: PRD.md"