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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user