models

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// Flight validation errors
	ErrInvalidTimeDistribution = errors.New("PIC and dual time are mutually exclusive")
	ErrInvalidNightTime        = errors.New("night time exceeds total time")
	ErrInvalidIFRTime          = errors.New("IFR time exceeds total time")
	ErrNegativeTime            = errors.New("flight times cannot be negative")
	ErrNegativeLandings        = errors.New("landings cannot be negative")

	// Aircraft validation errors
	ErrAircraftRegistrationRequired = errors.New("aircraft registration is required")
	ErrAircraftTypeRequired         = errors.New("aircraft type is required")
	ErrAircraftMakeRequired         = errors.New("aircraft make is required")
	ErrAircraftModelRequired        = errors.New("aircraft model is required")
	ErrAircraftInvalidEngineType    = errors.New("invalid engine type")
)

AllNotificationCategories is the default set of all categories (all enabled)

View Source
var ErrFieldTooLong = errors.New("field exceeds maximum length")

ErrFieldTooLong is returned when a text field exceeds its maximum allowed length.

View Source
var ValidApproachTypes = map[string]bool{
	"ILS": true, "LOC": true, "VOR": true, "RNAV/GPS": true, "NDB": true,
	"LDA": true, "SDF": true, "PAR": true, "ASR": true, "Visual": true,
	"Circling": true, "Other": true, "Unknown": true,
}

ValidApproachTypes lists all valid approach type values

Functions

func IsValidClassType

func IsValidClassType(ct ClassType) bool

IsValidClassType checks if a class type is valid

func IsValidCrewRole

func IsValidCrewRole(role CrewRole) bool

IsValidCrewRole checks if a crew role is valid

func ValidateAircraftTextFields

func ValidateAircraftTextFields(a *Aircraft) error

ValidateAircraftTextFields validates all text field lengths on an Aircraft.

func ValidateContactTextFields

func ValidateContactTextFields(ct *Contact) error

ValidateContactTextFields validates all text field lengths on a Contact.

func ValidateCredentialTextFields

func ValidateCredentialTextFields(cr *Credential) error

ValidateCredentialTextFields validates all text field lengths on a Credential.

func ValidateFlightTextFields

func ValidateFlightTextFields(f *Flight) error

ValidateFlightTextFields validates all text field lengths on a Flight.

func ValidateLicenseTextFields

func ValidateLicenseTextFields(l *License) error

ValidateLicenseTextFields validates all text field lengths on a License.

func ValidateOptionalStringLength

func ValidateOptionalStringLength(fieldName string, value *string, maxLen int) error

ValidateOptionalStringLength checks an optional string field.

func ValidateStringLength

func ValidateStringLength(fieldName, value string, maxLen int) error

ValidateStringLength checks that a string field does not exceed the given max length.

Types

type Aircraft

type Aircraft struct {
	ID                uuid.UUID `json:"id"`
	UserID            uuid.UUID `json:"userId"`
	Registration      string    `json:"registration"`
	Type              string    `json:"type"`
	Make              string    `json:"make"`
	Model             string    `json:"model"`
	IsComplex         bool      `json:"isComplex"`
	IsHighPerformance bool      `json:"isHighPerformance"`
	IsTailwheel       bool      `json:"isTailwheel"`
	Notes             *string   `json:"notes,omitempty"`
	IsActive          bool      `json:"isActive"`
	AircraftClass     *string   `json:"aircraftClass,omitempty"`
	CreatedAt         time.Time `json:"createdAt"`
	UpdatedAt         time.Time `json:"updatedAt"`
}

Aircraft represents an aircraft in a user's fleet

func (*Aircraft) Validate

func (a *Aircraft) Validate() error

Validate checks basic Aircraft field requirements

type ApproachEntry

type ApproachEntry struct {
	Type    string  `json:"type"`
	Airport *string `json:"airport,omitempty"`
	Runway  *string `json:"runway,omitempty"`
}

ApproachEntry represents a single instrument approach with type and location

type ClassRating

