feat: scaffold vin-decoder repo — server, data layer, Flux manifests, CI
CI — Build, Test, Push / test (pull_request) Failing after 6s
CI — Build, Test, Push / build-and-push (pull_request) Has been skipped

Closes leeworks-agents/api-company#122

- openapi.yaml: copied from leeworks-agents/api-company apis/vin-decoder/openapi.yaml (canonical spec)
- src/db.js: SQLite database init with vin_cache schema and indexes
- src/nhtsa.js: NHTSA vPIC fetch + field mapping
- src/cache.js: cache read/write with 90-day TTL, validateVin, getCacheStats, evictExpired
- src/server.js: Fastify server implementing GET /v1/decode, POST /v1/batch, GET /v1/health
  - X-RapidAPI-Proxy-Secret middleware on /decode and /batch
  - X-Request-Id, X-Cache, X-Data-Source response headers
  - Returns 403 for missing/wrong proxy secret
- scripts/seed.js: pre-warm cache with known VINs, runs eviction sweep
- src/tests/cache.test.js: unit tests for validateVin + cache integration (Honda Accord VIN)
- Dockerfile: Node 20 alpine, non-root, healthcheck on /v1/health
- .gitea/workflows/ci.yaml: test → build → push to registry.leeworks.dev/vin-decoder/api:<sha>
- flux/vin-decoder/: Namespace, Deployment (with RAPIDAPI_PROXY_SECRET from secret), Service, Ingress (vin.leeworks.dev + TLS), Kustomization
- .gitignore: node_modules, data/, .env
This commit is contained in:
agent-company
2026-05-30 20:08:47 +00:00
parent 79178119ba
commit 67097cf976
16 changed files with 1003 additions and 1 deletions
+71
View File
@@ -0,0 +1,71 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vin-decoder
namespace: vin-decoder
labels:
app: vin-decoder
spec:
replicas: 1
selector:
matchLabels:
app: vin-decoder
template:
metadata:
labels:
app: vin-decoder
spec:
imagePullSecrets:
- name: gitea-registry
containers:
- name: api
image: registry.leeworks.dev/vin-decoder/api:latest
ports:
- containerPort: 3000
env:
- name: PORT
value: "3000"
- name: DB_PATH
value: /data/vin_cache.db
- name: RAPIDAPI_PROXY_SECRET
valueFrom:
secretKeyRef:
name: rapidapi-proxy-secret
key: X-RapidAPI-Proxy-Secret
volumeMounts:
- name: data
mountPath: /data
livenessProbe:
httpGet:
path: /v1/health
port: 3000
initialDelaySeconds: 15
periodSeconds: 30
readinessProbe:
httpGet:
path: /v1/health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumes:
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: vin-decoder
namespace: vin-decoder
spec:
selector:
app: vin-decoder
ports:
- port: 3000
targetPort: 3000
+25
View File
@@ -0,0 +1,25 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vin-decoder
namespace: vin-decoder
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- vin.leeworks.dev
secretName: vin-tls
rules:
- host: vin.leeworks.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vin-decoder
port:
number: 3000
+6
View File
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- deployment.yaml
- ingress.yaml
+4
View File
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: vin-decoder