storage

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 18, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewUUID

func NewUUID() string

NewUUID generates a new UUID v4.

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 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 BotNotification struct {
	RecordID string    `gorm:"primaryKey;index" json:"record_id"`
	ChatID   int64     `gorm:"primaryKey;index" json:"chat_id"`
	SentAt   time.Time `json:"sent_at"`
}

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 Setting

type Setting struct {
	Key       string `gorm:"primaryKey" json:"key"`
	CreatedAt time.Time
	UpdatedAt time.Time

	Value string `json:"value"`
}

type Store

type Store struct {
	DB *gorm.DB
}

func Open

func Open(dsn string) (*Store, error)

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 (s *Store) FindOrCreateUser(provider, providerID, email, name, avatar string) (*User, error)
func (s *Store) GetBotLink(chatID int64) (*BotLink, error)

func (*Store) GetJWTSecret

func (s *Store) GetJWTSecret() (string, error)

func (*Store) GetUserAuditLogs added in v0.0.2

func (s *Store) GetUserAuditLogs(userID string, limit int) ([]AuditLog, error)

func (*Store) GetUserLikedCats added in v0.0.2

func (s *Store) GetUserLikedCats(userID string) ([]Cat, error)

func (*Store) IsLikedByUser added in v0.0.2

func (s *Store) IsLikedByUser(catID, userID string) (bool, error)

func (*Store) LikesCount added in v0.0.2

func (s *Store) LikesCount(catID string) (int64, error)

func (*Store) LinkBotChat

func (s *Store) LinkBotChat(chatID int64, userID string) error

func (*Store) ListImagesToOptimize

func (s *Store) ListImagesToOptimize(limit int) ([]Image, error)

Optimizer helpers and image maintenance ListImagesToOptimize returns up to 'limit' images that haven't been optimized yet.

func (*Store) MarkImageOptimizedEmpty

func (s *Store) MarkImageOptimizedEmpty(id string) error

MarkImageOptimizedEmpty marks an image as optimized when there is no image data to process.

func (*Store) MarkImageOptimizedNoChange

func (s *Store) MarkImageOptimizedNoChange(id string) error

MarkImageOptimizedNoChange marks an image as optimized without changing its data.

func (*Store) PruneAllCatsImages

func (s *Store) PruneAllCatsImages(keepN int) (int64, error)

PruneAllCatsImages iterates over all cats and prunes images to keep 'keepN' each. Returns total deleted count.

func (*Store) PruneOldCatImages

func (s *Store) PruneOldCatImages(catID string, keepN int) (int64, error)

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 (s *Store) SaveJWTSecret(secret string) error

func (*Store) SetLike added in v0.0.2

func (s *Store) SetLike(catID, userID string, like bool) error

func (*Store) UnlinkBotChat

func (s *Store) UnlinkBotChat(chatID int64) error

func (*Store) UpdateImageOptimizedData

func (s *Store) UpdateImageOptimizedData(id string, data []byte, mime string) error

UpdateImageOptimizedData stores optimized image bytes and MIME, marking it optimized.

type Tag

type Tag struct {
	ID        string    `gorm:"type:char(36);primaryKey" json:"id"`
	CreatedAt time.Time `json:"created_at"`

	Name string `gorm:"uniqueIndex" json:"name"`
}

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).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL