06-Operations / 06.01.API-Operations

06.01.API Operations

06.01. API Operations

This document describes operational commands for deploying and testing the Car Pulse Tracker API.

Tesla Report Module Logging

Charging Invoice Export

Charging invoice export is intentionally separate from the main vehicle report/PDF flow.

Current API foundation: - GET /api/v1/tesla/session/{id}/vehicles/{vin}/charging-invoices - returns charging-session invoice metadata and summary totals - default window is the last 24 months - response should be suitable for rendering individual invoice links in the UI - GET /api/v1/tesla/session/{id}/vehicles/{vin}/charging-invoices/{invoice_id} - proxies a single Tesla charging invoice PDF download - intended for per-invoice links from the charging summary view - GET /api/v1/tesla/session/{id}/vehicles/{vin}/charging-invoices.zip - streams a ZIP archive of separate Tesla invoice PDFs for the same VIN/window - default window is the last 24 months - archive is built in memory and not persisted after the response

Design rules: - Main report/PDF shows charging summary, totals, and invoice availability, not the full invoice archive. - Individual invoice PDF links are valid and should be exposed when invoice metadata exists. - ZIP export is the bulk-download convenience path for the same VIN-scoped invoice set. - Invoice PDFs should be fetched on demand, not eagerly during report generation. - Invoice export window is capped at 24 months to keep payloads and exports bounded. - Vehicle scoping must happen before invoice/export data is attached to a vehicle report. - ZIP export must be VIN-scoped only; no cross-vehicle invoice mixing is allowed. - ZIP filename uses a sanitized short vehicle label plus VIN suffix and date window metadata.

Production URLs

Environment API Base URL Swagger UI ReDoc
inf https://inf.api.carpulsetracker.com https://inf.api.carpulsetracker.com/docs https://inf.api.carpulsetracker.com/redoc
dev https://dev.api.carpulsetracker.com https://dev.api.carpulsetracker.com/docs https://dev.api.carpulsetracker.com/redoc
tst https://tst.api.carpulsetracker.com https://tst.api.carpulsetracker.com/docs https://tst.api.carpulsetracker.com/redoc
prd https://api.carpulsetracker.com https://api.carpulsetracker.com/docs https://api.carpulsetracker.com/redoc
prd (alias) https://prd.api.carpulsetracker.com https://prd.api.carpulsetracker.com/docs https://prd.api.carpulsetracker.com/redoc

GitHub Actions CD Workflow

The API is deployed via GitHub Actions when code is pushed to the main branch.

Trigger Deployment

# Deploy to a single environment
gh workflow run ci.yaml -f environment=dev --repo csitea/bnc-cpt-api

# Deploy to all environments
for env in inf dev tst prd; do
  echo "=== Deploying to $env ==="
  gh workflow run ci.yaml -f environment=$env --repo csitea/bnc-cpt-api
  sleep 30
done

Monitor Deployment

# List recent workflow runs
gh run list --workflow=ci.yaml --repo csitea/bnc-cpt-api

# Watch the latest run in real-time
gh run watch --repo csitea/bnc-cpt-api

# View logs of a specific run
gh run view --log --repo csitea/bnc-cpt-api

# View logs of failed run
gh run view --log-failed --repo csitea/bnc-cpt-api

Health Checks

Quick Health Check

# All environments using uniform URL pattern
for env in inf dev tst prd; do
  echo -n "$env: "
  curl -s "https://$env.api.carpulsetracker.com/health" | jq -r '.status'
done

Detailed Health Check

for env in inf dev tst prd; do
  echo "=== $env ==="
  curl -s "https://$env.api.carpulsetracker.com/health" | jq '.'
done

API Info Check

for env in inf dev tst prd; do
  echo "=== $env ==="
  curl -s "https://$env.api.carpulsetracker.com/api" | jq '.'
done

Testing Endpoints

Authentication

# Login and get JWT token
TOKEN=$(curl -s -X POST "https://dev.api.carpulsetracker.com/api/v1/auth/login/json" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"your-password"}' | jq -r '.access_token')

echo "Token: $TOKEN"

Payment Endpoints

BASE_URL="https://dev.api.carpulsetracker.com"

# Create payment intent (Stripe)
curl -s -X POST "$BASE_URL/api/v1/payment/create-intent" \
  -H "Content-Type: application/json" \
  -d '{
    "plan": "basic",
    "method": "stripe",
    "email": "test@example.com"
  }' | jq '.'

# Verify payment
curl -s -X POST "$BASE_URL/api/v1/payment/verify" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_id": "pi_xxx"
  }' | jq '.'

Receipt Download

# Download receipt PDF (requires auth)
curl -s -X GET "$BASE_URL/api/v1/payment/receipt/{payment_id}/pdf" \
  -H "Authorization: Bearer $TOKEN" \
  -o receipt.pdf

Local Development

Start API Locally

cd /opt/bnc/bnc-cpt/bnc-cpt-api/src/python/cpt-api
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python run.py  # Runs on port 8100

Start via Docker

cd /opt/bnc/bnc-cpt/bnc-cpt-utl
make do-setup-api

Test Local API

curl http://localhost:8100/health | jq '.'
curl http://localhost:8100/docs  # Open in browser

Cloud Run Operations

View Service Details

ENV=dev
gcloud run services describe bnc-cpt-api-$ENV \
  --region=europe-north1 \
  --project=bnc-cpt-$ENV

View Logs

ENV=dev
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=bnc-cpt-api-$ENV" \
  --project=bnc-cpt-$ENV \
  --limit=50 \
  --format="table(timestamp,textPayload)"

View Recent Revisions

ENV=dev
gcloud run revisions list \
  --service=bnc-cpt-api-$ENV \
  --region=europe-north1 \
  --project=bnc-cpt-$ENV

Troubleshooting

Service Not Responding

# Check if service is deployed
ENV=dev
gcloud run services list --project=bnc-cpt-$ENV --region=europe-north1

# Check service URL
gcloud run services describe bnc-cpt-api-$ENV \
  --region=europe-north1 \
  --project=bnc-cpt-$ENV \
  --format='value(status.url)'

Domain Mapping Issues

# Check domain mapping status
ENV=dev
gcloud run domain-mappings list \
  --region=europe-north1 \
  --project=bnc-cpt-$ENV

Secrets Not Loading

  1. Verify secrets exist in GCP: bash gcloud secrets list --project=bnc-cpt-dev

  2. Verify secret values exist: bash gcloud secrets versions list bnc-cpt-stripe-secret-key --project=bnc-cpt-dev

  3. Sync secrets from Google Sheet: bash cd /opt/bnc/bnc-cpt/bnc-cpt-utl make do-gcp-sync-secrets ENV=dev



WUI (Frontend) Endpoints

Environment URL
inf https://inf.carpulsetracker.com
dev https://dev.carpulsetracker.com
tst https://tst.carpulsetracker.com
prd https://carpulsetracker.com

Deploy WUI

cd /opt/bnc/bnc-cpt/bnc-cpt-utl

# Single environment
ENV=dev ./run -a do_gcp_deploy_wui

# All environments
for env in inf dev tst prd; do
  ENV=$env ./run -a do_gcp_deploy_wui
done

See bnc-cpt-utl/doc/md/bnc-cpt-inf.OPS.md for full WUI deployment documentation.