# Backend Refactoring Summary ## Problem `Entry.cs` was a 550-line god class that contained command dispatching, business logic, HTML sanitization, logging infrastructure, and 13 private payload record types. The two Python sidecar services (`PythonSidecarAiService` and `PythonSidecarSpeechService`) duplicated ~80 lines of identical process/JSON plumbing. Payload DTOs were hidden as private records inside `Entry.cs` instead of being in the `Dtos/` folder. ## What Changed ### 1. Slimmed `Entry.cs` to a thin dispatcher (~330 lines) Removed all business logic, HTML processing, logging implementation, and private record types. `Entry` now only parses the incoming JSON command, routes to the correct service, and returns the `{ok, data}` / `{ok: false, error}` envelope. ### 2. Extracted `HtmlSanitizer` (new file) `StripRichHtml` and `LooksLikeRichHtml` moved from `Entry.cs` to `Services/HtmlSanitizer.cs` as a static utility class. ### 3. Extracted `CommandLogger` (new file) `LogStart`, `LogSuccess`, `LogFailure`, `EmitLog`, `ShouldLog`, and `LogLevelRank` moved from `Entry.cs` to `Services/CommandLogger.cs`. Entry now receives this as a dependency. ### 4. Extracted `IEntryFileService` + `EntryFileService` (new files) `SaveEntry`, `LoadEntry`, `ListEntries`, and `ResolveTargetPath` moved out of `Entry.cs` into a proper service with an interface. This follows the same pattern as `IFragmentService` / `FragmentService`. ### 5. Added `IEntryFileRepository` + `DiskEntryFileRepository` (new files) `EntryFileService` now delegates all filesystem I/O (read, write, append, list, exists) to an `IEntryFileRepository`, keeping only business logic (HTML sanitization, parsing, merging) in the service. This mirrors the Fragment module's repository pattern (`IFragmentRepository` → `FragmentService`). An in-memory implementation can be swapped in for testing. ### 6. Extracted `PythonSidecarClient` (new file) The duplicated `SendAsync`, `LastJsonLine`, and `TryKill` methods were extracted from both `PythonSidecarAiService` and `PythonSidecarSpeechService` into a shared `Services/PythonSidecarClient.cs`. Both services now delegate to it. ### 7. Moved payload records to `Dtos/CommandDtos.cs` (new file) The 16 private payload/result records that were inside `Entry.cs` are now in `Dtos/CommandDtos.cs`. Records used through public interfaces (`EntrySavePayload`, `EntryListItem`, `EntryLoadResult`, `EntrySaveResult`) are public; the rest remain internal. ### 8. Moved database result records to `Dtos/DatabaseDtos.cs` (new file) `JournalDatabaseStatus` and `JournalDatabaseHydrationResult` moved from `IJournalDatabaseService.cs` to `Dtos/DatabaseDtos.cs` for consistency with the other DTO files. ## Files Created - `Journal.Core/Services/HtmlSanitizer.cs` - `Journal.Core/Services/CommandLogger.cs` - `Journal.Core/Services/IEntryFileService.cs` - `Journal.Core/Services/EntryFileService.cs` - `Journal.Core/Services/PythonSidecarClient.cs` - `Journal.Core/Repositories/IEntryFileRepository.cs` - `Journal.Core/Repositories/DiskEntryFileRepository.cs` - `Journal.Core/Dtos/CommandDtos.cs` - `Journal.Core/Dtos/DatabaseDtos.cs` ## Files Modified - `Journal.Core/Entry.cs` — slimmed to thin dispatcher - `Journal.Core/Services/PythonSidecarAiService.cs` — delegates to PythonSidecarClient - `Journal.Core/Services/PythonSidecarSpeechService.cs` — delegates to PythonSidecarClient - `Journal.Core/Services/IJournalDatabaseService.cs` — result records moved to Dtos - `Journal.Core/Services/JournalDatabaseService.cs` — added Dtos using - `Journal.Core/ServiceCollectionExtensions.cs` — registers new services and repository - `Journal.SmokeTests/Program.cs` — updated NewEntry() with new dependencies ## What Was NOT Changed - **Fragment module** — already clean, untouched - **Config module** — singleton reader, no changes needed - **Vault module** — already well-separated (crypto/storage), untouched - **AI/Speech interfaces and disabled variants** — untouched (only the sidecar implementations were refactored) - **Search module** — stateless query service, no repository needed - **All test logic** — no assertions or test behavior changed ## Verification - All 4 projects build successfully - 70/70 smoke tests pass (5 Python sidecar tests fail only when Python is not installed on the machine, which is pre-existing)