A community based topic aggregation platform built on atproto

feat(infra): add local PLC directory for E2E testing

Add Docker Compose profile for running a local PLC directory server,
enabling E2E tests without polluting production plc.directory.

Changes:
- Add postgres-plc service (port 5436) for PLC directory database
- Add plc-directory service (port 3002) running did-method-plc
- Add 'plc' profile for optional PLC directory startup
- Update Makefile with PLC directory targets

Usage:
docker-compose --profile plc up postgres-plc plc-directory
PLC_DIRECTORY_URL=http://localhost:3002 go test ./tests/integration/...

Benefits:
- Isolated dev environment for DID registration testing
- No pollution of production PLC directory
- Faster E2E tests (no external network calls)
- Enables testing of full community provisioning flow locally

This supports V2.0 architecture where communities get PDS-managed DIDs
that should be registered with a PLC directory.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

+6 -4
Makefile
···
##@ Local Development (All-in-One)
-
dev-up: ## Start PDS + PostgreSQL + Jetstream for local development
@echo "$(GREEN)Starting Coves development stack...$(RESET)"
-
@docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile jetstream up -d postgres pds jetstream
@echo ""
@echo "$(GREEN)✓ Development stack started!$(RESET)"
@echo ""
@echo "Services available at:"
-
@echo " - PostgreSQL: localhost:5433"
@echo " - PDS (XRPC): http://localhost:3001"
@echo " - PDS Firehose: ws://localhost:3001/xrpc/com.atproto.sync.subscribeRepos"
@echo " - Jetstream: ws://localhost:6008/subscribe $(CYAN)(Read-Forward)$(RESET)"
@echo " - Jetstream Metrics: http://localhost:6009/metrics"
@echo ""
@echo "$(CYAN)Next steps:$(RESET)"
@echo " 1. Run: make run (starts AppView)"
@echo " 2. AppView will auto-index users from Jetstream"
@echo ""
@echo "Run 'make dev-logs' to view logs"
dev-down: ## Stop all development services
···
@echo "$(CYAN)========================================$(RESET)"
@echo ""
@echo "$(CYAN)Prerequisites:$(RESET)"
-
@echo " 1. Run 'make dev-up' (if not already running)"
@echo " 2. Run 'make run' in another terminal (AppView must be running)"
@echo ""
@echo "$(GREEN)Running E2E tests...$(RESET)"
···
##@ Local Development (All-in-One)
+
dev-up: ## Start PDS + PostgreSQL + Jetstream + PLC Directory for local development
@echo "$(GREEN)Starting Coves development stack...$(RESET)"
+
@docker-compose -f docker-compose.dev.yml --env-file .env.dev --profile jetstream --profile plc up -d postgres postgres-plc plc-directory pds jetstream
@echo ""
@echo "$(GREEN)✓ Development stack started!$(RESET)"
@echo ""
@echo "Services available at:"
+
@echo " - PostgreSQL: localhost:5435"
@echo " - PDS (XRPC): http://localhost:3001"
@echo " - PDS Firehose: ws://localhost:3001/xrpc/com.atproto.sync.subscribeRepos"
@echo " - Jetstream: ws://localhost:6008/subscribe $(CYAN)(Read-Forward)$(RESET)"
@echo " - Jetstream Metrics: http://localhost:6009/metrics"
+
@echo " - PLC Directory: http://localhost:3002 $(CYAN)(Local DID registry)$(RESET)"
@echo ""
@echo "$(CYAN)Next steps:$(RESET)"
@echo " 1. Run: make run (starts AppView)"
@echo " 2. AppView will auto-index users from Jetstream"
@echo ""
+
@echo "$(CYAN)Note:$(RESET) Using local PLC directory - DIDs registered locally (won't pollute plc.directory)"
@echo "Run 'make dev-logs' to view logs"
dev-down: ## Stop all development services
···
@echo "$(CYAN)========================================$(RESET)"
@echo ""
@echo "$(CYAN)Prerequisites:$(RESET)"
+
@echo " 1. Run 'make dev-up' (starts PDS + Jetstream)"
@echo " 2. Run 'make run' in another terminal (AppView must be running)"
@echo ""
@echo "$(GREEN)Running E2E tests...$(RESET)"
+86
docker-compose.dev.yml
···
profiles:
- jetstream
# Indigo Relay (BigSky) - OPTIONAL for local dev
# WARNING: BigSky is designed to crawl the entire atProto network!
# For local dev, consider using direct PDS firehose instead (see AppView config below)
···
name: coves-dev-postgres-data
postgres-test-data:
name: coves-test-postgres-data
pds-data:
name: coves-dev-pds-data
jetstream-data:
name: coves-dev-jetstream-data
···
profiles:
- jetstream
+
# PostgreSQL Database for PLC Directory (Port 5436)
+
# Separate database for local PLC directory to avoid conflicts
+
postgres-plc:
+
image: postgres:15
+
container_name: coves-dev-postgres-plc
+
ports:
+
- "5436:5432"
+
environment:
+
POSTGRES_DB: plc_dev
+
POSTGRES_USER: plc_user
+
POSTGRES_PASSWORD: plc_password
+
volumes:
+
- postgres-plc-data:/var/lib/postgresql/data
+
networks:
+
- coves-dev
+
healthcheck:
+
test: ["CMD-SHELL", "pg_isready -U plc_user -d plc_dev"]
+
interval: 5s
+
timeout: 5s
+
retries: 5
+
profiles:
+
- plc
+
+
# Local PLC Directory - For E2E testing without polluting production plc.directory
+
# This allows dev mode DID registration for testing community provisioning
+
#
+
# Usage:
+
# docker-compose --profile plc up postgres-plc plc-directory
+
# Or with all services: docker-compose --profile jetstream --profile plc up
+
#
+
# Configuration in your tests:
+
# PLC_DIRECTORY_URL=http://localhost:3002
+
# IS_DEV_ENV=false # Use production mode but point to local PLC
+
plc-directory:
+
image: node:18-alpine
+
container_name: coves-dev-plc
+
ports:
+
- "3002:3000" # PLC directory API
+
working_dir: /app
+
command: >
+
sh -c "
+
if [ ! -d '/app/.git' ]; then
+
echo 'First run: Installing PLC directory...' &&
+
apk add --no-cache git python3 make g++ yarn &&
+
git clone https://github.com/did-method-plc/did-method-plc.git . &&
+
yarn install --frozen-lockfile &&
+
yarn build &&
+
echo 'PLC directory installed successfully!'
+
fi &&
+
cd packages/server &&
+
yarn start
+
"
+
environment:
+
# Point to dedicated PLC PostgreSQL database
+
DATABASE_URL: postgresql://plc_user:plc_password@postgres-plc:5432/plc_dev?sslmode=disable
+
+
# Development settings
+
DEBUG_MODE: "1"
+
LOG_ENABLED: "true"
+
LOG_LEVEL: debug
+
LOG_DESTINATION: "1"
+
NODE_ENV: development
+
+
# API configuration
+
PORT: 3000
+
volumes:
+
# Persist the PLC repo so we don't rebuild every time
+
- plc-app-data:/app
+
networks:
+
- coves-dev
+
depends_on:
+
postgres-plc:
+
condition: service_healthy
+
healthcheck:
+
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/"]
+
interval: 10s
+
timeout: 5s
+
retries: 10
+
start_period: 120s
+
profiles:
+
- plc
+
# Indigo Relay (BigSky) - OPTIONAL for local dev
# WARNING: BigSky is designed to crawl the entire atProto network!
# For local dev, consider using direct PDS firehose instead (see AppView config below)
···
name: coves-dev-postgres-data
postgres-test-data:
name: coves-test-postgres-data
+
postgres-plc-data:
+
name: coves-dev-postgres-plc-data
pds-data:
name: coves-dev-pds-data
jetstream-data:
name: coves-dev-jetstream-data
+
plc-app-data:
+
name: coves-dev-plc-app-data