type ClassRating struct {
	ID         uuid.UUID  `json:"id"`
	LicenseID  uuid.UUID  `json:"licenseId"`
	ClassType  ClassType  `json:"classType"`
	IssueDate  time.Time  `json:"issueDate"`
	ExpiryDate *time.Time `json:"expiryDate,omitempty"`
	Notes      *string    `json:"notes,omitempty"`
	CreatedAt  time.Time  `json:"createdAt"`
	UpdatedAt  time.Time  `json:"updatedAt"`
}

ClassRating represents a class rating attached to a license

func (*ClassRating) IsExpired

func (cr *ClassRating) IsExpired() bool

IsExpired checks if the class rating has expired

func (*ClassRating) IsExpiringSoon

func (cr *ClassRating) IsExpiringSoon(days int) bool

IsExpiringSoon checks if the class rating expires within N days

type ClassType

type ClassType string

ClassType represents the type of class rating

const (
	ClassTypeSEPLand ClassType = "SEP_LAND"
	ClassTypeSEPSea  ClassType = "SEP_SEA"
	ClassTypeMEPLand ClassType = "MEP_LAND"
	ClassTypeMEPSea  ClassType = "MEP_SEA"
	ClassTypeSETLand ClassType = "SET_LAND"
	ClassTypeSETSea  ClassType = "SET_SEA"
	ClassTypeTMG     ClassType = "TMG"
	ClassTypeIR      ClassType = "IR"
	ClassTypeOther   ClassType = "OTHER"
)

func ValidClassTypes

func ValidClassTypes() []ClassType

ValidClassTypes returns all valid class types

type Contact

