Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,32 @@ docker compose up -d db clickhouse redis
# Install dependencies
pnpm install

# Log in to Infisical (see "Secrets" section below), then run with secrets:
infisical run --env=prod -- pnpm migrate
# Configure local-only env vars (gitignored). Connection strings live here
# rather than .env because they target your Docker host.
cat > .env.local <<'EOF'
CLICKHOUSE_URL=http://default:health@localhost:8123
REDIS_URL=redis://localhost:6379
POSTGRES_PASSWORD=health
CLICKHOUSE_PASSWORD=health
EOF

# Log in to Infisical (see "Secrets" section below) and store the credential
# encryption key — required for boot, see "Credential encryption at rest":
infisical secrets set --env=prod \
CREDENTIAL_ENCRYPTION_KEY_BASE64=$(openssl rand -base64 32)

# Apply Postgres + ClickHouse migrations (idempotent — safe to re-run):
infisical run --env=prod -- pnpm setup-db

# Optional: run a one-shot sync if you have provider credentials configured.
infisical run --env=prod -- pnpm sync
```

`pnpm setup-db` is the canonical fresh-DB bootstrap and matches what
`entrypoint.sh migrate` runs in production: it applies SQL files in `drizzle/`
to Postgres, then runs the ClickHouse-side migrations. Use `pnpm migrate`
(drizzle-kit) only for incremental schema work after a `pnpm generate`.

## Adding a Provider

See [docs/adding-a-provider.md](docs/adding-a-provider.md).
Expand Down Expand Up @@ -114,10 +135,19 @@ The server imports shared code from the root package via `dofek` workspace depen
## Development

```bash
docker compose up -d db clickhouse redis # required for integration tests, projections, and local workers
# Optional local CDC stack (required for real-time Postgres -> ClickHouse metric_stream replication)
# Postgres + ClickHouse + Redis (required for any dev workflow)
docker compose up -d db clickhouse redis

# PeerDB CDC stack — required for the API server, since its boot path waits
# for postgres_fitness.metric_stream and analytics views in ClickHouse.
docker compose -f docker-compose.yml -f docker-compose.peerdb.yml up -d
pnpm clickhouse-cdc # configure PeerDB CDC mirror for peerdb.metric_stream
# (The peerdb-temporal-init container auto-registers the MirrorName Temporal
# search attribute that PeerDB workflows depend on. It exits after running.)

# Apply Postgres + ClickHouse migrations to a fresh DB (idempotent).
pnpm setup-db
# Configure the PeerDB metric_stream mirror (postgres_fitness.metric_stream).
pnpm clickhouse-cdc

pnpm test # run tests
pnpm test:watch # run tests in watch mode
Expand Down
32 changes: 28 additions & 4 deletions docker-compose.peerdb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ services:
POSTGRES_USER: postgres
POSTGRES_PWD: ${POSTGRES_PASSWORD:-health}
POSTGRES_SEEDS: peerdb-catalog
DYNAMIC_CONFIG_FILE_PATH: config/dynamicconfig/development-sql.yaml
DYNAMIC_CONFIG_FILE_PATH: config/dynamicconfig/docker.yaml
TEMPORAL_BROADCAST_HOST: "127.0.0.1"
restart: unless-stopped
depends_on:
peerdb-catalog:
condition: service_healthy
healthcheck:
test: ["CMD", "tctl", "--address", "127.0.0.1:7233", "workflow", "list"]
# tctl honors TEMPORAL_CLI_ADDRESS; use the service hostname rather than
# 127.0.0.1 since Temporal does not bind loopback inside the container.
test: ["CMD", "tctl", "--address", "peerdb-temporal:7233", "workflow", "list"]
interval: 10s
timeout: 10s
retries: 12
Expand All @@ -44,11 +46,31 @@ services:
TEMPORAL_CLI_ADDRESS: peerdb-temporal:7233
TEMPORAL_CLI_SHOW_STACKS: "1"

# Registers the MirrorName search attribute that PeerDB workflows require.
# Runs once after Temporal is healthy, then exits.
peerdb-temporal-init:
image: temporalio/admin-tools:1.29
environment:
TEMPORAL_ADDRESS: peerdb-temporal:7233
TEMPORAL_CLI_ADDRESS: peerdb-temporal:7233
depends_on:
peerdb-temporal:
condition: service_healthy
restart: "no"
entrypoint: /bin/sh
command:
- -c
- |
printf 'Y\n' | tctl admin cluster add-search-attributes \
--name MirrorName --type Keyword || true

peerdb-minio:
image: minio/minio:latest@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
environment:
MINIO_ROOT_USER: peerdb
MINIO_ROOT_PASSWORD: ${POSTGRES_PASSWORD:-health}
# MinIO requires a root password of at least 8 characters; do not reuse
# POSTGRES_PASSWORD here since the local default ("health") is too short.
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-peerdblocaldev}
PEERDB_CLICKHOUSE_AWS_S3_BUCKET_NAME: peerdbbucket
volumes:
- peerdb_minio_data:/data
Expand Down Expand Up @@ -83,7 +105,7 @@ services:
PEERDB_TEMPORAL_NAMESPACE: default
PEERDB_ALLOWED_TARGETS: ""
PEERDB_CLICKHOUSE_AWS_CREDENTIALS_AWS_ACCESS_KEY_ID: peerdb
PEERDB_CLICKHOUSE_AWS_CREDENTIALS_AWS_SECRET_ACCESS_KEY: ${POSTGRES_PASSWORD:-health}
PEERDB_CLICKHOUSE_AWS_CREDENTIALS_AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD:-peerdblocaldev}
PEERDB_CLICKHOUSE_AWS_CREDENTIALS_AWS_REGION: us-east-1
PEERDB_CLICKHOUSE_AWS_CREDENTIALS_AWS_ENDPOINT_URL_S3: http://peerdb-minio:9000
PEERDB_CLICKHOUSE_AWS_S3_BUCKET_NAME: peerdbbucket
Expand All @@ -97,6 +119,8 @@ services:
condition: service_healthy
peerdb-temporal:
condition: service_started
peerdb-temporal-init:
condition: service_completed_successfully
peerdb-minio:
condition: service_started

Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ services:
redis:
image: redis:7-alpine
restart: unless-stopped
ports:
- "127.0.0.1:${REDIS_PORT:-6379}:6379"
volumes:
- redis_data:/data
healthcheck:
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"sync": "./scripts/with-env.sh tsx src/index.ts sync",
"auth": "./scripts/with-env.sh tsx src/index.ts auth",
"migrate": "./scripts/with-env.sh drizzle-kit migrate && tsx scripts/generate-schema-diagram.ts",
"setup-db": "./scripts/with-env.sh tsx src/db/run-migrate.ts",
"seed": "tsx scripts/seed-dev-db.ts",
"generate": "drizzle-kit generate && tsx scripts/generate-schema-diagram.ts",
"schema:diagram": "tsx scripts/generate-schema-diagram.ts",
Expand Down
Loading