---
id: w1/m15/t002
title: `cron_job` type — `schedule` field + CronJob reconcile + run-history status
worker: worker1
status: done
estimate: 45m
depends_on: []
---

## Objective

Add Render's `cron_job` service type: a `schedule` (cron expression) field on the `App` spec, an operator reconcile path that materializes a Kubernetes `CronJob` (not a Deployment) running the built image's command on that schedule, and run-history recorded in the CR status.

## Context

- Types in `lego/types/v1alpha1/*_types.go`; regenerate CRD + deepcopy via `make manifests generate` from `lego/operator/`. A cron job needs a new `schedule` string field and a status area for recent runs.
- The kubernetes reconcile is `lego/operator/internal/controller/` — this type diverges most: it reconciles a `batch/v1` `CronJob` (with a Job template over the built image) rather than the Deployment/Service/Ingress trio, and the operator already has RBAC to regenerate; add `cronjobs`/`jobs` RBAC markers under `./...` if missing.
- Render exposes `/cron-jobs/{id}/runs`; the run trigger itself is t003 — this task only lands the CronJob mechanism + status run history it will read.

## Steps

1. Add `schedule` (cron expr) to the `App` spec and a run-history field to status in `lego/types/v1alpha1`; regenerate CRD + deepcopy from `lego/operator/`.
2. In the kubernetes reconcile, branch on the cron type: create/update a K8s `CronJob` from the spec (schedule, image, command); do not create Deployment/Service/Ingress. Add any needed `cronjobs`/`jobs` RBAC markers and regenerate.
3. Populate status run history from the CronJob's Jobs (recent run timestamps + outcomes).

## Files

- `lego/types/v1alpha1/*_types.go` (+ regenerated `zz_generated.deepcopy.go`)
- `lego/operator/config/crd/bases/` + `lego/operator/config/rbac/` (regenerated)
- `lego/operator/internal/controller/` (kubernetes reconcile)

## Acceptance criteria

- [x] An `App` with the cron type + a `schedule` reconciles to a K8s `CronJob` (no Deployment/Service/Ingress), and status shows recent runs.
- [x] `make manifests generate` output is committed and `make test` passes.

## Out of scope

- The `/cron-jobs/{id}/runs` trigger and MCP `create_cron_job` (t003).
- Dashboard run display (t004); `background_worker` (t001); static sites (`w1/012`).
