package models import "time" type User struct { ID string `json:"id"` Email string `json:"email"` PasswordHash string `json:"-"` Name string `json:"name"` AvatarURL string `json:"avatar_url,omitempty"` Preferences map[string]any `json:"preferences,omitempty"` CreatedAt time.Time `json:"created_at"` } type PublicUser struct { ID string `json:"id"` Email string `json:"email,omitempty"` Name string `json:"name"` AvatarURL string `json:"avatar_url,omitempty"` } func (u *User) Public() PublicUser { if u == nil { return PublicUser{} } return PublicUser{ID: u.ID, Email: u.Email, Name: u.Name, AvatarURL: u.AvatarURL} } type Album struct { ID string `json:"id"` OwnerID string `json:"owner_id"` Title string `json:"title"` Description string `json:"description"` CoverPhotoID *string `json:"cover_photo_id,omitempty"` CoverThumbKey string `json:"-"` CoverThumbURL string `json:"cover_thumb_url,omitempty"` CoverMediumKey string `json:"-"` CoverMediumURL string `json:"cover_medium_url,omitempty"` PhotosCount int `json:"photos_count"` MembersCount int `json:"members_count"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } type AlbumMember struct { AlbumID string `json:"album_id"` UserID string `json:"user_id"` Role string `json:"role"` InvitedBy *string `json:"invited_by,omitempty"` JoinedAt time.Time `json:"joined_at"` User PublicUser `json:"user"` } type Invite struct { ID string `json:"id"` AlbumID string `json:"album_id"` Token string `json:"token"` Role string `json:"role"` CreatedBy string `json:"created_by"` ExpiresAt time.Time `json:"expires_at"` MaxUses int `json:"max_uses"` Uses int `json:"uses"` CreatedAt time.Time `json:"created_at"` } type Photo struct { ID string `json:"id"` AlbumID string `json:"album_id"` UploaderID string `json:"uploader_id"` StorageKey string `json:"-"` ThumbKey string `json:"-"` MediumKey string `json:"-"` PreviewKey string `json:"-"` PlaybackKey string `json:"-"` OriginalFilename string `json:"original_filename"` Size int64 `json:"size"` Width int `json:"width"` Height int `json:"height"` Kind string `json:"kind"` DurationMS int64 `json:"duration_ms,omitempty"` MimeType string `json:"mime_type"` TakenAt *time.Time `json:"taken_at,omitempty"` Latitude *float64 `json:"latitude,omitempty"` Longitude *float64 `json:"longitude,omitempty"` Caption string `json:"caption"` EXIF map[string]any `json:"exif,omitempty"` Tags []Tag `json:"tags,omitempty"` DeletedAt *time.Time `json:"deleted_at,omitempty"` AlbumTitle string `json:"album_title,omitempty"` CreatedAt time.Time `json:"created_at"` Uploader PublicUser `json:"uploader"` LikesCount int `json:"likes_count"` CommentsCount int `json:"comments_count"` LikedByMe bool `json:"liked_by_me"` ThumbURL string `json:"thumb_url,omitempty"` MediumURL string `json:"medium_url,omitempty"` PreviewURL string `json:"preview_url,omitempty"` PlaybackURL string `json:"playback_url,omitempty"` OriginalURL string `json:"original_url,omitempty"` DownloadURL string `json:"download_url,omitempty"` } type Tag struct { ID string `json:"id"` Name string `json:"name"` } type Comment struct { ID string `json:"id"` PhotoID string `json:"photo_id"` UserID string `json:"user_id"` Text string `json:"text"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` User PublicUser `json:"user"` } type Notification struct { ID string `json:"id"` UserID string `json:"user_id"` Type string `json:"type"` PayloadJSON map[string]any `json:"payload"` ReadAt *time.Time `json:"read_at,omitempty"` CreatedAt time.Time `json:"created_at"` } type ShareLink struct { ID string `json:"id"` AlbumID string `json:"album_id"` Token string `json:"token"` CreatedBy string `json:"created_by"` CreatedAt time.Time `json:"created_at"` ExpiresAt time.Time `json:"expires_at"` RevokedAt *time.Time `json:"revoked_at,omitempty"` } func (s *ShareLink) Active(now time.Time) bool { return s.RevokedAt == nil && now.Before(s.ExpiresAt) } type RefreshToken struct { ID string UserID string TokenHash string ExpiresAt time.Time RevokedAt *time.Time CreatedAt time.Time }