# SignalR DataSource — TODO

Forward-looking work specific to `AcSignalRDataSource`. Transport-side TODOs live in `../SIGNALR/SIGNALR_TODO.md`.

## Priority legend
- **P0** blocker · **P1** important · **P2** nice-to-have · **P3** idea

---

## ACCORE-SIGDS-T-D9F2: Relocate AcSignalRDataSource + TrackingItemHelpers to AyCode.Services
**Priority:** P2 · **Type:** Architectural cleanup · **Status:** Closed (2026-06-07)

> **Note:** The code relocation is complete and verified (WASM AOT publish succeeds). Doc-link cross-reference cleanup across the workspace tracked in the Resolution below.

Both files currently live in `AyCode.Services.Server/SignalRs/`, but **neither has any Server-only dependency**:

- `AcSignalRDataSource.cs` using statements: only `AyCode.Core.*` + `AyCode.Services.SignalRs` (client-side namespace) — zero `AyCode.*.Server` references.
- `TrackingItemHelpers.cs` using statements: only `System.Reflection` + `AyCode.Core.Extensions`.
- `AyCode.Services.csproj` reference graph already covers all transitive needs (AyCode.Core, AyCode.Entities, AyCode.Interfaces, AyCode.Models).
- `SignalRCrudTags` (the DataSource constructor's required argument type) lives in `AyCode.Services` — consumers must currently reference both `AyCode.Services` and `AyCode.Services.Server` for one logical API.
- All other files in `AyCode.Services.Server/SignalRs/` are genuinely Server-only (Hub<T> subclasses, session service, broadcast, server protocol extensions, server hub interfaces).

**Practical impact:** Blazor.WebAssembly cannot reference `AyCode.Services.Server` (its dependency graph pulls in `AyCode.Database`, `KeyDerivation`, `SendGrid` — none WASM-compatible). WASM consumers wanting `AcSignalRDataSource` are currently blocked.

### Acceptance
- [x] `AcSignalRDataSource.cs` moved: `AyCode.Services.Server/SignalRs/` → `AyCode.Services/SignalRs/`; namespace `AyCode.Services.Server.SignalRs` → `AyCode.Services.SignalRs`.
- [x] `TrackingItemHelpers.cs` moved + namespace updated.
- [x] Consumer `using AyCode.Services.Server.SignalRs;` lines pulling these types updated to `using AyCode.Services.SignalRs;`.
- [x] Doc folder relocated: `AyCode.Services.Server/docs/SIGNALR_DATASOURCE/` → `AyCode.Services/docs/SIGNALR_DATASOURCE/` (3 files: README + ISSUES + TODO).
- [x] `TOPIC_CODES.md` SIGDS row "Docs location" updated (`AyCode.Services.Server/...` → `AyCode.Services/...`).
- [x] Doc-index READMEs updated: removed SIGDS row from `Services.Server/docs/README.md`; added to `Services/docs/README.md`.
- [x] All cross-refs updated: AyCode.Core 9 (registries + index READMEs + moved-README internals) + AyCode.Blazor 5 (GLOSSARY + MGGRID docs); FruitBankHybridApp had none (type mentions only, no path refs).
- [x] `AyCode.Services.Server/README.md` + `AyCode.Services.Server/SignalRs/README.md` doc tables: SIGDS rows removed.
- [ ] `AyCode.Services/SignalRs/README.md` doc table: DataSource entry — **deferred** (the `SignalRCrudTags` line cross-refs the spec; no standalone Data Source section added).
- [x] Tests in `AyCode.Services.Server.Tests/SignalRs/SignalRDatasources/` — `SignalRDataSourceTestBase.LoadItem.cs` was missing the `AyCode.Services.SignalRs` using (partial-file using list); **added**. Debug sln build green. (The Release sln config skips MSTest projects — that masked it during Release-only verification.)
- [x] New `LLMP-DEC` entry filed (`LLMP-DEC-68`).
- [x] Build green across consumers (AyCode.Core, AyCode.Blazor.Components, FruitBankHybrid.Web.Client WASM AOT publish verified).

### Resolution (2026-06-07)
**What:** Moved `AcSignalRDataSource.cs` + `TrackingItemHelpers.cs` → `AyCode.Services/SignalRs/` (namespace `AyCode.Services.SignalRs`); removed orphan `Microsoft.AspNetCore.SignalR.Core 1.2.0` PackageReference from `AyCode.Blazor.Components.csproj`; cleaned `.Server` DLL refs from Web.Client / Shared / Components; consumer usings updated; this doc folder moved here.
**Why:** Unblocks browser-WASM AOT — `FruitBankHybrid.Web.Client` AOT-publish now succeeds (AOT-input 175→165 assemblies, `SignalR.Core` gone, `[164/164]` + emcc link OK). Server stays JIT (IIS in-process compatible).
**Where:** Full detail in `LLMP-DEC-68`.
**Verified:** `dotnet publish FruitBankHybrid.Web.Client -c Release` (RunAOTCompilation=true) — green; **AyCode.Core.sln green in both Debug and Release** (Debug builds the MSTest projects the Release config skips — this caught a missing using in `SignalRDataSourceTestBase.LoadItem.cs`, since fixed).
**Doc-link sync:** ✅ completed this session — all path cross-refs rewritten to `AyCode.Services/docs/SIGNALR_DATASOURCE` (AyCode.Core 9; AyCode.Blazor 5; FruitBankHybridApp 0). **Optional residue (non-blocking):** no standalone DataSource section in `AyCode.Services/SignalRs/README.md`; Server.Tests `SignalRDatasources` usings keep a now-redundant `Server.SignalRs` import (build green). **Decision Log rolling-window:** LLMP-DEC-68 should rotate LLMP-DEC-53 on next `docs-archive` run (per LLMP-DEC-67).

### Related
- `LLMP-DEC-66` (SIGDS topic introduction — this TODO completes the architectural side that the docs-side migration left open)
- `LLMP-DEC-68` (this relocation — code side)
- Parallels `LLMP-DEC-58` Framework-First retightening principle (consumer-side code shouldn't live in Server-flavored projects)

---

## ACCORE-SIGDS-T-N5R8: ChangeTracking._trackingItems → Dictionary<TId, TrackingItem>
**Priority:** P3 · **Type:** Performance refactor · **Status:** Open

Pre-existing `//TODO: Dictionary... - J.` comment in `AcSignalRDataSource.cs:68`:

```csharp
private readonly List<TrackingItem<TDataItem, TId>> _trackingItems = [];
```

`ChangeTracking.FindIndex(newValue)` and `TryGetTrackingItem(id)` both linear-scan `_trackingItems`. For DataSources with many concurrent tracked changes (large grids with frequent edits), this is O(N) per operation. A `Dictionary<TId, TrackingItem<TDataItem, TId>>` would give O(1) lookup; `ToList()` enumeration (the only external read path) is order-agnostic, so no behavioural regression.

Trade-off: per-tracking-item dictionary overhead; negligible for typical workload.

**Acceptance:**
- `_trackingItems` switched to `Dictionary<TId, TrackingItem<TDataItem, TId>>`.
- `FindIndex` removed (caller paths in `AddTrackingItem` re-flow as TryGetValue + Add/Update).
- `TryGetTrackingItem` becomes single dict lookup.
- `ToList()` returns `_trackingItems.Values.ToList()`.
- `Remove(trackingItem)` → `Remove(trackingItem.CurrentValue.Id)`.
- All existing tests pass without change to public API surface.
