# Glossary — Platform Add-ons

Canonical vocabulary across the seven topics. Once defined here, every lesson uses it the same way.

## Migrations
- **golang-migrate** — the migration engine. Reads ordered `.sql` files, tracks the current version in
  a `schema_migrations` table, applies missing ones with `Up()`.
- **`NNNN_migrate.up.sql`** — this repo's file name: 4-digit sequence (from 1001), literal `migrate`.
  No `.down.sql` exists.
- **Up-only migration** — the repo never rolls back; a mistake is fixed by a *new* forward migration.
- **RLS boilerplate** — every new table ships with `resource_path` + two Row-Level-Security policies
  (tenant isolation), added in the same migration.
- **`gen-db-schema`** — the make target that rebuilds `eureka.sql`/`dwh.sql` (the sqlc schema inputs)
  by applying all migrations to a throwaway Postgres and `pg_dump`-ing it.

## Linting & githooks
- **golangci-lint** — the linter runner; `.golangci.yaml` picks which linters run.
- **Analyzer (`go/analysis`)** — a pluggable static-analysis pass. The repo's custom `sqlclosecheck`
  is one, built on SSA.
- **`sqlclosecheck` (custom)** — this repo's bespoke analyzer that flags **`pgx.Rows`** not closed (or
  closed without `defer`). Not the upstream linter; not enabled in golangci; not run in CI.
- **gitleaks** — a secret scanner; `gitleaks protect --staged` (staged changes) vs `gitleaks git`
  (history). Config `.gitleaks.toml`.
- **githook** — a git-triggered script. Here in `.githooks/`, installed via `core.hooksPath`.
  `commit-msg` (Jira ID), `pre-commit` (gitleaks), `prepare-commit-msg` (auto-prefix).

## Secrets
- **SOPS** — "Secrets OPerationS": encrypts the *values* in a YAML/JSON/env file (AES-256-GCM), leaving
  keys readable, and appends a `sops:` metadata block.
- **KMS (Key Management Service)** — a cloud service holding a master key. Here **GCP KMS** wraps the
  per-file **data key (DEK)**; SOPS asks KMS to unwrap it to decrypt.
- **DEK / envelope encryption** — data encrypted with a random data key; the data key encrypted by KMS.
  You only need KMS access (not the data key itself) to decrypt.
- **`.sops.yaml`** — the rules file mapping file `path_regex` → which KMS key. Generated; do not edit.
- **In-process decryption** — the repo's Go services are handed the *encrypted* file and decrypt it in
  memory at boot (`configs.LoadAll`), so no plaintext lands on disk.
- **App-level AES** — a *second*, separate layer: private keys stored in Postgres are AES-encrypted by
  the app (`golibs/crypt`), keyed from config — independent of SOPS.

## Build / Skaffold
- **Single-binary / multi-service** — one `server` binary contains every service; the runtime picks a
  service via a cobra subcommand + mounted config. Kubernetes runs the same image many times.
- **`gserver` / `gjob`** — the two cobra subtrees: the gRPC server vs the job runner (migrations, crons,
  data migrations).
- **Skaffold** — a build-and-deploy loop for k8s: builds images, tags them, deploys via Helm. Config in
  `skaffold.*.yaml`; `profiles` switch behaviour; a `custom.buildCommand` can replace Docker builds.
- **Cross-compile** — building a linux/amd64 binary on a Mac (`GOOS=linux GOARCH=amd64`) so it runs in
  a container.
- **kind** — "Kubernetes IN Docker": a local cluster. Skaffold `kind load`s images into it.

## Reliability
- **At-least-once delivery** — a broker may deliver a message more than once; handlers must tolerate it.
- **Idempotency** — processing the same message twice has the same effect as once. Achieved by recording
  processed message IDs and discarding duplicates (**idempotent consumer**).
- **`IdempotentService`** — the repo's DB-backed dedup (a row per `idempotent_id` + type in the **bob**
  DB); the marker is written only on success/non-retryable failure.
- **Retryable (`(retryable bool, err error)`)** — the handler's return contract: `true` = "try again"
  (redeliver / in-process retry), `false` = "give up, don't redeliver."
- **`try.Do` / `DoBackOff`** — the repo's generic retry helper (caps at 10 attempts).
- **Dual-write problem** — the risk of updating the DB and publishing a message in two steps: a crash
  between them loses consistency.
- **Transactional outbox** — write the message into an `outbox` table in the *same* DB transaction as
  the state change; a relay ships it later. Solves the dual-write problem. Here: eureka-only, relayed by
  **Debezium** (CDC), feature-flagged.
- **Publish-after-commit (dual-write + compensation)** — what spike/notification do instead: commit the
  row, then publish; on publish failure, mark a `*_FAILED` status and let the caller retry.

## Notification & email delivery
- **spike** — the email microservice (SendGrid). Has no DB of its own (uses the notificationmgmt DB).
- **SendGrid** — the email provider. Two clients here: **transactional** vs **notification** (chosen by
  `EmailType`, orthogonal to the priority lane).
- **Priority lane** — the Kafka topic an email goes on (normal vs high-priority), resolved from the
  per-email `client_id`.
- **Email status state machine** — `CREATED → QUEUED(/_FAILED) → PROCESSED(/_FAILED)` → per-recipient
  webhook events. `QUEUED` means "published to Kafka," not "sent."
- **Event Webhook** — SendGrid's callback (`delivered`/`bounce`/`dropped`…) → `email_recipient_events`.
- **FCM (Firebase Cloud Messaging)** — the push provider. Multicast up to **500 tokens**; a
  `BatchResponse` reports per-token success/failure.
- **Device token** — a per-device FCM registration string; **unregistered** tokens are cleaned up, not
  treated as delivery failures.
- **`NotificationPusher`** — the golibs Firebase wrapper (`PushMultiple`/`Push`); push failures are
  swallowed (non-retryable) to avoid double-push.

## Cron / scheduled jobs
- **`RegisterJob[T]`** — the bootstrap hook that turns a Go function into a cobra subcommand (a "job").
- **CronJob (k8s)** — the scheduler: a Helm-rendered Kubernetes CronJob with a `schedule:` cron
  expression runs the job binary on a timer. There is **no in-process Go scheduler.**
- **Job vs cronjob** — Helm `jobs:` = run-once (migrations, triggers); `cronjobs:` = recurring.
- **gjob consumer pod** — a long-running "job" (`notificationmgmt_consumers`) that runs Kafka consumers,
  **KEDA-autoscaled** on Kafka lag.
- **KEDA** — event-driven autoscaler; scales the consumer Deployment on **Kafka consumer-group lag**
  (via Prometheus), not CPU.
- **Three runtime shapes** — one binary as: in-gRPC-pod consumers, the KEDA gjob pod, or a CronJob.
