# Dashboard Policy Boundary ## Current ownership This boundary currently owns: ```js splitWatchedCasesBySubmissionState(records); ``` Purpose: ```text watched-case records ↓ classification by submission state ↓ watched bucket submitted bucket ``` ## Current contract `splitWatchedCasesBySubmissionState(records)` intentionally preserves: - loose-null semantics - null handling - undefined handling - truthy submitted markers - date-string submitted markers - input-order preservation - watched bucket count calculation In current behaviour, `pinswg_representationsubmitted == null` means a record remains in the watched bucket, so both `null` and `undefined` are treated as “not submitted”. Any non-null submitted marker, including booleans and date strings, is classified into the submitted bucket. ## Output contract Current return shape: ```js { watchedCases: { "@odata.count": number, value: [...] }, submittedRepresentations: [...] } ``` The asymmetry of this shape is intentional and must be preserved until an explicit contract-change initiative occurs. ## Explicit non-goals This boundary does **not** own: - sorting - ordering rules - createdon sorting - createdDate sorting - ticketnumber sorting - top-three truncation - detail merging - hydration - watch/unwatch orchestration - setState behaviour - React rendering - dashboard cards - search result rendering - CRM queries - API routes - authentication - authorization ## Caller-owned behaviour Current pattern: ```text classification belongs to dashboard-policy ordering belongs to the caller refresh orchestration belongs to the caller rendering belongs to the caller ``` Current examples: - `pages/myportal/index.js` - uses `splitWatchedCasesBySubmissionState(watchedCases.value)` to derive watched and submitted buckets for store hydration. - caller remains responsible for page-level orchestration and dispatch behaviour. - `components/myportal/viewall.js` - uses helper classification for watched-case membership. - caller still owns descending `createdon` sorting in the refresh path, current view refresh flow, and rendering. - `components/myportal/topthree.js` - uses helper classification for watched-case membership. - caller still owns created-date derivation, `createdDate` sorting, `ticketnumber` sorting, detail merging, final `createdon` ordering, and top-three truncation. - `components/search/searchresults.js` - uses helper classification only for the watched-case delete refresh path. - caller still owns descending `createdon` sorting after classification, watch/unwatch refresh orchestration, state updates, detail hydration, and result rendering. ## Adopted consumers Current known adopters: - `pages/myportal/index.js` - `components/myportal/viewall.js` - `components/myportal/topthree.js` - `components/search/searchresults.js` ## Remaining consumers Likely future adoption candidates: - `components/search/addresssearchresults.js` - `components/search/dnssearchresults.js` - `components/case/summary.js` These consumers require characterization before adoption. ## Testing expectations Current characterization safety net: ```bash node tests/phase22/dashboard-watched-case-classification.test.cjs node tests/phase22/dashboard-viewall-classification.test.cjs node tests/phase22/dashboard-topthree-classification.test.cjs node tests/phase22/dashboard-searchresults-classification.test.cjs npm run lint ``` ## Future evolution Future work may: ```text increase helper adoption ``` Future work should not: ```text move sorting into the helper move rendering into the helper move refresh orchestration into the helper ``` without a separate domain-boundary decision.