Commit Graph

33 Commits

Author SHA1 Message Date
a4c4ca6b6e refactor(features): split entities into models/ + errors/ subdirs
All 5 features (auth, blog, marketing-pages, navigation; media has no
entities yet) now follow Lazar's pattern:
- entities/<x>.ts → entities/models/<x>.ts
- entities/errors.ts → entities/errors/<domain>.ts + errors/common.ts

Updates all import paths across factories, contracts, tests, use cases,
controllers, repositories, integrations, and src/index.ts exports.

navigation divergence: had no errors.ts; errors/header.ts +
errors/common.ts added as new forward-looking stubs.

Refactor log: docs/superpowers/refactor-logs/2026-05-05-lazar-pattern-conformance.md
Spec: §5, §9.3

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 23:34:32 +02:00
9415eb1c5a test: enforce per-directory coverage thresholds
entities + use-cases + controllers must hit 100% (95% branches).
Project-wide baseline remains 80/75/80/80. Tightening these directories
reflects the architectural intent: these are the pure-logic layers and
should be exhaustively tested.

Added @vitest/coverage-v8@^3 to core-typescript, auth, blog,
marketing-pages, and navigation devDependencies.

Excluded from coverage (legitimately untestable):
- src/di/bind-production.ts — InversifyJS startup bootstrap
- src/application/repositories/** — pure TypeScript interfaces
- src/application/services/** — pure TypeScript interfaces (auth)
- src/integrations/cms/** — declarative Payload CMS config
- src/entities/cookie.ts — pure type aliases (auth)
- src/ui/** — React Query helpers, integration-tested in apps

Tests added (6 new files / 1 extended):
- auth/src/entities/errors.test.ts — UnauthenticatedError, UnauthorizedError,
  AuthenticationError, InputParseError constructors
- blog/src/entities/errors.test.ts — ArticleNotFoundError (default + custom
  message), InputParseError
- marketing-pages/src/entities/errors.test.ts — PageNotFoundError, InputParseError
- marketing-pages/src/entities/site-settings.test.ts — siteSettingsSchema
  (valid, no description, empty name rejection)
- navigation/src/entities/header.test.ts — headerItemSchema and headerSchema
  validation paths
- navigation/src/.../payload-header.repository.test.ts — logo relation-object,
  scalar-id, null, and null-item-field branches for full branch coverage

Spec: §6.9
2026-05-05 19:51:34 +02:00
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
b3c903fd36 fix(tests): address Task 4 code review feedback
- Deprecate mockPayloadModule with throw guard (hoisting incompatible)
- Replace `as never` with stubPayloadConfig in payload-articles test (consistency)
- Tighten pages contract to use toHaveLength (exact assertions)
- Header contract: define CONTRACT_HEADER_SEED, assert item count + order

Reviewer: superpowers:code-reviewer (Task 4 of Plan 7).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 16:04:07 +02:00
e1355e6bc7 feat(features): contract suites for all repository interfaces
Each repository interface now has a contract suite under
src/__contracts__/. Both Mock and Payload implementations run the
same suite, eliminating mock-vs-real drift. Payload impls back the
contract with an in-memory stub via vi.mock('payload') + a small
buildPayloadStub helper.

Spec: §5.2, §6.4
2026-05-05 15:28:38 +02:00
a74f217703 fix(features): address Task 3 code review feedback
- Add navItemFactory to navigation (spec §5.1 — was missing)
- Refactor blog/router.test.ts to use articleFactory (eliminate new Date())
- headerFactory uses sequence for logoId (deterministic buildList output)
- Align media/tsconfig.json with other features (jsx + tests/ include)
- Refactor auth/container.test.ts to use userFactory

Reviewer: superpowers:code-reviewer (Task 3 of Plan 7).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 15:18:35 +02:00
53c2fbb9e1 feat(features): add test factories to all 5 features
Adds src/__factories__/<entity>.factory.ts to auth, blog, marketing-pages,
navigation, media. Each factory uses defineFactory from @repo/core-testing
with stable date defaults (2026-01-01) so snapshot diffs reflect SUT
behavior only. Refactors mechanical inline-fixture tests to use factories.

Also adds vitest.config.ts and tsconfig path alias to @repo/media (lacked
both), and adds @repo/core-testing devDependency to @repo/media.

Spec: §5.1, §6.3
2026-05-05 14:56:50 +02:00
bf6affd404 feat(core-typescript): split vitest base into node + jsdom flavors
Adds vitest.base.node and vitest.base.jsdom with safety defaults
(clearMocks, restoreMocks, mockReset, unstubGlobals, sequence.shuffle)
and coverage thresholds (80/75/80/80). Migrates all feature configs
to the new base. Existing baseVitestConfig kept as backwards-compat
re-export of nodeVitestConfig.

Spec: §6.2
2026-05-05 14:04:19 +02:00
0972645ebb refactor: rename eslint-config + typescript-config to core-eslint + core-typescript
Aligns tooling packages with the core-* naming convention used by all
other foundation packages (core-shared, core-cms, core-api, core-trpc,
core-ui). Updates ~50 files: package.json names, devDependencies,
tsconfig extends, eslint.config imports, vitest.config imports, AGENTS.md
references, and the boundaries plugin patterns to match the new paths.

The tooling-specific patterns in boundaries/elements are now ordered BEFORE
the broader core-* pattern to ensure correct first-match-wins behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 10:37:07 +02:00
440315a4c1 docs(agents): add per-package AGENTS.md for all feature packages 2026-05-05 09:58:42 +02:00
22bee5362f feat(eslint-config): add boundaries plugin enforcing app→feature→core graph
- Install eslint-plugin-boundaries@^4.2.2 to enforce three-tag boundary model
- Configure element types: app, core-composition (core-api/core-cms), core, feature, tooling
- Enforce unidirectional dependency graph: apps→features→core, core-composition→features
- Add eslint.config.js to all 17 packages and apps (required for ESLint 9 flat config)
- Fix pre-existing linting issues to achieve clean lint pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:21:01 +02:00
1308fe4644 fix: enable overrideAccess=true for public Payload repository reads
All public pages (site settings, header, pages, articles) now bypass
Payload's access control checks when reading, as they should be publicly
accessible without authentication. This fixes 403 Forbidden errors on
homepage and article rendering.
2026-05-05 08:59:18 +02:00
f981266fd5 feat(blog): add bindProductionBlog(config) DI helper for app boot 2026-05-05 08:49:55 +02:00
ff6fec7eab fix(tsconfig): set rootDir explicitly in feature packages
TypeScript emits an informational diagnostic when source files span
multiple top-level dirs (src/ + tests/) without explicit rootDir.
Setting rootDir="." satisfies the recommendation and matches the
include pattern. Updates blog, auth, marketing-pages — and Plan 4
doc so navigation (still pending) starts correct.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 08:30:19 +02:00
aed8c9a6ad feat(core-api): compose @repo/auth/api into appRouter under 'auth' namespace 2026-05-05 08:16:25 +02:00
8667232c22 feat(blog): restore author relationship → users + featuredImage upload → media 2026-05-05 08:14:07 +02:00
e217652a87 fix(blog): remove rootDir constraint to allow tests/**/* inclusion in typecheck 2026-05-05 00:27:25 +02:00
3e6f632c4b test(blog): add feature-level test exercising router → controller → use-case → repo 2026-05-04 22:37:18 +02:00
87f43924be feat(blog): wire root barrel (entity types + ui query helpers) 2026-05-04 22:35:01 +02:00
82ef7c9ef6 feat(blog): add ui/query.ts (framework-agnostic React Query option builders) 2026-05-04 22:34:53 +02:00
1ae1702786 feat(core-api): compose @repo/blog/api into appRouter under 'blog' namespace 2026-05-04 22:34:43 +02:00
fde58f2d3d feat(blog): add tRPC router with articleBySlug + listArticles + createArticle 2026-05-04 22:32:53 +02:00
a92341fb74 feat(core-cms): compose @repo/blog/cms into payload config 2026-05-04 22:29:50 +02:00
1d59698ebe feat(blog): add articles collection (simplified — no cross-feature refs) 2026-05-04 22:27:03 +02:00
f041ae5473 feat(blog): add articles controller with Zod validation 2026-05-04 22:25:10 +02:00
b250cdff80 feat(blog): add PayloadArticlesRepository with doc-to-entity mapping 2026-05-04 22:23:31 +02:00
c00283506c feat(blog): add per-feature InversifyJS container (symbols, module, container) 2026-05-04 22:14:56 +02:00
41d7883e7a feat(blog): add MockArticlesRepository for tests 2026-05-04 22:14:14 +02:00
86228f2d3e feat(blog): add createArticleUseCase (test red until DI + mock repo exist) 2026-05-04 22:13:31 +02:00
b0dab254d1 feat(blog): add getArticlesUseCase (test red until DI + mock repo exist) 2026-05-04 22:13:00 +02:00
ab11f42e8d feat(blog): add IArticlesRepository interface 2026-05-04 22:11:17 +02:00
692ee58365 feat(blog): add Article entity with rich-text content + domain errors 2026-05-04 22:11:08 +02:00
161c858f32 feat(blog): scaffold empty package with feature tag + path aliases 2026-05-04 22:09:58 +02:00