Documentation
¶
Index ¶
- Variables
- func IsValidClassType(ct ClassType) bool
- func IsValidCrewRole(role CrewRole) bool
- func ValidateAircraftTextFields(a *Aircraft) error
- func ValidateContactTextFields(ct *Contact) error
- func ValidateCredentialTextFields(cr *Credential) error
- func ValidateFlightTextFields(f *Flight) error
- func ValidateLicenseTextFields(l *License) error
- func ValidateOptionalStringLength(fieldName string, value *string, maxLen int) error
- func ValidateStringLength(fieldName, value string, maxLen int) error
- type Aircraft
- type ApproachEntry
- type BackupDestination
- type BackupDestinationStatus
- type BackupRun
- type BackupRunStatus
- type BackupRunTrigger
- type BackupSchedule
- type ClassRating
- type ClassType
- type Contact
- type Credential
- type CredentialType
- type CrewRole
- type CurrencyData
- type Flight
- type FlightBaseline
- type FlightCrewMember
- type FlightStatistics
- type License
- type NotificationCategory
- type NotificationLog
- type NotificationPreferences
- type PasswordResetToken
- type RefreshToken
- type User
- type WebAuthnCredential
- type WebAuthnSession
Constants ¶
This section is empty.
Variables ¶
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") )
var AllNotificationCategories = pq.StringArray{ string(NotifCategoryCredentialMedical), string(NotifCategoryCredentialLanguage), string(NotifCategoryCredentialSecurity), string(NotifCategoryCredentialOther), string(NotifCategoryRatingExpiry), string(NotifCategoryCurrencyPassenger), string(NotifCategoryCurrencyNight), string(NotifCategoryCurrencyInstrument), string(NotifCategoryCurrencyFlightReview), string(NotifCategoryCurrencyRevalidation), }
AllNotificationCategories is the default set of all categories (all enabled)
var ErrFieldTooLong = errors.New("field exceeds maximum length")
ErrFieldTooLong is returned when a text field exceeds its maximum allowed length.
var ErrInvalidFlightBaseline = errors.New("invalid flight baseline")
ErrInvalidFlightBaseline indicates a baseline failed validation.
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 ¶
IsValidClassType checks if a class type is valid
func IsValidCrewRole ¶
IsValidCrewRole checks if a crew role is valid
func ValidateAircraftTextFields ¶
ValidateAircraftTextFields validates all text field lengths on an Aircraft.
func ValidateContactTextFields ¶
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 ¶
ValidateFlightTextFields validates all text field lengths on a Flight.
func ValidateLicenseTextFields ¶
ValidateLicenseTextFields validates all text field lengths on a License.
func ValidateOptionalStringLength ¶
ValidateOptionalStringLength checks an optional string field.
func ValidateStringLength ¶
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
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 BackupDestination ¶ added in v1.2.4
type BackupDestination struct {
ID uuid.UUID
UserID uuid.UUID
Provider string
DisplayName string
Config map[string]any
CredentialHint string
CredentialsEnc []byte
CredentialsNonce []byte
Schedule BackupSchedule
ScheduleHourUTC int
ScheduleDayOfWeek *int
ScheduleDayOfMonth *int
RetentionCount int
Status BackupDestinationStatus
LastError string
Enabled bool
ConsecutiveFailures int
LastRunAt *time.Time
LastSuccessAt *time.Time
LastSuccessSHA256 string
CreatedAt time.Time
UpdatedAt time.Time
}
BackupDestination is a user-owned cloud-storage target where NinerLog will upload JSON backups. Each destination is bound to one provider plugin (e.g. "s3") and carries provider-specific non-secret config in Config plus an encrypted credential blob.
type BackupDestinationStatus ¶ added in v1.2.4
type BackupDestinationStatus string
BackupDestinationStatus is the operational state of a destination.
const ( BackupStatusActive BackupDestinationStatus = "active" BackupStatusPaused BackupDestinationStatus = "paused" BackupStatusError BackupDestinationStatus = "error" )
func (BackupDestinationStatus) IsValid ¶ added in v1.2.4
func (s BackupDestinationStatus) IsValid() bool
IsValid reports whether the status is a known value.
type BackupRun ¶ added in v1.2.4
type BackupRun struct {
ID uuid.UUID
DestinationID uuid.UUID
UserID uuid.UUID
Status BackupRunStatus
Trigger BackupRunTrigger
StartedAt time.Time
CompletedAt *time.Time
DurationMs *int
SizeBytes *int64
SHA256 string
FlightCount *int
AircraftCount *int
LicenseCount *int
CredentialCount *int
RemotePath string
ErrorMessage string
CreatedAt time.Time
}
BackupRun is the audit record of a single backup attempt.
type BackupRunStatus ¶ added in v1.2.4
type BackupRunStatus string
BackupRunStatus is the outcome of a single backup run.
const ( BackupRunStatusSuccess BackupRunStatus = "success" BackupRunStatusFailed BackupRunStatus = "failed" BackupRunStatusSkipped BackupRunStatus = "skipped" )
type BackupRunTrigger ¶ added in v1.2.4
type BackupRunTrigger string
BackupRunTrigger captures whether a run was scheduled or user-triggered.
const ( BackupRunTriggerScheduled BackupRunTrigger = "scheduled" BackupRunTriggerManual BackupRunTrigger = "manual" )
type BackupSchedule ¶ added in v1.2.4
type BackupSchedule string
BackupSchedule controls how often the scheduler runs a destination.
const ( BackupScheduleManual BackupSchedule = "manual" BackupScheduleDaily BackupSchedule = "daily" BackupScheduleWeekly BackupSchedule = "weekly" BackupScheduleMonthly BackupSchedule = "monthly" )
func (BackupSchedule) IsValid ¶ added in v1.2.4
func (s BackupSchedule) IsValid() bool
IsValid reports whether the schedule is a known value.
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 CurrencyData ¶
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) ValidateTimeDistribution ¶
ValidateTimeDistribution checks if time distribution is valid
type FlightBaseline ¶ added in v1.2.3
type FlightBaseline struct {
UserID uuid.UUID
BaselineDate time.Time
TotalFlights int
TotalMinutes int
PICMinutes int
SICMinutes int
DualMinutes int
DualGivenMinutes int
MultiPilotMinutes int
NightMinutes int
IFRMinutes int
SoloMinutes int
CrossCountryMinutes int
LandingsDay int
LandingsNight int
Notes *string
CreatedAt time.Time
UpdatedAt time.Time
}
FlightBaseline represents a per-user "initial hours snapshot": a carried-forward total of pre-existing flying experience that is added on top of logged flights when computing aggregated user-level statistics.
func (*FlightBaseline) Validate ¶ added in v1.2.3
func (b *FlightBaseline) Validate() error
Validate enforces the basic invariants that aren't covered by DB CHECK constraints (non-negative values are enforced in the database, but we still fail fast at the API boundary).
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
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
type WebAuthnCredential ¶ added in v1.2.0
type WebAuthnCredential struct {
ID uuid.UUID
UserID uuid.UUID
CredentialID []byte // raw credential id from the authenticator
PublicKey []byte // CBOR-encoded COSE public key
AttestationType string
AAGUID []byte
SignCount uint32
Transports pq.StringArray
Label *string
UserPresent bool
UserVerified bool
BackupEligible bool
BackupState bool
CreatedAt time.Time
LastUsedAt *time.Time
}
WebAuthnCredential represents a passkey / WebAuthn credential registered by a user.
type WebAuthnSession ¶ added in v1.2.0
type WebAuthnSession struct {
ID uuid.UUID
UserID *uuid.UUID // nil for usernameless / discoverable login
Challenge string
SessionData []byte // serialized webauthn.SessionData
Purpose string // "registration" | "login"
ExpiresAt time.Time
CreatedAt time.Time
}
WebAuthnSession holds the transient state of an in-flight WebAuthn ceremony (registration or authentication) until the client returns its assertion.