Skip to content
BoringStack
Star

Glossary

5 min read

Project-specific terminology used across the docs, collected here for reference.

The folders that compose BoringStack’s runtime: apps/api, apps/ui, and infra/compose. They live in one monorepo so Compose, CI, and docs can reference every layer through stable relative paths. infra/bootstrap provisions a VPS via OpenTofu and is optional.

A single directory per feature (src/api/<feature>/, src/features/<feature>/). Holds the routes, services, types, and tests for that one feature. The unit of independent change. The api ships auth, users, billing, dashboard, admin, and health as framework features; no demo domain resource. See Repository layout.

The API app’s per-feature pattern. For a hypothetical posts resource: posts.routes.ts does HTTP only, posts.service.ts does business logic plus DB access, posts.types.ts holds the shapes shared between them. Enforced by ESLint. See API overview.

The UI app’s per-component pattern. A page like DashboardPage/ is a folder of about eight files (.tsx, .hooks.ts, .types.ts, .constants.ts, .utils.ts, .test.tsx, .stories.tsx, index.ts). See UI overview.

The shape a hook returns to its component (IDashboardPageView returned by useDashboardPage). The component never reads queries, stores, or env directly; it only renders the view object. Decouples logic from JSX.

The lint-enforced rule that a file can have one semantic concern. No mixing routes, services, and utils in one file. Enforced by @boring-stack-pkg/eslint-plugin-module-boundaries.

The deployment target: STACK=dev or STACK=prod. Picks which compose overlay (HTTP routes plus host ports for dev, HTTPS plus ACME for prod) gets merged on top of the base.

A docker-compose.<name>.yml file that adds services to the base stack, gated by a WITH_<NAME> env var. Observability and GlitchTip default to on; niche overlays (BullMQ, Mailpit, WUD in dev) default to off. See Profiles and overlays.

A docker-compose feature for grouping services within a single file. The infra stack uses profiles (--profile dev, --profile observability) alongside overlays; profiles activate services within a file, overlays add files.

The always-on services: Postgres, Valkey, api-migrate (one-shot), and the app containers. Traefik is in the prod profile only; dev uses Vite’s dev-server proxy. Observability and GlitchTip layer in by default on top.

Postgres plus Valkey. The services that hold state. Deliberately not exposed to the frontend Docker network, so the only path from the world to the data plane is through the API.

The BSD-licensed Redis-protocol-compatible store BoringStack uses for cache and queues. Drop-in compatible with Redis: same wire protocol, same client libraries (ioredis, BullMQ). Env vars are renamed VALKEY_HOST, VALKEY_PORT, VALKEY_PASSWORD, VALKEY_DB so the operator-facing names match the binary; third-party containers (bull-board, GlitchTip) still read their own REDIS_* env names internally, with our compose overlays bridging the value. Maintained by the Linux Foundation with AWS, Google, and Oracle as primary sponsors.

Shorthand for “the rules the ESLint plugins enforce.” When something is “in the contract”, violating it fails bun run validate. The lint rules are enforceable boundaries, not just documentation. See Lint as the contract.

A call site that intentionally doesn’t await a Promise. Used for audit-log writes and other telemetry where failure must never propagate to the caller. The void prefix marks the intent for both readers and the linter.

An interface with multiple concrete implementations, selected by env var. Used for email, AI, and cache. The interface is the contract; the implementations are interchangeable.

The TypeScript-first ORM the api uses for Postgres. Schema-as-TS, migrations as generated SQL files, queries that look like SQL but are typed. Picked over Prisma because there’s no shadow database and migrations are plain SQL.

A namespace within a database. The api uses several: auth, billing, audit, app, notifications. Keeping them separate lets you grant, archive, or migrate them independently.

The append-only audit.audit_log table. Records security- and compliance-relevant events. Fire-and-forget; writes never block requests. See Audit log.

A named work buffer in Valkey, owned by a directory under src/queues/<name>/. Producers enqueue; workers consume. The directory follows a fixed pattern (constants, types, queue, worker, setup) so producer and consumer can’t drift on names.

The process-singleton that owns all queues and workers. Application code never imports BullMQ’s Queue class directly; it calls manager.enqueueX(...). See Queues.

A job that produces the same result if run twice. BullMQ retries on failure, so workers must be idempotent. Patterns: natural keys, UNIQUE constraints with caught violations, check-then-do inside a transaction.

The infra orchestrator. Forwards every argument to docker compose with the right overlay and profile flags based on STACK= and WITH_*= env vars. Plain bash; you can read what it does.

The merge gate. Typecheck plus lint plus tests. A PR can’t merge if validate fails. The phrase “the merge gate” anywhere in the docs refers to this command.