package inventory import ( "context" "fmt" "time" "royal-pop-backend/internal/database" ) type Level struct { Style string ColorwayID string FinishID string QuantityOnHand int64 Notes string CreatedAt time.Time UpdatedAt time.Time } type UpsertInput struct { Style string ColorwayID string FinishID string QuantityOnHand int64 Notes string } type Store struct { db *database.DB } func NewStore(db *database.DB) *Store { return &Store{db: db} } func (s *Store) List(ctx context.Context) ([]Level, error) { if s == nil || s.db == nil || s.db.Pool == nil { return nil, fmt.Errorf("postgres store is not configured") } rows, err := s.db.Pool.Query(ctx, ` SELECT style, colorway_id, finish_id, quantity_on_hand, notes, created_at, updated_at FROM inventory_levels ORDER BY style ASC, colorway_id ASC, finish_id ASC `) if err != nil { return nil, err } defer rows.Close() levels := make([]Level, 0) for rows.Next() { var level Level if err := rows.Scan( &level.Style, &level.ColorwayID, &level.FinishID, &level.QuantityOnHand, &level.Notes, &level.CreatedAt, &level.UpdatedAt, ); err != nil { return nil, err } levels = append(levels, level) } if err := rows.Err(); err != nil { return nil, err } return levels, nil } func (s *Store) Upsert(ctx context.Context, input UpsertInput) (*Level, error) { if s == nil || s.db == nil || s.db.Pool == nil { return nil, fmt.Errorf("postgres store is not configured") } row := s.db.Pool.QueryRow(ctx, ` INSERT INTO inventory_levels (style, colorway_id, finish_id, quantity_on_hand, notes) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (style, colorway_id, finish_id) DO UPDATE SET quantity_on_hand = EXCLUDED.quantity_on_hand, notes = EXCLUDED.notes, updated_at = NOW() RETURNING style, colorway_id, finish_id, quantity_on_hand, notes, created_at, updated_at `, input.Style, input.ColorwayID, input.FinishID, input.QuantityOnHand, input.Notes) var level Level if err := row.Scan( &level.Style, &level.ColorwayID, &level.FinishID, &level.QuantityOnHand, &level.Notes, &level.CreatedAt, &level.UpdatedAt, ); err != nil { return nil, err } return &level, nil }