The Veza backend API uses two architectural patterns:
1.**Core (DDD-style)**: `internal/core/track/`, `internal/core/auth/`, `internal/core/marketplace/`, `internal/core/social/` — handlers and services colocated per domain
2.**Legacy (flat handlers)**: `internal/handlers/` — analytics_handler, playlist_handler, comment_handler, playback_analytics_handler, etc.
This inconsistency creates confusion for developers and makes it unclear where new code should live.
## Decision
**Option A**: Migrate all handlers to `internal/core/` (domain-driven structure).
We choose Option A for long-term consistency with the existing core domains (track, auth, marketplace, social). New features will follow the same pattern.
## Migration Strategy
1.**Incremental migration** — One domain at a time, with tests passing after each step
2.**Order of migration** (by priority and coupling):
-`playback_analytics_handler` → `internal/core/playback/` (or integrate into track)
-`playlist_handler` → `internal/core/playlist/`
-`comment_handler` → `internal/core/comment/` (or integrate into track)
-`room_handler`, `session` → `internal/core/chat/` or `internal/core/session/`
-`health.go`, `upload.go`, `bitrate_handler` — evaluate per ADR update
3.**Service layer** — Handlers in core use existing `internal/services/*` packages; no new service packages unless domain logic warrants it
4.**Response helpers** — Core handlers continue to use `handlers.RespondWithAppError`, `handlers.RespondSuccess` from the handlers package (shared HTTP utilities)
## Consequences
- **Positive**: Single, consistent architecture; easier onboarding
- **Negative**: Migration effort; temporary coexistence of both patterns during transition
- **Risk**: Breaking changes if imports are not updated correctly — mitigate with `go build ./...` and tests after each migration