Session: you-are-a-senior-harmonic-dolphin-subagent-a7fab103 — 2026-04-27

workspace-doctolib · Claude · branch HEAD · claude-sonnet-4-6 · 2026-04-27 15:47 · 1 msgs · 37 tools · 16 min read · updated 9 days ago

Review the frontend architecture of the PR on branch `fhir-2219_implement-multi-select-category-filter` in the...

tools: Bash, Read
← workspace-doctolib Download .md .txt .json
Tool calls
Bash Bash: 19 calls (51.4%) 19 Read Read: 18 calls (48.6%) 18
Token usage1.3M total
Input48
Cache creation190.0K
Cache read1.2M
Output4.4K
Cache hit ratio86%· healthy

Project: workspace-doctolib · Branch: HEAD · Mode: ` · **Model:**claude-sonnet-4-6`

Stats: 1 user messages, 37 tool calls, tools used: Bash, Read.

Conversation

Turn 1 — User

Review the frontend architecture of the PR on branch fhir-2219_implement-multi-select-category-filter in the treatment-plan repo at /Users/USER/workspace/doctolib/treatment-plan.

Run git diff origin/main...HEAD to see all changes. Also read the relevant source files directly.

Context

This PR adds a custom MultiSelectDropdown component in packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/. The directory contains: - MultiSelectDropdown.tsx — orchestrator (state + filtering logic) - MultiSelectDropdownTrigger.tsx — combobox input + clear button + chevron icon - MultiSelectDropdownPopup.tsx — fieldset/dialog with legend - MultiSelectDropdownLabel.tsx — label sub-component - MultiSelectDropdownOptions.tsx — checkbox list sub-component - hooks.tsuseDropdownClose (click-outside + Escape) - helpers.tsnormalize (diacritic stripping) - index.ts — only exports MultiSelectDropdown

The component is then consumed by: - NhrDocumentCategoryFilter.tsx (thin wrapper re-exporting props) - createNhrDocumentCategoryFilterConfig.tsx (factory)

Check for compliance with UpFront architecture patterns: separation of concerns, naming conventions, component structure, barrel exports, hook placement, helper placement, presentational vs. container split, and any anti-patterns. Report specific violations with file and line references where possible.

Turn 1 — Assistant

I'll start by examining the git diff and the relevant source files in parallel.

Tools used:

  • Bash: git diff origin/main...HEAD --name-only

Tool results:

→ result (ok): packages/tpf-national-health-records-ui/package.json packages/tpf-national-health-records-ui/src/business/factories/filters/createNhrDocumentCategoryFilterConfig.test.tsx packages/tpf-national-health-records-ui/src/business/factories/filters/createNhrDocumentCategoryFilterConfig.tsx packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdown.stories.tsx packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdown.test.tsx packa …(truncated, 1888 more chars)

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/

Tool results:

→ result (ok): helpers.test.ts helpers.ts hooks.test.tsx hooks.ts index.ts MultiSelectDropdown.stories.tsx MultiSelectDropdown.test.tsx MultiSelectDropdown.tsx MultiSelectDropdownLabel.test.tsx MultiSelectDropdownLabel.tsx MultiSelectDropdownOptions.test.tsx MultiSelectDropdownOptions.tsx MultiSelectDropdownPopup.test.tsx MultiSelectDropdownPopup.tsx MultiSelectDropdownTrigger.test.tsx MultiSelectDropdownTrigger.tsx

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdown.tsx

Tool results:

