Fix (recoverability bug):
- TransferFilesToBucketActivity returned Completed() with no log, so its
compensation could never delete the transferred files (orphaned objects on
fault). IStorageService.TransferFilesAsync now returns the real uploaded
keys; the activity logs them so Compensate can remove them. Also drops the
Path.Combine key recomputation (produced backslash keys on Windows).
Consistency / DRY:
- Normalize all courier activities to internal + folder-based namespaces
(several were public and in the flat .Activities namespace)
- Extract the duplicated exponential retry into UseStandardRetry
- Unify endpoint-name logic into a single EndpointHelper (remove the parallel
MassTransitEndpointNames helper)
Build: 0 warnings, 0 errors.
- Add Musify.Application.AddApplication(services, config) as the layer's DI
entry point: registers Mediator, UploadIntentValidator and all app configs
- Collapse the 5 near-identical AddXConfiguration methods into a single
generic AddValidatedOptions<T>(config, section)
- Move UploadIntentValidator registration out of Infrastructure into the
Application layer (fixes layering leak); Infra config binding now uses the
generic helper
- Api calls AddApplication; Worker uses AddValidatedOptions for its configs
Build: 0 warnings, 0 errors.
- Move all .NET (6 projects, solution, Directory.*.props, nuget.config)
into backend/ so the monorepo root can host non-.NET projects later
- Remove throwaway test artifacts: player.html, pl.json
- Trim dead Flutter rules from .gitignore
Build from backend/Musify.slnx: 0 warnings, 0 errors.