refactor(marketing-pages)!: delete marketing-pages demo feature

Veect retrofit (ADR-027): fourth slice of the demo-content removal.
Deletes packages/marketing-pages whole and prunes every composition
edge in one commit: core-api router mount + dep, core-cms
collection/global composition + dep + regenerated Payload types,
web-next bindAll (prod + dev-seed) + tests + about page + Tailwind
source + transpilePackages + dep, cms/core-cms payload config test
assertions, marketing-page e2e spec, tsconfig paths, fallow ignore
entry, anchor-guard + generator e2e feature lists, compliance
data-map + retention-policy regeneration, lockfile prune, and
feature-list doc entries (CLAUDE.md, AGENTS.md, glossary, app/feature
AGENTS.md).

Event teardown: marketing-pages was the sole consumer of
auth.user.signed-up (welcome-email handler + job). The handler, its
Payload tasks, and the bus subscription all lived inside the package's
own binders, so they die with it — no other package wires the
subscription. Auth's manifest `publishes` stays untouched: a publisher
with zero consumers is legal (pnpm conformance only fails on orphan
consumers, verified green). The app-level sign-up-welcome-email test
asserted the marketing-pages mailer stays empty without a bus; it is
deleted with the feature, and the now-unused test-only bind-state
helpers in web-next bind-production.ts go with it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
2026-07-12 16:53:44 +02:00
parent 7dd3e7ceac
commit 9ee941863d
108 changed files with 35 additions and 3205 deletions

View File