type Contact struct {
	ID        uuid.UUID `json:"id"`
	UserID    uuid.UUID `json:"userId"`
	Name      string    `json:"name"`
	Email     *string   `json:"email,omitempty"`
	Phone     *string   `json:"phone,omitempty"`
	Notes     *string   `json:"notes,omitempty"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

Contact represents a reusable person that a user can reference across flights

type Credential

type Credential struct {
	ID               uuid.UUID      `json:"id"`
	UserID           uuid.UUID      `json:"userId"`
	CredentialType   CredentialType `json:"credentialType"`
	CredentialNumber *string        `json:"credentialNumber,omitempty"`
	IssueDate        time.Time      `json:"issueDate"`
	ExpiryDate       *time.Time     `json:"expiryDate,omitempty"`
	IssuingAuthority string         `json:"issuingAuthority"`
	Notes            *string        `json:"notes,omitempty"`
	CreatedAt        time.Time      `json:"createdAt"`
	UpdatedAt        time.Time      `json:"updatedAt"`
}

Credential represents a pilot credential (medical, language proficiency, security clearance)

func (*Credential) IsExpired

func (c *Credential) IsExpired() bool

IsExpired checks if the credential has expired

func (*Credential) IsExpiringSoon

func (c *Credential) IsExpiringSoon(days int) bool

IsExpiringSoon checks if the credential expires within the given number of days

type CredentialType

type CredentialType string
const (
	CredentialTypeEASAClass1Medical CredentialType = "EASA_CLASS1_MEDICAL"
	CredentialTypeEASAClass2Medical CredentialType = "EASA_CLASS2_MEDICAL"
	CredentialTypeEASALAPLMedical   CredentialType = "EASA_LAPL_MEDICAL"
	CredentialTypeFAAClass1Medical  CredentialType = "FAA_CLASS1_MEDICAL"
	CredentialTypeFAAClass2Medical  CredentialType = "FAA_CLASS2_MEDICAL"
	CredentialTypeFAAClass3Medical  CredentialType = "FAA_CLASS3_MEDICAL"
	CredentialTypeLangICAOLevel4    CredentialType = "LANG_ICAO_LEVEL4"
	CredentialTypeLangICAOLevel5    CredentialType = "LANG_ICAO_LEVEL5"
	CredentialTypeLangICAOLevel6    CredentialType = "LANG_ICAO_LEVEL6"
	CredentialTypeSecClearanceZUP   CredentialType = "SEC_CLEARANCE_ZUP"
	CredentialTypeSecClearanceZUBB  CredentialType = "SEC_CLEARANCE_ZUBB"
	CredentialTypeOther             CredentialType = "OTHER"
)

type CrewRole

type CrewRole string

CrewRole represents a person's role on a flight

const (
	CrewRolePIC         CrewRole = "PIC"
	CrewRoleSIC         CrewRole = "SIC"
	CrewRoleInstructor  CrewRole = "Instructor"
	CrewRoleStudent     CrewRole = "Student"
	CrewRolePassenger   CrewRole = "Passenger"
	CrewRoleSafetyPilot CrewRole = "SafetyPilot"
	CrewRoleExaminer    CrewRole = "Examiner"
)

func ValidCrewRoles

func ValidCrewRoles() []CrewRole

ValidCrewRoles returns all valid crew roles

type CurrencyData

type CurrencyData struct {
	Flights       int
	TotalLandings int
	DayLandings   int
	NightLandings int
}

CurrencyData holds landing/flight counts for currency calculation

type Flight

type Flight struct {
	ID     uuid.UUID `json:"id"`
	UserID uuid.UUID `json:"userId"`
	Date   time.Time `json:"date"`

	// Aircraft information
	AircraftReg  string `json:"aircraftReg"`
	AircraftType string `json:"aircraftType"`

	// Route information
	DepartureICAO *string `json:"departureIcao,omitempty"`
	ArrivalICAO   *string `json:"arrivalIcao,omitempty"`
	OffBlockTime  *string `json:"offBlockTime,omitempty"`  // HH:MM:SS format - chocks off / engine start (UTC)
	OnBlockTime   *string `json:"onBlockTime,omitempty"`   // HH:MM:SS format - chocks on / engine shutdown (UTC)
	DepartureTime *string `json:"departureTime,omitempty"` // HH:MM:SS format - takeoff time (UTC)
	ArrivalTime   *string `json:"arrivalTime,omitempty"`   // HH:MM:SS format - landing time (UTC)

	// Flight times (in minutes)
	TotalTime int  `json:"totalTime"`
	IsPIC     bool `json:"isPic"`
	IsDual    bool `json:"isDual"`
	PICTime   int  `json:"picTime"`
	DualTime  int  `json:"dualTime"`
	NightTime int  `json:"nightTime"`
	IFRTime   int  `json:"ifrTime"`

	// Landings
	LandingsDay   int `json:"landingsDay"`
	LandingsNight int `json:"landingsNight"`
	AllLandings   int `json:"allLandings"` // Auto-calculated: day + night

	// Takeoffs
	TakeoffsDay   int `json:"takeoffsDay"`   // Auto-calculated from sunset/sunrise at departure (with manual override)
	TakeoffsNight int `json:"takeoffsNight"` // Auto-calculated from sunset/sunrise at departure (with manual override)

	// Route
	Route *string `json:"route,omitempty"` // Comma-separated ICAO waypoints

	// Auto-calculated fields
	SoloTime         int     `json:"soloTime"`         // Auto-calculated when not dual and not PIC with crew
	CrossCountryTime int     `json:"crossCountryTime"` // Auto-calculated when departure ≠ arrival
	Distance         float64 `json:"distance"`         // Auto-calculated from airport coordinates (NM)

	// Manual override flags
	TakeoffsDayOverride   bool `json:"-"` // When true, takeoffsDay is not auto-calculated
	TakeoffsNightOverride bool `json:"-"` // When true, takeoffsNight is not auto-calculated
	LandingsDayOverride   bool `json:"-"` // When true, landingsDay is not auto-calculated
	LandingsNightOverride bool `json:"-"` // When true, landingsNight is not auto-calculated

	// Instructor & comments
	InstructorName     *string `json:"instructorName,omitempty"`
	InstructorComments *string `json:"instructorComments,omitempty"`

	// PIC name (EASA AMC1 FCL.050 Col 12)
	PICName *string `json:"picName,omitempty"`

	// Multi-crew / advanced times
	SICTime             int `json:"sicTime"`
	DualGivenTime       int `json:"dualGivenTime"`
	SimulatedFlightTime int `json:"simulatedFlightTime"`
	GroundTrainingTime  int `json:"groundTrainingTime"`
	MultiPilotTime      int `json:"multiPilotTime"` // EASA AMC1 FCL.050 Col 10

	// FSTD type designation (EASA AMC1 FCL.050 Col 22, FAA §61.51(b)(1)(iv))
	FSTDType *string `json:"fstdType,omitempty"`

	// Instrument tracking
	ActualInstrumentTime    int             `json:"actualInstrumentTime"`
	SimulatedInstrumentTime int             `json:"simulatedInstrumentTime"`
	Holds                   int             `json:"holds"`
	ApproachesCount         int             `json:"approachesCount"`
	Approaches              []ApproachEntry `json:"approaches,omitempty"` // Structured approach data (FAA §61.51(g)(3))
	IsIPC                   bool            `json:"isIpc"`
	IsFlightReview          bool            `json:"isFlightReview"`
	IsProficiencyCheck      bool            `json:"isProficiencyCheck"`

	// Endorsements (EASA AMC1 FCL.050 Col 24, FAA §61.51(h))
	Endorsements *string `json:"endorsements,omitempty"`

	// SPL / Glider
	LaunchMethod *string `json:"launchMethod,omitempty"` // winch, aerotow, self-launch

	// Crew members on board (populated from flight_crew_members table)
	CrewMembers []FlightCrewMember `json:"crewMembers,omitempty"`

	// Additional information
	Remarks *string `json:"remarks,omitempty"`

	// Metadata
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

Flight represents a flight log entry

func (*Flight) IsValid

func (f *Flight) IsValid() bool

IsValid checks if all required fields are set

func (*Flight) ValidateTimeDistribution

func (f *Flight) ValidateTimeDistribution() error

ValidateTimeDistribution checks if time distribution is valid

type FlightCrewMember

type FlightCrewMember struct {
	ID        uuid.UUID  `json:"id"`
	FlightID  uuid.UUID  `json:"flightId"`
	ContactID *uuid.UUID `json:"contactId,omitempty"`
	Name      string     `json:"name"`
	Role      CrewRole   `json:"role"`
}

FlightCrewMember represents a person on board a specific flight

type FlightStatistics

type FlightStatistics struct {
	TotalFlights        int
	TotalMinutes        int
	PICMinutes          int
	DualMinutes         int
	NightMinutes        int
	IFRMinutes          int
	SoloMinutes         int
	CrossCountryMinutes int
	LandingsDay         int
	LandingsNight       int
	SICMinutes          int
	DualGivenMinutes    int
}

FlightStatistics holds aggregated flight statistics for a license

type License

type License struct {
	ID                      uuid.UUID `json:"id"`
	UserID                  uuid.UUID `json:"userId"`
	RegulatoryAuthority     string    `json:"regulatoryAuthority" binding:"required"`
	LicenseType             string    `json:"licenseType" binding:"required"`
	LicenseNumber           string    `json:"licenseNumber" binding:"required"`
	IssueDate               time.Time `json:"issueDate" binding:"required"`
	IssuingAuthority        string    `json:"issuingAuthority" binding:"required"`
	RequiresSeparateLogbook bool      `json:"requiresSeparateLogbook"`
	CreatedAt               time.Time `json:"createdAt"`
	UpdatedAt               time.Time `json:"updatedAt"`
}

License represents a pilot license

func (*License) IsValid

func (l *License) IsValid() bool

IsValid checks if all required fields are set

func (*License) Validate

func (l *License) Validate() error

Validate checks all required fields and returns a descriptive error

type NotificationCategory

type NotificationCategory string

NotificationCategory represents a granular notification category

const (
	NotifCategoryCredentialMedical    NotificationCategory = "credential_medical"
	NotifCategoryCredentialLanguage   NotificationCategory = "credential_language"
	NotifCategoryCredentialSecurity   NotificationCategory = "credential_security"
	NotifCategoryCredentialOther      NotificationCategory = "credential_other"
	NotifCategoryRatingExpiry         NotificationCategory = "rating_expiry"
	NotifCategoryCurrencyPassenger    NotificationCategory = "currency_passenger"
	NotifCategoryCurrencyNight        NotificationCategory = "currency_night"
	NotifCategoryCurrencyInstrument   NotificationCategory = "currency_instrument"
	NotifCategoryCurrencyFlightReview NotificationCategory = "currency_flight_review"
	NotifCategoryCurrencyRevalidation NotificationCategory = "currency_revalidation"
)

func CredentialCategoryForType

func CredentialCategoryForType(credType CredentialType) NotificationCategory

CredentialCategoryForType maps a credential type to a notification category

type NotificationLog

type NotificationLog struct {
	ID                  uuid.UUID  `json:"id"`
	UserID              uuid.UUID  `json:"userId"`
	NotificationType    string     `json:"notificationType"`
	ReferenceID         *uuid.UUID `json:"referenceId,omitempty"`
	ReferenceType       *string    `json:"referenceType,omitempty"`
	DaysBeforeExpiry    *int       `json:"daysBeforeExpiry,omitempty"`
	ExpiryReferenceDate *time.Time `json:"expiryReferenceDate,omitempty"`
	Subject             *string    `json:"subject,omitempty"`
	SentAt              time.Time  `json:"sentAt"`
}

NotificationLog tracks sent notifications to avoid duplicates

type NotificationPreferences

type NotificationPreferences struct {
	ID                uuid.UUID      `json:"id"`
	UserID            uuid.UUID      `json:"userId"`
	EmailEnabled      bool           `json:"emailEnabled"`
	EnabledCategories pq.StringArray `json:"enabledCategories"`
	WarningDays       pq.Int64Array  `json:"warningDays"`
	CheckHour         int            `json:"checkHour"`
	CreatedAt         time.Time      `json:"createdAt"`
	UpdatedAt         time.Time      `json:"updatedAt"`
}

NotificationPreferences holds a user's notification settings

func (*NotificationPreferences) IsCategoryEnabled

func (p *NotificationPreferences) IsCategoryEnabled(category NotificationCategory) bool

IsCategoryEnabled checks if a specific notification category is enabled

type PasswordResetToken

type PasswordResetToken struct {
	ID        uuid.UUID `json:"id"`
	UserID    uuid.UUID `json:"user_id"`
	TokenHash string    `json:"-"`
	ExpiresAt time.Time `json:"expires_at"`
	Used      bool      `json:"used"`
	CreatedAt time.Time `json:"created_at"`
}

PasswordResetToken represents a password reset token

type RefreshToken

type RefreshToken struct {
	ID        uuid.UUID `json:"id"`
	UserID    uuid.UUID `json:"user_id"`
	TokenHash string    `json:"-"`
	ExpiresAt time.Time `json:"expires_at"`
	Revoked   bool      `json:"revoked"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

RefreshToken represents a refresh token in the system

type User

type User struct {
	ID                  uuid.UUID      `json:"id"`
	Email               string         `json:"email"`
	PasswordHash        string         `json:"-"`
	Name                string         `json:"name"`
	TwoFactorEnabled    bool           `json:"twoFactorEnabled"`
	TwoFactorSecret     *string        `json:"-"` // never exposed in JSON
	RecoveryCodes       pq.StringArray `json:"-"` // never exposed in JSON
	FailedLoginAttempts int            `json:"-"`
	LockedUntil         *time.Time     `json:"-"`
	Disabled            bool           `json:"disabled"`
	LastLoginAt         *time.Time     `json:"lastLoginAt,omitempty"`
	TimeDisplayFormat   string         `json:"timeDisplayFormat"`
	DateFormat          string         `json:"dateFormat"`
	DecimalSeparator    string         `json:"decimalSeparator"`
	PreferredLocale     string         `json:"preferredLocale"`
	CreatedAt           time.Time      `json:"created_at"`
	UpdatedAt           time.Time      `json:"updated_at"`
}

User represents a user in the system

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL