Context
From a repo-wide over-engineering audit (ponytail-audit). The six file actions (queue, stop, extract, deleteLocal, deleteRemote, validate) are written out longhand across five layers — ~30 near-identical methods differing only by a URL verb, a log noun, or a status guard. Estimated cut: ~150 lines.
Findings
ModelFileService (src/angular/src/app/services/files/model-file.service.ts): 6 methods differing only by URL verb.
ViewFileCommandService (services/files/view-file-command.service.ts): 6 methods differing only by log noun.
ViewFileService (services/files/view-file.service.ts:152-176,207-227): 6 pure pass-through facades + 4 bulk facades.
FileListComponent (pages/files/file-list.component.ts:143-193,230-233): 6 byte-identical onX subscribe blocks + 4 onBulkX.
FileComponent (pages/files/file.component.ts:122-145,168-197): 6 onX handlers + 6 isX guards.
Task
Thread the existing FileAction enum through one command(action: FileAction, file: ViewFile) per layer:
- One table (per action: URL segment, log noun, capability flag) at the lowest layer that needs each datum.
- Components call
onAction(action, file) / onBulkAction(action); templates pass the enum member.
- Capability guards (
isQueueable etc.) can stay as data lookups against the same table.
Constraints
- HTTP endpoints, request shapes, and user-visible log/notification text unchanged.
- Bulk actions keep their
forkJoin semantics.
- Follow the Angular mutating-service contract in CLAUDE.md (mutations inside the returned pipeline via
tap, typed WebReaction results — don't regress this).
- Update specs to the new single entry point; per-action coverage can become a parameterized loop over the 6 actions so no action loses a test.
npx ng lint and npx ng test pass (Node ≥22.22.3 required locally).
Acceptance
Workflow: branch refactor/file-action-fanout off develop, PR to develop.
Context
From a repo-wide over-engineering audit (ponytail-audit). The six file actions (
queue,stop,extract,deleteLocal,deleteRemote,validate) are written out longhand across five layers — ~30 near-identical methods differing only by a URL verb, a log noun, or a status guard. Estimated cut: ~150 lines.Findings
ModelFileService(src/angular/src/app/services/files/model-file.service.ts): 6 methods differing only by URL verb.ViewFileCommandService(services/files/view-file-command.service.ts): 6 methods differing only by log noun.ViewFileService(services/files/view-file.service.ts:152-176,207-227): 6 pure pass-through facades + 4 bulk facades.FileListComponent(pages/files/file-list.component.ts:143-193,230-233): 6 byte-identicalonXsubscribe blocks + 4onBulkX.FileComponent(pages/files/file.component.ts:122-145,168-197): 6onXhandlers + 6isXguards.Task
Thread the existing
FileActionenum through onecommand(action: FileAction, file: ViewFile)per layer:onAction(action, file)/onBulkAction(action); templates pass the enum member.isQueueableetc.) can stay as data lookups against the same table.Constraints
forkJoinsemantics.tap, typedWebReactionresults — don't regress this).npx ng lintandnpx ng testpass (Node ≥22.22.3 required locally).Acceptance
Workflow: branch
refactor/file-action-fanoutoffdevelop, PR todevelop.