feat: rebuild pet app and backend around core care flows
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Base gives every persisted model a PostgreSQL uuid primary key.
|
||||
// GORM's naming strategy maps Go fields to snake_case columns.
|
||||
type Base struct {
|
||||
ID string `gorm:"type:uuid;primaryKey" json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (b *Base) BeforeCreate(_ *gorm.DB) error {
|
||||
if b.ID == "" {
|
||||
b.ID = uuid.NewString()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type File struct {
|
||||
Base
|
||||
Bucket string `gorm:"size:128;not null" json:"bucket"`
|
||||
ObjectKey string `gorm:"size:512;uniqueIndex;not null" json:"object_key"`
|
||||
MD5 string `gorm:"column:md5;size:32;uniqueIndex;not null" json:"md5"`
|
||||
URL string `gorm:"size:1024;not null" json:"url"`
|
||||
Name string `gorm:"size:255;not null" json:"name"`
|
||||
ContentType string `gorm:"size:128;not null" json:"content_type"`
|
||||
Size int64 `gorm:"not null" json:"size"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Base
|
||||
OpenID string `gorm:"size:128;uniqueIndex;not null" json:"-"`
|
||||
Nickname string `gorm:"size:64;not null" json:"nickname"`
|
||||
AvatarFileID *string `gorm:"type:uuid;index" json:"avatar_file_id"`
|
||||
Disabled bool `gorm:"not null;default:false" json:"disabled"`
|
||||
}
|
||||
|
||||
type Admin struct {
|
||||
Base
|
||||
Username string `gorm:"size:64;uniqueIndex;not null" json:"username"`
|
||||
PasswordHash string `gorm:"size:255;not null" json:"-"`
|
||||
}
|
||||
|
||||
type Pet struct {
|
||||
Base
|
||||
UserID string `gorm:"type:uuid;index;not null" json:"user_id"`
|
||||
Name string `gorm:"size:64;not null" json:"name"`
|
||||
Species string `gorm:"size:16;not null;default:dog" json:"species"`
|
||||
Breed string `gorm:"size:64" json:"breed"`
|
||||
Gender string `gorm:"size:16" json:"gender"`
|
||||
BirthDate *time.Time `gorm:"type:date" json:"birth_date"`
|
||||
WeightKg float64 `gorm:"type:numeric(6,2)" json:"weight_kg"`
|
||||
AvatarFileID *string `gorm:"type:uuid;index" json:"avatar_file_id"`
|
||||
Coat string `gorm:"size:64" json:"coat"`
|
||||
Allergies string `gorm:"size:255" json:"allergies"`
|
||||
CareNotes string `gorm:"size:1000" json:"care_notes"`
|
||||
Archived bool `gorm:"not null;default:false" json:"archived"`
|
||||
}
|
||||
|
||||
type CareTask struct {
|
||||
Base
|
||||
UserID string `gorm:"type:uuid;index;not null" json:"user_id"`
|
||||
PetID string `gorm:"type:uuid;index;not null" json:"pet_id"`
|
||||
Title string `gorm:"size:128;not null" json:"title"`
|
||||
Category string `gorm:"size:32;not null" json:"category"`
|
||||
TimeOfDay string `gorm:"size:5;not null" json:"time_of_day"`
|
||||
RepeatRule string `gorm:"size:16;not null;default:daily" json:"repeat_rule"`
|
||||
ReminderEnabled bool `gorm:"not null;default:false" json:"reminder_enabled"`
|
||||
}
|
||||
|
||||
type TaskCompletion struct {
|
||||
Base
|
||||
TaskID string `gorm:"type:uuid;uniqueIndex:idx_task_date;not null" json:"task_id"`
|
||||
UserID string `gorm:"type:uuid;index;not null" json:"user_id"`
|
||||
Date time.Time `gorm:"type:date;uniqueIndex:idx_task_date;not null" json:"date"`
|
||||
CompletedAt time.Time `gorm:"not null" json:"completed_at"`
|
||||
}
|
||||
|
||||
type Walk struct {
|
||||
Base
|
||||
UserID string `gorm:"type:uuid;index;not null" json:"user_id"`
|
||||
Status string `gorm:"size:16;index;not null" json:"status"`
|
||||
StartedAt time.Time `gorm:"not null" json:"started_at"`
|
||||
SegmentStartedAt time.Time `gorm:"not null" json:"segment_started_at"`
|
||||
PausedAt *time.Time `json:"paused_at"`
|
||||
PausedSeconds int `gorm:"not null;default:0" json:"paused_seconds"`
|
||||
EndedAt *time.Time `json:"ended_at"`
|
||||
DurationSeconds int `gorm:"not null;default:0" json:"duration_seconds"`
|
||||
DistanceMeters float64 `gorm:"type:numeric(12,2);not null;default:0" json:"distance_meters"`
|
||||
ShareEnabled bool `gorm:"not null;default:false" json:"share_enabled"`
|
||||
ShareToken string `gorm:"type:uuid;uniqueIndex" json:"-"`
|
||||
ShareExpiresAt *time.Time `json:"share_expires_at"`
|
||||
}
|
||||
|
||||
type WalkPet struct {
|
||||
Base
|
||||
WalkID string `gorm:"type:uuid;uniqueIndex:idx_walk_pet;not null" json:"walk_id"`
|
||||
PetID string `gorm:"type:uuid;uniqueIndex:idx_walk_pet;index;not null" json:"pet_id"`
|
||||
}
|
||||
|
||||
type WalkPoint struct {
|
||||
Base
|
||||
WalkID string `gorm:"type:uuid;index;not null" json:"walk_id"`
|
||||
Latitude float64 `gorm:"type:numeric(10,7);not null" json:"latitude"`
|
||||
Longitude float64 `gorm:"type:numeric(10,7);not null" json:"longitude"`
|
||||
RecordedAt time.Time `gorm:"index;not null" json:"recorded_at"`
|
||||
}
|
||||
|
||||
type Meetup struct {
|
||||
Base
|
||||
HostUserID string `gorm:"type:uuid;index;not null" json:"host_user_id"`
|
||||
Title string `gorm:"size:128;not null" json:"title"`
|
||||
Description string `gorm:"size:1000" json:"description"`
|
||||
PlaceName string `gorm:"size:255;not null" json:"place_name"`
|
||||
Latitude float64 `gorm:"type:numeric(10,7)" json:"latitude"`
|
||||
Longitude float64 `gorm:"type:numeric(10,7)" json:"longitude"`
|
||||
StartsAt time.Time `gorm:"index;not null" json:"starts_at"`
|
||||
MaxPeople int `gorm:"not null;default:8" json:"max_people"`
|
||||
Status string `gorm:"size:16;index;not null;default:open" json:"status"`
|
||||
CoverFileID *string `gorm:"type:uuid;index" json:"cover_file_id"`
|
||||
}
|
||||
|
||||
type MeetupParticipant struct {
|
||||
Base
|
||||
MeetupID string `gorm:"type:uuid;uniqueIndex:idx_meetup_user;not null" json:"meetup_id"`
|
||||
UserID string `gorm:"type:uuid;uniqueIndex:idx_meetup_user;index;not null" json:"user_id"`
|
||||
}
|
||||
|
||||
type MeetupPet struct {
|
||||
Base
|
||||
ParticipantID string `gorm:"type:uuid;uniqueIndex:idx_participant_pet;not null" json:"participant_id"`
|
||||
PetID string `gorm:"type:uuid;uniqueIndex:idx_participant_pet;index;not null" json:"pet_id"`
|
||||
}
|
||||
|
||||
func All() []any {
|
||||
return []any{
|
||||
&File{}, &User{}, &Admin{}, &Pet{}, &CareTask{}, &TaskCompletion{},
|
||||
&Walk{}, &WalkPet{}, &WalkPoint{}, &Meetup{}, &MeetupParticipant{}, &MeetupPet{},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user