98 lines
4.0 KiB
Go
98 lines
4.0 KiB
Go
package model
|
||
|
||
import "time"
|
||
|
||
// SadhnaLog is one persisted row of the sadhna_logs table — the chanting
|
||
// half of a day's sādhana. The posting half is derived from the posts
|
||
// table at read time, so it has no column here.
|
||
type SadhnaLog struct {
|
||
ID string `json:"id"`
|
||
UserID string `json:"user_id"`
|
||
LogDate time.Time `json:"log_date"`
|
||
RoundsCompleted int `json:"rounds_completed"`
|
||
ChantDone bool `json:"chant_done"`
|
||
CreatedAt time.Time `json:"created_at"`
|
||
UpdatedAt time.Time `json:"updated_at"`
|
||
}
|
||
|
||
// SadhnaDay is one cell of the 7-day streak strip. `Completed` is the
|
||
// conjunction the streak counts: both the chanting and the posting were
|
||
// done that calendar day.
|
||
type SadhnaDay struct {
|
||
Date string `json:"date"` // YYYY-MM-DD (UTC)
|
||
ChantDone bool `json:"chant_done"`
|
||
QuoteDone bool `json:"quote_done"`
|
||
Completed bool `json:"completed"`
|
||
}
|
||
|
||
// VineDay is one fold of the sādhana creeper — one day of practice the
|
||
// vine has wound around its pole. The creeper grows a fresh fold for each
|
||
// day of the current streak (oldest first), plus a final in-progress fold
|
||
// for an unfinished today. Rounds/Posts annotate the fold so the devotee
|
||
// sees exactly what they offered that day.
|
||
type VineDay struct {
|
||
Date string `json:"date"` // YYYY-MM-DD (UTC)
|
||
Rounds int `json:"rounds"` // rounds chanted that day
|
||
Posts int `json:"posts"` // quotes posted that day
|
||
Completed bool `json:"completed"` // both disciplines done (a full fold)
|
||
InProgress bool `json:"in_progress"` // today, not yet complete (the growing tip)
|
||
}
|
||
|
||
// SadhnaReward is one gift item in the streak-reward catalog.
|
||
type SadhnaReward struct {
|
||
ID string `json:"id"`
|
||
Key string `json:"key"`
|
||
Name string `json:"name"`
|
||
Meaning string `json:"meaning"`
|
||
ImageURL string `json:"image_url"`
|
||
Active bool `json:"active"`
|
||
Sort int `json:"sort"`
|
||
}
|
||
|
||
// SadhnaRewardGrant is a reward a user earned at a streak milestone (a
|
||
// multiple of 7 days). The full reward is embedded for direct rendering.
|
||
type SadhnaRewardGrant struct {
|
||
Milestone int `json:"milestone"`
|
||
GrantedAt time.Time `json:"granted_at"`
|
||
Reward SadhnaReward `json:"reward"`
|
||
}
|
||
|
||
// SadhnaDashboard is the single payload the /sadhna-streak page reads. It
|
||
// folds together today's progress, the week strip, the streak counters,
|
||
// and the plant's growth state so the client renders without further
|
||
// round-trips.
|
||
type SadhnaDashboard struct {
|
||
// Today's two disciplines.
|
||
TargetRounds int `json:"target_rounds"` // user's goal (16 if unset)
|
||
RoundsCompleted int `json:"rounds_completed"` // saved progress today
|
||
ChantDone bool `json:"chant_done"` // rounds reached target
|
||
QuoteDone bool `json:"quote_done"` // posted at least one quote today
|
||
TodayCompleted bool `json:"today_completed"` // both done today
|
||
|
||
// Streak counters.
|
||
CurrentStreak int `json:"current_streak"`
|
||
LongestStreak int `json:"longest_streak"`
|
||
|
||
// Plant state. Growth is 0–100; Stage is the derived label the client
|
||
// maps to a visual; Alive is false only when growth has decayed to 0.
|
||
Growth int `json:"growth"`
|
||
Stage string `json:"stage"` // dead | sprout | seedling | sapling | young | mature
|
||
Alive bool `json:"alive"`
|
||
|
||
// The trailing 7 calendar days, oldest first, for the top strip.
|
||
Week []SadhnaDay `json:"week"`
|
||
|
||
// The creeper: one fold per day of the current streak (oldest first),
|
||
// plus a final in-progress fold for an unfinished today. Capped to the
|
||
// most recent vineMaxDays folds for payload sanity; CurrentStreak holds
|
||
// the true length.
|
||
VineDays []VineDay `json:"vine_days"`
|
||
|
||
// Rewards. NextRewardDate is the projected UTC date (YYYY-MM-DD) the next
|
||
// gift lands if the streak continues — for the calendar's gift marker.
|
||
// PendingReward is a freshly earned, not-yet-celebrated gift the client
|
||
// should celebrate now (nil when there's nothing to show).
|
||
NextRewardDate *string `json:"next_reward_date"`
|
||
PendingReward *SadhnaRewardGrant `json:"pending_reward"`
|
||
}
|