Stability checkpoint — customers split D1 steps 2+3 (MR !116)
Completes the CustomerStateService split started with
ImportExportService. Two more bounded services extracted :
1. CustomerSelectionService (B-7-2c step 2) — batch select + batch
delete. Owns selectedIds (Set<number>) + selectAll + hasSelection
+ confirmBatchDelete + batchDeleteLoading signals.
5 methods : toggleSelectAll(pageContent) / toggleSelectOne(id) /
openBatchDelete / cancelBatchDelete / executeBatchDelete(cb).
Clear separation from other customer concerns.
2. CustomerCrudService (B-7-2c step 3) — single-customer edit +
delete + random-create. Owns editingCustomer + editName +
editEmail + editLoading + editError + deletingCustomer +
deleteLoading + randomCreate* signals.
7 methods : openEdit/cancelEdit/saveEdit/openDelete/cancelDelete/
confirmDelete/addRandomCustomer (each with onAfterChange callback
for list reload).
Shared httpError() helper hoisted from customers.component.ts to
customers-helpers.ts so the 4 call sites (component + 3 services)
share one implementation.
Counts (cumulative from B-7-2b baseline) :
- customers.component.ts : 838 → 573 LOC (-32 %)
- 3 new services : 187 + 127 + 163 = 477 LOC bounded, each one
concern, each Injectable{providedIn:'root'} for Angular DI
Template bindings routed through `selection.*` and `crud.*` via
bulk sed — 11 references updated atomically.
Remaining customers complexity : list pagination + sort + search +
apiVersion + summaryMode + detail panel + aggregate. These are more
intertwined (shared customers() signal + load() calls from many
paths) — deferred to future session whether a full
CustomerListStateService gives enough boundary value vs leaving
the component at ~580 LOC.