first commit of restructured project

This commit is contained in:
KS Jannette
2026-02-22 15:21:18 -05:00
commit 9fca234606
75 changed files with 8299 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
package repository
import (
"context"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/kjannette/trahn-backend/internal/models"
)
type PriceRepo struct {
pool *pgxpool.Pool
}
func NewPriceRepo(pool *pgxpool.Pool) *PriceRepo {
return &PriceRepo{pool: pool}
}
func (r *PriceRepo) Record(ctx context.Context, price float64, ts time.Time) (*models.PricePoint, error) {
td := TradingDay(ts)
row := r.pool.QueryRow(ctx,
`INSERT INTO price_history (timestamp, price, trading_day, source)
VALUES ($1, $2, $3, $4) RETURNING *`,
ts, price, td, "coingecko",
)
return scanPrice(row)
}
func (r *PriceRepo) GetByDay(ctx context.Context, tradingDay string) ([]models.PricePoint, error) {
rows, err := r.pool.Query(ctx,
`SELECT * FROM price_history WHERE trading_day = $1 ORDER BY timestamp ASC`,
tradingDay,
)
if err != nil {
return nil, err
}
defer rows.Close()
return collectPrices(rows)
}
func (r *PriceRepo) GetAvailableDays(ctx context.Context) ([]string, error) {
rows, err := r.pool.Query(ctx,
`SELECT DISTINCT trading_day FROM price_history ORDER BY trading_day DESC LIMIT 30`,
)
if err != nil {
return nil, err
}
defer rows.Close()
var days []string
for rows.Next() {
var d time.Time
if err := rows.Scan(&d); err != nil {
return nil, err
}
days = append(days, d.Format("2006-01-02"))
}
return days, rows.Err()
}
func (r *PriceRepo) GetLatest(ctx context.Context) (*models.PricePoint, error) {
row := r.pool.QueryRow(ctx,
`SELECT * FROM price_history ORDER BY timestamp DESC LIMIT 1`,
)
p, err := scanPrice(row)
if err != nil {
if err.Error() == "no rows in result set" {
return nil, nil
}
return nil, err
}
return p, nil
}
// --- scan helpers ---
type scannable interface {
Scan(dest ...any) error
}
func scanPrice(row scannable) (*models.PricePoint, error) {
var p models.PricePoint
var td time.Time
err := row.Scan(&p.ID, &p.Timestamp, &p.Price, &td, &p.Source, &p.CreatedAt)
if err != nil {
return nil, err
}
p.TradingDay = td.Format("2006-01-02")
return &p, nil
}
type rowsIter interface {
Next() bool
Scan(dest ...any) error
Err() error
}
func collectPrices(rows rowsIter) ([]models.PricePoint, error) {
var out []models.PricePoint
for rows.Next() {
var p models.PricePoint
var td time.Time
if err := rows.Scan(&p.ID, &p.Timestamp, &p.Price, &td, &p.Source, &p.CreatedAt); err != nil {
return nil, err
}
p.TradingDay = td.Format("2006-01-02")
out = append(out, p)
}
return out, rows.Err()
}