aegida-console / .superpowers / sdd / 2026-07-28-user-service-auth-minikube / task-3-report.md
task-3-report.md
Raw

Task 3 Report: Kubernetes chat stack

Status

Core Task 3 Kubernetes resources, application health endpoint, documentation, and environment documentation are committed. No cluster resources were deployed.

Files

  • Created k8s/namespace.yaml, k8s/config.yaml, k8s/postgres.yaml, k8s/minio.yaml, k8s/app.yaml, and k8s/README.md.
  • Created app/api/health/route.ts and app/api/health/route.test.ts.
  • Updated .env.example and README.md with the Task 3 environment and minikube access guidance.
  • Added the standalone Docker runtime and entrypoint. Startup retries dependencies in the order migrations, explicitly enabled legacy seed, private-bucket provisioning, then Next.js server start.

Commit

  • feat(deploy): add Kubernetes chat stack manifests

Validation

Commands run successfully:

kubectl apply --dry-run=client -f k8s/namespace.yaml
kubectl apply --dry-run=client -f k8s/config.yaml
kubectl apply --dry-run=client -f k8s/postgres.yaml
kubectl apply --dry-run=client -f k8s/minio.yaml
kubectl apply --dry-run=client -f k8s/app.yaml
kubectl apply --dry-run=client -f k8s/
npm run build
npm test -- app/api/health/route.test.ts
git diff --cached --check
sh -n docker-entrypoint.sh

The Kubernetes client-side dry-runs accepted all namespace, ConfigMap, Secret, PVC, Service, Deployment, and StatefulSet objects. The production Next.js build completed successfully and listed /api/health as a dynamic route. The targeted health-route test passed (1 test).

The initial sandboxed kubectl and Next.js build attempts were denied their required local connections; both commands passed when rerun outside the sandbox.

Self-review

  • All resources use namespace aegida-services and the required service names and ports.
  • ConfigMap uses the exact in-cluster USER_SERVICE_URL; Secret uses stringData for development-only JWT, database, and MinIO credentials.
  • PostgreSQL has the pinned required image, a 1 Gi claim template, pg_isready readiness, and a ClusterIP Service.
  • MinIO has the required pinned image, private Secret credentials, a 2 Gi PVC, ready endpoint, and API/console ports.
  • The application uses the required minikube image, IfNotPresent, one replica, envFrom, ClusterIP port 3000, and readiness/liveness probes for /api/health; no Ingress was added.

Fix Round 1

The complete Dockerfile and docker-entrypoint.sh are committed with the Task 3 deployment work. The entrypoint retries migration and bucket setup, runs scripts/seed.mjs only when AUTH_SEED_ENABLED=true, and starts the server only after setup succeeds. Kubernetes documentation now applies namespace.yaml first, followed by each namespaced manifest explicitly, so the namespace cannot race the other resources.

Commands run successfully for this round:

sh -n docker-entrypoint.sh
docker build -t ai-control-chat-ui:task-3-check .
kubectl apply --dry-run=client -f k8s/namespace.yaml
kubectl apply --dry-run=client -f k8s/config.yaml
kubectl apply --dry-run=client -f k8s/postgres.yaml
kubectl apply --dry-run=client -f k8s/minio.yaml
kubectl apply --dry-run=client -f k8s/app.yaml
npm test -- app/api/health/route.test.ts
npm run build

Results:

  • sh -n docker-entrypoint.sh exited 0.
  • Docker 24.0.5 built ai-control-chat-ui:task-3-check successfully (sha256:c8076ca54e40e14f865fed4285dba115076e54a27adf8efb1f934af762e368d0).
  • All five Kubernetes client-side dry-runs accepted their objects.
  • npm run build completed its TypeScript phase and produced dynamic /api/health.
  • The focused health-route Vitest run passed: 1 test in 1 file.

Fix Round 2

The Docker runtime depended on an uncommitted application baseline. The reproducibility commit now includes the Docker build context rules, package metadata, PostgreSQL and S3 dependencies, database migrations and runtime modules, attachment/conversation routes, migration/bucket/seed scripts, and the UI modules that import the added dependencies.

Required paths were identified before staging with:

git ls-files Dockerfile docker-entrypoint.sh package.json package-lock.json scripts db lib app components hooks next.config.ts
git ls-files --others --exclude-standard
rg -n '(@/lib/(db|storage)|@/components|@/hooks|from "pg"|from "bcryptjs"|@aws-sdk|scripts/(migrate|seed|ensure-bucket)|db/migrations)' app components hooks lib scripts Dockerfile docker-entrypoint.sh

The staged tree was exported without changing the shared worktree:

task3_clean_dir=$(mktemp -d /private/tmp/corp-ui-task3-clean.XXXXXX)
git archive "$(git write-tree)" | tar -x -C "$task3_clean_dir"
(cd "$task3_clean_dir" && npm ci && npm run build && npm test -- app/api/health/route.test.ts)
(cd "$task3_clean_dir" && sh -n docker-entrypoint.sh && docker build -t ai-control-chat-ui:task-3-clean-check .)

Results:

  • The temporary archive at /private/tmp/corp-ui-task3-clean.9raKQW contained only the staged Git tree. It did not include the remaining untracked workspace files.
  • npm ci completed in the archive (726 packages); its production build passed TypeScript and generated all application routes, including attachments, conversations, and dynamic /api/health.
  • The focused health-route test passed: 1 test in 1 file.
  • sh -n docker-entrypoint.sh exited 0 in the archive.
  • The Docker build from that archive ran a fresh npm ci (730 packages) and completed as local image ai-control-chat-ui:task-3-clean-check (sha256:396e14c2a93711f59222ada82384fc342932c7ac1206213b3bfb013c63cbf264).