refactor(domain): enrich NoteInput with extractScopeAndTags (#210) - #216
Merged
Conversation
Move tag/scope extraction from Parser into NoteInput, making the domain layer the primary owner of this invariant. - SCOPE_DEFAULT migrated from src/vscode/conf.ts to src/model/config.ts (re-exported from vscode layer for backward compat) - Input._text/_scope/_tags changed private → protected to enable subclass method; _scope initializes to SCOPE_DEFAULT at field declaration - NoteInput.extractScopeAndTags(availableScopes) added: uses hardened regex /#\w+(?:\s|$)/g to handle end-of-string tags; no state reset - Parser.resolveNotePathForInput delegates to extractScopeAndTags; removes inline tag loop and SCOPE_DEFAULT/isNullOrUndefined imports - LoadNotes constructor narrowed from Input to NoteInput; callers updated with type assertions where parseInput() return type is still Input - 5 unit tests added to input.test.ts (no vscode API needed) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Owner
Author
Architecture Review: Final Approval (PR #216)I have performed a critical architectural and OOP-focused review of this PR. The implementation is technically sound and represents a significant maturity leap for our domain layer. Key Achievements:
Final Observation:While the type assertions ( This is a high-quality, domain-driven refactor. LGTM. Note: Gemini was involved in creating this comment (but not without consulting me). |
The (input as NoteInput) cast is TypeScript-only; at runtime Parser receives plain Input objects from parseInput(), causing "extractScopeAndTags is not a function". The service contract resolveNotePathForInput(input: Input) requires the method on Input. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SCOPE_DEFAULTfromsrc/vscode/conf.ts→src/model/config.ts(re-exported for backward compat)Input._text/_scope/_tagsfromprivate→protected;_scopeinitializes toSCOPE_DEFAULTat field declaration (no more empty-string default)NoteInput.extractScopeAndTags(availableScopes: string[]): voidwith hardened regex/#\w+(?:\s|$)/g(handles end-of-string tags)Parser.resolveNotePathForInputdelegates toextractScopeAndTags; removes inline tag loop and now-unused importsLoadNotesconstructor narrowed toNoteInput; callers updated with type assertionsCloses #210
Spec: docs/specs/2026-05-17-210-rich-domain-models.md
Plan: docs/plans/2026-05-17-210-rich-domain-models.md
Test plan
npm run compile— clean buildnpx tsc --noEmit— no type errorsNoteInput.extractScopeAndTagssuite (5 scenarios including end-of-string regex coverage)#scopetag, verify scope routing and tag stripping🤖 Generated with Claude Code