// ignore_for_file: invalid_annotation_target import 'package:freezed_annotation/freezed_annotation.dart'; part 'backend_models.freezed.dart'; part 'backend_models.g.dart'; /// Supported authentication methods. @JsonEnum(fieldRename: FieldRename.snake) enum SignInMethod { /// Email link based sign-in. emailMagicLink, /// Email/password sign-in. password, /// OIDC token based sign-in. oidc, } /// Allowed change operation types. @JsonEnum(alwaysCreate: true) enum ChangeOperation { /// Create or update entity state. @JsonValue('upsert') upsert, /// Remove entity state. @JsonValue('delete') delete, } /// Action taken by user against a signal item. @JsonEnum(alwaysCreate: true) enum SignalAction { /// Item was viewed. viewed, /// Item was dismissed. dismissed, /// Item was saved. saved, /// Item resulted in purchase. purchased, } /// Upload category. @JsonEnum(alwaysCreate: true) enum UploadPurpose { /// Avatar upload. @JsonValue('avatar') avatar, /// Generic attachment upload. @JsonValue('attachment') attachment, } /// Request body for sign-in. @freezed abstract class SignInRequest with _$SignInRequest { const factory SignInRequest({ required SignInMethod method, String? email, String? password, String? idToken, }) = _SignInRequest; factory SignInRequest.fromJson(Map json) => _$SignInRequestFromJson(json); } /// User profile returned by backend. @freezed abstract class UserProfile with _$UserProfile { const factory UserProfile({ required String id, String? email, String? displayName, String? avatarFileId, }) = _UserProfile; factory UserProfile.fromJson(Map json) => _$UserProfileFromJson(json); } /// Auth session bundle used by gateway and token storage. @freezed abstract class AuthSession with _$AuthSession { @JsonSerializable(explicitToJson: true) const factory AuthSession({ required String accessToken, required String refreshToken, required DateTime expiresAt, required UserProfile user, }) = _AuthSession; factory AuthSession.fromJson(Map json) => _$AuthSessionFromJson(json); } /// Refresh token request body. @freezed abstract class AuthRefreshRequest with _$AuthRefreshRequest { const factory AuthRefreshRequest({required String refreshToken}) = _AuthRefreshRequest; factory AuthRefreshRequest.fromJson(Map json) => _$AuthRefreshRequestFromJson(json); } /// Refresh token response body. @freezed abstract class AuthRefreshResponse with _$AuthRefreshResponse { const factory AuthRefreshResponse({ required String accessToken, String? refreshToken, required DateTime expiresAt, }) = _AuthRefreshResponse; factory AuthRefreshResponse.fromJson(Map json) => _$AuthRefreshResponseFromJson(json); } /// Generic envelope for offline-first change operations. @freezed abstract class ChangeEnvelope with _$ChangeEnvelope { const factory ChangeEnvelope({ required int schemaVersion, required String entityType, required String entityId, required ChangeOperation op, required DateTime modifiedAt, required String clientMutationId, Map? payload, }) = _ChangeEnvelope; factory ChangeEnvelope.fromJson(Map json) => _$ChangeEnvelopeFromJson(json); } /// Push request for batched local changes. @freezed abstract class SyncPushRequest with _$SyncPushRequest { @JsonSerializable(explicitToJson: true) const factory SyncPushRequest({ required String deviceId, String? cursor, required List changes, required String idempotencyKey, }) = _SyncPushRequest; factory SyncPushRequest.fromJson(Map json) => _$SyncPushRequestFromJson(json); } /// Acknowledgement for an accepted mutation. @freezed abstract class MutationAck with _$MutationAck { const factory MutationAck({ required String clientMutationId, String? serverMutationId, DateTime? acceptedAt, }) = _MutationAck; factory MutationAck.fromJson(Map json) => _$MutationAckFromJson(json); } /// Rejection detail for a mutation. @freezed abstract class MutationRejection with _$MutationRejection { const factory MutationRejection({ required String clientMutationId, required String code, required String message, }) = _MutationRejection; factory MutationRejection.fromJson(Map json) => _$MutationRejectionFromJson(json); } /// Result body returned by sync push. @freezed abstract class SyncPushResult with _$SyncPushResult { @JsonSerializable(explicitToJson: true) const factory SyncPushResult({ required String cursor, @Default([]) List accepted, @Default([]) List rejected, }) = _SyncPushResult; factory SyncPushResult.fromJson(Map json) => _$SyncPushResultFromJson(json); } /// Result body returned by sync pull. @freezed abstract class SyncPullResult with _$SyncPullResult { @JsonSerializable(explicitToJson: true) const factory SyncPullResult({ required String cursor, @Default([]) List changes, }) = _SyncPullResult; factory SyncPullResult.fromJson(Map json) => _$SyncPullResultFromJson(json); } /// Signals feed item. @freezed abstract class SignalItem with _$SignalItem { const factory SignalItem({ required String id, required String type, required String title, String? description, String? personId, required DateTime createdAt, Map? metadata, }) = _SignalItem; factory SignalItem.fromJson(Map json) => _$SignalItemFromJson(json); } /// Cursor-based signals response. @freezed abstract class SignalsFeed with _$SignalsFeed { @JsonSerializable(explicitToJson: true) const factory SignalsFeed({ String? cursor, @Default([]) List items, }) = _SignalsFeed; factory SignalsFeed.fromJson(Map json) => _$SignalsFeedFromJson(json); } /// Signal acknowledgement request body. @freezed abstract class SignalAckRequest with _$SignalAckRequest { const factory SignalAckRequest({ required SignalAction action, required DateTime at, }) = _SignalAckRequest; factory SignalAckRequest.fromJson(Map json) => _$SignalAckRequestFromJson(json); } /// Upload init request. @freezed abstract class UploadInitRequest with _$UploadInitRequest { const factory UploadInitRequest({ required UploadPurpose purpose, required String contentType, required int sizeBytes, }) = _UploadInitRequest; factory UploadInitRequest.fromJson(Map json) => _$UploadInitRequestFromJson(json); } /// Upload init response. @freezed abstract class UploadInitResult with _$UploadInitResult { const factory UploadInitResult({ required String uploadUrl, required String fileId, required DateTime expiresAt, }) = _UploadInitResult; factory UploadInitResult.fromJson(Map json) => _$UploadInitResultFromJson(json); } /// Download URL response. @freezed abstract class DownloadUrl with _$DownloadUrl { const factory DownloadUrl({ required String downloadUrl, required DateTime expiresAt, }) = _DownloadUrl; factory DownloadUrl.fromJson(Map json) => _$DownloadUrlFromJson(json); }