Files
agentic-dev/packages/blog/AGENTS.md
Danijel Martinek 5ea4c67f93 docs(adr): ADR-011 TDD foundation; update AGENTS.md per-feature
Captures the decision to add @repo/core-testing, factories, contract
suites, vitest safety defaults, coverage thresholds, Storybook
test-runner, and CI as one cohesive TDD foundation. Per-feature
AGENTS.md gains a Tests section pointing to factories, contract suite,
and the canonical test commands.

Spec: §7.4, §7.5

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 19:31:31 +02:00

4.5 KiB

AGENTS.md — blog

Articles collection + content use cases (get article, list articles, create, publish, unpublish). Provides the Articles Payload collection and tRPC procedures for content management and retrieval.

What it owns

  • Entities — Article type, article-related errors (ArticleNotFound, InvalidSlug)
  • Use cases — Get article, list articles, create, publish, unpublish, delete
  • Repository interfaceIArticlesRepository for article persistence
  • Mock repository — In-memory article store for tests
  • Payload repository — Real Payload-backed article repository (constructor-injected at boot)
  • Payload collection — Articles collection definition + hooks (publish timestamp, slugify)
  • tRPC router — Procedures for list, get-by-slug, create, publish
  • DI container — Per-feature InversifyJS container with blog symbols
  • UI components — Article-specific components (ArticleCard, ArticleList, etc.)

Public exports

From package.json:

  • . — Article type + blog errors + UI components
  • ./api — tRPC router (blogRouter)
  • ./cms — Payload Articles collection
  • ./di/bind-productionbindProductionArticles() to wire Payload repo at boot

What it must NOT import

  • Any other feature package (@repo/auth, @repo/media, etc.)
  • Any app package
  • @repo/core-api, @repo/core-cms, @repo/core-trpc, @repo/core-ui directly; only import from @repo/core-shared and use DI for Payload config

Layer rules

src/ files use relative imports

Avoid @/ in source code:

// ✓ Correct
import type { IArticlesRepository } from "../repositories/articles.repository.interface.js";

// ✗ Wrong (don't do this in src/)
import { Article } from "@/entities/article.js";

Tests use @/ alias

Test files use @/:

// ✓ Correct
import { getArticleUseCase } from "@/application/use-cases/get-article.use-case.js";

DI container is per-feature

Tests rebind their own container:

import { container as blogContainer, BLOG_SYMBOLS } from "@/di/container.js";
import { MockArticlesRepository } from "@/infrastructure/repositories/mock-articles.repository.js";

beforeEach(() => {
  blogContainer.unbindAll();
  blogContainer.bind(BLOG_SYMBOLS.IArticlesRepository).to(MockArticlesRepository);
});

Test conventions

  • Unit tests colocated with source: *.test.ts suffix
  • Feature tests in tests/ folder: *.feature.test.ts suffix (cross-layer tests like publish flow)
  • Vitest environmentnode
  • Alias@/ resolves to src/
  • Runpnpm test --filter @repo/blog

Covered areas: article CRUD use cases, slug validation, publish/unpublish flows, DI container binding.

Tests

  • Factories: src/__factories__/article.factory.ts — use articleFactory.build({ overrides }) to construct test data with stable defaults.
  • Contract suite: src/__contracts__/articles-repository.contract.ts — runs against every repository implementation (mock + payload).
  • Unit tests: colocated as *.test.ts next to the source file.
  • Feature integration: tests/articles.feature.test.ts — full slice through tRPC router → controller → use case → mock repo.
pnpm test --filter @repo/blog           # all tests for this feature
pnpm test --filter @repo/blog -- --watch # watch mode

See docs/guides/tdd-workflow.md for the cycle.

Structure

src/
  entities/
    article.ts               # Article schema + type
    errors.ts                # ArticleNotFound, InvalidSlug, etc.
  application/
    repositories/
      articles.repository.interface.ts
    use-cases/
      get-article.use-case.ts
      list-articles.use-case.ts
      publish-article.use-case.ts
  infrastructure/
    repositories/
      payload-articles.repository.ts   # constructor-injected: Config
      mock-articles.repository.ts
  di/
    symbols.ts               # BLOG_SYMBOLS
    container.ts             # blogContainer
    bind-production.ts       # bindProductionArticles(container, config)
  interface-adapters/
    controllers/
      articles.controller.ts # input validation
  integrations/
    cms/
      collections/
        articles.ts          # Payload CollectionConfig
      hooks/
        after-publish.ts     # revalidate, effects
      index.ts
    api/
      router.ts              # tRPC procedures
      index.ts
  ui/
    article-card.tsx
    article-list.tsx
    query.ts                 # typed tRPC query helpers
  index.ts                   # re-exports: Article, UI components
tests/
  publish-article.feature.test.ts