Skip to content

Latest commit

 

History

History
90 lines (68 loc) · 6.07 KB

File metadata and controls

90 lines (68 loc) · 6.07 KB

AGENTS.md

Flagr — Go feature flag service with Vue 3 UI.

Commands

Run make help from the repo root for the full catalog. Common targets:

Command What it does
make build Go server → ./flagr
make build-ui UI: lint, typecheck, Vite → browser/flagr-ui/dist/
make build-docs VitePress production build → docs/.vitepress/dist
make start Backend :18000 + UI dev :8080
make stop-ui Free ports :18000 / :8080 (lsof, not pkill)
make rebuild-run buildstop-uistart
make test Lint + swagger validate + Go unit tests
make test-e2e build + UI lint/typecheck + Playwright
make test-integration API integration tests (SQLite, local server)
make test-integration-compose Same suite vs Docker Compose (6 DBs)
make bench-integration HTTP eval benchmarks (local)
make swagger Regenerate swagger_gen/

Go tests: Prefer t.Parallel() unless the test mutates global state (config.Config, singletons, os.Setenv). See docs/flagr_testing.md for the decision tree.

Before commit / push (PR)

Run from repo root. Match what .github/workflows/ci.yml enforces so PR checks stay green.

You changed Run before commit Run before push (recommended)
browser/flagr-ui/ only make flagr-ui-check make test-e2e
docs/ (VitePress) make build-docs make build-docs
pkg/ or Go tests make test make test (+ make test-integration if handler/API behavior)
Swagger (swagger/, handlers → OpenAPI) make swagger then commit swagger_gen/ + cmd/flagr-server/main.go make ci-swagger (regen + git diff --exit-code)
UI + Go or unsure make test and make flagr-ui-check make test + make test-e2e

CI mapping (same commands):

GitHub Actions job Makefile
unit_test make ci-swagger then make ci (= make test: golangci-lint + swagger validate + go test ./pkg/...)
ui_lint make build-ui (= flagr-ui-check + Vite production build)
docs_build make build-docs (VitePress; same as Pages deploy)
e2e_test make test-e2e (= make build + flagr-ui-check + Playwright)
integration_test make ci-integration (Docker Compose; usually not every UI PR)

Fast UI loop: make flagr-ui-check ≈ ESLint + vue-tsc + Vitest (~10s). Do not rely on make run-ui alone — it does not lint.

PR hygiene: Follow PULL_REQUEST_TEMPLATE.md. For UI work, use plan As-built in docs/plans/2026-06-26-001-migrate-flagr-ui-js-to-ts-plan.md.

Key Code

Backend (pkg/):

  • handler/eval.go — evaluation engine (POST/GET), batch; handler/eval_get_test.go — GET eval tests; handler/crud.go — CRUD API handlers
  • handler/builtin_context.go — built-in context injection (@ts*, @http_* keys into entityContext)
  • handler/exposure.go — exposure (impression) logging; handler/data_recorder*.go — recorders (Kafka, Kinesis, Pub/Sub, Datar)
  • entity/ — domain models (flag, segment, constraint, variant, distribution)
  • config/env.go — all environment variables (single source of truth)

Frontend (browser/flagr-ui/src/):

  • api/types.ts — DTOs; api/crud.ts (flag CRUD + tags/variants/segments), api/eval.ts (POST /evaluation), http.ts
  • pages/flagPage.ts, pages/flagsListPage.ts (incl. list snapshot cache) — orchestration; flagPage.*(page) / flagsListPage.*(page) via castFlagPage / castFlagsList
  • Composed REST in api/crud.ts; UI via helpers/runApi; eval UI helpers in helpers/evaluation.ts
  • Architecture: docs/plans/2026-06-26-001-migrate-flagr-ui-js-to-ts-plan.md (As-built)
  • Duplicate flag + transactional snapshots: docs/plans/2026-06-30-001-duplicate-flag-plan.md (As-built)

Swagger / OpenAPI workflow

The API spec has a two-step generation pipeline:

  1. Source of truth: edit swagger/index.yaml (and the split files under swagger/ that it references).
  2. Bundle: make api_docs merges swagger/index.yaml into docs/api_docs/bundle.yaml via swagger-merger.
  3. Generate Go server models: make swagger regenerates swagger_gen/ from docs/api_docs/bundle.yaml.

Never hand-edit docs/api_docs/bundle.yaml or swagger_gen/ directly. If you change a model used by handlers, commit all three artifacts: swagger/index.yaml, docs/api_docs/bundle.yaml, and swagger_gen/.

Single command: make gen (runs api_docs + swagger).

Constraints

  • Don't edit swagger_gen/make swagger
  • Dev mode uses SQLite, no external deps needed
  • Process management uses lsof -ti:<port> not pkill -f — never touches other projects' processes
  • See deepwiki.com/openflagr/flagr and docs/
  • File size & layout: Prefer medium-sized files with a clear, logical split — not monoliths, not one-off micro-files for a single helper. Group by responsibility (e.g. handler error.go for API/handler errors and DB error classification; validate.go for request validation; crud*.go for CRUD surfaces). New code should extend an existing cohesive file when it fits; add a new file only when it names a real subsystem or API slice.
  • No magic numbers: Prefer named constants over inline literals. In Go, define const blocks for test values, timing durations, rollout percents, and HTTP status codes (use http.StatusOK not 200). In CSS/SCSS, use design tokens (--space-*, --font-size-*, --radius-*) or component-scoped variables (--constraint-logic-col) instead of hardcoded px values. Exceptions: 0, 1, -1, and values defined in :root variable declarations.
  • Go tests: Prefer t.Parallel() unless the test mutates global state (config.Config, singletons, os.Setenv). See docs/flagr_testing.md for the decision tree.
  • When creating a PR, follow PULL_REQUEST_TEMPLATE.md
  • Never push directly to main — always create a PR