→ result (ok): 1 import type { Option } from '@doctolib/design-system/Option' 2 import { useId, useMemo, useRef, useState } from 'react' 3
4 import { MultiSelectDropdownLabel } from './MultiSelectDropdownLabel' 5 import { MultiSelectDropdownPopup } from './MultiSelectDropdownPopup' 6 import { MultiSelectDropdownTrigger } from './MultiSelectDropdownTrigger' 7 import { normalize } from './helpers' 8 import { useDropdownClose } from './hooks' 9
10 type MultiSelectDropdownProps = { 11 label: string 12 values …(truncated, 2252 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/hooks.ts

Tool results:

→ result (ok): 1 import { type RefObject, useEffect, useRef } from 'react' 2
3 export const useDropdownClose = ( 4 containerRef: RefObject<HTMLDivElement | null>, 5 onClose: () => void, 6 isOpen: boolean 7 ) => { 8 const onCloseRef = useRef(onClose) 9 // Sync ref so the stable event listeners always call the latest onClose. 10 useEffect(() => { 11 onCloseRef.current = onClose 12 }, [onClose]) 13
14 useEffect(() => { 15 if (!isOpen) return undefined 16
17 const handlePointerDown = …(truncated, 625 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/helpers.ts

Tool results:

→ result (ok): 1 export const normalize = (s: string) => 2 s 3 .normalize('NFD') 4 .replace(/\p{Diacritic}/gu, '') 5 .toLowerCase() 6

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/index.ts

Tool results:

→ result (ok): 1 export * from './MultiSelectDropdown' 2

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdownTrigger.tsx

Tool results:

→ result (ok): 1 import { ChevronDownRegularIcon } from '@doctolib/design-system-icons/ChevronDownRegularIcon' 2 import { IconButton } from '@doctolib/design-system/IconButton/v2' 3
4 type MultiSelectDropdownTriggerProps = { 5 triggerId: string 6 popupId: string 7 isOpen: boolean 8 displayLabel: string 9 searchQuery: string 10 placeholder?: string 11 hasValues: boolean 12 onInputChange: (value: string) => void 13 onInputClick: () => void 14 onClear: () => void 15 } 16
17 export const Mult …(truncated, 1459 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdownPopup.tsx

Tool results:

→ result (ok): 1 import type { Option } from '@doctolib/design-system/Option' 2
3 import { MultiSelectDropdownOptions } from './MultiSelectDropdownOptions' 4
5 type MultiSelectDropdownPopupProps = { 6 id: string 7 label: string 8 options: Option[] 9 values: string[] 10 onToggle: (value: string) => void 11 } 12
13 export const MultiSelectDropdownPopup = ({ id, label, options, values, onToggle }: MultiSelectDropdownPopupProps) => ( 14 <fieldset 15 id={id} 16 role='dialog' 17 aria-label …(truncated, 412 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdownLabel.tsx

Tool results:

→ result (ok): 1 type MultiSelectDropdownLabelProps = { 2 htmlFor: string 3 label: string 4 } 5
6 export const MultiSelectDropdownLabel = ({ htmlFor, label }: MultiSelectDropdownLabelProps) => ( 7 <label htmlFor={htmlFor} className='oxygen-input-field__label mb-1 block'> 8 {label} 9 </label> 10 ) 11

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdownOptions.tsx

Tool results:

→ result (ok): 1 import { Checkbox } from '@doctolib/design-system/Checkbox/v2' 2 import type { Option } from '@doctolib/design-system/Option' 3
4 type MultiSelectDropdownOptionsProps = { 5 options: Option[] 6 values: string[] 7 onToggle: (value: string) => void 8 } 9
10 export const MultiSelectDropdownOptions = ({ options, values, onToggle }: MultiSelectDropdownOptionsProps) => ( 11 <> 12 {options.map((option) => ( 13 <Checkbox 14 key={option.value} 15 name={option.value} 1 …(truncated, 269 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentCategoryFilter/NhrDocumentCategoryFilter.tsx

Tool results:

→ result (ok): 1 import { MultiSelectDropdown } from '#components/MultiSelectDropdown' 2 import type { ComponentProps } from 'react' 3
4 export type NhrDocumentCategoryFilterProps = ComponentProps<typeof MultiSelectDropdown> 5
6 export const NhrDocumentCategoryFilter = (props: NhrDocumentCategoryFilterProps) => <MultiSelectDropdown {...props} /> 7

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentCategoryFilter/index.ts

Tool results:

→ result (ok): 1 export * from './NhrDocumentCategoryFilter' 2

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/business/factories/filters/createNhrDocumentCategoryFilterConfig.tsx

Tool results:

→ result (ok): 1 import { NhrDocumentCategoryFilter } from '#components/NhrDocumentList/NhrDocumentCategoryFilter' 2 import type { Option } from '@doctolib/design-system/Option' 3
4 import type { FilterConfig } from '../../../types' 5
6 export const createNhrDocumentCategoryFilterConfig = ({ 7 options = [], 8 label = 'Document Category', 9 placeholder, 10 }: { 11 options?: Option[] 12 label?: string 13 placeholder?: string 14 } = {}): FilterConfig => ({ 15 key: 'typeCodes', 16 render: (filter …(truncated, 651 more chars)

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/

Tool results:

→ result (ok): tests business components dev entry.ts i18n.test.ts i18n.ts index.ts locales test-helpers types.ts utils

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/business/factories/filters/

Tool results:

→ result (ok): createNhrDateSelectionFilterConfig.test.tsx createNhrDateSelectionFilterConfig.tsx createNhrDocumentCategoryFilterConfig.test.tsx createNhrDocumentCategoryFilterConfig.tsx createNhrDocumentStatusFilterConfig.test.tsx createNhrDocumentStatusFilterConfig.tsx createNhrDocumentVisibilityFilterConfig.test.tsx createNhrDocumentVisibilityFilterConfig.tsx

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/hooks/ 2>/dev/null || echo "no hooks dir"

Tool results:

→ result (ok): no hooks dir

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/

Tool results:

→ result (ok): MultiSelectDropdown NhrDateRangeFilter NhrDateSelectionFilter NhrDateTypeFilter NhrDocumentList NhrDocumentListFilterPanel NhrDocumentListModal NhrDocumentVisibilityFilter NhrEntryPoint NhrEntryPointButton

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDateSelectionFilter/ 2>/dev/null

Tool results:

→ result (ok): NhrDateSelectionFilter.stories.tsx NhrDateSelectionFilter.test.tsx NhrDateSelectionFilter.tsx

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentVisibilityFilter/

Tool results:

→ result (ok): NhrDocumentVisibilityFilter.stories.tsx NhrDocumentVisibilityFilter.test.tsx NhrDocumentVisibilityFilter.tsx

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentCategoryFilter/

Tool results:

→ result (ok): index.ts NhrDocumentCategoryFilter.stories.tsx NhrDocumentCategoryFilter.test.tsx NhrDocumentCategoryFilter.tsx

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/

Tool results:

→ result (ok): NhrDocumentCategoryCell NhrDocumentCategoryFilter NhrDocumentList.stories.tsx NhrDocumentList.test.tsx NhrDocumentList.tsx NhrDocumentNameCell NhrDocumentStatusFilter NhrProcedureDateCell NhrShareDateCell NhrSharedByCell NhrStatusCell NhrVisibilityCell

Tools used:

  • Bash: cat /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentStatusFilter/index.ts 2>/dev/null && ls /Users/USER/worksp …(truncated, 123 more chars)

Tool results:

→ result (ERROR): Exit code 1

Tools used:

  • Bash: cat /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts | head -60

Tool results:

→ result (ERROR): <tool_use_error>Cancelled: parallel tool call Bash(cat /Users/USER/workspace/doctolib/…) errored</tool_use_error>

Tools used:

  • Bash: ls /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentStatusFilter/

Tool results:

→ result (ok): NhrDocumentStatusFilter.stories.tsx NhrDocumentStatusFilter.test.tsx NhrDocumentStatusFilter.tsx

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts (1–60)

Tool results:

→ result (ok): 1 export { NhrDocumentList } from './components/NhrDocumentList/NhrDocumentList' 2 export { NhrDocumentListFilterPanel } from './components/NhrDocumentListFilterPanel/NhrDocumentListFilterPanel' 3 export type { 4 ActionConfig, 5 DropdownActionOption, 6 BasicActionConfig, 7 DropdownActionConfig, 8 SimpleActionConfig, 9 ActionsFactory, 10 ColumnConfig, 11 FilterConfig, 12 FilterRenderContext, 13 NhrPatientInfo, 14 NhrVisibilityEntry, 15 StatusOption, 16 NhrDocumentStatusF …(truncated, 2177 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts (60–?)

Tool results:

→ result (ok): 60 type NhrDocumentVisibilityFilterProps, 61 } from './components/NhrDocumentVisibilityFilter/NhrDocumentVisibilityFilter' 62

Tools used:

  • Bash: grep -r "MultiSelectDropdown\|NhrDocumentCategoryFilter" /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts:export { createNhrDocumentCategoryFilterConfig } from './business/factories/filters/createNhrDocumentCategoryFilterConfig'

Tools used:

  • Bash: git -C /Users/USER/workspace/doctolib/treatment-plan diff origin/main...HEAD -- packages/tpf-national-health-records-ui/src/index.ts

Tool results:

→ result (ok): (Bash completed with no output)

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/business/factories/filters/createNhrDocumentCategoryFilterConfig.test.tsx

Tool results:

→ result (ok): 1 import { setup } from '@doctolib/test-helpers' 2 import { screen } from '@testing-library/react' 3 import { afterEach, describe, expect, it, vi } from 'vitest' 4
5 import { mockPatientInfo } from '../../../test-helpers' 6 import { createNhrDocumentCategoryFilterConfig } from './createNhrDocumentCategoryFilterConfig' 7
8 const ctx = { patient: mockPatientInfo } 9
10 const sampleOptions = [ 11 { value: 'A', label: 'Report A' }, 12 { value: 'B', label: 'Report B' }, 13 { value: 'C', labe …(truncated, 4905 more chars)

Now let me look at the remaining files and the package.json to check export configuration and compare with existing patterns.

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/package.json

Tool results:

→ result (ok): 1 { 2 "name": "@doctolib/tpf-national-health-records-ui", 3 "version": "16.0.2", 4 "repository": { 5 "type": "git", 6 "url": "git+https://github.com/doctolib/treatment-plan.git" 7 }, 8 "keywords": [ 9 "upfront", 10 "modular frontend", 11 "smaller-scope" 12 ], 13 "author": "@doctolib/fire", 14 "license": "Doctolib", 15 "doctolib": { 16 "upfront-type": "smaller-scope" 17 }, 18 "type": "module", 19 "sideEffects": [ 20 "./src/i18n.ts" 21 ], 22
…(truncated, 3911 more chars)

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdown.test.tsx

Tool results:

→ result (ok): 1 import { setup } from '@doctolib/test-helpers' 2 import { screen } from '@testing-library/react' 3 import type { ComponentProps } from 'react' 4 import { afterEach, describe, expect, it, vi } from 'vitest' 5
6 import { MultiSelectDropdown } from './MultiSelectDropdown' 7
8 const sampleOptions = [ 9 { value: 'A', label: 'Report A' }, 10 { value: 'B', label: 'Report B' }, 11 { value: 'C', label: 'Report C' }, 12 ] 13
14 describe('MultiSelectDropdown', () => { 15 afterEach(() => { 16
…(truncated, 16079 more chars)

Now I have a complete picture of the PR. Let me check one more thing — the path aliases configuration and whether #business/ and #hooks/ aliases exist.

Tools used:

  • Bash: grep -r '"#' /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/package.json

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/package.json: "#i18n": "./src/i18n.ts", /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/package.json: "#components/": "./src/components/", /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/package.json: "#data/": "./src/data/.ts", /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/package.js …(truncated, 37 more chars)

Tools used:

  • Bash: grep -r "NhrDocumentCategoryFilter" /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/index.ts:export { createNhrDocumentCategoryFilterConfig } from './business/factories/filters/createNhrDocumentCategoryFilterConfig'

Tools used:

  • Bash: git -C /Users/USER/workspace/doctolib/treatment-plan diff origin/main...HEAD -- packages/tpf-national-health-records-ui/package.json

Tool results:

→ result (ok): diff --git a/packages/tpf-national-health-records-ui/package.json b/packages/tpf-national-health-records-ui/package.json index e75bfbe03..75bbe7d7f 100644 --- a/packages/tpf-national-health-records-ui/package.json +++ b/packages/tpf-national-health-records-ui/package.json @@ -55,6 +55,7 @@ ], "imports": { "#i18n": "./src/i18n.ts", + "#components/": "./src/components/", "#data/": "./src/data/.ts", "#utils/": "./src/utils/.ts" },

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentCategoryFilter/NhrDocumentCategoryFilter.stories.tsx

Tool results:

→ result (ok): 1 import type { Meta, StoryObj } from '@storybook/react' 2
3 import { NhrDocumentCategoryFilter } from './NhrDocumentCategoryFilter' 4
5 const meta = { 6 title: 'NHR/DocumentList/Filters/DocumentCategoryFilter', 7 component: NhrDocumentCategoryFilter, 8 tags: ['autodocs'], 9 decorators: [ 10 (Story) => ( 11 <div data-theme='doctolib2023' style={{ height: '40vh', padding: '24px', maxWidth: '400px' }}> 12 <Story /> 13 </div> 14 ), 15 ], 16 args: { 17 l …(truncated, 919 more chars)

Now let me check the stories file for MultiSelectDropdown and look at whether NhrDocumentCategoryFilter has its own index.ts correctly:

Tools used:

  • Read: /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdown.stories.tsx

Tool results:

→ result (ok): 1 import type { Meta, StoryObj } from '@storybook/react' 2 import { useState } from 'react' 3
4 import { MultiSelectDropdown } from './MultiSelectDropdown' 5
6 const meta = { 7 title: 'Components/MultiSelectDropdown', 8 component: MultiSelectDropdown, 9 tags: ['autodocs'], 10 decorators: [ 11 (Story) => ( 12 <div data-theme='doctolib2023' style={{ height: '40vh', padding: '24px', maxWidth: '400px' }}> 13 <Story /> 14 </div> 15 ), 16 ], 17 args: { 18
…(truncated, 1790 more chars)

Tools used:

  • Bash: grep -rn "default export\|export default" /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/ /Users/USER/workspace/doct …(truncated, 281 more chars)

Tool results:

→ result (ok): /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/MultiSelectDropdown.stories.tsx:26:export default meta /Users/USER/workspace/doctolib/treatment-plan/packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentCategoryFilter/NhrDocumentCategoryFilter.stories.tsx:23:export default meta

I now have a complete picture of all the changes. Here is the structured architecture review.


Architecture Review: fhir-2219_implement-multi-select-category-filter


Critical Issues (must fix)

1. hooks.ts and helpers.ts use generic names instead of the component-scoped naming convention

Files: /packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/hooks.ts and helpers.ts

The UpFront component directory pattern mandates that local hook and helper files carry the component name as their mantissa:

MultiSelectDropdown.hooks.ts   # not hooks.ts
MultiSelectDropdown.helpers.ts # not helpers.ts

The bare names hooks.ts and helpers.ts are reserved for multi-export module-level files in src/hooks/ or src/helpers/. Using generic names inside a component directory violates the naming convention, makes file origin ambiguous in IDE tabs and search results, and undermines the Josh Comeau structure the pattern relies on.

The test files follow the same problem: - helpers.test.ts should be MultiSelectDropdown.helpers.test.ts - hooks.test.tsx should be MultiSelectDropdown.hooks.test.tsx

Required renames: - hooks.tsMultiSelectDropdown.hooks.ts - hooks.test.tsxMultiSelectDropdown.hooks.test.tsx - helpers.tsMultiSelectDropdown.helpers.ts - helpers.test.tsMultiSelectDropdown.helpers.test.ts


2. NhrDocumentCategoryFilter is placed inside NhrDocumentList/ instead of at the top-level src/components/

Files: /packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentCategoryFilter/

The existing filters in this package — NhrDateSelectionFilter, NhrDocumentVisibilityFilter, NhrDateRangeFilter, NhrDateTypeFilter — are all top-level siblings under src/components/. Nesting NhrDocumentCategoryFilter inside NhrDocumentList/ breaks that consistency without justification. The filter is not a private sub-component of NhrDocumentList; it is consumed independently via createNhrDocumentCategoryFilterConfig, which imports it directly through the #components/ alias, confirming it is a standalone reusable component.

The correct location is:

src/components/NhrDocumentCategoryFilter/
  NhrDocumentCategoryFilter.tsx
  NhrDocumentCategoryFilter.test.tsx
  NhrDocumentCategoryFilter.stories.tsx
  index.ts

Compare with every other filter: /src/components/NhrDocumentVisibilityFilter/NhrDocumentVisibilityFilter.tsx.


3. NhrDocumentCategoryFilter has no index.ts re-exporter

The NhrDocumentCategoryFilter directory currently does have an index.ts (export * from './NhrDocumentCategoryFilter'), but this only exists because it is nested inside NhrDocumentList. The peer filters NhrDateSelectionFilter and NhrDocumentVisibilityFilter have no index.ts — their src/components/ placement makes it unnecessary. If NhrDocumentCategoryFilter moves to the top level (as required by issue 2), it should follow the same pattern as those peers: no index.ts, and any consuming code imports from the file directly or through the #components/ alias pointing at the directory.

The current setup is inconsistent: NhrDocumentCategoryFilter has an index.ts wrapper; NhrDateSelectionFilter and NhrDocumentVisibilityFilter do not.


4. createNhrDocumentCategoryFilterConfig.tsx contains React JSX but lives in src/business/

File: /packages/tpf-national-health-records-ui/src/business/factories/filters/createNhrDocumentCategoryFilterConfig.tsx

The src/business/ layer is defined as pure functions only, no React imports. This factory directly renders <NhrDocumentCategoryFilter ... /> inline in the render callback and uses JSX. Importing a React component and returning JSX from a function in src/business/ is a business/presentation layer separation violation.

Look at the pre-existing factories for comparison:

createNhrDateSelectionFilterConfig.tsx and createNhrDocumentVisibilityFilterConfig.tsx both follow the same pattern (they also render JSX from src/business/). This means the violation is pre-existing and not introduced by this PR alone. However, this PR adds a new instance of the same violation and should not perpetuate it.

The FilterConfig.render callback is architecture-imposed — FilterConfig is typed to accept a React render function. If src/business/ must stay as the location for these factories (because that is where the FilterConfig type is materialized), then either the src/business/ rule needs an explicit documented exception for "render factories", or these factories belong in src/components/ alongside the UI components they configure. The PR should at minimum not add a new violating file without acknowledging this tension.


Warnings (should fix)

5. MultiSelectDropdown/index.ts re-exports nothing beyond the main component — internal sub-components are not re-exported but also not hidden

File: /packages/tpf-national-health-records-ui/src/components/MultiSelectDropdown/index.ts

The index.ts only exports MultiSelectDropdown. The sub-components MultiSelectDropdownTrigger, MultiSelectDropdownPopup, MultiSelectDropdownLabel, and MultiSelectDropdownOptions are not in index.ts but are exported as named exports from their own files, making them directly importable by any code in the package. If these are intended as private implementation details of MultiSelectDropdown, they should either: - Not export their symbols at all (or export only within the component directory), or - Be explicitly re-exported if they are intentionally part of the public surface.

The current setup is ambiguous. The UpFront rule is that the index.ts defines the component's public surface — anything not in index.ts should not carry a named export if it is internal.


6. #components/* alias was missing before this PR and only added now

File: /packages/tpf-national-health-records-ui/package.json

The imports field gains "#components/*": "./src/components/*" in this PR. This is the right direction, but it means all pre-existing cross-component imports that used relative paths could not use the alias. The PR does use the alias in two new files (NhrDocumentCategoryFilter.tsx and createNhrDocumentCategoryFilterConfig.tsx), which is correct. However, the fact that #business/ and #hooks/ aliases are still absent from the imports field means the architecture cannot be consistently enforced: createNhrDocumentCategoryFilterConfig.tsx uses a relative path '../../../types' (3 levels deep) rather than a # alias for that import. This is acceptable for types.ts which lives outside the standard alias directories, but the incomplete alias set is a broader gap.


7. NhrDocumentCategoryFilter.tsx is a pure pass-through wrapper that adds no value

File: /packages/tpf-national-health-records-ui/src/components/NhrDocumentList/NhrDocumentCategoryFilter/NhrDocumentCategoryFilter.tsx

export const NhrDocumentCategoryFilter = (props: NhrDocumentCategoryFilterProps) => <MultiSelectDropdown {...props} />

This component does nothing except forward all props. NhrDocumentCategoryFilterProps is defined as ComponentProps<typeof MultiSelectDropdown>, so it is a structural alias, not an abstraction. If MultiSelectDropdown is the implementation and NhrDocumentCategoryFilter is the domain-named public face, the wrapper pattern is legitimate — but it implies MultiSelectDropdown should not appear in src/index.ts public exports, and NhrDocumentCategoryFilter should be what consumers reference. Currently MultiSelectDropdown is not in src/index.ts, so the intent seems correct. However, the wrapper provides zero encapsulation: if MultiSelectDropdown's props change, NhrDocumentCategoryFilterProps changes automatically via ComponentProps<...>, meaning no stable API contract is actually maintained by the wrapper. …(truncated, 4146 more chars)

Keyboard shortcuts

⌘K / Ctrl+KOpen command palette
/Focus search
g hGo to home
g pGo to projects
g sGo to sessions
j / kNext / prev row (tables)
?Show this help
EscClose dialogs

Structured queries

Mix key:value filters with free text in the palette:

type:sessionOnly session pages
project:llm-wikiFilter by project name (substring)
model:claudeFilter by model name (substring)
date:>2026-03-01Sessions after a date
date:<2026-04-01Sessions before a date
tags:rustPages mentioning a tag/topic
sort:dateSort results by date (newest first)

Example: type:session project:llm-wiki date:>2026-04 sort:date