diff options
| author | Chia <Chia@93.nz> | 2026-08-06 09:29:41 +1200 |
|---|---|---|
| committer | Chia <Chia@93.nz> | 2026-08-06 09:32:46 +1200 |
| commit | 41e322c53d7b4b796eb377d0df9c29ecd10ba431 (patch) | |
| tree | c730526150e55e39b822d5197e4a20318ecaa449 /scripts/start-debug.sh | |
| parent | eadb2ffe85c43cf6fc741c9823cd28eedb4a844c (diff) | |
feat: complete commercial control plane, billing, auth, and model catalog
- add PostgreSQL control-plane persistence with Redis-degraded hot reload
- implement prepaid balance, usage ledger, Stripe top-up and reconciliation
- add registration, email verification, password reset, invitations and RBAC
- support TOTP, Passkey MFA, device sessions, quotas and rate limits
- add tenant billing profiles, audit logs and operational readiness checks
- build authenticated admin console, Quickstart, Playground and usage analytics
- add public model catalog with pricing, filtering and cost estimation
- support OpenAI Responses providers and provider health failover
- validate real upstream usage reporting and balance settlement
Diffstat (limited to '')
| -rwxr-xr-x | scripts/start-debug.sh | 97 |
1 files changed, 18 insertions, 79 deletions
diff --git a/scripts/start-debug.sh b/scripts/start-debug.sh index bf18de5..80db5de 100755 --- a/scripts/start-debug.sh +++ b/scripts/start-debug.sh @@ -22,104 +22,43 @@ if [[ ! -f "$env_file" ]]; then command -v openssl >/dev/null 2>&1 || fail "openssl is required to generate local credentials" credential_key="$(openssl rand -base64 32 | tr -d '\n')" admin_token="aigw-admin-$(openssl rand -hex 24)" - postgres_password="$(openssl rand -hex 24)" umask 077 { - printf 'AIGW_SERVER_ADDRESS=:8080\n' - printf 'AIGW_PUBLIC_ADDRESS=:8080\n' - printf 'AIGW_ADMIN_ADDRESS=:8081\n' - printf 'AIGW_WEBHOOK_ADDRESS=:8082\n' - printf 'AIGW_OPERATIONS_ADDRESS=:9090\n' - printf 'AIGW_TRUSTED_PROXY_CIDRS=\n' - printf 'AIGW_REQUIRE_HTTPS=false\n' - printf 'AIGW_DEPLOYMENT_REGION=\n' - printf 'AIGW_POSTGRES_USER=aigw\n' - printf 'AIGW_POSTGRES_PASSWORD=%s\n' "$postgres_password" - printf 'AIGW_POSTGRES_DB=aigw\n' - printf 'AIGW_DATABASE_URL=postgres://aigw:%s@127.0.0.1:5432/aigw?sslmode=disable\n' "$postgres_password" - printf 'AIGW_DATABASE_URL_DOCKER=postgres://aigw:%s@postgres:5432/aigw?sslmode=disable\n' "$postgres_password" - printf 'AIGW_REDIS_URL=redis://127.0.0.1:6379/0\n' - printf 'AIGW_REDIS_URL_DOCKER=redis://redis:6379/0\n' printf 'AIGW_CREDENTIAL_KEY=%s\n' "$credential_key" - printf 'AIGW_CREDENTIAL_PREVIOUS_KEYS=\n' printf 'AIGW_ADMIN_TOKEN=%s\n' "$admin_token" - printf 'AIGW_PUBLIC_URL=http://localhost:8081/admin/\n' - printf 'AIGW_WEBAUTHN_RP_ID=localhost\n' - printf 'AIGW_WEBAUTHN_ORIGINS=http://localhost:8081\n' - printf 'AIGW_SMTP_FROM_ADDRESS=no-reply@aigw.local\n' - printf 'AIGW_SMTP_ADDRESS=127.0.0.1:1025\n' - printf 'AIGW_SMTP_ADDRESS_DOCKER=mailpit:1025\n' - printf 'AIGW_SMTP_USERNAME=\n' - printf 'AIGW_SMTP_PASSWORD=\n' - printf 'AIGW_STRIPE_API_KEY=rk_test_replace_me\n' - printf 'AIGW_STRIPE_CLI_API_KEY=rk_test_replace_me\n' - printf 'AIGW_STRIPE_WEBHOOK_SECRET=whsec_replace_me\n' - printf 'AIGW_STRIPE_SUCCESS_URL=http://localhost:8081/admin/?topup=success\n' - printf 'AIGW_STRIPE_CANCEL_URL=http://localhost:8081/admin/?topup=cancel\n' - printf 'AIGW_STRIPE_PORTAL_RETURN_URL=http://localhost:8081/admin/?billing=portal\n' - printf 'AIGW_STRIPE_AUTOMATIC_TAX_ENABLED=false\n' - printf 'AIGW_STRIPE_TAX_REGISTRATION_CONFIRMED=false\n' - printf 'AIGW_STRIPE_PRODUCT_TAX_CODE=\n' - printf 'AIGW_SETTLEMENT_SPOOL_PATH=/var/lib/aigw/settlements.jsonl\n' } >"$env_file" chmod 600 "$env_file" log "created $env_file" fi -# Backfill non-secret deployment settings when an older local environment file -# is reused. Exact legacy localhost values are moved to the split admin port. -sed -i \ - -e 's|^AIGW_PUBLIC_URL=http://localhost:8080/admin/$|AIGW_PUBLIC_URL=http://localhost:8081/admin/|' \ - -e 's|^AIGW_WEBAUTHN_ORIGINS=http://localhost:8080$|AIGW_WEBAUTHN_ORIGINS=http://localhost:8081|' \ - -e 's|^AIGW_STRIPE_SUCCESS_URL=http://localhost:8080/admin/?topup=success$|AIGW_STRIPE_SUCCESS_URL=http://localhost:8081/admin/?topup=success|' \ - -e 's|^AIGW_STRIPE_CANCEL_URL=http://localhost:8080/admin/?topup=cancel$|AIGW_STRIPE_CANCEL_URL=http://localhost:8081/admin/?topup=cancel|' \ - "$env_file" -for setting in \ - 'AIGW_PUBLIC_ADDRESS=:8080' \ - 'AIGW_ADMIN_ADDRESS=:8081' \ - 'AIGW_WEBHOOK_ADDRESS=:8082' \ - 'AIGW_OPERATIONS_ADDRESS=:9090' \ - 'AIGW_STRIPE_PORTAL_RETURN_URL=http://localhost:8081/admin/?billing=portal' \ - 'AIGW_SETTLEMENT_SPOOL_PATH=/var/lib/aigw/settlements.jsonl'; do - name="${setting%%=*}" - grep -q "^${name}=" "$env_file" || printf '%s\n' "$setting" >>"$env_file" +for required_name in AIGW_CREDENTIAL_KEY AIGW_ADMIN_TOKEN; do + grep -q "^${required_name}=." "$env_file" || fail "$required_name is missing from $env_file" done -admin_token="$(sed -n 's/^AIGW_ADMIN_TOKEN=//p' "$env_file" | head -n 1)" -[[ -n "$admin_token" ]] || fail "AIGW_ADMIN_TOKEN is missing from $env_file" -for required_name in AIGW_SERVER_ADDRESS AIGW_POSTGRES_USER AIGW_POSTGRES_PASSWORD AIGW_POSTGRES_DB AIGW_DATABASE_URL_DOCKER AIGW_CREDENTIAL_KEY AIGW_PUBLIC_URL AIGW_WEBAUTHN_RP_ID AIGW_WEBAUTHN_ORIGINS AIGW_SMTP_FROM_ADDRESS AIGW_SMTP_ADDRESS_DOCKER AIGW_STRIPE_API_KEY AIGW_STRIPE_WEBHOOK_SECRET AIGW_STRIPE_SUCCESS_URL AIGW_STRIPE_CANCEL_URL; do - grep -q "^${required_name}=." "$env_file" || fail "$required_name is missing from $env_file; compare it with .env.control.example" -done +compose=(docker compose --project-directory "$repo_dir") +if [[ -n "${AIGW_COMPOSE_PROJECT_NAME:-}" ]]; then + compose+=(--project-name "$AIGW_COMPOSE_PROJECT_NAME") +fi +compose+=(--env-file "$env_file") cd "$repo_dir" if [[ "${AIGW_DEBUG_SKIP_BUILD:-0}" == "1" ]]; then - log "skipping image build (AIGW_DEBUG_SKIP_BUILD=1)" + log "starting all services without rebuilding the gateway image" + up_args=(up -d --no-build --remove-orphans --wait --wait-timeout 120) else - build_network="${AIGW_DOCKER_BUILD_NETWORK:-host}" - log "building gateway image (network: $build_network)" - docker build --network="$build_network" -t aigw-debug:local . + log "building and starting all services" + up_args=(up -d --build --remove-orphans --wait --wait-timeout 120) fi -log "starting PostgreSQL, Redis, Mailpit, and gateway" -if ! docker compose --env-file "$env_file" up -d --no-build --wait --wait-timeout 120; then - docker compose --env-file "$env_file" ps >&2 || true - gateway_logs="$(docker compose --env-file "$env_file" logs --no-color --tail=120 aigw 2>&1 || true)" - printf '%s\n' "$gateway_logs" >&2 - if [[ "$gateway_logs" == *"decrypt credential"* ]]; then - printf '[aigw-debug] the AIGW_CREDENTIAL_KEY in %s does not match credentials already stored in the PostgreSQL volume\n' "$env_file" >&2 - printf '[aigw-debug] restore the previous key, or explicitly remove the debug volumes if the stored control-plane data is disposable\n' >&2 - fi +if ! "${compose[@]}" "${up_args[@]}"; then + "${compose[@]}" ps >&2 || true + "${compose[@]}" logs --no-color --tail=120 aigw >&2 || true fail "services did not become healthy" fi -log "services are ready" -printf '\nAdmin UI: http://localhost:8081/admin/\n' -printf 'Mail inbox: http://127.0.0.1:8025/\n' -printf 'Health: http://127.0.0.1:9090/readyz\n' +log "all services are ready" +printf '\nAdmin UI: http://127.0.0.1:8080/admin/\n' +printf 'Health: http://127.0.0.1:8080/readyz\n' printf 'Secrets: %s (mode 0600)\n' "$env_file" -printf '\nLogs: docker compose --env-file %q logs -f aigw\n' "$env_file" +printf '\nLogs: docker compose --project-directory %q --env-file %q logs -f\n' "$repo_dir" "$env_file" printf 'Stop: ./scripts/stop-debug.sh\n' - -if grep -q '^AIGW_STRIPE_API_KEY=rk_test_replace_me$' "$env_file" 2>/dev/null; then - printf '\nStripe uses placeholders. Replace the two Stripe values in %s before testing Checkout.\n' "$env_file" -fi |
