193 lines
5.9 KiB
Go
193 lines
5.9 KiB
Go
package api
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"carcontrol/api/internal/models"
|
|
)
|
|
|
|
// PocketBase stores datetimes as e.g. "2015-06-12 00:00:00.000Z". These layouts
|
|
// are tried (in order) when parsing values coming back from PocketBase.
|
|
var pbDateLayouts = []string{
|
|
"2006-01-02 15:04:05.000Z",
|
|
"2006-01-02 15:04:05Z",
|
|
time.RFC3339,
|
|
"2006-01-02",
|
|
}
|
|
|
|
func parsePBDate(s string) time.Time {
|
|
s = strings.TrimSpace(s)
|
|
if s == "" {
|
|
return time.Time{}
|
|
}
|
|
for _, l := range pbDateLayouts {
|
|
if t, err := time.Parse(l, s); err == nil {
|
|
return t
|
|
}
|
|
}
|
|
return time.Time{}
|
|
}
|
|
|
|
// formatPBDate renders a date in the format PocketBase expects on write.
|
|
func formatPBDate(t time.Time) string {
|
|
if t.IsZero() {
|
|
return ""
|
|
}
|
|
return t.UTC().Format("2006-01-02 15:04:05.000Z")
|
|
}
|
|
|
|
// --- cars ---
|
|
|
|
// carRecord is the PocketBase-facing shape of a car (snake_case fields).
|
|
type carRecord struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Make string `json:"make"`
|
|
Model string `json:"model"`
|
|
Year int `json:"year"`
|
|
Registration string `json:"registration"`
|
|
RegistrationCountry string `json:"registration_country"`
|
|
VIN string `json:"vin"`
|
|
ServiceIntervalDays int `json:"service_interval_days"`
|
|
ServiceIntervalKm int `json:"service_interval_km"`
|
|
OilSpec string `json:"oil_spec"`
|
|
TransmissionOilSpec string `json:"transmission_oil_spec"`
|
|
DifferentialOilSpec string `json:"differential_oil_spec"`
|
|
BrakeFluidSpec string `json:"brake_fluid_spec"`
|
|
CoolantSpec string `json:"coolant_spec"`
|
|
CurrentKm int `json:"current_km"`
|
|
FuelType string `json:"fuel_type"`
|
|
BuildDate string `json:"build_date"`
|
|
FirstRegistrationDate string `json:"first_registration_date"`
|
|
Owner string `json:"owner"`
|
|
Created string `json:"created"`
|
|
Updated string `json:"updated"`
|
|
}
|
|
|
|
func (rec carRecord) toModel() models.Car {
|
|
return models.Car{
|
|
ID: rec.ID,
|
|
Name: rec.Name,
|
|
Make: rec.Make,
|
|
Model: rec.Model,
|
|
Year: rec.Year,
|
|
Registration: rec.Registration,
|
|
RegistrationCountry: rec.RegistrationCountry,
|
|
VIN: rec.VIN,
|
|
ServiceIntervalDays: rec.ServiceIntervalDays,
|
|
ServiceIntervalKm: rec.ServiceIntervalKm,
|
|
OilSpec: rec.OilSpec,
|
|
TransmissionOilSpec: rec.TransmissionOilSpec,
|
|
DifferentialOilSpec: rec.DifferentialOilSpec,
|
|
BrakeFluidSpec: rec.BrakeFluidSpec,
|
|
CoolantSpec: rec.CoolantSpec,
|
|
CurrentKm: rec.CurrentKm,
|
|
FuelType: rec.FuelType,
|
|
BuildDate: rec.BuildDate,
|
|
FirstRegistrationDate: rec.FirstRegistrationDate,
|
|
Owner: rec.Owner,
|
|
Created: rec.Created,
|
|
Updated: rec.Updated,
|
|
}
|
|
}
|
|
|
|
// carPayload builds the write payload for create/update from a domain Car.
|
|
func carPayload(c models.Car) map[string]any {
|
|
return map[string]any{
|
|
"name": c.Name,
|
|
"make": c.Make,
|
|
"model": c.Model,
|
|
"year": c.Year,
|
|
"registration": c.Registration,
|
|
"registration_country": c.RegistrationCountry,
|
|
"vin": c.VIN,
|
|
"service_interval_days": c.ServiceIntervalDays,
|
|
"service_interval_km": c.ServiceIntervalKm,
|
|
"oil_spec": c.OilSpec,
|
|
"transmission_oil_spec": c.TransmissionOilSpec,
|
|
"differential_oil_spec": c.DifferentialOilSpec,
|
|
"brake_fluid_spec": c.BrakeFluidSpec,
|
|
"coolant_spec": c.CoolantSpec,
|
|
"current_km": c.CurrentKm,
|
|
"fuel_type": c.FuelType,
|
|
"build_date": c.BuildDate,
|
|
"first_registration_date": c.FirstRegistrationDate,
|
|
}
|
|
}
|
|
|
|
// --- service records ---
|
|
|
|
type serviceRecord struct {
|
|
ID string `json:"id"`
|
|
Car string `json:"car"`
|
|
Date string `json:"date"`
|
|
Km int `json:"km"`
|
|
ChangedOil bool `json:"changed_oil"`
|
|
ChangedEngineAirFilter bool `json:"changed_engine_air_filter"`
|
|
ChangedCabinAirFilter bool `json:"changed_cabin_air_filter"`
|
|
Notes string `json:"notes"`
|
|
Created string `json:"created"`
|
|
Updated string `json:"updated"`
|
|
}
|
|
|
|
func (rec serviceRecord) toModel() models.ServiceRecord {
|
|
return models.ServiceRecord{
|
|
ID: rec.ID,
|
|
Car: rec.Car,
|
|
Date: parsePBDate(rec.Date),
|
|
Km: rec.Km,
|
|
ChangedOil: rec.ChangedOil,
|
|
ChangedEngineAirFilter: rec.ChangedEngineAirFilter,
|
|
ChangedCabinAirFilter: rec.ChangedCabinAirFilter,
|
|
Notes: rec.Notes,
|
|
Created: rec.Created,
|
|
Updated: rec.Updated,
|
|
}
|
|
}
|
|
|
|
func servicePayload(r models.ServiceRecord) map[string]any {
|
|
return map[string]any{
|
|
"car": r.Car,
|
|
"date": formatPBDate(r.Date),
|
|
"km": r.Km,
|
|
"changed_oil": r.ChangedOil,
|
|
"changed_engine_air_filter": r.ChangedEngineAirFilter,
|
|
"changed_cabin_air_filter": r.ChangedCabinAirFilter,
|
|
"notes": r.Notes,
|
|
}
|
|
}
|
|
|
|
// --- parts ---
|
|
|
|
type partRecord struct {
|
|
ID string `json:"id"`
|
|
Car string `json:"car"`
|
|
Name string `json:"name"`
|
|
PartNumber string `json:"part_number"`
|
|
Category string `json:"category"`
|
|
Created string `json:"created"`
|
|
Updated string `json:"updated"`
|
|
}
|
|
|
|
func (rec partRecord) toModel() models.Part {
|
|
return models.Part{
|
|
ID: rec.ID,
|
|
Car: rec.Car,
|
|
Name: rec.Name,
|
|
PartNumber: rec.PartNumber,
|
|
Category: rec.Category,
|
|
Created: rec.Created,
|
|
Updated: rec.Updated,
|
|
}
|
|
}
|
|
|
|
func partPayload(p models.Part) map[string]any {
|
|
return map[string]any{
|
|
"car": p.Car,
|
|
"name": p.Name,
|
|
"part_number": p.PartNumber,
|
|
"category": p.Category,
|
|
}
|
|
}
|