@@ -44,7 +44,7 @@ See `docs/guides/tdd-workflow.md` for the full cycle.
## Project Overview
Turborepo + pnpm monorepo organized by vertical features. Each feature (`auth`, `marketing-pages`, `navigation`) owns its Clean Architecture layers. Must-have core packages (`core-shared`, `core-cms`, `core-api`) provide foundation; five optional core packages (`core-realtime`, `core-events`, `core-trpc`, `core-ui`, `core-audit`) scaffold on demand via `pnpm turbo gen core-package <name>` (see `docs/architecture/template-tiers.md`). Two tooling packages (`core-eslint`, `core-typescript`) provide shared configs. Workspace boundaries are enforced by ESLint (lint-time) and Turborepo (build-graph time). Supports Next.js and TanStack Start as frontend frameworks, Payload CMS for content management, and comprehensive agent-optimized documentation.
Turborepo + pnpm monorepo organized by vertical features. Each feature (`auth`, `navigation`) owns its Clean Architecture layers. Must-have core packages (`core-shared`, `core-cms`, `core-api`) provide foundation; five optional core packages (`core-realtime`, `core-events`, `core-trpc`, `core-ui`, `core-audit`) scaffold on demand via `pnpm turbo gen core-package <name>` (see `docs/architecture/template-tiers.md`). Two tooling packages (`core-eslint`, `core-typescript`) provide shared configs. Workspace boundaries are enforced by ESLint (lint-time) and Turborepo (build-graph time). Supports Next.js and TanStack Start as frontend frameworks, Payload CMS for content management, and comprehensive agent-optimized documentation.
## Read First
@@ -95,7 +95,7 @@ See `docs/guides/coverage.md` for the cookbook and ADR-020 for the full rational
## Key Conventions
- **Conventional Commits (non-negotiable)** Every commit message MUST follow the [Conventional Commits](https://www.conventionalcommits.org/) spec: `<type>(<scope>): <imperative subject>` (≤72 chars). Types: `feat | fix | docs | style | refactor | test | chore | perf | ci | build | revert`. Use `!` after type/scope for breaking changes. Body explains WHY if non-obvious. Examples: `feat(auth): hash password before persisting`, `test(blog): assert article not found error`, `refactor(docs)!: consolidate scaffolding into guides`. The sandcastle implementer + reviewer prompts both enforce this; agents authoring commits autonomously MUST honor it. Commits become versions + changelog entries automatically via release-please (ADR-021 / `docs/guides/releasing.md`).
- **Versioning is hybrid (ADR-021)** Root template (`template-vertical`) + 3 feature packages (`@repo/{auth,marketing-pages,navigation}`) each version independently from `0.1.0`. release-please reads Conventional Commits since the last tag and opens a rolling release PR on every merge to main; merging it cuts per-package tags (`template-v0.2.0`, `auth-v0.1.1`, etc.) + GitHub releases. **Bump targeting is by commit path** files under `packages/<feature>/**` bump that feature; cross-cutting paths (`docs/`, `scripts/`, `.github/`, root configs) bump the root. Pre-1.0 policy: `feat:` patch, `feat!:` minor.
- **Versioning is hybrid (ADR-021)** Root template (`template-vertical`) + 2 feature packages (`@repo/{auth,navigation}`) each version independently from `0.1.0`. release-please reads Conventional Commits since the last tag and opens a rolling release PR on every merge to main; merging it cuts per-package tags (`template-v0.2.0`, `auth-v0.1.1`, etc.) + GitHub releases. **Bump targeting is by commit path** files under `packages/<feature>/**` bump that feature; cross-cutting paths (`docs/`, `scripts/`, `.github/`, root configs) bump the root. Pre-1.0 policy: `feat:` patch, `feat!:` minor.
- **Relative imports in `src/`** Source files use relative paths (`../repositories/...`), not `@/` alias
- **`@/` alias in tests** Test files (`*.test.ts`) use `@/` to import from `src/`
- **`vitest.config.ts`** Every package must define `resolve.alias: { "@": path.resolve(__dirname, "./src") }`
@@ -119,7 +119,7 @@ See `docs/guides/coverage.md` for the cookbook and ADR-020 for the full rational
- **PII handling is non-negotiable** `sendDefaultPii: false` everywhere (CI grep gate); replay default-masks all text/inputs/media (allowlist starts empty); `setUser({ id })` only no email/username; server-side PII scrubbing happens at the OTel processor layer (`PiiScrubSpanProcessor` + `PiiScrubLogRecordProcessor`) before any exporter sees the data (ADR-017 §7)
- **Two apps, two Sentry projects** `WEB_NEXT_SENTRY_DSN`, `CMS_SENTRY_DSN`. The browser DSN uses the `NEXT_PUBLIC_` prefix (web-next)
- **Instrumentation binding is orthogonal to repo binding** `bindAll()`'s Rule 0 (DSN OTel+Sentry vs Noop) is independent of `USE_DEV_SEED` / `NODE_ENV`. Run `pnpm dev` with `WEB_NEXT_SENTRY_DSN` set to test the integration locally
- **Cross-feature events go through `IEventBus` (E0)** In-feature reactions are direct use-case calls, not bus publishes. The bus is for _crossing_ feature boundaries (e.g. `auth` `marketing-pages` welcome email)
- **Cross-feature events go through `IEventBus` (E0)** In-feature reactions are direct use-case calls, not bus publishes. The bus is for _crossing_ feature boundaries (e.g. an `auth` signed-up event consumed by another feature)
- **Event contracts are public; handlers are private (E1)** Publisher's `events/<x>.event.ts` is exported from the feature root barrel. Consumer's `events/handlers/on-<publisher>-<event>.handler.ts` is never re-exported (ESLint-enforced via `core-eslint/rules/no-handler-reexport`)
- **Jobs are for _deferred_ work, not abstraction (J0)** Synchronous code stays synchronous. A job exists only when something must run off the request path (latency, retries, cron). Feature packages enqueue via `IJobQueue` only direct `payload.jobs.queue()` is ESLint-blocked outside `core-shared/jobs/`
- **Realtime is for state delivery, not for replacing tRPC (R0)** Persistent request/response operations belong on tRPC procedures. Use realtime when the server needs to push without a request or the data is too high-frequency for HTTP