initial boilerplate

This commit is contained in:
2026-05-03 16:43:53 +03:00
parent bea266e066
commit 2e63e0e95b
18 changed files with 1878 additions and 1 deletions
+110
View File
@@ -0,0 +1,110 @@
// Package models defines the core data structures shared across the app.
// These are plain Go structs — no ORM tags, no magic.
package models
import (
"time"
"github.com/google/uuid"
)
// ── Database models (match table columns exactly) ─────────────────────────────
type Receipt struct {
ID uuid.UUID `json:"id"`
StoreName *string `json:"store_name"`
ReceiptDate time.Time `json:"receipt_date"`
ImageURL *string `json:"image_url"`
City *string `json:"city"`
SubmittedAt time.Time `json:"submitted_at"`
}
type LineItem struct {
ID uuid.UUID `json:"id"`
ReceiptID uuid.UUID `json:"receipt_id"`
RawName string `json:"raw_name"`
CanonicalName *string `json:"canonical_name"`
Category *string `json:"category"`
PriceCents int `json:"price_cents"`
Quantity float64 `json:"quantity"`
}
type PriceSnapshot struct {
CanonicalName string `json:"canonical_name"`
YearMonth time.Time `json:"year_month"`
AvgPriceCents int `json:"avg_price_cents"`
SampleCount int `json:"sample_count"`
}
type PriceMover struct {
CanonicalName string `json:"canonical_name"`
CurrentPriceCents int `json:"current_price_cents"`
PrevPriceCents int `json:"prev_price_cents"`
PctChange float64 `json:"pct_change"`
}
type InflationSummary struct {
FromDate time.Time `json:"from_date"`
ToDate time.Time `json:"to_date"`
PurchasingPower float64 `json:"purchasing_power"` // e.g. 58.3 means $1 → $0.583
ItemCount int `json:"item_count"`
}
// ── Insert params (what the API layer passes to db.Queries) ───────────────────
type InsertReceiptParams struct {
StoreName *string
ReceiptDate time.Time
ImageURL *string
City *string
}
type InsertLineItemParams struct {
ReceiptID uuid.UUID
RawName string
CanonicalName *string
Category *string
PriceCents int
Quantity float64
}
// ── API request/response shapes ───────────────────────────────────────────────
// SubmitReceiptRequest is the JSON body (or form data) for POST /api/receipts
type SubmitReceiptRequest struct {
StoreName string `json:"store_name"`
ReceiptDate string `json:"receipt_date"` // ISO 8601: "2024-03-15"
City string `json:"city"`
Items []ItemInput `json:"items"`
}
type ItemInput struct {
Name string `json:"name"` // raw name as on the receipt
Price float64 `json:"price"` // in dollars, e.g. 3.99
Quantity float64 `json:"quantity"` // default 1
}
// SubmitReceiptResponse is returned after a successful submission
type SubmitReceiptResponse struct {
ReceiptID uuid.UUID `json:"receipt_id"`
ItemsAdded int `json:"items_added"`
Message string `json:"message"`
}
// PriceHistoryResponse is returned by GET /api/items/:name/history
type PriceHistoryResponse struct {
CanonicalName string `json:"canonical_name"`
DataPoints []PriceDataPoint `json:"data_points"`
}
type PriceDataPoint struct {
Month string `json:"month"` // "2024-03"
AvgPrice float64 `json:"avg_price"` // in dollars
SampleCount int `json:"sample_count"`
}
// ErrorResponse is the standard shape for all API errors
type ErrorResponse struct {
Error string `json:"error"`
Details string `json:"details,omitempty"`
}