Files
agentic-dev/packages/marketing-pages/AGENTS.md

3.4 KiB

AGENTS.md — marketing-pages

Pages collection and SiteSettings global for site-wide metadata. Provides marketing/landing page content, SEO settings, and site configuration via Payload.

What it owns

  • Entities — Page type (slug, title, content, published), SiteSettings type (site name, description, logo)
  • Use cases — Get page, list pages, publish page, get site settings, update settings
  • Repository interfacesIPagesRepository, ISiteSettingsRepository
  • Mock repositories — In-memory stores for tests
  • Payload repositories — Real Payload-backed repositories (constructor-injected at boot)
  • Payload collection — Pages collection definition
  • Payload global — SiteSettings global definition
  • tRPC router — Procedures for list pages, get page, get site settings
  • DI container — Per-feature InversifyJS container with marketing-pages symbols
  • UI components — Page display, hero section, CTA blocks, footer with site settings

Public exports

From package.json:

  • . — Page type, SiteSettings type, UI components
  • ./api — tRPC router (marketingPagesRouter)
  • ./cms — Payload Pages collection + SiteSettings global (as separate exports)
  • ./di/bind-productionbindProductionMarketing() to wire Payload repos at boot

What it must NOT import

  • Any other feature package (@repo/auth, @repo/blog, 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

// ✓ Correct
import type { IPagesRepository } from "../repositories/pages.repository.interface.js";

// ✗ Wrong
import { Page } from "@/entities/page.js";

Tests use @/ alias

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

DI container is per-feature

Tests rebind:

import { container as marketingContainer, MARKETING_SYMBOLS } from "@/di/container.js";
import { MockPagesRepository } from "@/infrastructure/repositories/mock-pages.repository.js";

beforeEach(() => {
  marketingContainer.unbindAll();
  marketingContainer.bind(MARKETING_SYMBOLS.IPagesRepository).to(MockPagesRepository);
});

Test conventions

  • Unit tests colocated: *.test.ts
  • Feature tests in tests/: *.feature.test.ts
  • Vitest environmentnode
  • Alias@/ resolves to src/
  • Runpnpm test --filter @repo/marketing-pages

Structure (minimal)

src/
  entities/
    page.ts
    site-settings.ts
    errors.ts
  application/
    repositories/
      pages.repository.interface.ts
      site-settings.repository.interface.ts
    use-cases/
      get-page.use-case.ts
      list-pages.use-case.ts
      get-site-settings.use-case.ts
  infrastructure/
    repositories/
      payload-pages.repository.ts
      payload-site-settings.repository.ts
      mock-pages.repository.ts
      mock-site-settings.repository.ts
  di/
    symbols.ts
    container.ts
    bind-production.ts
  interface-adapters/
    controllers/
      pages.controller.ts
  integrations/
    cms/
      collections/
        pages.ts
      globals/
        site-settings.ts
      index.ts
    api/
      router.ts
      index.ts
  ui/
    page-display.tsx
    hero-section.tsx
    footer.tsx
  index.ts
tests/
  publish-page.feature.test.ts