import 'package:objectbox/objectbox.dart'; /// User entity - works for both HOME and GUEST servers /// /// On HOME server: /// - isLocal = true /// - stores password, encrypted private key /// - this is where identity lives /// /// On GUEST server: /// - isLocal = false /// - homeServer contains the URL of user's home /// - publicKey cached for verification @Entity(uid: 3848231140411393897) class ChatUser { @Id() int id = 0; // Global immutable identifier (opaque, host-independent). @Unique() String userId; // Basic profile @Index() String username; String? displayName; String? avatarUrl; String? bio; // Identity String publicKey; // ECDSA public key, always stored // HOME SERVER ONLY: Auth & key backup String? passwordHash; String? encryptedPrivateKey; // Encrypted with user's password String? keyPairSalt; // Server relationship bool isLocal; // true = this is their home server String? homeServer; // if guest, where is their home? (e.g., "https://my.server.com") // Server-specific List roles; // ["admin", "moderator", "member"] @Property(type: PropertyType.date) DateTime createdAt; @Property(type: PropertyType.date) DateTime? lastSyncedAt; // When profile was last refreshed from home ChatUser({ required this.userId, required this.username, required this.publicKey, required this.isLocal, this.displayName, this.avatarUrl, this.bio, this.passwordHash, this.encryptedPrivateKey, this.keyPairSalt, this.homeServer, List? roles, DateTime? createdAt, DateTime? lastSyncedAt, }) : roles = roles ?? ['member'], createdAt = createdAt ?? DateTime.now(), lastSyncedAt = lastSyncedAt; } @Entity(uid: 2663861829934850300) class ChatChannel { @Id() int id = 0; @Unique() String name; String? description; @Property(type: PropertyType.date) DateTime createdAt; ChatChannel({ required this.name, this.description, DateTime? createdAt, }) : createdAt = createdAt ?? DateTime.now(); } @Entity(uid: 2697867424319168785) class ChatMessage { @Id() int id = 0; int channelId; // Author info - includes enough for cross-server profile fetch int authorLocalId; String authorUserId; // Immutable userId String? authorHomeServer; // for profile fetching // Cached for display (snapshot at message time) String authorUsername; String? authorAvatarUrl; String content; String componentsJson; @Property(type: PropertyType.date) DateTime createdAt; @Property(type: PropertyType.date) DateTime? editedAt; ChatMessage({ required this.channelId, required this.authorLocalId, required this.authorUserId, required this.authorUsername, required this.content, required this.componentsJson, this.authorHomeServer, this.authorAvatarUrl, DateTime? createdAt, this.editedAt, }) : createdAt = createdAt ?? DateTime.now(); } @Entity() class ChatFile { @Id() int id = 0; @Unique() String attachmentId; int uploaderId; String path; String originalFileName; String storedFileName; String sha256; String mimeType; int width; int height; int sizeBytes; bool isAttached; String usageType; // message | avatar | server_icon | server_banner String status; // pending | ready | failed String? errorCode; @Property(type: PropertyType.date) DateTime createdAt; ChatFile({ required this.attachmentId, required this.uploaderId, required this.path, required this.originalFileName, required this.storedFileName, required this.sha256, required this.mimeType, required this.width, required this.height, required this.sizeBytes, this.usageType = 'message', this.status = 'pending', this.isAttached = false, this.errorCode, DateTime? createdAt, }) : createdAt = createdAt ?? DateTime.now(); } @Entity() class ServerSettings { @Id() int id = 0; @Unique() String singletonKey; String serverName; String? description; String? iconAttachmentId; String? bannerAttachmentId; String? updatedByUserId; @Property(type: PropertyType.date) DateTime updatedAt; ServerSettings({ this.singletonKey = 'default', required this.serverName, this.description, this.iconAttachmentId, this.bannerAttachmentId, this.updatedByUserId, DateTime? updatedAt, }) : updatedAt = updatedAt ?? DateTime.now(); } @Entity() class ChatMessageMedia { @Id() int id = 0; int messageId; int channelId; String authorUserId; // local_upload String? attachmentId; // external_url String? externalUrl; // image | video | file String kind; String? mimeType; String? originalFileName; int? sizeBytes; int? width; int? height; String? thumbHash; @Property(type: PropertyType.date) DateTime createdAt; ChatMessageMedia({ required this.messageId, required this.channelId, required this.authorUserId, required this.kind, this.attachmentId, this.externalUrl, this.mimeType, this.originalFileName, this.sizeBytes, this.width, this.height, this.thumbHash, DateTime? createdAt, }) : createdAt = createdAt ?? DateTime.now(); }