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, } }