2b595c40cd
Hand-rolled to match the server's actual JSON shapes: - AdminRequest carries user_id (UUID, not username); kind switches which title field is the display name - AdminQuarantineItem aggregates reports per track with reason_counts and a nested reports[] list, mirroring adminQueueRowView - AdminUser includes display_name + auto_approve_requests - Invite uses invited_by UUID + note (server hardcodes 24h TTL) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
41 lines
1.3 KiB
Dart
41 lines
1.3 KiB
Dart
/// Mirrors `inviteResp` from internal/api/admin_invites.go. The list
|
|
/// endpoint wraps these in `{"invites": [...]}`; the create endpoint
|
|
/// returns a single bare invite. Envelope parsing is done in
|
|
/// `AdminInvitesApi`, not here.
|
|
///
|
|
/// `invitedBy` is the UUID of the inviting admin (not their username);
|
|
/// the server doesn't currently denormalize it. Likewise `redeemedBy`.
|
|
/// TTL is hardcoded server-side at 24h, so admins can't customise the
|
|
/// expiry — only the optional `note`.
|
|
class Invite {
|
|
const Invite({
|
|
required this.token,
|
|
required this.invitedBy,
|
|
this.note,
|
|
required this.createdAt,
|
|
required this.expiresAt,
|
|
this.redeemedAt,
|
|
this.redeemedBy,
|
|
});
|
|
|
|
final String token;
|
|
final String invitedBy;
|
|
final String? note;
|
|
final String createdAt;
|
|
final String expiresAt;
|
|
final String? redeemedAt;
|
|
final String? redeemedBy;
|
|
|
|
bool get isRedeemed => redeemedAt != null;
|
|
|
|
factory Invite.fromJson(Map<String, dynamic> j) => Invite(
|
|
token: j['token'] as String? ?? '',
|
|
invitedBy: j['invited_by'] as String? ?? '',
|
|
note: j['note'] as String?,
|
|
createdAt: j['created_at'] as String? ?? '',
|
|
expiresAt: j['expires_at'] as String? ?? '',
|
|
redeemedAt: j['redeemed_at'] as String?,
|
|
redeemedBy: j['redeemed_by'] as String?,
|
|
);
|
|
}
|