From 7e79390d86c4d0775dc0ed252a9e3d9f27909fd4 Mon Sep 17 00:00:00 2001 From: "cartsnitch-engineer[bot]" <269717931+cartsnitch-engineer[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 19:51:45 +0000 Subject: [PATCH] feat(scripts): add dev environment seed script and K8s Job (#99) * fix(api): replace UUID type with str for Better-Auth nanoid user IDs Better-Auth uses nanoid strings for user IDs, not UUIDs. Changed all user_id parameter/return types in the API layer from UUID to str, removed the obsolete UUID import where unused, and updated the _validate_session_token return type accordingly. Co-Authored-By: Paperclip * feat(scripts): add dev environment seed script and K8s Job Co-Authored-By: Paperclip --------- Co-authored-by: CartSnitch Engineer Bot Co-authored-by: Paperclip --- scripts/seed-dev-job.yaml | 61 ++++++++++++++++++++++ scripts/seed-dev.sh | 104 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 scripts/seed-dev-job.yaml create mode 100755 scripts/seed-dev.sh diff --git a/scripts/seed-dev-job.yaml b/scripts/seed-dev-job.yaml new file mode 100644 index 0000000..2d5cc86 --- /dev/null +++ b/scripts/seed-dev-job.yaml @@ -0,0 +1,61 @@ +# seed-dev-job.yaml +# K8s Job to run the CartSnitch seed runner against the dev database. +# +# Usage: +# kubectl apply -f seed-dev-job.yaml -n cartsnitch-dev +# +# To view logs: +# kubectl logs -n cartsnitch-dev job/seed-dev -f +# +# To re-run after fixing issues: +# kubectl delete -f seed-dev-job.yaml -n cartsnitch-dev && kubectl apply -f seed-dev-job.yaml -n cartsnitch-dev +# +apiVersion: batch/v1 +kind: Job +metadata: + name: seed-dev + namespace: cartsnitch-dev + labels: + app: cartsnitch + component: seed + environment: dev + annotations: + description: "Runs cartsnitch-common seed runner to populate dev database with realistic test data." +spec: + # Prevent retries — a failed seed run should be investigated, not auto-repeated. + backoffLimit: 0 + # Do not run concurrently; sequential runs are safer for truncate+reseed. + concurrencyPolicy: Forbid + template: + metadata: + labels: + app: cartsnitch + component: seed + environment: dev + spec: + restartPolicy: Never + containers: + - name: seed + # Use slim Python image with the cartsnitch-common package installed from git. + # The common repo is public; no additional secret is needed for the pip install. + image: python:3.12-slim + command: + - sh + - -c + - | + pip install --no-cache-dir "cartsnitch-common @ git+https://github.com/cartsnitch/common.git@main" && \ + python -m cartsnitch_common.seed --database-url "$${DATABASE_URL}" + env: + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: cartsnitch-secrets + key: database-url-pg + optional: false + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi diff --git a/scripts/seed-dev.sh b/scripts/seed-dev.sh new file mode 100755 index 0000000..a478015 --- /dev/null +++ b/scripts/seed-dev.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +# ============================================================================= +# seed-dev.sh — Run the CartSnitch seed runner against the dev database. +# +# Usage: +# ./seed-dev.sh Run full seed against dev +# ./seed-dev.sh --dry-run Show planned record counts without writing +# ./seed-dev.sh --help Show this help +# +# Prerequisites: +# - kubectl configured for the cartsnitch-dev cluster +# - Namespace cartsnitch-dev exists (CNPG Postgres must be running) +# +# What it does: +# 1. Starts a background port-forward to cartsnitch-pg-rw:5432 +# 2. Waits for the tunnel to be ready +# 3. Runs python -m cartsnitch_common.seed with --database-url pointing +# to localhost:/cartsnitch +# 4. Cleans up the port-forward on exit (normal, interrupt, or error) +# ============================================================================= + +set -euo pipefail + +# --- Config ------------------------------------------------------------------- +readonly NAMESPACE="cartsnitch-dev" +readonly SVC_NAME="cartsnitch-pg-rw" +readonly LOCAL_PORT="5433" # use a non-privileged port to avoid conflicts +readonly DB_NAME="cartsnitch" +readonly PG_USER="cartsnitch" +# Retrieve password from the CNPG credentials secret +readonly PG_PASSWORD="$( + kubectl get secret cartsnitch-pg-credentials \ + -n "$NAMESPACE" \ + -o jsonpath='{.data.password}' \ + | base64 -d +)" +readonly DB_URL="postgresql://${PG_USER}:${PG_PASSWORD}@localhost:${LOCAL_PORT}/${DB_NAME}" + +# --- Helpers ------------------------------------------------------------------ +log() { echo "[seed-dev] $*"; } +fail() { log "ERROR: $*" >&2; exit 1; } + +# Cleanup port-forward and exit. +cleanup() { + if [[ -n "${PF_PID:-}" ]]; then + log "Stopping port-forward (PID $PF_PID)..." + kill "$PF_PID" 2>/dev/null || true + wait "$PF_PID" 2>/dev/null || true + fi +} +trap cleanup EXIT + +# --- Args --------------------------------------------------------------------- +DRY_RUN="" +HELP_FLAG="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --dry-run) DRY_RUN="--dry-run"; shift ;; + --help) HELP_FLAG="1"; shift ;; + *) fail "Unknown argument: $1";; + esac +done + +if [[ -n "$HELP_FLAG" ]]; then + sed -n '3,/^# ---/p' "$0" | head -n -1 | sed 's/^# //' + echo "" + echo "Additional arguments are passed through to the seed runner." + echo "Common seed-runner options:" + echo " --dry-run Show planned record counts without writing" + echo " --seed N Set random seed (default: 42)" + exit 0 +fi + +# --- Prerequisites ------------------------------------------------------------ +if ! command -v kubectl &>/dev/null; then + fail "kubectl not found — must be installed and configured." +fi + +# --- Port-forward ------------------------------------------------------------- +log "Starting port-forward ${SVC_NAME}:5432 -> localhost:${LOCAL_PORT} ..." +kubectl port-forward \ + -n "$NAMESPACE" \ + svc/"$SVC_NAME" \ + "${LOCAL_PORT}:5432" \ + &>/dev/null & +PF_PID=$! + +# Give the tunnel a moment to establish +sleep 2 + +# Verify the tunnel is up +if ! kill -0 "$PF_PID" 2>/dev/null; then + fail "Port-forward failed to start." +fi +log "Port-forward active (PID $PF_PID) on localhost:${LOCAL_PORT}" + +# --- Seed -------------------------------------------------------------------- +log "Running seed against dev database..." +set -x +python -m cartsnitch_common.seed --database-url "$DB_URL" $DRY_RUN +set +x + +log "Done."