vertical-slices

$npx mdskill add databuddy-analytics/Databuddy/vertical-slices

Build 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