vertical-slices
$
npx mdskill add databuddy-analytics/Databuddy/vertical-slicesBuild feature-first code with clear boundaries and tests.
- Refactors layered code into independent capability slices.
- Enforces strict repository rules and explicit coupling limits.
- Validates slice completion against defined capability criteria.
- Generates complete, testable modules ready for production use.
SKILL.md
.github/skills/vertical-slicesView on GitHub ↗
--- name: vertical-slices description: Design, implement, and review software using vertical slices (feature-first architecture) instead of horizontal layers. Use when creating a new feature, refactoring layered code (controllers/services/repositories), defining clear API-domain-data boundaries, improving slice-level testability, or reducing cross-module coupling in backend or fullstack TypeScript projects. --- # Vertical Slices Build features as independent slices that own contract, business rules, persistence logic, and tests. Prefer feature-first folders and thin entrypoints. Keep business behavior inside the slice, not in transport or framework code. Always follow stricter repository rules when present (for example `AGENTS.md`). ## Outcomes A slice is complete only when all are true: - One clear capability is owned by one slice. - Behavior is implemented in the slice, not in handlers/controllers/routes. - Persistence logic is co-located and transaction-safe. - Tests cover behavior, boundaries, and failure paths with regression depth. - Cross-slice coupling is explicit, minimal, and one-way. If these are not met, do not call the slice done. ## Execution Workflow (Required) ### 1) Define the slice boundary before coding - Name exactly one capability in business language. - Define one owner module (for example `billing`, `session`, `question`). - State what is intentionally out of scope for this slice. - Limit dependencies to shared infrastructure and explicit contracts. ### 2) Write a compact Slice Design Spec before implementation Create a short design note in your working context with: - Capability statement: one sentence with actor + action + outcome. - Invariants: 3-7 rules that must remain true. - Boundary contracts: input, output, error model, idempotency behavior. - Data ownership: tables/entities read and written by the slice. - Dependency map: entrypoint -> slice -> infrastructure only. - Cross-slice touchpoints: event names or explicit interfaces only. - Failure model: validation, conflict, upstream, and persistence failures. If this spec is missing, pause and define it first. ### 3) Define contracts before behavior - Create input/output schemas at the boundary (HTTP, queue, CLI, RPC). - Use the same contract definitions in adapters and tests. - Keep contract definitions in the slice area, not spread across global folders. - Map internal errors to boundary errors in one place. ### 4) Implement business behavior in the slice - Keep handlers/routes thin: validate -> invoke slice -> map result/error. - Keep orchestration and rules in slice functions. - Avoid leaking framework request/response objects into business logic. - Prefer explicit return types at public slice boundaries. ### 5) Co-locate persistence and side effects - Keep slice-specific reads/writes near slice behavior. - Use explicit transaction boundaries for multi-write flows. - Emit side effects only after successful commit. - Make idempotency explicit when retries can happen. ### 6) Enforce low coupling - Use event publication for asynchronous cross-slice reactions. - Use explicit interfaces only when immediate response is required. - Do not deep-import another slice internals. - Keep dependency direction one-way: entrypoint -> slice -> infrastructure. ### 7) Apply test maturity gates (required) Do not stop at export/smoke tests. Build behavior-focused suites: - Unit-level slice tests: - happy path with realistic data - validation failures - domain invariant failures - edge cases for optional/empty/limit inputs - Boundary integration tests when behavior crosses boundaries: - transport + contract validation + error mapping - persistence side effects and rollback behavior - idempotency and duplicate request handling when relevant - Regression tests: - every bug fix must add at least one failing-then-passing test - test must assert behavior outcome, not implementation details ### 8) Run final quality gate before completion - Execute `references/checklist.md` fully. - Discover verification commands from the host repository before running tests: - inspect package/workspace scripts for unit/integration/e2e commands - inspect CI workflows to identify required checks for affected paths - do not assume script names; infer by behavior - Run concrete verification commands for the touched slice paths: - smallest relevant unit command(s) - integration command(s) when boundaries/persistence changed - e2e command(s) when user-visible workflows changed - Prefer package/service-local commands first. Do not use repository root tests when the repo uses a root test guard. - Keep verification aligned with required CI checks for the affected area. - Record exact commands executed, pass/fail outcome, and intentional skips with residual risk. - Record residual risks and follow-ups. - Call out compatibility or migration impact. ## Choose a Blueprint Read `references/blueprints.md` to pick folder templates for backend-only and fullstack repositories. ## Apply Naming Conventions Read `references/naming.md` and pick canonical package and slice names before creating folders and contracts. ## Validate Slice Quality Read `references/checklist.md` and execute the checks before finalizing changes. Do not mark complete if any required check fails. ## Build Mature Test Suites Read `references/testing-maturity.md` when designing tests. Use it to choose test depth, avoid shallow suites, and ensure regressions are captured. ## Refactor Toward Slices If starting from layered architecture, read `references/adoption-playbook.md` and migrate one feature at a time.
More from databuddy-analytics/Databuddy
- databuddyWork effectively in the Databuddy monorepo. Use when the user asks to build, debug, review, or refactor anything in Databuddy, including the dashboard, api, basket ingest service, links service, docs app, uptime service, SDK, tracker, auth, RPC, database schema, ClickHouse, or shared packages.
- databuddy-integrationHelp users integrate Databuddy into their own products. Use when the user wants to install or use Databuddy's SDK, React or Vue component, tracker helpers, Node SDK, server-side feature flags, REST API, event tracking endpoint, or LLM observability package.
- desloppifyReduce codebase slop by deleting code, flattening abstractions, and replacing custom helpers/types/assertions with native SDK/npm helpers or straightforward schemas (for example Zod). Use when asked to simplify, delete code, or "desloppify" TypeScript/Bun/Nuxt code.
- react-doctorDiagnose and fix React codebase health issues. Use when reviewing React code, fixing performance problems, auditing security, or improving code quality.
- typescript-bun-drizzle-qualityBuild or review Bun fullstack TypeScript code with Drizzle-backed SQL. Use for backend or cross-layer changes touching API/domain logic, schema or query design, migrations, runtime/type debugging, and boundary validation between contracts, business rules, and persistence.