feat: add web push and sadhna tracker
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/prabhupadasays/spsays-bff/internal/model"
|
||||
@@ -215,6 +216,65 @@ func (r *PostRepo) CountByUser(ctx context.Context, userID string) (int, error)
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// PostedDates returns the set of UTC calendar days, on or after `since`,
|
||||
// on which the user created at least one post. Used by the sādhana streak
|
||||
// to detect the "posted a quote today" discipline (and to score past days
|
||||
// of the streak) without loading whole posts. Keys are "YYYY-MM-DD".
|
||||
func (r *PostRepo) PostedDates(ctx context.Context, userID string, since time.Time) (map[string]bool, error) {
|
||||
rows, err := r.pg.Pool.Query(ctx, `
|
||||
SELECT DISTINCT (created_at AT TIME ZONE 'UTC')::date AS d
|
||||
FROM posts
|
||||
WHERE user_id = $1 AND created_at >= $2`,
|
||||
userID, since,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("posted dates: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
out := make(map[string]bool)
|
||||
for rows.Next() {
|
||||
var d time.Time
|
||||
if err := rows.Scan(&d); err != nil {
|
||||
return nil, fmt.Errorf("scan posted date: %w", err)
|
||||
}
|
||||
out[d.Format("2006-01-02")] = true
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// PostCountsByDate returns, for each UTC calendar day on or after `since`,
|
||||
// how many posts the user created that day. Keys are "YYYY-MM-DD"; days
|
||||
// with no posts are absent (so a missing key reads as zero). The sādhana
|
||||
// vine uses this both for the "posted a quote today" discipline and to
|
||||
// annotate each day's fold with the number of quotes shared.
|
||||
func (r *PostRepo) PostCountsByDate(ctx context.Context, userID string, since time.Time) (map[string]int, error) {
|
||||
rows, err := r.pg.Pool.Query(ctx, `
|
||||
SELECT (created_at AT TIME ZONE 'UTC')::date AS d, count(*) AS n
|
||||
FROM posts
|
||||
WHERE user_id = $1 AND created_at >= $2
|
||||
GROUP BY d`,
|
||||
userID, since,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("post counts by date: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
out := make(map[string]int)
|
||||
for rows.Next() {
|
||||
var (
|
||||
d time.Time
|
||||
n int
|
||||
)
|
||||
if err := rows.Scan(&d, &n); err != nil {
|
||||
return nil, fmt.Errorf("scan post count: %w", err)
|
||||
}
|
||||
out[d.Format("2006-01-02")] = n
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// Reshare creates a new posts row owned by `resharerID` that points at
|
||||
// the canonical original via `reshared_from_post_id`. Copies the
|
||||
// original's caption / source_url / source_title and its current images
|
||||
|
||||
Reference in New Issue
Block a user