Documentation
¶
Index ¶
- func NewUUID() string
- type AuditLog
- type BotLink
- type BotNotification
- type Cat
- type CatLocation
- type Image
- type Like
- type Record
- type Setting
- type Store
- func (s *Store) FindOrCreateUser(provider, providerID, email, name, avatar string) (*User, error)
- func (s *Store) GetBotLink(chatID int64) (*BotLink, error)
- func (s *Store) GetJWTSecret() (string, error)
- func (s *Store) GetUserAuditLogs(userID string, limit int) ([]AuditLog, error)
- func (s *Store) GetUserLikedCats(userID string) ([]Cat, error)
- func (s *Store) IsLikedByUser(catID, userID string) (bool, error)
- func (s *Store) LikesCount(catID string) (int64, error)
- func (s *Store) LinkBotChat(chatID int64, userID string) error
- func (s *Store) ListImagesToOptimize(limit int) ([]Image, error)
- func (s *Store) MarkImageOptimizedEmpty(id string) error
- func (s *Store) MarkImageOptimizedNoChange(id string) error
- func (s *Store) PruneAllCatsImages(keepN int) (int64, error)
- func (s *Store) PruneOldCatImages(catID string, keepN int) (int64, error)
- func (s *Store) SaveJWTSecret(secret string) error
- func (s *Store) SetLike(catID, userID string, like bool) error
- func (s *Store) UnlinkBotChat(chatID int64) error
- func (s *Store) UpdateImageOptimizedData(id string, data []byte, mime string) error
- type Tag
- type User
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AuditLog ¶
type AuditLog struct {
ID string `gorm:"type:char(36);primaryKey" json:"id"`
Timestamp time.Time `gorm:"index" json:"ts"`
UserID string `gorm:"type:char(36);index" json:"user_id"`
Method string `json:"method"`
Route string `json:"route"`
TargetType string `gorm:"index" json:"target_type"`
TargetID string `gorm:"index" json:"target_id"`
Status string `json:"status"` // success, error
IP string `json:"ip"`
UserAgent string `json:"user_agent"`
RequestID string `json:"request_id"`
Delta string `json:"delta"`
}
AuditLog tracks all mutating actions.
type BotLink ¶
type BotLink struct {
ChatID int64 `gorm:"primaryKey" json:"chat_id"`
UserID string `gorm:"type:char(36);index" json:"user_id"`
CreatedAt time.Time `json:"created_at"`
}
BotLink associates a Telegram chat with a User.
type BotNotification ¶
type Cat ¶
type Cat struct {
ID string `gorm:"type:char(36);primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Name string `json:"name"`
Description string `json:"description"`
Color string `json:"color"`
BirthDate *time.Time `json:"birth_date,omitempty"`
Gender string `json:"gender"` // male, female, unknown
IsSterilized bool `json:"is_sterilized"`
NeedAttention bool `json:"need_attention"`
Condition int `gorm:"type:integer;default:3" json:"condition"` // 1..5 scale
LastSeen *time.Time `json:"last_seen,omitempty"`
Locations []CatLocation `gorm:"constraint:OnDelete:CASCADE;" json:"locations"`
Images []Image `gorm:"constraint:OnDelete:CASCADE;" json:"images"`
Records []Record `gorm:"constraint:OnDelete:CASCADE;" json:"records"`
Tags []Tag `gorm:"many2many:cat_tags;" json:"tags"`
// Virtual fields for API (populated in handlers)
Likes int64 `gorm:"-" json:"likes"`
Liked bool `gorm:"-" json:"liked"`
}
Cat represents a homeless cat.
type CatLocation ¶
type CatLocation struct {
ID string `gorm:"type:char(36);primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
CatID string `gorm:"type:char(36);index" json:"cat_id"`
Name string `json:"name"`
Description string `json:"description"`
Latitude float64 `json:"lat"`
Longitude float64 `json:"lon"`
}
CatLocation represents a place where a cat was seen.
type Image ¶
type Image struct {
ID string `gorm:"type:char(36);primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
CatID string `gorm:"type:char(36);index" json:"cat_id"`
URL string `json:"url"`
Data []byte `json:"-"` // Optional: embedded image data (BLOB for SQLite, BYTEA for Postgres)
MIME string `json:"mime"`
Title string `json:"title"`
// Optimized marks that the optimizer has processed this image (resized/recompressed)
Optimized bool `gorm:"index;default:false" json:"-"`
}
Image represents a cat photo.
type Like ¶ added in v0.0.2
type Like struct {
ID string `gorm:"type:char(36);primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
CatID string `gorm:"type:char(36);index:idx_cat_user,unique" json:"cat_id"`
UserID string `gorm:"type:char(36);index:idx_cat_user,unique" json:"user_id"`
}
Like represents a like from a user to a cat.
type Record ¶
type Record struct {
ID string `gorm:"type:char(36);primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
CatID string `gorm:"type:char(36);index" json:"cat_id"`
UserID string `gorm:"type:char(36);index" json:"user_id"`
User User `json:"user"`
Type string `json:"type"` // feeding, medical, observation, sterilization, vaccination, vet_visit, medication
Note string `json:"note"`
Timestamp time.Time `json:"timestamp"`
PlannedAt *time.Time `json:"planned_at,omitempty"`
DoneAt *time.Time `json:"done_at,omitempty"`
// Recurrence fields
Recurrence string `json:"recurrence,omitempty"` // daily, weekly, monthly
Interval int `json:"interval,omitempty"` // e.g. every 2 days
EndDate *time.Time `json:"end_date,omitempty"`
}
Record represents a service event for a cat (feeding, medical, etc.)
type Store ¶
func Open ¶
Open initializes the database (SQLite or PostgreSQL based on DSN) and runs auto-migrations. If the provided string looks like a PostgreSQL DSN (starts with postgres:// or postgresql://, or contains key=val pairs like host=/user=/dbname=), Postgres driver will be used. Otherwise, it's treated as a SQLite path/DSN.
func (*Store) FindOrCreateUser ¶
func (*Store) GetJWTSecret ¶
func (*Store) GetUserAuditLogs ¶ added in v0.0.2
func (*Store) GetUserLikedCats ¶ added in v0.0.2
func (*Store) IsLikedByUser ¶ added in v0.0.2
func (*Store) ListImagesToOptimize ¶
Optimizer helpers and image maintenance ListImagesToOptimize returns up to 'limit' images that haven't been optimized yet.
func (*Store) MarkImageOptimizedEmpty ¶
MarkImageOptimizedEmpty marks an image as optimized when there is no image data to process.
func (*Store) MarkImageOptimizedNoChange ¶
MarkImageOptimizedNoChange marks an image as optimized without changing its data.
func (*Store) PruneAllCatsImages ¶
PruneAllCatsImages iterates over all cats and prunes images to keep 'keepN' each. Returns total deleted count.
func (*Store) PruneOldCatImages ¶
PruneOldCatImages keeps only the newest 'keepN' images for the given cat and deletes the rest. Returns the number of deleted images and an error if occurred.
func (*Store) SaveJWTSecret ¶
func (*Store) UnlinkBotChat ¶
type User ¶
type User struct {
ID string `gorm:"type:char(36);primaryKey" json:"id"`
CreatedAt time.Time
UpdatedAt time.Time
Provider string `json:"provider"`
ProviderID string `gorm:"uniqueIndex" json:"provider_id"`
Email string `gorm:"index" json:"email"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url"`
}
User represents an application user (volunteer/caretaker).