Documentation
¶
Index ¶
- Constants
- Variables
- func BuildPostgresConnString(cfg config.PostgresConfig) string
- func CountRoutes() (total int, international int, domestic int)
- func EnsurePostgresAirportsSeeded(ctx context.Context, connString string) error
- func GetAirportCountry(code string) string
- func GetPool() *pgxpool.Pool
- func InitTestPostgres(cfg *config.Config) *pgxpool.Pool
- func RunMigrations(connString string) error
- func Top100AirportCodes() []string
- type Airline
- type Airport
- type BulkSearch
- type BulkSearchOffer
- type BulkSearchOfferRecord
- type BulkSearchResult
- type BulkSearchResultRecord
- type BulkSearchSummary
- type Certificate
- type Connection
- type ContinuousSweepProgress
- type ContinuousSweepResultsFilter
- type ContinuousSweepStats
- type DealAlert
- type DealFilter
- type DealSource
- type DetectedDeal
- type ErrInvalidSearchID
- type FlightOffer
- type FlightSegment
- type JobDetails
- type LegInfo
- type Neo4jDB
- func (n *Neo4jDB) AddPricePoint(originCode, destCode string, departDate string, returnDate string, ...) error
- func (n *Neo4jDB) Close() error
- func (n *Neo4jDB) CreateAirline(code, name, country string) error
- func (n *Neo4jDB) CreateAirport(code, name, city, country string, latitude, longitude float64) error
- func (n *Neo4jDB) CreateFlightRoute(originCode, destCode, airlineCode string, distance int) error
- func (n *Neo4jDB) CreateRoute(originCode, destCode, airlineCode, flightNumber string, avgPrice float64, ...) error
- func (n *Neo4jDB) ExecuteReadQuery(ctx context.Context, query string, params map[string]interface{}) (Neo4jResult, error)
- func (n *Neo4jDB) FindCheapestPath(ctx context.Context, origin, dest string, maxHops int, maxPrice float64) ([]PathResult, error)
- func (n *Neo4jDB) FindConnections(ctx context.Context, origin string, maxHops int, maxPrice float64) ([]Connection, error)
- func (n *Neo4jDB) GetRouteStats(ctx context.Context, origin, dest string) (*RouteStats, error)
- func (n *Neo4jDB) InitSchema() error
- func (n *Neo4jDB) SeedNeo4jData(ctx context.Context, postgresDB PostgresDB) error
- type Neo4jDatabase
- type Neo4jResult
- type Neo4jResultWithSession
- type Neo4jSession
- type PathResult
- type PostgresDB
- type PostgresDBImpl
- func (p *PostgresDBImpl) BeginTx(ctx context.Context) (Tx, error)
- func (p *PostgresDBImpl) Close() error
- func (p *PostgresDBImpl) CompleteBulkSearch(ctx context.Context, summary BulkSearchSummary) error
- func (p *PostgresDBImpl) CountSearches(ctx context.Context) (int, error)
- func (p *PostgresDBImpl) CreateBulkSearchRecord(ctx context.Context, jobID sql.NullInt32, totalSearches int, ...) (int, error)
- func (p *PostgresDBImpl) CreateJobDetails(ctx context.Context, tx Tx, details JobDetails) error
- func (p *PostgresDBImpl) CreatePriceGraphSweep(ctx context.Context, jobID sql.NullInt32, originCount, destinationCount int, ...) (int, error)
- func (p *PostgresDBImpl) CreateScheduledJob(ctx context.Context, tx Tx, name, cronExpression string, enabled bool) (int, error)
- func (p *PostgresDBImpl) DeleteJobDetailsByJobID(ctx context.Context, tx Tx, jobID int) error
- func (p *PostgresDBImpl) DeleteScheduledJobByID(ctx context.Context, tx Tx, jobID int) (int64, error)
- func (p *PostgresDBImpl) ExpireOldDeals(ctx context.Context) (int64, error)
- func (p *PostgresDBImpl) FinalizeBulkSearch(ctx context.Context, bulkSearchID int) error
- func (p *PostgresDBImpl) GetBulkSearchByID(ctx context.Context, searchID int) (*BulkSearch, error)
- func (p *PostgresDBImpl) GetCertificate(domain string) (*Certificate, error)
- func (p *PostgresDBImpl) GetContinuousSweepProgress(ctx context.Context) (*ContinuousSweepProgress, error)
- func (p *PostgresDBImpl) GetDetectedDealByFingerprint(ctx context.Context, fingerprint string) (*DetectedDeal, error)
- func (p *PostgresDBImpl) GetFlightOffersBySearchID(ctx context.Context, searchID int) (Rows, error)
- func (p *PostgresDBImpl) GetFlightSegmentsByOfferID(ctx context.Context, offerID int) (Rows, error)
- func (p *PostgresDBImpl) GetJobByID(ctx context.Context, jobID int) (*ScheduledJob, error)
- func (p *PostgresDBImpl) GetJobCronExpression(ctx context.Context, jobID int) (string, error)
- func (p *PostgresDBImpl) GetJobDetailsByID(ctx context.Context, jobID int) (*JobDetails, error)
- func (p *PostgresDBImpl) GetPriceGraphSweepByID(ctx context.Context, sweepID int) (*PriceGraphSweep, error)
- func (p *PostgresDBImpl) GetPriceHistoryForRoute(ctx context.Context, origin, dest string, tripLength int, class string, ...) ([]float64, error)
- func (p *PostgresDBImpl) GetRouteBaseline(ctx context.Context, origin, dest string, tripLength int, class string) (*RouteBaseline, error)
- func (p *PostgresDBImpl) GetSearchByID(id string) (*Search, error)
- func (p *PostgresDBImpl) GetSearchQueryByID(ctx context.Context, id int) (*SearchQuery, error)
- func (p *PostgresDBImpl) IncrementBulkSearchProgress(ctx context.Context, bulkSearchID int) (completed, total int, err error)
- func (p *PostgresDBImpl) InitSchema() error
- func (p *PostgresDBImpl) InsertBulkSearchOffer(ctx context.Context, record BulkSearchOfferRecord) error
- func (p *PostgresDBImpl) InsertBulkSearchResult(ctx context.Context, result BulkSearchResultRecord) error
- func (p *PostgresDBImpl) InsertBulkSearchResultsBatch(ctx context.Context, results []BulkSearchResultRecord) error
- func (p *PostgresDBImpl) InsertContinuousSweepStats(ctx context.Context, stats ContinuousSweepStats) error
- func (p *PostgresDBImpl) InsertDealAlert(ctx context.Context, alert DealAlert) (int, error)
- func (p *PostgresDBImpl) InsertDetectedDeal(ctx context.Context, deal DetectedDeal) (int, error)
- func (p *PostgresDBImpl) InsertPriceGraphResult(ctx context.Context, record PriceGraphResultRecord) error
- func (p *PostgresDBImpl) ListActiveDeals(ctx context.Context, filter DealFilter) ([]DetectedDeal, error)
- func (p *PostgresDBImpl) ListBulkSearchOffers(ctx context.Context, searchID int) ([]BulkSearchOffer, error)
- func (p *PostgresDBImpl) ListBulkSearches(ctx context.Context, limit, offset int) (Rows, error)
- func (p *PostgresDBImpl) ListContinuousSweepResults(ctx context.Context, filters ContinuousSweepResultsFilter) ([]PriceGraphResultRecord, error)
- func (p *PostgresDBImpl) ListContinuousSweepStats(ctx context.Context, limit int) ([]ContinuousSweepStats, error)
- func (p *PostgresDBImpl) ListDealAlerts(ctx context.Context, limit, offset int) ([]DealAlert, error)
- func (p *PostgresDBImpl) ListJobs(ctx context.Context) (Rows, error)
- func (p *PostgresDBImpl) ListPriceGraphResults(ctx context.Context, sweepID, limit, offset int) (Rows, error)
- func (p *PostgresDBImpl) ListPriceGraphSweeps(ctx context.Context, limit, offset int) (Rows, error)
- func (p *PostgresDBImpl) QueryAirlines(ctx context.Context) (Rows, error)
- func (p *PostgresDBImpl) QueryAirports(ctx context.Context) (Rows, error)
- func (p *PostgresDBImpl) QueryBulkSearchOffersPaginated(ctx context.Context, searchID, limit, offset int) (Rows, error)
- func (p *PostgresDBImpl) QueryBulkSearchResultsPaginated(ctx context.Context, searchID, limit, offset int) (Rows, error)
- func (p *PostgresDBImpl) QuerySearchesPaginated(ctx context.Context, limit, offset int) (Rows, error)
- func (p *PostgresDBImpl) SaveContinuousSweepProgress(ctx context.Context, progress ContinuousSweepProgress) error
- func (p *PostgresDBImpl) SaveSearch(search *Search) (string, error)
- func (p *PostgresDBImpl) Search(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
- func (p *PostgresDBImpl) SeedData() error
- func (p *PostgresDBImpl) SetContinuousSweepControlFlags(ctx context.Context, isRunning, isPaused *bool) error
- func (p *PostgresDBImpl) StoreCertificate(domain string, certChain []byte, privateKey []byte, expires time.Time) error
- func (p *PostgresDBImpl) UpdateBulkSearchProgress(ctx context.Context, bulkSearchID int, completed, totalOffers, errorCount int) error
- func (p *PostgresDBImpl) UpdateBulkSearchStatus(ctx context.Context, bulkSearchID int, status string) error
- func (p *PostgresDBImpl) UpdateBulkSearchTotalSearches(ctx context.Context, bulkSearchID int, totalSearches int) error
- func (p *PostgresDBImpl) UpdateJobDetails(ctx context.Context, tx Tx, jobID int, details JobDetails) error
- func (p *PostgresDBImpl) UpdateJobEnabled(ctx context.Context, jobID int, enabled bool) (int64, error)
- func (p *PostgresDBImpl) UpdateJobLastRun(ctx context.Context, jobID int) error
- func (p *PostgresDBImpl) UpdatePriceGraphSweepStatus(ctx context.Context, sweepID int, status string, ...) error
- func (p *PostgresDBImpl) UpdateScheduledJob(ctx context.Context, tx Tx, jobID int, name, cronExpression string) error
- func (p *PostgresDBImpl) UpsertDetectedDeal(ctx context.Context, deal DetectedDeal) error
- func (p *PostgresDBImpl) UpsertRouteBaseline(ctx context.Context, baseline RouteBaseline) error
- type PriceGraphResult
- type PriceGraphResultRecord
- type PriceGraphSweep
- type PriceGraphSweepJobDetails
- type Route
- type RouteBaseline
- type RoutePricePoint
- type RouteStats
- type RowScanner
- type Rows
- type ScheduledJob
- type Search
- type SearchNotFoundError
- type SearchQuery
- type SweepStatusResponse
- type TopAirport
- type Tx
- type TxWrapper
Constants ¶
const ( DealClassGood = "good" // 20-35% below baseline DealClassGreat = "great" // 35-50% below baseline DealClassAmazing = "amazing" // 50%+ below baseline DealClassErrorFare = "error_fare" // Suspiciously cheap (70%+) )
DealClassification constants
const ( DealSourceSweep = "sweep" // From continuous price sweeps DealSourceSocial = "social" // From social-pulse webhook DealSourceWebhook = "webhook" // From external webhook DealSourceManual = "manual" // Manually entered )
DealSourceType constants
const ( DealStatusActive = "active" DealStatusExpired = "expired" DealStatusPublished = "published" DealStatusVerified = "verified" )
DealStatus constants
Variables ¶
var Top100Airports = []TopAirport{
{"ATL", "US"},
{"DFW", "US"},
{"DEN", "US"},
{"LAX", "US"},
{"ORD", "US"},
{"JFK", "US"},
{"SFO", "US"},
{"LAS", "US"},
{"MIA", "US"},
{"CLT", "US"},
{"SEA", "US"},
{"PHX", "US"},
{"EWR", "US"},
{"MCO", "US"},
{"MSP", "US"},
{"BOS", "US"},
{"DTW", "US"},
{"IAH", "US"},
{"BWI", "US"},
{"FLL", "US"},
{"TPA", "US"},
{"SAN", "US"},
{"PDX", "US"},
{"STL", "US"},
{"HNL", "US"},
{"YYZ", "CA"},
{"MEX", "MX"},
{"CUN", "MX"},
{"LHR", "GB"},
{"LGW", "GB"},
{"MAN", "GB"},
{"STN", "GB"},
{"CDG", "FR"},
{"ORY", "FR"},
{"FRA", "DE"},
{"MUC", "DE"},
{"DUS", "DE"},
{"HAM", "DE"},
{"AMS", "NL"},
{"MAD", "ES"},
{"BCN", "ES"},
{"PMI", "ES"},
{"FCO", "IT"},
{"MXP", "IT"},
{"ZRH", "CH"},
{"VIE", "AT"},
{"LIS", "PT"},
{"OSL", "NO"},
{"CPH", "DK"},
{"ARN", "SE"},
{"DUB", "IE"},
{"ATH", "GR"},
{"BRU", "BE"},
{"WAW", "PL"},
{"IST", "TR"},
{"AYT", "TR"},
{"SAW", "TR"},
{"DME", "RU"},
{"SVO", "RU"},
{"HND", "JP"},
{"NRT", "JP"},
{"ICN", "KR"},
{"PVG", "CN"},
{"PEK", "CN"},
{"CAN", "CN"},
{"SHA", "CN"},
{"SZX", "CN"},
{"CTU", "CN"},
{"KMG", "CN"},
{"XIY", "CN"},
{"HGH", "CN"},
{"CKG", "CN"},
{"NKG", "CN"},
{"TAO", "CN"},
{"WUH", "CN"},
{"CSX", "CN"},
{"HKG", "HK"},
{"TPE", "TW"},
{"SIN", "SG"},
{"BKK", "TH"},
{"KUL", "MY"},
{"MNL", "PH"},
{"CGK", "ID"},
{"DEL", "IN"},
{"BOM", "IN"},
{"DXB", "AE"},
{"DOH", "QA"},
{"AUH", "AE"},
{"SYD", "AU"},
{"MEL", "AU"},
{"GRU", "BR"},
{"BOG", "CO"},
{"JNB", "ZA"},
{"CMN", "MA"},
{"CAI", "EG"},
}
Top100Airports contains IATA codes and country codes for major global airports. Despite the name, the list currently has 95 airports (not 100). Route calculations:
- All routes (n*(n-1)): 95*94 = 8,930 routes
- International routes (different countries): ~8,096 routes
- With 2 trip lengths (7,14 days): ~16,192 queries per sweep
Source: ACI World Airport Traffic Rankings 2023
Functions ¶
func BuildPostgresConnString ¶
func BuildPostgresConnString(cfg config.PostgresConfig) string
BuildPostgresConnString builds a lib/pq keyword/value connection string from config.
func CountRoutes ¶
CountRoutes returns statistics about route generation
func GetAirportCountry ¶
GetAirportCountry returns the country code for an airport, or empty string if not found
func InitTestPostgres ¶
InitTestPostgres initializes a test PostgreSQL pool
func RunMigrations ¶
RunMigrations applies embedded SQL migrations in filename order and records them in schema_migrations.
The connString may be either a lib/pq keyword/value DSN or a postgres:// URL.
func Top100AirportCodes ¶
func Top100AirportCodes() []string
Top100AirportCodes returns IATA codes from the Top100Airports list
Types ¶
type Airport ¶
type Airport struct {
Code string
Name string
City string
Country string
Latitude sql.NullFloat64
Longitude sql.NullFloat64
}
Airport represents an airport row
type BulkSearch ¶
type BulkSearch struct {
ID int
JobID sql.NullInt32
Status string
TotalSearches int
Completed int
TotalOffers int
ErrorCount int
Currency string
CreatedAt time.Time
CompletedAt sql.NullTime
UpdatedAt time.Time
MinPrice sql.NullFloat64
MaxPrice sql.NullFloat64
AveragePrice sql.NullFloat64
}
BulkSearch represents the metadata for a bulk search
type BulkSearchOffer ¶
type BulkSearchOffer struct {
ID int
BulkSearchID int
Origin string
Destination string
DepartureDate time.Time
ReturnDate sql.NullTime
Price float64
Currency string
AirlineCodes []string
SrcAirportCode sql.NullString
DstAirportCode sql.NullString
SrcCity sql.NullString
DstCity sql.NullString
FlightDuration sql.NullInt32
ReturnFlightDuration sql.NullInt32
DistanceMiles sql.NullFloat64
CostPerMile sql.NullFloat64
OutboundFlights json.RawMessage
ReturnFlights json.RawMessage
OfferJSON json.RawMessage
CreatedAt time.Time
}
BulkSearchOffer represents all offers captured during a bulk run
type BulkSearchOfferRecord ¶
type BulkSearchOfferRecord struct {
BulkSearchID int
Origin string
Destination string
DepartureDate time.Time
ReturnDate sql.NullTime
Price float64
Currency string
AirlineCodes []string
SrcAirportCode sql.NullString
DstAirportCode sql.NullString
SrcCity sql.NullString
DstCity sql.NullString
FlightDuration sql.NullInt32
ReturnFlightDuration sql.NullInt32
DistanceMiles sql.NullFloat64
CostPerMile sql.NullFloat64
OutboundFlightsJSON []byte
ReturnFlightsJSON []byte
OfferJSON []byte
}
BulkSearchOfferRecord represents the data needed to insert an offer for a bulk run
type BulkSearchResult ¶
type BulkSearchResult struct {
Origin string
Destination string
DepartureDate time.Time
ReturnDate sql.NullTime
Price float64
Currency string
AirlineCode sql.NullString
Duration sql.NullInt32
SrcAirportCode sql.NullString
DstAirportCode sql.NullString
SrcCity sql.NullString
DstCity sql.NullString
FlightDuration sql.NullInt32
ReturnFlightDuration sql.NullInt32
OutboundFlights json.RawMessage
ReturnFlights json.RawMessage
OfferJSON json.RawMessage
}
BulkSearchResult represents a single result row from a bulk search
type BulkSearchResultRecord ¶
type BulkSearchResultRecord struct {
BulkSearchID int
Origin string
Destination string
DepartureDate time.Time
ReturnDate sql.NullTime
Price float64
Currency string
AirlineCode sql.NullString
Duration sql.NullInt32
SrcAirportCode sql.NullString
DstAirportCode sql.NullString
SrcCity sql.NullString
DstCity sql.NullString
FlightDuration sql.NullInt32
ReturnFlightDuration sql.NullInt32
OutboundFlightsJSON []byte
ReturnFlightsJSON []byte
OfferJSON []byte
}
BulkSearchResultRecord represents the data needed to insert a bulk search result
type BulkSearchSummary ¶
type BulkSearchSummary struct {
ID int
Status string
Completed int
TotalOffers int
ErrorCount int
MinPrice sql.NullFloat64
MaxPrice sql.NullFloat64
AveragePrice sql.NullFloat64
}
BulkSearchSummary represents aggregated results for a bulk search run
type Certificate ¶
Certificate represents a TLS certificate stored in the database
type Connection ¶
type Connection struct {
Airport string `json:"airport"` // Destination airport code
Name string `json:"name"` // Airport name
Country string `json:"country"` // Country code
CheapestPath float64 `json:"cheapest_path"` // Cheapest total price to reach
Hops int `json:"hops"` // Number of stops
}
Connection represents a reachable destination from an origin
type ContinuousSweepProgress ¶
type ContinuousSweepProgress struct {
ID int
SweepNumber int
RouteIndex int
TotalRoutes int
CurrentOrigin sql.NullString
CurrentDestination sql.NullString
QueriesCompleted int
ErrorsCount int
LastError sql.NullString
SweepStartedAt sql.NullTime
LastUpdated time.Time
TripLengths []int
PacingMode string // "adaptive" or "fixed"
TargetDurationHours int
MinDelayMs int
IsRunning bool
IsPaused bool
InternationalOnly bool
}
ContinuousSweepProgress tracks the current state of the continuous sweep
type ContinuousSweepResultsFilter ¶
type ContinuousSweepResultsFilter struct {
Origin string
Destination string
FromDate time.Time
ToDate time.Time
Limit int
Offset int
}
ContinuousSweepResultsFilter defines filters for querying continuous sweep results
type ContinuousSweepStats ¶
type ContinuousSweepStats struct {
ID int
SweepNumber int
StartedAt time.Time
CompletedAt sql.NullTime
TotalRoutes int
SuccessfulQueries int
FailedQueries int
TotalDurationSeconds sql.NullInt32
AvgDelayMs sql.NullInt32
MinPriceFound sql.NullFloat64
MaxPriceFound sql.NullFloat64
CreatedAt time.Time
}
ContinuousSweepStats represents historical stats for completed sweeps
type DealAlert ¶
type DealAlert struct {
ID int
DetectedDealID int
Origin string
Destination string
Price float64
Currency string
DiscountPercent sql.NullFloat64
DealClassification sql.NullString
DealScore sql.NullInt32
PublishedAt time.Time
PublishMethod string
NotificationSent bool
NotificationSentAt sql.NullTime
NotificationChannels []string
CreatedAt time.Time
}
DealAlert represents a published deal ready for notification
type DealFilter ¶
type DealFilter struct {
Origin string
Destination string
MinScore int
MaxPrice *float64
MinDiscount *float64
Classification string
Status string
SourceType string
IncludeExpired bool
Limit int
Offset int
}
DealFilter is used to filter deals in queries
type DealSource ¶
type DealSource struct {
ID int
Name string
SourceType string
WebhookURL sql.NullString
APIKey sql.NullString
Enabled bool
LastReceivedAt sql.NullTime
DealsReceived int
CreatedAt time.Time
UpdatedAt time.Time
}
DealSource represents an external deal source (for webhook integration)
type DetectedDeal ¶
type DetectedDeal struct {
ID int
Origin string
Destination string
DepartureDate time.Time
ReturnDate sql.NullTime
TripLength sql.NullInt32
Price float64
Currency string
BaselineMean sql.NullFloat64
BaselineMedian sql.NullFloat64
DiscountPercent sql.NullFloat64
DealScore sql.NullInt32
DealClassification sql.NullString
DistanceMiles sql.NullFloat64
CostPerMile sql.NullFloat64
CabinClass string
SourceType string
SourceID sql.NullString
SearchURL sql.NullString
DealFingerprint string
FirstSeenAt time.Time
LastSeenAt time.Time
TimesSeen int
Status string
Verified bool
VerifiedPrice sql.NullFloat64
VerifiedAt sql.NullTime
ExpiresAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
}
DetectedDeal represents a flight deal identified by the system
type ErrInvalidSearchID ¶
type ErrInvalidSearchID struct {
ID string
}
ErrInvalidSearchID is returned when the search ID is invalid
func (*ErrInvalidSearchID) Error ¶
func (e *ErrInvalidSearchID) Error() string
type FlightOffer ¶
type FlightOffer struct {
ID int
Price float64
Currency string
AirlineCodes sql.NullString
OutboundDuration sql.NullInt64
OutboundStops sql.NullInt64
ReturnDuration sql.NullInt64
ReturnStops sql.NullInt64
CreatedAt time.Time
}
FlightOffer represents the data structure for a single flight offer row
type FlightSegment ¶
type FlightSegment struct {
ID int
FlightOfferID int // Foreign key
AirlineCode string
FlightNumber string
DepartureAirport string
ArrivalAirport string
DepartureTime time.Time
ArrivalTime time.Time
Duration int
Airplane string
Legroom string
IsReturn bool
}
FlightSegment represents the data structure for a single flight segment row
type JobDetails ¶
type JobDetails struct {
JobID int // Foreign key or primary key if separate table
Origin string
Destination string
DepartureDateStart time.Time
DepartureDateEnd time.Time
ReturnDateStart sql.NullTime
ReturnDateEnd sql.NullTime
TripLength sql.NullInt32
DynamicDates bool // Use dates relative to execution time
DaysFromExecution sql.NullInt32 // Start searching X days from now
SearchWindowDays sql.NullInt32 // Search within X days window
Adults int
Children int
InfantsLap int
InfantsSeat int
TripType string
Class string
Stops string
Currency string // Added Currency
}
JobDetails represents the data structure for job details row
type LegInfo ¶
type LegInfo struct {
Origin string `json:"origin"`
Destination string `json:"destination"`
Price float64 `json:"price"`
Airline string `json:"airline,omitempty"`
}
LegInfo contains pricing info for a single leg
type Neo4jDB ¶
type Neo4jDB struct {
// contains filtered or unexported fields
}
Neo4jDB represents a Neo4j database connection. It implicitly implements the Neo4jDatabase interface.
func NewNeo4jDB ¶
func NewNeo4jDB(cfg config.Neo4jConfig) (*Neo4jDB, error)
NewNeo4jDB creates a new Neo4j database connection
func (*Neo4jDB) AddPricePoint ¶
func (n *Neo4jDB) AddPricePoint(originCode, destCode string, departDate string, returnDate string, price float64, airlineCode string, tripType string, class string) error
AddPricePoint adds or updates a price point for a route on a specific date
func (*Neo4jDB) CreateAirline ¶
CreateAirline creates or updates an airline node in Neo4j
func (*Neo4jDB) CreateAirport ¶
func (n *Neo4jDB) CreateAirport(code, name, city, country string, latitude, longitude float64) error
CreateAirport creates or updates an airport node in Neo4j
func (*Neo4jDB) CreateFlightRoute ¶
CreateFlightRoute creates a directed flight route relationship with properties
func (*Neo4jDB) CreateRoute ¶
func (n *Neo4jDB) CreateRoute(originCode, destCode, airlineCode, flightNumber string, avgPrice float64, avgDuration int) error
CreateRoute creates or updates a route relationship between airports
func (*Neo4jDB) ExecuteReadQuery ¶
func (n *Neo4jDB) ExecuteReadQuery(ctx context.Context, query string, params map[string]interface{}) (Neo4jResult, error)
ExecuteReadQuery runs a read-only query against Neo4j. The returned Neo4jResult wraps both the result and session - caller MUST call Close() when done.
func (*Neo4jDB) FindCheapestPath ¶
func (n *Neo4jDB) FindCheapestPath(ctx context.Context, origin, dest string, maxHops int, maxPrice float64) ([]PathResult, error)
FindCheapestPath finds the cheapest multi-hop paths between two airports
func (*Neo4jDB) FindConnections ¶
func (n *Neo4jDB) FindConnections(ctx context.Context, origin string, maxHops int, maxPrice float64) ([]Connection, error)
FindConnections finds all reachable destinations from an origin within budget
func (*Neo4jDB) GetRouteStats ¶
GetRouteStats returns aggregated price statistics for a specific route
func (*Neo4jDB) InitSchema ¶
InitSchema initializes the database schema
func (*Neo4jDB) SeedNeo4jData ¶
func (n *Neo4jDB) SeedNeo4jData(ctx context.Context, postgresDB PostgresDB) error
SeedNeo4jData seeds the Neo4j database with airports from the iata package. This is IDEMPOTENT - uses MERGE to create or update nodes.
type Neo4jDatabase ¶
type Neo4jDatabase interface {
CreateAirport(code, name, city, country string, latitude, longitude float64) error
CreateRoute(originCode, destCode, airlineCode, flightNumber string, avgPrice float64, avgDuration int) error
AddPricePoint(originCode, destCode string, departDate string, returnDate string, price float64, airlineCode string, tripType string, class string) error
CreateAirline(code, name, country string) error
Close() error
ExecuteReadQuery(ctx context.Context, query string, params map[string]interface{}) (Neo4jResult, error)
InitSchema() error
// Graph traversal methods
FindCheapestPath(ctx context.Context, origin, dest string, maxHops int, maxPrice float64) ([]PathResult, error)
FindConnections(ctx context.Context, origin string, maxHops int, maxPrice float64) ([]Connection, error)
GetRouteStats(ctx context.Context, origin, dest string) (*RouteStats, error)
}
Neo4jDatabase defines the interface for Neo4j database operations.
type Neo4jResult ¶
type Neo4jResult interface {
Next() bool // Removed context from Next again based on error at line 96
Record() *neo4j.Record
Err() error
Close() error // Close the result and underlying session
}
Neo4jResult defines the interface for Neo4j query results
type Neo4jResultWithSession ¶
type Neo4jResultWithSession struct {
// contains filtered or unexported fields
}
Neo4jResultWithSession wraps a Neo4j result and its session to ensure proper cleanup. The session is closed when Close() is called on this wrapper.
func (*Neo4jResultWithSession) Close ¶
func (r *Neo4jResultWithSession) Close() error
Close closes the underlying session (and implicitly the result)
func (*Neo4jResultWithSession) Err ¶
func (r *Neo4jResultWithSession) Err() error
Err returns any error from result iteration
func (*Neo4jResultWithSession) Next ¶
func (r *Neo4jResultWithSession) Next() bool
Next advances the result cursor
func (*Neo4jResultWithSession) Record ¶
func (r *Neo4jResultWithSession) Record() *neo4j.Record
Record returns the current record
type Neo4jSession ¶
type Neo4jSession interface {
Run(ctx context.Context, cypher string, params map[string]interface{}) (Neo4jResult, error)
Close() error // Keep context removed from Close
}
Neo4jSession defines the interface for a Neo4j session (read operations)
type PathResult ¶
type PathResult struct {
Stops []string `json:"stops"` // Airport codes in order
TotalPrice float64 `json:"total_price"` // Sum of leg prices
Legs []LegInfo `json:"legs"` // Details per leg
}
PathResult represents a multi-hop route path with total cost
type PostgresDB ¶
type PostgresDB interface {
GetSearchByID(id string) (*Search, error)
SaveSearch(search *Search) (string, error)
Search(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
GetCertificate(domain string) (*Certificate, error)
StoreCertificate(domain string, cert []byte, key []byte, expires time.Time) error
Close() error
// GetDB() *sql.DB // Remove this to enforce mocking via interface methods
InitSchema() error
BeginTx(ctx context.Context) (Tx, error) // Add transaction support
// Add specific query methods needed by handlers
QueryAirports(ctx context.Context) (Rows, error)
QueryAirlines(ctx context.Context) (Rows, error)
GetSearchQueryByID(ctx context.Context, id int) (*SearchQuery, error) // Define SearchQuery struct later
GetFlightOffersBySearchID(ctx context.Context, searchID int) (Rows, error)
GetFlightSegmentsByOfferID(ctx context.Context, offerID int) (Rows, error)
CountSearches(ctx context.Context) (int, error)
QuerySearchesPaginated(ctx context.Context, limit, offset int) (Rows, error)
DeleteJobDetailsByJobID(ctx context.Context, tx Tx, jobID int) error
DeleteScheduledJobByID(ctx context.Context, tx Tx, jobID int) (int64, error)
GetJobDetailsByID(ctx context.Context, jobID int) (*JobDetails, error) // Define JobDetails struct later
UpdateJobLastRun(ctx context.Context, jobID int) error
UpdateJobEnabled(ctx context.Context, jobID int, enabled bool) (int64, error)
GetJobCronExpression(ctx context.Context, jobID int) (string, error)
ListJobs(ctx context.Context) (Rows, error)
CreateScheduledJob(ctx context.Context, tx Tx, name, cronExpression string, enabled bool) (int, error)
CreateJobDetails(ctx context.Context, tx Tx, details JobDetails) error
UpdateScheduledJob(ctx context.Context, tx Tx, jobID int, name, cronExpression string) error
UpdateJobDetails(ctx context.Context, tx Tx, jobID int, details JobDetails) error
GetJobByID(ctx context.Context, jobID int) (*ScheduledJob, error) // Define ScheduledJob struct later
GetBulkSearchByID(ctx context.Context, searchID int) (*BulkSearch, error) // Define BulkSearch struct later
QueryBulkSearchResultsPaginated(ctx context.Context, searchID, limit, offset int) (Rows, error)
InsertBulkSearchOffer(ctx context.Context, record BulkSearchOfferRecord) error
QueryBulkSearchOffersPaginated(ctx context.Context, searchID, limit, offset int) (Rows, error)
ListBulkSearchOffers(ctx context.Context, searchID int) ([]BulkSearchOffer, error)
CreateBulkSearchRecord(ctx context.Context, jobID sql.NullInt32, totalSearches int, currency, status string) (int, error)
UpdateBulkSearchStatus(ctx context.Context, bulkSearchID int, status string) error
UpdateBulkSearchTotalSearches(ctx context.Context, bulkSearchID int, totalSearches int) error
UpdateBulkSearchProgress(ctx context.Context, bulkSearchID int, completed, totalOffers, errorCount int) error
CompleteBulkSearch(ctx context.Context, summary BulkSearchSummary) error
InsertBulkSearchResult(ctx context.Context, result BulkSearchResultRecord) error
InsertBulkSearchResultsBatch(ctx context.Context, results []BulkSearchResultRecord) error
// IncrementBulkSearchProgress atomically increments the completed count for a fan-out bulk search
// and returns the new completed count and total routes.
IncrementBulkSearchProgress(ctx context.Context, bulkSearchID int) (completed, total int, err error)
// FinalizeBulkSearch computes final stats (min/max/avg price) and marks the search complete.
FinalizeBulkSearch(ctx context.Context, bulkSearchID int) error
ListBulkSearches(ctx context.Context, limit, offset int) (Rows, error)
CreatePriceGraphSweep(ctx context.Context, jobID sql.NullInt32, originCount, destinationCount int, tripLengthMin, tripLengthMax sql.NullInt32, currency string) (int, error)
UpdatePriceGraphSweepStatus(ctx context.Context, sweepID int, status string, startedAt, completedAt sql.NullTime, errorCount int) error
GetPriceGraphSweepByID(ctx context.Context, sweepID int) (*PriceGraphSweep, error)
ListPriceGraphSweeps(ctx context.Context, limit, offset int) (Rows, error)
InsertPriceGraphResult(ctx context.Context, record PriceGraphResultRecord) error
ListPriceGraphResults(ctx context.Context, sweepID, limit, offset int) (Rows, error)
// Continuous sweep progress methods
SaveContinuousSweepProgress(ctx context.Context, progress ContinuousSweepProgress) error
SetContinuousSweepControlFlags(ctx context.Context, isRunning, isPaused *bool) error
GetContinuousSweepProgress(ctx context.Context) (*ContinuousSweepProgress, error)
InsertContinuousSweepStats(ctx context.Context, stats ContinuousSweepStats) error
ListContinuousSweepStats(ctx context.Context, limit int) ([]ContinuousSweepStats, error)
ListContinuousSweepResults(ctx context.Context, filters ContinuousSweepResultsFilter) ([]PriceGraphResultRecord, error)
// Deal detection methods
GetRouteBaseline(ctx context.Context, origin, dest string, tripLength int, class string) (*RouteBaseline, error)
UpsertRouteBaseline(ctx context.Context, baseline RouteBaseline) error
GetPriceHistoryForRoute(ctx context.Context, origin, dest string, tripLength int, class string, windowDays int) ([]float64, error)
InsertDetectedDeal(ctx context.Context, deal DetectedDeal) (int, error)
UpsertDetectedDeal(ctx context.Context, deal DetectedDeal) error
GetDetectedDealByFingerprint(ctx context.Context, fingerprint string) (*DetectedDeal, error)
ListActiveDeals(ctx context.Context, filter DealFilter) ([]DetectedDeal, error)
ExpireOldDeals(ctx context.Context) (int64, error)
InsertDealAlert(ctx context.Context, alert DealAlert) (int, error)
ListDealAlerts(ctx context.Context, limit, offset int) ([]DealAlert, error)
}
PostgresDB interface defines the database operations
func NewPostgresDB ¶
func NewPostgresDB(cfg config.PostgresConfig) (PostgresDB, error)
NewPostgresDB creates a new PostgreSQL database connection
type PostgresDBImpl ¶
type PostgresDBImpl struct {
// contains filtered or unexported fields
}
PostgresDBImpl is the concrete implementation
func (*PostgresDBImpl) BeginTx ¶
func (p *PostgresDBImpl) BeginTx(ctx context.Context) (Tx, error)
BeginTx starts a new transaction
func (*PostgresDBImpl) Close ¶
func (p *PostgresDBImpl) Close() error
Close closes the database connection
func (*PostgresDBImpl) CompleteBulkSearch ¶
func (p *PostgresDBImpl) CompleteBulkSearch(ctx context.Context, summary BulkSearchSummary) error
func (*PostgresDBImpl) CountSearches ¶
func (p *PostgresDBImpl) CountSearches(ctx context.Context) (int, error)
func (*PostgresDBImpl) CreateBulkSearchRecord ¶
func (*PostgresDBImpl) CreateJobDetails ¶
func (p *PostgresDBImpl) CreateJobDetails(ctx context.Context, tx Tx, details JobDetails) error
func (*PostgresDBImpl) CreatePriceGraphSweep ¶
func (*PostgresDBImpl) CreateScheduledJob ¶
func (*PostgresDBImpl) DeleteJobDetailsByJobID ¶
func (*PostgresDBImpl) DeleteScheduledJobByID ¶
func (*PostgresDBImpl) ExpireOldDeals ¶
func (p *PostgresDBImpl) ExpireOldDeals(ctx context.Context) (int64, error)
ExpireOldDeals marks expired deals
func (*PostgresDBImpl) FinalizeBulkSearch ¶
func (p *PostgresDBImpl) FinalizeBulkSearch(ctx context.Context, bulkSearchID int) error
FinalizeBulkSearch computes final stats from bulk_search_results and marks the search complete.
func (*PostgresDBImpl) GetBulkSearchByID ¶
func (p *PostgresDBImpl) GetBulkSearchByID(ctx context.Context, searchID int) (*BulkSearch, error)
func (*PostgresDBImpl) GetCertificate ¶
func (p *PostgresDBImpl) GetCertificate(domain string) (*Certificate, error)
GetCertificate retrieves a certificate from the database
func (*PostgresDBImpl) GetContinuousSweepProgress ¶
func (p *PostgresDBImpl) GetContinuousSweepProgress(ctx context.Context) (*ContinuousSweepProgress, error)
GetContinuousSweepProgress retrieves the current continuous sweep progress
func (*PostgresDBImpl) GetDetectedDealByFingerprint ¶
func (p *PostgresDBImpl) GetDetectedDealByFingerprint(ctx context.Context, fingerprint string) (*DetectedDeal, error)
GetDetectedDealByFingerprint retrieves a deal by its fingerprint
func (*PostgresDBImpl) GetFlightOffersBySearchID ¶
func (*PostgresDBImpl) GetFlightSegmentsByOfferID ¶
func (*PostgresDBImpl) GetJobByID ¶
func (p *PostgresDBImpl) GetJobByID(ctx context.Context, jobID int) (*ScheduledJob, error)
func (*PostgresDBImpl) GetJobCronExpression ¶
func (*PostgresDBImpl) GetJobDetailsByID ¶
func (p *PostgresDBImpl) GetJobDetailsByID(ctx context.Context, jobID int) (*JobDetails, error)
func (*PostgresDBImpl) GetPriceGraphSweepByID ¶
func (p *PostgresDBImpl) GetPriceGraphSweepByID(ctx context.Context, sweepID int) (*PriceGraphSweep, error)
func (*PostgresDBImpl) GetPriceHistoryForRoute ¶
func (p *PostgresDBImpl) GetPriceHistoryForRoute(ctx context.Context, origin, dest string, tripLength int, class string, windowDays int) ([]float64, error)
GetPriceHistoryForRoute retrieves historical prices for baseline calculation
func (*PostgresDBImpl) GetRouteBaseline ¶
func (p *PostgresDBImpl) GetRouteBaseline(ctx context.Context, origin, dest string, tripLength int, class string) (*RouteBaseline, error)
GetRouteBaseline retrieves price baseline for a route
func (*PostgresDBImpl) GetSearchByID ¶
func (p *PostgresDBImpl) GetSearchByID(id string) (*Search, error)
GetSearchByID retrieves a search record by its ID
func (*PostgresDBImpl) GetSearchQueryByID ¶
func (p *PostgresDBImpl) GetSearchQueryByID(ctx context.Context, id int) (*SearchQuery, error)
func (*PostgresDBImpl) IncrementBulkSearchProgress ¶
func (p *PostgresDBImpl) IncrementBulkSearchProgress(ctx context.Context, bulkSearchID int) (completed, total int, err error)
IncrementBulkSearchProgress atomically increments the completed count for a fan-out bulk search and returns the new completed count along with total_searches to check if we're done.
func (*PostgresDBImpl) InitSchema ¶
func (p *PostgresDBImpl) InitSchema() error
InitSchema initializes the database schema
func (*PostgresDBImpl) InsertBulkSearchOffer ¶
func (p *PostgresDBImpl) InsertBulkSearchOffer(ctx context.Context, record BulkSearchOfferRecord) error
func (*PostgresDBImpl) InsertBulkSearchResult ¶
func (p *PostgresDBImpl) InsertBulkSearchResult(ctx context.Context, result BulkSearchResultRecord) error
func (*PostgresDBImpl) InsertBulkSearchResultsBatch ¶
func (p *PostgresDBImpl) InsertBulkSearchResultsBatch(ctx context.Context, results []BulkSearchResultRecord) error
InsertBulkSearchResultsBatch inserts multiple bulk search results in a single transaction using multi-row INSERT for better performance. This reduces round-trips to the database.
func (*PostgresDBImpl) InsertContinuousSweepStats ¶
func (p *PostgresDBImpl) InsertContinuousSweepStats(ctx context.Context, stats ContinuousSweepStats) error
InsertContinuousSweepStats inserts a completed sweep's statistics
func (*PostgresDBImpl) InsertDealAlert ¶
InsertDealAlert inserts a new deal alert
func (*PostgresDBImpl) InsertDetectedDeal ¶
func (p *PostgresDBImpl) InsertDetectedDeal(ctx context.Context, deal DetectedDeal) (int, error)
InsertDetectedDeal inserts a new detected deal
func (*PostgresDBImpl) InsertPriceGraphResult ¶
func (p *PostgresDBImpl) InsertPriceGraphResult(ctx context.Context, record PriceGraphResultRecord) error
func (*PostgresDBImpl) ListActiveDeals ¶
func (p *PostgresDBImpl) ListActiveDeals(ctx context.Context, filter DealFilter) ([]DetectedDeal, error)
ListActiveDeals retrieves active deals with optional filtering
func (*PostgresDBImpl) ListBulkSearchOffers ¶
func (p *PostgresDBImpl) ListBulkSearchOffers(ctx context.Context, searchID int) ([]BulkSearchOffer, error)
func (*PostgresDBImpl) ListBulkSearches ¶
func (*PostgresDBImpl) ListContinuousSweepResults ¶
func (p *PostgresDBImpl) ListContinuousSweepResults(ctx context.Context, filters ContinuousSweepResultsFilter) ([]PriceGraphResultRecord, error)
ListContinuousSweepResults returns price graph results from continuous sweeps (sweep_id = 0)
func (*PostgresDBImpl) ListContinuousSweepStats ¶
func (p *PostgresDBImpl) ListContinuousSweepStats(ctx context.Context, limit int) ([]ContinuousSweepStats, error)
ListContinuousSweepStats retrieves the most recent sweep statistics
func (*PostgresDBImpl) ListDealAlerts ¶
func (p *PostgresDBImpl) ListDealAlerts(ctx context.Context, limit, offset int) ([]DealAlert, error)
ListDealAlerts retrieves published deal alerts with pagination
func (*PostgresDBImpl) ListJobs ¶
func (p *PostgresDBImpl) ListJobs(ctx context.Context) (Rows, error)
func (*PostgresDBImpl) ListPriceGraphResults ¶
func (*PostgresDBImpl) ListPriceGraphSweeps ¶
func (*PostgresDBImpl) QueryAirlines ¶
func (p *PostgresDBImpl) QueryAirlines(ctx context.Context) (Rows, error)
func (*PostgresDBImpl) QueryAirports ¶
func (p *PostgresDBImpl) QueryAirports(ctx context.Context) (Rows, error)
func (*PostgresDBImpl) QueryBulkSearchOffersPaginated ¶
func (*PostgresDBImpl) QueryBulkSearchResultsPaginated ¶
func (*PostgresDBImpl) QuerySearchesPaginated ¶
func (*PostgresDBImpl) SaveContinuousSweepProgress ¶
func (p *PostgresDBImpl) SaveContinuousSweepProgress(ctx context.Context, progress ContinuousSweepProgress) error
SaveContinuousSweepProgress saves or updates the continuous sweep progress (upsert)
func (*PostgresDBImpl) SaveSearch ¶
func (p *PostgresDBImpl) SaveSearch(search *Search) (string, error)
SaveSearch saves a search record to the database TODO: Implement SaveSearch logic
func (*PostgresDBImpl) Search ¶
func (p *PostgresDBImpl) Search(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
Search executes a generic search query TODO: Implement Search logic if needed, or remove if unused
func (*PostgresDBImpl) SeedData ¶
func (p *PostgresDBImpl) SeedData() error
SeedData seeds the database with initial data
func (*PostgresDBImpl) SetContinuousSweepControlFlags ¶
func (p *PostgresDBImpl) SetContinuousSweepControlFlags(ctx context.Context, isRunning, isPaused *bool) error
func (*PostgresDBImpl) StoreCertificate ¶
func (p *PostgresDBImpl) StoreCertificate(domain string, certChain []byte, privateKey []byte, expires time.Time) error
StoreCertificate saves a certificate to the database
func (*PostgresDBImpl) UpdateBulkSearchProgress ¶
func (*PostgresDBImpl) UpdateBulkSearchStatus ¶
func (*PostgresDBImpl) UpdateBulkSearchTotalSearches ¶
func (*PostgresDBImpl) UpdateJobDetails ¶
func (p *PostgresDBImpl) UpdateJobDetails(ctx context.Context, tx Tx, jobID int, details JobDetails) error
func (*PostgresDBImpl) UpdateJobEnabled ¶
func (*PostgresDBImpl) UpdateJobLastRun ¶
func (p *PostgresDBImpl) UpdateJobLastRun(ctx context.Context, jobID int) error
func (*PostgresDBImpl) UpdatePriceGraphSweepStatus ¶
func (*PostgresDBImpl) UpdateScheduledJob ¶
func (*PostgresDBImpl) UpsertDetectedDeal ¶
func (p *PostgresDBImpl) UpsertDetectedDeal(ctx context.Context, deal DetectedDeal) error
UpsertDetectedDeal inserts or updates a deal (for deduplication)
func (*PostgresDBImpl) UpsertRouteBaseline ¶
func (p *PostgresDBImpl) UpsertRouteBaseline(ctx context.Context, baseline RouteBaseline) error
UpsertRouteBaseline inserts or updates a route baseline
type PriceGraphResult ¶
type PriceGraphResult struct {
ID int
SweepID int
Origin string
Destination string
DepartureDate time.Time
ReturnDate sql.NullTime
TripLength sql.NullInt32
Price float64
Currency string
DistanceMiles sql.NullFloat64
CostPerMile sql.NullFloat64
Adults int
Children int
InfantsLap int
InfantsSeat int
TripType string
Class string
Stops string
SearchURL sql.NullString
QueriedAt time.Time
CreatedAt time.Time
}
PriceGraphResult represents the cheapest fare returned by the price graph API
type PriceGraphResultRecord ¶
type PriceGraphResultRecord struct {
SweepID int
Origin string
Destination string
DepartureDate time.Time
ReturnDate sql.NullTime
TripLength sql.NullInt32
Price float64
Currency string
DistanceMiles sql.NullFloat64
CostPerMile sql.NullFloat64
Adults int
Children int
InfantsLap int
InfantsSeat int
TripType string
Class string
Stops string
SearchURL sql.NullString
QueriedAt time.Time
}
PriceGraphResultRecord is used when inserting price graph results
type PriceGraphSweep ¶
type PriceGraphSweep struct {
ID int
JobID sql.NullInt32
Status string
OriginCount int
DestinationCount int
TripLengthMin sql.NullInt32
TripLengthMax sql.NullInt32
Currency string
ErrorCount int
CreatedAt time.Time
UpdatedAt time.Time
StartedAt sql.NullTime
CompletedAt sql.NullTime
}
PriceGraphSweep captures metadata about a price graph sweep run
type PriceGraphSweepJobDetails ¶
type PriceGraphSweepJobDetails struct {
ID int
JobID int
TripLengths []int
DepartureWindowDays int
DynamicDates bool
TripType string
Class string
Stops string
Adults int
Currency string
RateLimitMillis int
InternationalOnly bool
CreatedAt time.Time
UpdatedAt time.Time
}
PriceGraphSweepJobDetails represents sweep-specific job configuration
type Route ¶
Route represents an origin-destination pair
func GenerateAllRoutes ¶
func GenerateAllRoutes(airports []TopAirport) []Route
GenerateAllRoutes returns all origin-destination pairs (including domestic)
func GenerateInternationalRoutes ¶
func GenerateInternationalRoutes(airports []TopAirport) []Route
GenerateInternationalRoutes returns all origin-destination pairs where countries differ
type RouteBaseline ¶
type RouteBaseline struct {
ID int
Origin string
Destination string
TripLength int
Class string
SampleCount int
MeanPrice sql.NullFloat64
MedianPrice sql.NullFloat64
StddevPrice sql.NullFloat64
MinPrice sql.NullFloat64
MaxPrice sql.NullFloat64
P10Price sql.NullFloat64
P25Price sql.NullFloat64
P75Price sql.NullFloat64
P90Price sql.NullFloat64
WindowStart sql.NullTime
WindowEnd sql.NullTime
UpdatedAt time.Time
CreatedAt time.Time
}
RouteBaseline stores historical price statistics for a route
type RoutePricePoint ¶
type RouteStats ¶
type RouteStats struct {
Origin string `json:"origin"`
Destination string `json:"destination"`
MinPrice float64 `json:"min_price"`
MaxPrice float64 `json:"max_price"`
AvgPrice float64 `json:"avg_price"`
PricePoints int `json:"price_points"` // Number of observations
Airlines []string `json:"airlines"` // Airlines serving the route
// Source indicates which graph dataset produced these stats.
// - price_point: derived from :PRICE_POINT relationships (date-specific, filterable by date/age/trip type)
// - route: derived from :ROUTE relationships (avgPrice aggregates, no date-specific samples)
Source string `json:"source,omitempty"`
Note string `json:"note,omitempty"`
RouteEdges int `json:"route_edges,omitempty"` // Populated when Source=route.
MinPriceDate string `json:"min_price_date,omitempty"`
MinPriceAirline string `json:"min_price_airline,omitempty"`
MinPriceSeenAt string `json:"min_price_seen_at,omitempty"`
MinPriceTripType string `json:"min_price_trip_type,omitempty"`
MinPriceReturnDate string `json:"min_price_return_date,omitempty"`
MaxPriceDate string `json:"max_price_date,omitempty"`
MaxPriceAirline string `json:"max_price_airline,omitempty"`
MaxPriceSeenAt string `json:"max_price_seen_at,omitempty"`
MaxPriceTripType string `json:"max_price_trip_type,omitempty"`
MaxPriceReturnDate string `json:"max_price_return_date,omitempty"`
FirstSeenAt string `json:"first_seen_at,omitempty"`
LastSeenAt string `json:"last_seen_at,omitempty"`
Samples []RoutePricePoint `json:"samples,omitempty"`
}
RouteStats contains aggregated statistics for a route
type RowScanner ¶
type RowScanner interface {
Scan(dest ...interface{}) error
}
RowScanner defines the interface for scanning a single row result. This allows mocking database row scanning behavior.
type ScheduledJob ¶
type ScheduledJob struct {
ID int
Name string
CronExpression string
Enabled bool
LastRun sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
JobType string // "bulk_search" or "price_graph_sweep"
}
ScheduledJob represents the data structure for a scheduled job row
type Search ¶
type Search struct {
ID string
SearchID string
Origin string
Destination string
Departure time.Time
Return *time.Time
Passengers int
CabinClass string
Status string
Results []flights.FullOffer
CreatedAt time.Time
UpdatedAt time.Time
}
Search represents a flight search query and results (kept for potential future use, though might be redundant)
type SearchNotFoundError ¶
type SearchNotFoundError struct {
ID string
}
SearchNotFoundError is returned when the search is not found
func (*SearchNotFoundError) Error ¶
func (e *SearchNotFoundError) Error() string
type SearchQuery ¶
type SearchQuery struct {
ID int
Origin string
Destination string
DepartureDate time.Time
ReturnDate sql.NullTime
Status string
CreatedAt time.Time
}
SearchQuery represents the data structure for a single search query row
type SweepStatusResponse ¶
type SweepStatusResponse struct {
IsRunning bool `json:"is_running"`
IsPaused bool `json:"is_paused"`
SweepNumber int `json:"sweep_number"`
RouteIndex int `json:"route_index"`
TotalRoutes int `json:"total_routes"`
ProgressPercent float64 `json:"progress_percent"`
CurrentOrigin string `json:"current_origin"`
CurrentDestination string `json:"current_destination"`
Class string `json:"class"`
Stops string `json:"stops"`
TripLengths []int `json:"trip_lengths"`
QueriesCompleted int `json:"queries_completed"`
ErrorsCount int `json:"errors_count"`
LastError string `json:"last_error,omitempty"`
SweepStartedAt time.Time `json:"sweep_started_at,omitempty"`
EstimatedCompletion time.Time `json:"estimated_completion,omitempty"`
PacingMode string `json:"pacing_mode"`
CurrentDelayMs int `json:"current_delay_ms"`
MinDelayMs int `json:"min_delay_ms"`
TargetDurationHours int `json:"target_duration_hours"`
QueriesPerHour float64 `json:"queries_per_hour"`
}
SweepStatusResponse is the API response for sweep status
type TopAirport ¶
TopAirport represents an airport with its country code for international filtering
type Tx ¶
type Tx interface {
Commit() error
Rollback() error
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
QueryRowContext(ctx context.Context, query string, args ...any) RowScanner // Use RowScanner and ...any
}
Tx defines the interface for database transactions
type TxWrapper ¶
TxWrapper wraps *sql.Tx to satisfy the db.Tx interface, specifically adapting QueryRowContext.
func (*TxWrapper) QueryRowContext ¶
QueryRowContext calls the underlying *sql.Tx.QueryRowContext and returns the *sql.Row, which satisfies the db.RowScanner interface.