/// Mirrors `requestView` from internal/api/requests.go. Server returns /// these as a flat list (no envelope) from GET /api/admin/requests. /// /// Note the requester is exposed only as a UUID (`user_id`) — the /// response does not include the username. The Flutter Requests screen /// joins client-side against the AdminUser list for display. class AdminRequest { const AdminRequest({ required this.id, required this.userId, required this.status, required this.kind, required this.artistName, this.albumTitle, this.trackTitle, required this.requestedAt, this.decidedAt, this.notes, required this.importedAlbumCount, required this.importedTrackCount, }); final String id; final String userId; /// One of: pending, approved, rejected, completed, failed. final String status; /// One of: artist, album, track. final String kind; final String artistName; final String? albumTitle; final String? trackTitle; final String requestedAt; final String? decidedAt; final String? notes; final int importedAlbumCount; final int importedTrackCount; /// Display label depending on the kind of request — what the user /// asked for. For an album request it's the album title; for an /// artist request it's the artist name; etc. String get displayName => switch (kind) { 'album' => albumTitle ?? artistName, 'track' => trackTitle ?? artistName, _ => artistName, }; factory AdminRequest.fromJson(Map j) => AdminRequest( id: j['id'] as String? ?? '', userId: j['user_id'] as String? ?? '', status: j['status'] as String? ?? 'pending', kind: j['kind'] as String? ?? 'artist', artistName: j['artist_name'] as String? ?? '', albumTitle: j['album_title'] as String?, trackTitle: j['track_title'] as String?, requestedAt: j['requested_at'] as String? ?? '', decidedAt: j['decided_at'] as String?, notes: j['notes'] as String?, importedAlbumCount: (j['imported_album_count'] as int?) ?? 0, importedTrackCount: (j['imported_track_count'] as int?) ?? 0, ); }