Compare commits

...

4 Commits

Author SHA1 Message Date
agent-company 54cd793d5e chore: update STATUS.md — 2026-05-26 PM agent cycle 2026-05-26 20:04:40 +00:00
AI-Manager 58eba5f342 Merge pull request 'feat: scaffold Flux manifests for zip-enrichment, holidays, air-quality API services (closes #46)' (#48) from feature/flux-api-services-46 into main
Build Docs Site / Aggregate OpenAPI Specs (push) Failing after 49s
2026-05-26 20:03:47 +00:00
agent-company ae978a0bb3 feat: scaffold Flux manifests for zip-enrichment, holidays, air-quality API services
Closes leeworks-agents/api-company#46

Add flux/ directories for all three API services, each containing:
- namespace.yaml — Kubernetes Namespace
- helmrelease.yaml — HelmRelease using bedag/raw chart with Deployment,
  Service, and Ingress (TLS via cert-manager letsencrypt-prod)
- externalsecret.yaml — placeholder/comment for RapidAPI proxy-secret;
  includes kubectl manual-create instructions until ESO is deployed
- kustomization.yaml — per-directory Kustomize resources list

Services and subdomains:
  zip-enrichment  → zip.leeworks.dev
  holidays        → holidays.leeworks.dev
  air-quality     → aqi.leeworks.dev

Images:
  registry.leeworks.dev/zip-enrichment/server:latest
  registry.leeworks.dev/holidays/server:latest
  registry.leeworks.dev/air-quality/server:latest

Update root flux/kustomization.yaml to include all three new directories.
kustomize build flux/ passes with zero errors.
2026-05-26 20:02:42 +00:00
AI-Manager 01bfe2693a Merge pull request 'docs: add secrets-checklist.md — all required Kubernetes secrets with kubectl commands (closes #43)' (#45) from feature/secrets-checklist-43 into main
Build Docs Site / Aggregate OpenAPI Specs (push) Failing after 56s
2026-05-26 15:03:31 +00:00
14 changed files with 439 additions and 25 deletions
+16 -25
View File
@@ -1,6 +1,6 @@
# Company Status
_Last updated: 2026-05-26 (agent cycle)_
_Last updated: 2026-05-26 (agent cycle — afternoon)_
## APIs
| API | Spec | Code | Deployed | Listed on RapidAPI | Paying Users | MRR |
@@ -18,8 +18,13 @@ Legend: [x]=done, [~]=in-progress, [ ]=not started
- **Container registry:** Gitea built-in registry selected; docs/registry.md committed — PENDING Gitea packages enabled (issue #4)
- **Prometheus + Grafana:** Flux HelmRelease at `flux/monitoring/` — PENDING Flux wiring + Grafana secret (issue #7)
- **Gatus status page:** Flux HelmRelease at `flux/monitoring/gatus-helmrelease.yaml` — PENDING Flux wiring (issue #8)
- **API service manifests (NEW):** `flux/zip-enrichment/`, `flux/holidays/`, `flux/air-quality/` scaffolded (PR #48, closes #46)
## Completed This Cycle (2026-05-26)
## Completed This Cycle (2026-05-26 PM)
- **#46** — Scaffolded Flux deployment manifests for all three API services (zip-enrichment, holidays, air-quality). PR #48 merged.
## Completed Previous Cycle (2026-05-26 AM)
- **#43** — secrets-checklist.md added (closed, PR #45)
- **#36** — Cluster audit committed to `docs/cluster-audit.md` (closed)
- **#40** — Legal docs (ToS, Privacy Policy, AUP) under `docs/legal/` (closed)
- **#37** — docs-site Astro skeleton with Redoc pages; `npm run build` passes (closed)
@@ -33,28 +38,14 @@ All flux manifests validate successfully. Deployed components pending Flux activ
- `monitoring` namespace + kube-prometheus-stack HelmRelease
- `monitoring` Gatus HelmRelease (status.leeworks.dev, 90-day retention)
- `docs-site` HelmRelease (docs.leeworks.dev)
- `zip-enrichment` namespace + HelmRelease (zip.leeworks.dev) + rapidapi-proxy-secret placeholder ← NEW
- `holidays` namespace + HelmRelease (holidays.leeworks.dev) + rapidapi-proxy-secret placeholder ← NEW
- `air-quality` namespace + HelmRelease (aqi.leeworks.dev) + rapidapi-proxy-secret placeholder ← NEW
## Blockers (human operator action required)
1. **Add api-company GitRepository+Kustomization to 0xWheatyz/Talos** at `testing1/first-cluster/cluster/flux/` — reference manifests ready in `flux/api-company-source/`
2. **Create `gitea-leeworks-agents-token` secret** in `flux-system` namespace (HTTPS token for Gitea)
3. **Create `gitea-runner-token` secret** in `gitea-runner` namespace (Gitea Admin → Actions → Runners → New Runner)
4. **Enable Gitea packages** (`[packages] ENABLED=true` in app.ini) + DNS record `registry.leeworks.dev` → Gitea ingress
5. **Create Grafana admin secret** in `monitoring` namespace (`GRAFANA_ADMIN_PASSWORD`)
6. **Create Slack webhook secret** in `monitoring` namespace for Gatus alerts
7. **DNS A records** for all 6 subdomains (zip, holidays, aqi, docs, status, registry) → cluster ingress IP (issue #33)
## API Repos Status
- `zip-enrichment`: Phase 3 server in progress (Fastify scaffold, routes, CI workflows)
- `holidays`: Phase 3 server in progress (Fastify scaffold, business-day routes)
- `air-quality`: Phase 1 in progress (openapi.yaml, Dockerfile)
## Revenue
- Gross MRR: $0
- Net MRR (after ~26.5% fees): $0
- Target: $100/mo net
- Gap: $100
## Next actions
1. **Human operator:** unblock infrastructure (items 1-7 above)
2. Once runner + Flux are live: API repo CI will build/push images and deploy to cluster
3. Phase 1→2→3 completion across zip-enrichment, holidays, air-quality repos
1. **Create `0xWheatyz/api-company` repo on Gitea** — every ship cycle fails until this exists (#41, #47)
2. **Add api-company GitRepository+Kustomization to 0xWheatyz/Talos** at `testing1/first-cluster/cluster/flux/` — reference manifests ready in `flux/api-company-source/` (#2)
3. **Create `gitea-leeworks-agents-token` secret** in `flux-system` namespace (HTTPS token for Gitea)
4. **Create `gitea-runner-token` secret** in `gitea-runner` namespace (Gitea Admin → Actions → Runners → New Runner) (#3)
5. **Enable Gitea packages** (for container registry at `registry.leeworks.dev`) (#4)
6. **RapidAPI + PayPal setup** — manual, gated on operator turning 18 (#19, #44)
+29
View File
@@ -0,0 +1,29 @@
# Placeholder: inject the RapidAPI Proxy Secret here once ESO is deployed.
# Replace with a real ExternalSecret once leeworks-agents/api-company#2 and
# the external-secrets operator are running in the cluster.
#
# Example (uncomment and fill in secretStore name):
#
# apiVersion: external-secrets.io/v1beta1
# kind: ExternalSecret
# metadata:
# name: rapidapi-proxy-secret
# namespace: air-quality
# spec:
# refreshInterval: 1h
# secretStoreRef:
# name: <your-secret-store>
# kind: ClusterSecretStore
# target:
# name: rapidapi-proxy-secret
# creationPolicy: Owner
# data:
# - secretKey: X-RapidAPI-Proxy-Secret
# remoteRef:
# key: rapidapi/air-quality
# property: proxy-secret
#
# Until then, create manually:
# kubectl create secret generic rapidapi-proxy-secret \
# --from-literal=X-RapidAPI-Proxy-Secret=<value> \
# -n air-quality
+101
View File
@@ -0,0 +1,101 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: air-quality
namespace: air-quality
spec:
interval: 10m
chart:
spec:
chart: raw
version: ">=0.2.0"
sourceRef:
kind: HelmRepository
name: bedag
namespace: flux-system
interval: 60m
values:
resources:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: air-quality
namespace: air-quality
spec:
replicas: 1
selector:
matchLabels:
app: air-quality
template:
metadata:
labels:
app: air-quality
spec:
imagePullSecrets:
- name: gitea-registry
containers:
- name: air-quality
image: registry.leeworks.dev/air-quality/server:latest
ports:
- containerPort: 3000
env:
- name: RAPIDAPI_PROXY_SECRET
valueFrom:
secretKeyRef:
name: rapidapi-proxy-secret
key: X-RapidAPI-Proxy-Secret
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
- apiVersion: v1
kind: Service
metadata:
name: air-quality
namespace: air-quality
spec:
selector:
app: air-quality
ports:
- port: 80
targetPort: 3000
- apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: air-quality
namespace: air-quality
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- aqi.leeworks.dev
secretName: air-quality-tls
rules:
- host: aqi.leeworks.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: air-quality
port:
number: 80
+6
View File
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- externalsecret.yaml
- helmrelease.yaml
+4
View File
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: air-quality
+29
View File
@@ -0,0 +1,29 @@
# Placeholder: inject the RapidAPI Proxy Secret here once ESO is deployed.
# Replace with a real ExternalSecret once leeworks-agents/api-company#2 and
# the external-secrets operator are running in the cluster.
#
# Example (uncomment and fill in secretStore name):
#
# apiVersion: external-secrets.io/v1beta1
# kind: ExternalSecret
# metadata:
# name: rapidapi-proxy-secret
# namespace: holidays
# spec:
# refreshInterval: 1h
# secretStoreRef:
# name: <your-secret-store>
# kind: ClusterSecretStore
# target:
# name: rapidapi-proxy-secret
# creationPolicy: Owner
# data:
# - secretKey: X-RapidAPI-Proxy-Secret
# remoteRef:
# key: rapidapi/holidays
# property: proxy-secret
#
# Until then, create manually:
# kubectl create secret generic rapidapi-proxy-secret \
# --from-literal=X-RapidAPI-Proxy-Secret=<value> \
# -n holidays
+101
View File
@@ -0,0 +1,101 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: holidays
namespace: holidays
spec:
interval: 10m
chart:
spec:
chart: raw
version: ">=0.2.0"
sourceRef:
kind: HelmRepository
name: bedag
namespace: flux-system
interval: 60m
values:
resources:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: holidays
namespace: holidays
spec:
replicas: 1
selector:
matchLabels:
app: holidays
template:
metadata:
labels:
app: holidays
spec:
imagePullSecrets:
- name: gitea-registry
containers:
- name: holidays
image: registry.leeworks.dev/holidays/server:latest
ports:
- containerPort: 3000
env:
- name: RAPIDAPI_PROXY_SECRET
valueFrom:
secretKeyRef:
name: rapidapi-proxy-secret
key: X-RapidAPI-Proxy-Secret
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
- apiVersion: v1
kind: Service
metadata:
name: holidays
namespace: holidays
spec:
selector:
app: holidays
ports:
- port: 80
targetPort: 3000
- apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: holidays
namespace: holidays
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- holidays.leeworks.dev
secretName: holidays-tls
rules:
- host: holidays.leeworks.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: holidays
port:
number: 80
+6
View File
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- externalsecret.yaml
- helmrelease.yaml
+4
View File
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: holidays
+3
View File
@@ -4,3 +4,6 @@ resources:
- gitea-runner
- monitoring
- docs-site
- zip-enrichment
- holidays
- air-quality
+29
View File
@@ -0,0 +1,29 @@
# Placeholder: inject the RapidAPI Proxy Secret here once ESO is deployed.
# Replace with a real ExternalSecret once leeworks-agents/api-company#2 and
# the external-secrets operator are running in the cluster.
#
# Example (uncomment and fill in secretStore name):
#
# apiVersion: external-secrets.io/v1beta1
# kind: ExternalSecret
# metadata:
# name: rapidapi-proxy-secret
# namespace: zip-enrichment
# spec:
# refreshInterval: 1h
# secretStoreRef:
# name: <your-secret-store>
# kind: ClusterSecretStore
# target:
# name: rapidapi-proxy-secret
# creationPolicy: Owner
# data:
# - secretKey: X-RapidAPI-Proxy-Secret
# remoteRef:
# key: rapidapi/zip-enrichment
# property: proxy-secret
#
# Until then, create manually:
# kubectl create secret generic rapidapi-proxy-secret \
# --from-literal=X-RapidAPI-Proxy-Secret=<value> \
# -n zip-enrichment
+101
View File
@@ -0,0 +1,101 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: zip-enrichment
namespace: zip-enrichment
spec:
interval: 10m
chart:
spec:
chart: raw
version: ">=0.2.0"
sourceRef:
kind: HelmRepository
name: bedag
namespace: flux-system
interval: 60m
values:
resources:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: zip-enrichment
namespace: zip-enrichment
spec:
replicas: 1
selector:
matchLabels:
app: zip-enrichment
template:
metadata:
labels:
app: zip-enrichment
spec:
imagePullSecrets:
- name: gitea-registry
containers:
- name: zip-enrichment
image: registry.leeworks.dev/zip-enrichment/server:latest
ports:
- containerPort: 3000
env:
- name: RAPIDAPI_PROXY_SECRET
valueFrom:
secretKeyRef:
name: rapidapi-proxy-secret
key: X-RapidAPI-Proxy-Secret
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
- apiVersion: v1
kind: Service
metadata:
name: zip-enrichment
namespace: zip-enrichment
spec:
selector:
app: zip-enrichment
ports:
- port: 80
targetPort: 3000
- apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: zip-enrichment
namespace: zip-enrichment
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- zip.leeworks.dev
secretName: zip-enrichment-tls
rules:
- host: zip.leeworks.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: zip-enrichment
port:
number: 80
+6
View File
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- externalsecret.yaml
- helmrelease.yaml
+4
View File
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: zip-enrichment