Convention now: <name>.repository.{ts,mock.ts,interface.ts}.
Renames .mock prefix to .mock suffix; drops .payload prefix from real
impls (canonical name = real impl); dot-separates the .repository
qualifier in interface filenames. Class names follow suit:
PayloadXRepository → XRepository; Mock* unchanged.
Refactor log: §1, §3
Spec: §9.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
13 KiB
Refactor Changelog — Lazar Pattern Conformance
Started: 2026-05-05 Spec: 2026-05-05-lazar-pattern-conformance-design.md Plan: 2026-05-05-plan-8-lazar-conformance.md Branch: feature/lazar-conformance
This document captures every architectural change made during Plan 8 execution, organized by category. After the plan is merged, use the "Doc update checklist" at the bottom to update external docs in a single follow-up pass.
Summary
(Filled in at Task 10 — total files added/modified/deleted/renamed; net test count change; commits.)
1. File renames (before → after)
Task 3: File and class renames
File renames — 27 files (git mv — history preserved):
auth:
packages/auth/src/infrastructure/repositories/mock-users.repository.ts→users.repository.mock.tspackages/auth/src/infrastructure/repositories/mock-users.repository.test.ts→users.repository.mock.test.tspackages/auth/src/application/repositories/users-repository.interface.ts→users.repository.interface.tspackages/auth/src/infrastructure/services/mock-authentication.service.ts→authentication.service.mock.tspackages/auth/src/application/services/authentication-service.interface.ts→authentication.service.interface.ts
blog:
packages/blog/src/infrastructure/repositories/mock-articles.repository.ts→articles.repository.mock.tspackages/blog/src/infrastructure/repositories/mock-articles.repository.test.ts→articles.repository.mock.test.tspackages/blog/src/infrastructure/repositories/payload-articles.repository.ts→articles.repository.tspackages/blog/src/infrastructure/repositories/payload-articles.repository.test.ts→articles.repository.test.tspackages/blog/src/application/repositories/articles-repository.interface.ts→articles.repository.interface.ts
marketing-pages:
packages/marketing-pages/src/infrastructure/repositories/mock-pages.repository.ts→pages.repository.mock.tspackages/marketing-pages/src/infrastructure/repositories/mock-pages.repository.test.ts→pages.repository.mock.test.tspackages/marketing-pages/src/infrastructure/repositories/payload-pages.repository.ts→pages.repository.tspackages/marketing-pages/src/infrastructure/repositories/payload-pages.repository.test.ts→pages.repository.test.tspackages/marketing-pages/src/application/repositories/pages-repository.interface.ts→pages.repository.interface.tspackages/marketing-pages/src/infrastructure/repositories/mock-site-settings.repository.ts→site-settings.repository.mock.tspackages/marketing-pages/src/infrastructure/repositories/mock-site-settings.repository.test.ts→site-settings.repository.mock.test.tspackages/marketing-pages/src/infrastructure/repositories/payload-site-settings.repository.ts→site-settings.repository.tspackages/marketing-pages/src/infrastructure/repositories/payload-site-settings.repository.test.ts→site-settings.repository.test.tspackages/marketing-pages/src/application/repositories/site-settings-repository.interface.ts→site-settings.repository.interface.ts
navigation:
packages/navigation/src/infrastructure/repositories/mock-header.repository.ts→header.repository.mock.tspackages/navigation/src/infrastructure/repositories/mock-header.repository.test.ts→header.repository.mock.test.tspackages/navigation/src/infrastructure/repositories/payload-header.repository.ts→header.repository.tspackages/navigation/src/infrastructure/repositories/payload-header.repository.test.ts→header.repository.test.tspackages/navigation/src/application/repositories/header-repository.interface.ts→header.repository.interface.ts
Class renames (4 classes — Payload prefix dropped; Mock prefix unchanged):
PayloadArticlesRepository→ArticlesRepository(inarticles.repository.ts)PayloadPagesRepository→PagesRepository(inpages.repository.ts)PayloadSiteSettingsRepository→SiteSettingsRepository(insite-settings.repository.ts)PayloadHeaderRepository→HeaderRepository(inheader.repository.ts)
Consumers updated (imports + class references): DI modules, bind-production files, contract suites, use case source files, use case tests, controller tests, router tests, feature tests — approximately 35 files total.
Task 2: Entities split
Entity model moves (git mv — history preserved):
packages/auth/src/entities/user.ts→packages/auth/src/entities/models/user.tspackages/auth/src/entities/user.test.ts→packages/auth/src/entities/models/user.test.tspackages/auth/src/entities/session.ts→packages/auth/src/entities/models/session.tspackages/auth/src/entities/session.test.ts→packages/auth/src/entities/models/session.test.tspackages/auth/src/entities/cookie.ts→packages/auth/src/entities/models/cookie.tspackages/auth/src/entities/errors.test.ts→packages/auth/src/entities/errors/errors.test.tspackages/blog/src/entities/article.ts→packages/blog/src/entities/models/article.tspackages/blog/src/entities/article.test.ts→packages/blog/src/entities/models/article.test.tspackages/blog/src/entities/errors.test.ts→packages/blog/src/entities/errors/errors.test.tspackages/marketing-pages/src/entities/page.ts→packages/marketing-pages/src/entities/models/page.tspackages/marketing-pages/src/entities/page.test.ts→packages/marketing-pages/src/entities/models/page.test.tspackages/marketing-pages/src/entities/site-settings.ts→packages/marketing-pages/src/entities/models/site-settings.tspackages/marketing-pages/src/entities/site-settings.test.ts→packages/marketing-pages/src/entities/models/site-settings.test.tspackages/marketing-pages/src/entities/errors.test.ts→packages/marketing-pages/src/entities/errors/errors.test.tspackages/navigation/src/entities/header.ts→packages/navigation/src/entities/models/header.tspackages/navigation/src/entities/header.test.ts→packages/navigation/src/entities/models/header.test.ts
2. Files added (with purpose)
Task 2: Entities split — new error files
packages/auth/src/entities/errors/auth.ts— AuthenticationError, UnauthenticatedError, UnauthorizedError (split from errors.ts)packages/auth/src/entities/errors/common.ts— InputParseError (auth copy)packages/blog/src/entities/errors/article.ts— ArticleNotFoundError (split from errors.ts)packages/blog/src/entities/errors/common.ts— InputParseError (blog copy)packages/marketing-pages/src/entities/errors/page.ts— PageNotFoundError (split from errors.ts)packages/marketing-pages/src/entities/errors/common.ts— InputParseError (marketing-pages copy)packages/navigation/src/entities/errors/header.ts— HeaderNotFoundError (new; navigation had no errors.ts)packages/navigation/src/entities/errors/common.ts— InputParseError (navigation copy)
3. Files deleted (with reason)
Task 2: Entities split — old errors.ts files removed
packages/auth/src/entities/errors.ts— replaced byerrors/auth.ts+errors/common.tspackages/blog/src/entities/errors.ts— replaced byerrors/article.ts+errors/common.tspackages/marketing-pages/src/entities/errors.ts— replaced byerrors/page.ts+errors/common.ts- (navigation had no
errors.tsto delete)
4. Pattern changes (code-level)
4.1 Use cases — factory function pattern
(populated when a use case is migrated)
4.2 Controllers — one per use case
(populated when controllers are split)
4.3 Entities split — models/ + errors/ subdirs
Pattern now in place across auth, blog, marketing-pages, navigation (media skipped — no entities yet):
- Entity Zod schemas + types live at
entities/models/<x>.ts - Domain errors live at
entities/errors/<domain>.ts(e.g.errors/auth.ts,errors/article.ts) - Shared
InputParseErrorlives atentities/errors/common.ts(one copy per feature — ~6 lines each) - Colocated entity test files moved alongside their respective sources (
models/*.test.ts,errors/errors.test.ts) - All imports across factories, contracts, repositories, use cases, controllers, tests, and
src/index.tsupdated to new paths - navigation divergence: no
errors.tsexisted pre-refactor;errors/header.ts(HeaderNotFoundError) anderrors/common.tsadded as new forward-looking stubs
5. DI changes
5.1 Inversify .toDynamicValue bindings
(populated when DI modules are updated)
5.2 Mock siblings registered as default bindings
(populated when modules are updated)
6. Test refactor patterns
6.1 Direct injection (no container rebinding)
(populated when tests are migrated)
7. Open issues / deferred decisions
(populated as encountered)
Doc update checklist (deferred — run after merge)
After Plan 8 is merged to main, work through this list in a single
batched doc-update pass. Each item points at an external doc that
references the pre-Plan-8 layout or pattern and needs to be brought
in line.
CLAUDE.md— Key Conventions section: update file path examples to useentities/models/<x>.ts; mention factory-function use cases; showI*UseCasetype aliasesAGENTS.md(root) — Per-Package Conventions: update naming examples (<x>.repository.{ts,mock.ts,interface.ts}); add note aboutI*UseCase/I*Controllertype aliases; document factory-style DIdocs/guides/adding-a-feature.md— restructure to use factory-function pattern in every step; update file paths to new layout; show.toDynamicValue()bindingsdocs/guides/tdd-workflow.md— update "When to mock" decision tree to show direct factory injection (signInUseCase(mocks)(input)) instead of container rebinding; update factory usage examples to referenceentities/models/*pathsdocs/guides/testing-strategy.md— Mocking section: remove DI-rebinding pattern as the default; show direct factory injectiondocs/architecture/vertical-feature-spec.md— update §10 (file shape examples) to new template; update §13 (testing) to reflect factory pattern + direct injectiondocs/architecture/overview.md— layer descriptions: mention factory-function use cases; add note that controllers are one-per-use-casedocs/architecture/dependency-flow.md— verify dep flow still accurate with new DI bindings; update examples if any reference old pathsdocs/decisions/adr-012-lazar-conformance.md— NEW ADR documenting the conformance decision and the four intentional divergences (per-feature DI, inversify retained, colocated tests, no Sentry/instrumentation services)- Per-feature
AGENTS.md(auth/blog/media/marketing-pages/navigation) — update file path references; document factory pattern; update Tests section packages/core-testing/AGENTS.md— update factory examples to referenceentities/models/<x>.tspathspackages/auth/AGENTS.md— document the new realUsersRepositoryandAuthenticationService(Payload-backed)packages/media/AGENTS.md— full rewrite — media now has all Clean Architecture layers (entities, application, infrastructure, interface-adapters, DI, integrations/api)- Plan 7 plan/spec docs — add a one-line note at the top noting that paths reference the pre-Plan-8 layout; link to refactor changelog
Notes for the doc-update pass author
When updating external docs, apply these substitutions globally:
| Old reference | New reference |
|---|---|
entities/<x>.ts |
entities/models/<x>.ts |
entities/errors.ts |
entities/errors/<domain>.ts (or entities/errors/common.ts) |
mock-<x>.repository.ts |
<x>.repository.mock.ts |
payload-<x>.repository.ts |
<x>.repository.ts (real impl is now the canonical name) |
<x>-repository.interface.ts |
<x>.repository.interface.ts |
class PayloadXRepository |
class XRepository |
Use case calls container.get(...) inside its body |
Use case is a factory function: (deps) => async (input) => result |
Controller bundles multiple methods (articles.controller.ts) |
One controller per use case (get-articles.controller.ts, create-article.controller.ts) |
Test does container.unbind(...).bind(...) in beforeEach |
Test constructs mocks and injects: const useCase = signInUseCase(mockUsers, mockAuth); |
DI binds use case with .to(...) |
DI binds use case with .toDynamicValue((ctx) => factoryFn(ctx.container.get(...))) |
| Use case + controller imports inject via container | Imports take dependencies as constructor/factory args |
Add I*UseCase and I*Controller type alias examples wherever use cases / controllers are explained.