write-service-codelisted
Install: claude install-skill kennguyen887/agent-foundation
## When to use
Reach for this when you're writing the **body** of a handler/service/query/event/test and want the
team's implementation conventions — readability, async, nullability, SQL performance, messaging,
logging, and test shape. For *where files go and what they're named*, use the companion skill
[structure-a-backend-service](./structure-a-backend-service.md).
Each rule: **portable principle** → **▸ Example (TS/NestJS)** (neutral `listing` domain;
`<Entity>`/`<feature>` = rename) → **▸ Other stacks**. Some rules restate global policy; the global
rule stays authoritative (see Related).
## Steps
### 1. Control flow — return early, no manual loops
- **Return (or throw) early; don't nest.** Handle the invalid/empty case first and bail, so the
happy path stays unindented.
```ts
if (minPrice == null && maxPrice == null) return; // guard
if (!items?.length) return null;
// ...happy path, never more than ~2 levels deep
```
- **Transform collections with pipeline functions, not `for`/`while`.** `map`/`filter`/`reduce`/
`find`/`some`/`every`/`flatMap`. Keep callbacks pure (no mutating the source).
```ts
const coverIds = media.filter((m) => m.type === MediaType.COVER).map((m) => m.id);
const labelByCode = categories.reduce((acc, c) => { acc[c.code] = c.label; return acc; }, {} as Record<string, string>);
```
- **Imperative iteration only for:** side effects (`forEach` / `for...of` to mutate external state,
dispatch, log) and **sequential async tha