api

package
v0.2.13 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 69 Imported by: 0

Documentation

Overview

Package api builds Shrike's HTTP API.

The API, authentication, and image routes share one Huma registry and one OpenAPI document on the main eve-kill.com origin. API operations live below /api, images below /images, and browser OAuth below /auth.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SafeAccountBioHTML added in v0.2.0

func SafeAccountBioHTML(raw string) string

Preserve the bio renderer's styles and internal links while revalidating historical stored previews before they reach an administrative page.

func SafeCommentHTML added in v0.2.0

func SafeCommentHTML(raw string) string

SafeCommentHTML revalidates stored comment markup before server-side pages emit it as HTML. The API's renderer already sanitizes new writes, but older rows and imported content pass through the same policy on read.

func Site

func Site(opts Options) http.Handler

Site constructs the main-origin handler.

func WS

func WS(Options) http.Handler

WS is a lightweight placeholder used by ingress-focused tests. Production supplies the real same-origin /ws handler from internal/websocket.

Types

type AdvancedSearchFit added in v0.2.0

type AdvancedSearchFit struct {
	KillmailID    int64               `json:"killmail_id"`
	KillmailTime  time.Time           `json:"killmail_time"`
	ShipTypeID    int64               `json:"victim_ship_type_id"`
	ShipName      string              `json:"victim_ship_name"`
	TotalValue    float64             `json:"total_value"`
	AttackerCount int                 `json:"attacker_count"`
	Modules       []UniverseFitModule `json:"modules"`
	Drones        []UniverseFitDrone  `json:"drones"`
	Count         int                 `json:"count"`
	Hash          string              `json:"hash"`
	DedupMode     string              `json:"dedup_mode"`
}

AdvancedSearchFit is the existing FitPreview contract shared by search and later fitting catalogue pages. The slot and drone types are already used by the item fitting reader.

type AdvancedSearchResult added in v0.2.0

type AdvancedSearchResult struct {
	Kills   []KilllistRow       `json:"kills"`
	Fits    []AdvancedSearchFit `json:"fits"`
	HasMore bool                `json:"hasMore"`
	Cursor  *int64              `json:"cursor"`
}

type Announcement

type Announcement struct {
	ID        int64     `json:"id"`
	Tier      int16     `json:"tier" enum:"1,2,3"`
	Title     string    `json:"title"`
	BodyMD    string    `json:"body_md"`
	BodyHTML  string    `json:"body_html"`
	Color     string    `json:"color" enum:"info,warning,danger,success"`
	Icon      *string   `json:"icon"`
	LinkURL   *string   `json:"link_url"`
	LinkLabel *string   `json:"link_label"`
	StartsAt  time.Time `json:"starts_at"`
	ExpiresAt time.Time `json:"expires_at"`
	CreatedAt time.Time `json:"created_at"`
}

Announcement is the stable public shape shared by editorial announcements stored in Postgres and ephemeral ticker announcements stored in Valkey.

Database-only bookkeeping such as created_by, updated_at, and archived_at is intentionally not part of the public contract. Ephemeral announcements never had those fields, and the frontend only consumes the presentation fields.

type AnnouncementDismissalResponse

type AnnouncementDismissalResponse struct {
	OK bool `json:"ok"`
}

type AnnouncementsResponse

type AnnouncementsResponse struct {
	Announcements []Announcement `json:"announcements" nullable:"false"`
}

AnnouncementsResponse is the canonical frontend and public API payload. Defining it here, rather than importing a database row in Nuxt, makes the generated Huma contract authoritative for both persisted and live tickers.

type AuthOptions

type AuthOptions struct {
	ClientID     string
	ClientSecret string
	StateSecret  string
	CallbackURL  string
	UserAgent    string
	Production   bool
	HTTPClient   *http.Client
	// contains filtered or unexported fields
}

AuthOptions configures EVE SSO and the browser session cookie.

StateSecret signs browser OAuth state and may be rotated independently from EVE's client secret. An empty value falls back to ClientSecret for transition compatibility. HTTPClient is injected for deterministic OAuth tests; nil uses a bounded production client.

type BlogCursor added in v0.2.0

type BlogCursor struct {
	PublishedAt time.Time
	ID          int64
}

BlogCursor follows the listing's publication-time and ID ordering. ID zero represents a legacy timestamp-only cursor, which remains accepted.

func ParseBlogCursor added in v0.2.0

func ParseBlogCursor(raw string) (BlogCursor, error)

func (BlogCursor) String added in v0.2.0

func (cursor BlogCursor) String() string

type BlogListPage added in v0.2.0

type BlogListPage struct {
	Posts      []BlogListPost
	NextCursor string
}

type BlogListPost added in v0.2.0

type BlogListPost struct {
	ID            int64      `json:"id"`
	Slug          string     `json:"slug"`
	Title         string     `json:"title"`
	Excerpt       *string    `json:"excerpt"`
	CoverImageURL *string    `json:"cover_image_url"`
	Tags          []string   `json:"tags"`
	PublishedAt   *time.Time `json:"published_at"`
}

type BlogPost added in v0.2.0

type BlogPost struct {
	BlogListPost
	BodyMD                string  `json:"body_md"`
	BodyHTML              string  `json:"body_html"`
	Status                int16   `json:"status"`
	AuthorID              int64   `json:"author_id"`
	AuthorName            string  `json:"author_name"`
	AuthorCorporationID   *int64  `json:"author_corporation_id"`
	AuthorCorporationName *string `json:"author_corporation_name"`
	AuthorAllianceID      *int64  `json:"author_alliance_id"`
	AuthorAllianceName    *string `json:"author_alliance_name"`
}

func (*BlogPost) SanitizeBody added in v0.2.0

func (post *BlogPost) SanitizeBody()

type CoalitionAlliance added in v0.2.0

type CoalitionAlliance struct {
	AllianceID       int64  `json:"alliance_id"`
	Name             string `json:"name"`
	Ticker           string `json:"ticker"`
	MemberCount      int64  `json:"member_count"`
	CorporationCount int64  `json:"corporation_count"`
	SystemCount      int64  `json:"system_count"`
}

type CoalitionDetailData added in v0.2.0

type CoalitionDetailData struct {
	Coalition       CoalitionSummary    `json:"coalition"`
	Alliances       []CoalitionAlliance `json:"alliances"`
	Edits           []CoalitionEdit     `json:"edits"`
	StatsWindowDays int                 `json:"stats_window_days"`
}

type CoalitionDirectoryData added in v0.2.0

type CoalitionDirectoryData struct {
	Coalitions      []CoalitionSummary `json:"coalitions"`
	StatsWindowDays int                `json:"stats_window_days"`
}

CoalitionDirectoryData is the existing public coalition API contract. The Go page calls the same handlers as /api/coalitions, so membership, combat totals, and edit history have one source of truth.

type CoalitionEdit added in v0.2.0

type CoalitionEdit struct {
	EditID              int64  `json:"edit_id"`
	EditorCharacterID   *int64 `json:"editor_character_id"`
	EditorCharacterName string `json:"editor_character_name"`
	Action              string `json:"action"`
	Summary             string `json:"summary"`
	CreatedAt           string `json:"created_at"`
}

type CoalitionSummary added in v0.2.0

type CoalitionSummary struct {
	CoalitionID            int64   `json:"coalition_id"`
	Slug                   string  `json:"slug"`
	Name                   string  `json:"name"`
	Description            string  `json:"description"`
	SourceURL              *string `json:"source_url"`
	Revision               int64   `json:"revision"`
	AllianceCount          int64   `json:"alliance_count"`
	MemberCount            int64   `json:"member_count"`
	SystemCount            int64   `json:"system_count"`
	Kills                  int64   `json:"kills"`
	Losses                 int64   `json:"losses"`
	ISKDestroyed           float64 `json:"isk_destroyed"`
	ISKLost                float64 `json:"isk_lost"`
	UpdatedAt              string  `json:"updated_at"`
	UpdatedByCharacterID   *int64  `json:"updated_by_character_id"`
	UpdatedByCharacterName *string `json:"updated_by_character_name"`
}

type Database

type Database interface {
	Ping(context.Context) error
	Query(context.Context, string, ...any) (pgx.Rows, error)
	QueryRow(context.Context, string, ...any) pgx.Row
}

Database is the read-only subset of pgxpool.Pool used by API handlers. Keeping it as an interface makes the HTTP contract testable without a live Postgres server; *pgxpool.Pool satisfies it directly in production.

type DismissedAnnouncementIDsResponse

type DismissedAnnouncementIDsResponse struct {
	DismissedIDs []int64 `json:"dismissedIds" nullable:"false"`
}

type DomainAssetStorage

type DomainAssetStorage interface {
	Put(context.Context, string, []byte, string) error
	Get(context.Context, string) ([]byte, error)
	Delete(context.Context, string) error
}

DomainAssetStorage is the object-store boundary used by custom-domain images. The API owns key generation and validates every key read from the database before calling this interface; an implementation should treat a nil body and nil error from Get as "not found".

Keeping this boundary small lets production use its S3-compatible B2 bucket while tests use an in-memory store without coupling the API to an SDK.

type EntityAchievement added in v0.2.0

type EntityAchievement struct {
	ID              string  `json:"achievement_id"`
	Name            string  `json:"name"`
	Description     string  `json:"description"`
	Category        string  `json:"category"`
	Rarity          string  `json:"rarity"`
	Type            string  `json:"type"`
	PointsModifier  string  `json:"points_modifier"`
	CurrentCount    int64   `json:"current_count"`
	Threshold       int64   `json:"threshold"`
	NextThreshold   int64   `json:"next_threshold"`
	Level           int64   `json:"level"`
	MaxLevel        int64   `json:"max_level"`
	LevelThresholds []int64 `json:"level_thresholds"`
	IsCompleted     bool    `json:"is_completed"`
	Points          int64   `json:"points"`
	CompletedAt     string  `json:"completed_at"`
}

type EntityBattleEntry added in v0.2.0

type EntityBattleEntry struct {
	BattleID            int64   `json:"battle_id"`
	SolarSystemID       int64   `json:"solar_system_id"`
	SolarSystemName     string  `json:"solar_system_name"`
	SolarSystemSecurity float64 `json:"solar_system_security"`
	RegionID            int64   `json:"region_id"`
	RegionName          string  `json:"region_name"`
	StartTime           string  `json:"start_time"`
	DurationMinutes     int64   `json:"duration_minutes"`
	KillCount           int64   `json:"kill_count"`
	TotalISKDestroyed   float64 `json:"total_isk_destroyed"`
	IsMultiParty        bool    `json:"is_multi_party"`
	Teams               []struct {
		AllianceCount     int64   `json:"alliance_count"`
		TotalKills        int64   `json:"total_kills"`
		TotalISKDestroyed float64 `json:"total_isk_destroyed"`
		TopAlliances      []struct {
			AllianceID      int64  `json:"alliance_id"`
			AllianceName    string `json:"alliance_name"`
			CorporationID   int64  `json:"corporation_id"`
			CorporationName string `json:"corporation_name"`
		} `json:"top_alliances"`
	} `json:"teams"`
}

type EntityBattlesData added in v0.2.0

type EntityBattlesData struct {
	Battles []EntityBattleEntry `json:"battles"`
	Page    int                 `json:"page"`
}

type EntityCampaignEntry added in v0.2.0

type EntityCampaignEntry struct {
	CampaignID  string `json:"campaign_id"`
	Name        string `json:"name"`
	Description string `json:"description"`
	Mode        string `json:"mode"`
	Status      int    `json:"status"`
	Visibility  int    `json:"visibility"`
	StartTime   string `json:"start_time"`
	EndTime     string `json:"end_time"`
	Creator     struct {
		CharacterID int64  `json:"character_id"`
		Name        string `json:"name"`
	} `json:"creator"`
	Totals *struct {
		KillCount    int64   `json:"killCount"`
		ISKDestroyed float64 `json:"iskDestroyed"`
	} `json:"totals"`
	Location struct {
		SystemIDs        []int64 `json:"systemIds"`
		ConstellationIDs []int64 `json:"constellationIds"`
		RegionIDs        []int64 `json:"regionIds"`
	} `json:"location"`
	Sides []EntityCampaignSide `json:"sides"`
}

type EntityCampaignSide added in v0.2.0

type EntityCampaignSide struct {
	SideIndex    int64       `json:"side_index"`
	Name         string      `json:"name"`
	Kills        int64       `json:"kills"`
	Losses       int64       `json:"losses"`
	ISKDestroyed float64     `json:"isk_destroyed"`
	ISKLost      float64     `json:"isk_lost"`
	Palette      *TopPalette `json:"palette"`
	Entities     []struct {
		EntityType int   `json:"entity_type"`
		EntityID   int64 `json:"entity_id"`
	} `json:"entities"`
}

type EntityCampaignsData added in v0.2.0

type EntityCampaignsData struct {
	Campaigns []EntityCampaignEntry `json:"campaigns"`
	HasMore   bool                  `json:"hasMore"`
	Page      int                   `json:"page"`
}

type EntityCorporation added in v0.2.0

type EntityCorporation struct {
	CorporationID int64       `json:"corporation_id"`
	Name          string      `json:"name"`
	Ticker        string      `json:"ticker"`
	MemberCount   int64       `json:"member_count"`
	Palette       *TopPalette `json:"palette"`
}

type EntityCorporationsData added in v0.2.0

type EntityCorporationsData struct {
	Corporations []EntityCorporation `json:"corporations"`
	Total        int64               `json:"total"`
}

type EntityDashboard added in v0.2.0

type EntityDashboard struct {
	Stats                 EntityDashboardStats `json:"stats"`
	HeatMap               map[string]int64     `json:"heatMap"`
	TopShipsUsed          []EntityShipEntry    `json:"topShipsUsed"`
	TopShipsLost          []EntityShipEntry    `json:"topShipsLost"`
	FliesWithCorporations []TopEntry           `json:"fliesWithCorporations"`
	FliesWithAlliances    []TopEntry           `json:"fliesWithAlliances"`
	DiesToCorporations    []TopEntry           `json:"diesToCorporations"`
	DiesToAlliances       []TopEntry           `json:"diesToAlliances"`
}

type EntityDashboardStats added in v0.2.0

type EntityDashboardStats struct {
	Kills          int64   `json:"kills"`
	Losses         int64   `json:"losses"`
	Efficiency     int64   `json:"efficiency"`
	ISKDestroyed   float64 `json:"isk_destroyed"`
	ISKLost        float64 `json:"isk_lost"`
	ISKEfficiency  int64   `json:"isk_efficiency"`
	SoloKills      int64   `json:"solo_kills"`
	SoloLosses     int64   `json:"solo_losses"`
	NPCLosses      int64   `json:"npc_losses"`
	BlobFactor     float64 `json:"blob_factor"`
	ActiveTimezone string  `json:"active_timezone"`
	FinalBlows     int64   `json:"final_blows"`
	Points         int64   `json:"points"`
}

type EntityFactionFlip added in v0.2.0

type EntityFactionFlip struct {
	SolarSystemID int64  `json:"solar_system_id"`
	SystemName    string `json:"system_name"`
	NewFactionID  int64  `json:"new_faction_id"`
	OldFactionID  int64  `json:"old_faction_id"`
	FlippedAt     string `json:"flipped_at"`
}

type EntityFactionMilitiaCorp added in v0.2.0

type EntityFactionMilitiaCorp struct {
	ID     int64
	Name   string
	Pilots int
}

type EntityFactionOverview added in v0.2.0

type EntityFactionOverview struct {
	Matchup      string
	Side         int
	FactionStats struct {
		Side1 EntityFactionSideStats `json:"side1"`
		Side2 EntityFactionSideStats `json:"side2"`
	} `json:"factionStats"`
	Warzone struct {
		TotalSystems int64                  `json:"total_systems"`
		Side1        EntityFactionZoneStats `json:"side1"`
		Side2        EntityFactionZoneStats `json:"side2"`
	} `json:"warzone"`
	FlipDays []struct {
		Items []EntityFactionFlip `json:"items"`
	} `json:"flipDays"`
	Leaderboards struct {
		Characters struct {
			Side1 []struct {
				ID    int64  `json:"id"`
				Name  string `json:"name"`
				Kills int64  `json:"kills"`
			} `json:"side1"`
			Side2 []struct {
				ID    int64  `json:"id"`
				Name  string `json:"name"`
				Kills int64  `json:"kills"`
			} `json:"side2"`
		} `json:"characters"`
	} `json:"leaderboards"`
}

type EntityFactionSideStats added in v0.2.0

type EntityFactionSideStats struct {
	SystemsControlled int64 `json:"systems_controlled"`
	Pilots            int64 `json:"pilots"`
	KillsYesterday    int64 `json:"kills_yesterday"`
	KillsLastWeek     int64 `json:"kills_last_week"`
	VPLastWeek        int64 `json:"vp_last_week"`
}

type EntityFactionZoneStats added in v0.2.0

type EntityFactionZoneStats struct {
	Contested  int64 `json:"contested"`
	Vulnerable int64 `json:"vulnerable"`
}

type EntityIntelData added in v0.2.0

type EntityIntelData struct {
	Playstyle struct {
		Solo         int64   `json:"solo"`
		SmallGang    int64   `json:"small_gang"`
		MidGang      int64   `json:"mid_gang"`
		Fleet        int64   `json:"fleet"`
		Blob         int64   `json:"blob"`
		TotalKills   int64   `json:"total_kills"`
		AvgFleetSize float64 `json:"avg_fleet_size"`
	} `json:"playstyle"`
	FC struct {
		Likelihood string `json:"likelihood"`
	} `json:"fc"`
	DominantStyle string            `json:"dominant_style"`
	CapitalPilot  bool              `json:"capital_pilot"`
	IsLogi        bool              `json:"is_logi"`
	AWOXKills     int64             `json:"awox_kills"`
	CynoDeaths    int64             `json:"cyno_deaths"`
	Bait          string            `json:"bait"`
	BaitCount     int64             `json:"bait_count"`
	ShipsFlown    []TopEntry        `json:"ships_flown"`
	ShipsLost     []TopEntry        `json:"ships_lost"`
	Targets       []TopEntry        `json:"targets"`
	FleetPartners []EntityIntelPeer `json:"fleet_partners"`
	ActiveMembers struct {
		Days7  int64 `json:"days_7"`
		Days30 int64 `json:"days_30"`
		Days90 int64 `json:"days_90"`
	} `json:"activeMembers"`
	Census struct {
		Total int64 `json:"total"`
		FCs   int64 `json:"fcs"`
		Logis int64 `json:"logis"`
		Caps  int64 `json:"caps"`
	} `json:"census"`
	Allies           []EntityIntelPeer `json:"allies"`
	Enemies          []EntityIntelPeer `json:"enemies"`
	HuntingGrounds   []EntityIntelPeer `json:"huntingGrounds"`
	RecentDepartures []EntityIntelPeer `json:"recentDepartures"`
	RecentJoins      []EntityIntelPeer `json:"recentJoins"`
}

type EntityIntelPeer added in v0.2.0

type EntityIntelPeer struct {
	ID               int64  `json:"id"`
	Name             string `json:"name"`
	Count            int64  `json:"count"`
	CorpName         string `json:"corp_name"`
	AllianceName     string `json:"alliance_name"`
	SharedEnemyKills int64  `json:"shared_enemy_kills"`
	Total            int64  `json:"total"`
	ActiveCharacters int64  `json:"active_characters"`
	LeftAt           string `json:"left_at"`
	JoinedAt         string `json:"joined_at"`
}

type EntityMember added in v0.2.0

type EntityMember struct {
	CharacterID    int64   `json:"character_id"`
	CorporationID  int64   `json:"corporation_id"`
	Name           string  `json:"name"`
	SecurityStatus float64 `json:"security_status"`
	LastActive     string  `json:"last_active"`
	Kills90D       int64   `json:"kills_90d"`
	Losses90D      int64   `json:"losses_90d"`
	IsFC           bool    `json:"is_fc"`
	IsLogi         bool    `json:"is_logi"`
	IsCapitalPilot bool    `json:"is_capital_pilot"`
}

type EntityMembersData added in v0.2.0

type EntityMembersData struct {
	Members []EntityMember `json:"members"`
	Total   int64          `json:"total"`
	Page    int            `json:"page"`
	Limit   int            `json:"limit"`
}

type EntityShipEntry added in v0.2.0

type EntityShipEntry struct {
	ShipTypeID int64   `json:"ship_type_id"`
	ShipName   string  `json:"ship_name"`
	Count      float64 `json:"count"`
}

type EntityTopCollection added in v0.2.0

type EntityTopCollection struct {
	Characters   []TopEntry `json:"characters"`
	Corporations []TopEntry `json:"corporations"`
	Alliances    []TopEntry `json:"alliances"`
}

type EntityTopData added in v0.2.0

type EntityTopData struct {
	CharactersByKills    []TopEntry `json:"charactersByKills"`
	CharactersByPoints   []TopEntry `json:"charactersByPoints"`
	CharactersByISK      []TopEntry `json:"charactersByIsk"`
	SoloKillers          []TopEntry `json:"soloKillers"`
	CorporationsByKills  []TopEntry `json:"corporationsByKills"`
	AchievementPoints    []TopEntry `json:"achievementPoints"`
	RecentMembers        []TopEntry `json:"recentMembers"`
	ShipsUsed            []TopEntry `json:"shipsUsed"`
	Systems              []TopEntry `json:"systems"`
	Constellations       []TopEntry `json:"constellations"`
	Regions              []TopEntry `json:"regions"`
	KilledCorporations   []TopEntry `json:"killedCorporations"`
	KilledAlliances      []TopEntry `json:"killedAlliances"`
	KilledByCorporations []TopEntry `json:"killedByCorporations"`
	KilledByAlliances    []TopEntry `json:"killedByAlliances"`
}

type EntityTopLists added in v0.2.0

type EntityTopLists struct {
	Killed   EntityTopCollection `json:"killed"`
	KilledBy EntityTopCollection `json:"killedBy"`
}

type EntityWarEntry added in v0.2.0

type EntityWarEntry struct {
	WarID         int64         `json:"war_id"`
	Aggressor     EntityWarSide `json:"aggressor"`
	Defender      EntityWarSide `json:"defender"`
	Started       string        `json:"started"`
	Finished      string        `json:"finished"`
	Mutual        bool          `json:"mutual"`
	OpenForAllies bool          `json:"open_for_allies"`
}

type EntityWarSide added in v0.2.0

type EntityWarSide struct {
	ID           int64   `json:"id"`
	Type         string  `json:"type"`
	Name         string  `json:"name"`
	ISKDestroyed float64 `json:"isk_destroyed"`
	ShipsKilled  int64   `json:"ships_killed"`
}

type EntityWarsData added in v0.2.0

type EntityWarsData struct {
	Wars []EntityWarEntry `json:"wars"`
	Page int              `json:"page"`
}

type FactionWarCelestial added in v0.2.0

type FactionWarCelestial struct {
	SystemID int64   `json:"system_id"`
	GroupID  int64   `json:"group_id"`
	X        float64 `json:"x"`
	Z        float64 `json:"z"`
}

type FactionWarData added in v0.2.0

type FactionWarData struct {
	Matchup  string             `json:"matchup"`
	Days     int                `json:"days"`
	Side1    FactionWarSideData `json:"side1"`
	Side2    FactionWarSideData `json:"side2"`
	TopShips []FactionWarShip   `json:"topShips"`
	Overview FactionWarOverview `json:"overview"`
}

type FactionWarFactionStats added in v0.2.0

type FactionWarFactionStats struct {
	Pilots    int64 `json:"pilots"`
	Systems   int64 `json:"systems_controlled"`
	WeekVP    int64 `json:"vp_last_week"`
	WeekKills int64 `json:"kills_last_week"`
}

type FactionWarFlip added in v0.2.0

type FactionWarFlip struct {
	SystemID   int64  `json:"solar_system_id"`
	SystemName string `json:"system_name"`
	OldFaction string `json:"old_faction_name"`
	NewFaction string `json:"new_faction_name"`
	Time       string `json:"flipped_at"`
}

type FactionWarFlipDay added in v0.2.0

type FactionWarFlipDay struct {
	Day   string           `json:"day"`
	Items []FactionWarFlip `json:"items"`
}

type FactionWarLeaderboardEntry added in v0.2.0

type FactionWarLeaderboardEntry struct {
	ID              int64  `json:"id"`
	Name            string `json:"name"`
	Kills           int64  `json:"kills"`
	CorporationName string `json:"corporation_name"`
}

type FactionWarLeaderboardSides added in v0.2.0

type FactionWarLeaderboardSides struct {
	Side1 []FactionWarLeaderboardEntry `json:"side1"`
	Side2 []FactionWarLeaderboardEntry `json:"side2"`
}

type FactionWarOverview added in v0.2.0

type FactionWarOverview struct {
	FactionStats struct {
		Side1 *FactionWarFactionStats `json:"side1"`
		Side2 *FactionWarFactionStats `json:"side2"`
	} `json:"factionStats"`
	Warzone struct {
		Total int64                     `json:"total_systems"`
		Side1 factionWarSystemBreakdown `json:"side1"`
		Side2 factionWarSystemBreakdown `json:"side2"`
	} `json:"warzone"`
	FlipDays     []FactionWarFlipDay `json:"flipDays"`
	Leaderboards struct {
		Characters   FactionWarLeaderboardSides `json:"characters"`
		Corporations FactionWarLeaderboardSides `json:"corporations"`
	} `json:"leaderboards"`
}

type FactionWarShip added in v0.2.0

type FactionWarShip struct {
	ID    int64  `json:"ship_type_id"`
	Name  string `json:"ship_name"`
	Kills int64  `json:"kills"`
}

type FactionWarSide added in v0.2.0

type FactionWarSide struct {
	FactionID         int64   `json:"faction_id"`
	Name              string  `json:"name"`
	Kills             int64   `json:"kills"`
	ISKDestroyed      float64 `json:"isk_destroyed"`
	SystemsControlled int64   `json:"systems_controlled"`
	Pilots            int64   `json:"pilots"`
}

type FactionWarSideData added in v0.2.0

type FactionWarSideData struct {
	ID           int64   `json:"id"`
	Name         string  `json:"name"`
	CorpID       int64   `json:"corpId"`
	Kills        int64   `json:"kills"`
	Losses       int64   `json:"losses"`
	ISKDestroyed float64 `json:"isk_destroyed"`
	ISKLost      float64 `json:"isk_lost"`
}

Public HTML and JSON share the authoritative faction warfare loaders.

type FactionWarSystem added in v0.2.0

type FactionWarSystem struct {
	ID                int64   `json:"solar_system_id"`
	Name              string  `json:"system_name"`
	X                 float64 `json:"x"`
	Y                 float64 `json:"y"`
	Security          float64 `json:"security"`
	RegionID          int64   `json:"region_id"`
	RegionName        string  `json:"region_name"`
	ConstellationName string  `json:"constellation_name"`
	OccupierID        int64   `json:"occupier_faction_id"`
	Contested         string  `json:"contested"`
	VP                int64   `json:"victory_points"`
	Threshold         int64   `json:"victory_points_threshold"`
	Kills             int64   `json:"kills_24h"`
	ISK               float64 `json:"isk_24h"`
}

type FactionWarSystems added in v0.2.0

type FactionWarSystems struct {
	Systems    []FactionWarSystem    `json:"systems"`
	Jumps      [][]int64             `json:"jumps"`
	Celestials []FactionWarCelestial `json:"celestials"`
}

type FactionWarsData added in v0.2.0

type FactionWarsData struct {
	CaldariVsGallente struct {
		Caldari  FactionWarSide `json:"caldari"`
		Gallente FactionWarSide `json:"gallente"`
	} `json:"caldariVsGallente"`
	AmarrVsMinmatar struct {
		Amarr    FactionWarSide `json:"amarr"`
		Minmatar FactionWarSide `json:"minmatar"`
	} `json:"amarrVsMinmatar"`
}

type FeedManager

type FeedManager struct {
	// contains filtered or unexported fields
}

FeedManager fans Redis notifications out to SSE clients. Poll/catch-up reads remain in Postgres, which is the durable sequence source.

func NewFeedManager

func NewFeedManager(db Database, client *redis.Client) *FeedManager

func (*FeedManager) Start

func (m *FeedManager) Start(ctx context.Context)

type GraphDatabase

type GraphDatabase interface {
	Read(context.Context, string, map[string]any) ([]map[string]any, error)
}

type HomepageReader added in v0.2.0

type HomepageReader struct {
	// contains filtered or unexported fields
}

HomepageReader exposes the existing public read paths to HTML pages. API handlers and pages use the same SQL and enrichment functions.

func NewHomepageReader added in v0.2.0

func NewHomepageReader(db Database) *HomepageReader

func (*HomepageReader) AdvancedSearch added in v0.2.0

func (r *HomepageReader) AdvancedSearch(ctx context.Context, query url.Values) (AdvancedSearchResult, error)

AdvancedSearch delegates to the established query parser and loaders. Page and API reads have the same filters, sort cursor, fitting grouping, and TTL.

func (*HomepageReader) BattleGeneratorPreview added in v0.2.0

func (r *HomepageReader) BattleGeneratorPreview(ctx context.Context, input json.RawMessage) (json.RawMessage, error)

BattleGeneratorPreview retains the API's validation and authoritative calculation while letting HTML render without a loopback HTTP request.

func (*HomepageReader) CoalitionDetail added in v0.2.0

func (r *HomepageReader) CoalitionDetail(ctx context.Context, slug string) (CoalitionDetailData, bool, error)

func (*HomepageReader) CoalitionDirectory added in v0.2.0

func (r *HomepageReader) CoalitionDirectory(ctx context.Context) (CoalitionDirectoryData, error)

func (*HomepageReader) CoalitionDirectoryOverview added in v0.2.0

func (r *HomepageReader) CoalitionDirectoryOverview(ctx context.Context) (CoalitionDirectoryData, error)

CoalitionDirectoryOverview supplies useful SSR content without combat totals. The cache key remains under /coalitions so edits invalidate both datasets.

func (*HomepageReader) EntityAchievements added in v0.2.0

func (r *HomepageReader) EntityAchievements(ctx context.Context, id int64) ([]EntityAchievement, error)

EntityAchievements returns the character's award progress, including unstarted definitions so the filter controls have the full catalogue.

func (*HomepageReader) EntityBattles added in v0.2.0

func (r *HomepageReader) EntityBattles(ctx context.Context, kind string, id int64, page int) (EntityBattlesData, error)

func (*HomepageReader) EntityCampaigns added in v0.2.0

func (r *HomepageReader) EntityCampaigns(ctx context.Context, kind string, id int64, page int) (EntityCampaignsData, error)

func (*HomepageReader) EntityCorporations added in v0.2.0

func (r *HomepageReader) EntityCorporations(ctx context.Context, id int64, sortBy, direction string) (EntityCorporationsData, error)

func (*HomepageReader) EntityDashboard added in v0.2.0

func (r *HomepageReader) EntityDashboard(ctx context.Context, kind string, id int64, days int) (EntityDashboard, error)

EntityDashboard uses the same windowed stats/breakdown loader as Nuxt's dashboard API, with a small cache for repeat page and period requests.

func (*HomepageReader) EntityDetail added in v0.2.0

func (r *HomepageReader) EntityDetail(ctx context.Context, kind string, id int64) (map[string]any, error)

EntityDetail gives Go-rendered pages the same consolidated data as the public /api/{character,corporation,alliance,faction}/{id} routes. A missing entity returns nil, matching the frontend's 404 handling.

func (*HomepageReader) EntityFactionMilitiaCorps added in v0.2.0

func (r *HomepageReader) EntityFactionMilitiaCorps(ctx context.Context, id int64) ([]EntityFactionMilitiaCorp, error)

func (*HomepageReader) EntityFactionOverview added in v0.2.0

func (r *HomepageReader) EntityFactionOverview(ctx context.Context, id int64) (EntityFactionOverview, error)

func (*HomepageReader) EntityIntel added in v0.2.0

func (r *HomepageReader) EntityIntel(ctx context.Context, kind string, id int64, days int) (EntityIntelData, error)

func (*HomepageReader) EntityKilllist added in v0.2.0

func (r *HomepageReader) EntityKilllist(ctx context.Context, kind string, id int64, role string, page, limit int, after *int64, shipGroup int64) (KilllistPage, error)

EntityKilllist reuses the scoped killmail query and enrichment behind the public entity endpoint, including its numbered-page and cursor behavior.

func (*HomepageReader) EntityMembers added in v0.2.0

func (r *HomepageReader) EntityMembers(ctx context.Context, kind string, id int64, page int, sortBy string, activity int, corporationID int64) (EntityMembersData, error)

func (*HomepageReader) EntityTop added in v0.2.0

func (r *HomepageReader) EntityTop(ctx context.Context, kind string, id int64, slice, days string) (EntityTopData, error)

EntityTop reads one independently selectable Top-tab slice.

func (*HomepageReader) EntityTopLists added in v0.2.0

func (r *HomepageReader) EntityTopLists(ctx context.Context, kind string, id int64, days int) (EntityTopLists, error)

EntityTopLists serves the lazy desktop sidebars on entity kill tabs.

func (*HomepageReader) EntityWars added in v0.2.0

func (r *HomepageReader) EntityWars(ctx context.Context, kind string, id int64, page int, sortBy string) (EntityWarsData, error)

func (*HomepageReader) FactionWarDashboard added in v0.2.0

func (r *HomepageReader) FactionWarDashboard(ctx context.Context, slug string) (FactionWarData, error)

func (*HomepageReader) FactionWarIntel added in v0.2.0

func (r *HomepageReader) FactionWarIntel(ctx context.Context, slug string) (WarIntelData, error)

func (*HomepageReader) FactionWarKilllist added in v0.2.0

func (r *HomepageReader) FactionWarKilllist(ctx context.Context, slug, side string, page, limit int, after *int64) (KilllistPage, error)

The side denotes the attacking faction, so its killfeed contains its opponent's losses. It intentionally has the same unlimited history as Nuxt.

func (*HomepageReader) FactionWarMembers added in v0.2.0

func (r *HomepageReader) FactionWarMembers(ctx context.Context, slug string, query url.Values) (WarMembersData, error)

func (*HomepageReader) FactionWarOverview added in v0.2.0

func (r *HomepageReader) FactionWarOverview(ctx context.Context, slug, period string) (FactionWarOverview, error)

func (*HomepageReader) FactionWarSystems added in v0.2.0

func (r *HomepageReader) FactionWarSystems(ctx context.Context, slug string) (FactionWarSystems, error)

func (*HomepageReader) FactionWars added in v0.2.0

func (r *HomepageReader) FactionWars(ctx context.Context) (FactionWarsData, error)

func (*HomepageReader) FilteredKills added in v0.2.0

func (r *HomepageReader) FilteredKills(
	ctx context.Context, filters string, after *int64, limit int,
) (KilllistPage, error)

FilteredKills uses the same advanced query parser and SQL as the public API. The filters value is the advanced endpoint's JSON contract.

func (*HomepageReader) Killlist added in v0.2.0

func (r *HomepageReader) Killlist(ctx context.Context, kind string, page, limit int) (KilllistPage, error)

Killlist reads any validated /kills/{type} subset through the same rollup and enrichment path as the public killlist API.

func (*HomepageReader) KilllistFresh added in v0.2.0

func (r *HomepageReader) KilllistFresh(ctx context.Context, kind string, page, limit int) (KilllistPage, error)

func (*HomepageReader) KillmailPage added in v0.2.0

func (r *HomepageReader) KillmailPage(ctx context.Context, id int64) (KillmailPageData, bool, error)

func (*HomepageReader) Labels added in v0.2.0

func (r *HomepageReader) Labels(ctx context.Context) ([]LabelEntry, error)

Labels serves the API and the Go categories page from one catalogue and one count query. The response cache is shared with other HTML read models.

func (*HomepageReader) LatestKills added in v0.2.0

func (r *HomepageReader) LatestKills(ctx context.Context, page, limit int) (KilllistPage, error)

func (*HomepageReader) LatestKillsFresh added in v0.2.0

func (r *HomepageReader) LatestKillsFresh(ctx context.Context, page, limit int) (KilllistPage, error)

LatestKillsFresh bypasses a one-minute cache entry after a live notification. Limit explicit refreshes to one per ten seconds per key and process, even if many visitors click the badge together. It updates the same cache key so the next HTML request receives that page.

func (*HomepageReader) LegacyArchiveKill added in v0.2.0

func (r *HomepageReader) LegacyArchiveKill(ctx context.Context, id int64) (LegacyArchiveKillData, bool, error)

func (*HomepageReader) LegacyArchiveKills added in v0.2.0

func (r *HomepageReader) LegacyArchiveKills(ctx context.Context, values url.Values) (KilllistPage, error)

func (*HomepageReader) LegacyArchiveStats added in v0.2.0

func (r *HomepageReader) LegacyArchiveStats(ctx context.Context) (LegacyArchiveStats, error)

func (*HomepageReader) LegacyArchiveTop added in v0.2.0

func (r *HomepageReader) LegacyArchiveTop(ctx context.Context, kind string, year int) ([]TopEntry, error)

func (*HomepageReader) MostValuable added in v0.2.0

func (r *HomepageReader) MostValuable(ctx context.Context, kind string, days, limit int) ([]ValuableKill, error)

func (*HomepageReader) MostValuableKills added in v0.2.0

func (r *HomepageReader) MostValuableKills(ctx context.Context, kind string, days, limit int) ([]ValuableKill, error)

func (*HomepageReader) PublicBlogPost added in v0.2.0

func (r *HomepageReader) PublicBlogPost(ctx context.Context, slug string) (BlogPost, bool, error)

PublicBlogPost shares the API's published-or-archived visibility rule. Regenerating HTML from Markdown also keeps older stored HTML under today's allowlist before a Go template deliberately emits it as markup.

func (*HomepageReader) PublicBlogPosts added in v0.2.0

func (r *HomepageReader) PublicBlogPosts(ctx context.Context, cursor *BlogCursor, tag string, limit int) (BlogListPage, error)

PublicBlogPosts gives the server-rendered listing the same ordered rows and cursor semantics as GET /api/blog without routing an HTTP request internally.

func (*HomepageReader) PublicWallet added in v0.2.0

func (r *HomepageReader) PublicWallet(ctx context.Context, page, division int) (PublicWalletData, error)

func (*HomepageReader) Rankings added in v0.2.0

func (r *HomepageReader) Rankings(ctx context.Context, entityType, window string) ([]RankingEntry, error)

func (*HomepageReader) RoamReport added in v0.2.0

func (r *HomepageReader) RoamReport(ctx context.Context, id string) (RoamReport, bool, error)

RoamReport reads mutable reports from the primary, without the HTTP or JSON response round trip. The API uses the same enrichment for legacy reports.

func (*HomepageReader) RoamReportKilllist added in v0.2.0

func (r *HomepageReader) RoamReportKilllist(ctx context.Context, report RoamReport, query url.Values) (KilllistPage, error)

RoamReportKilllist reuses the report already loaded for the page. API callers use the same killlist query after loading their saved report.

func (*HomepageReader) SavedScan added in v0.2.0

func (r *HomepageReader) SavedScan(ctx context.Context, scanType, hash string) (json.RawMessage, bool, error)

SavedScan returns the public, stored analysis for a shared scan page. The result is kept as JSON text so the HTML renderer can decode the same payload the API returns without depending on pgx's JSONB value representation.

func (*HomepageReader) StatisticsBoard added in v0.2.0

func (*HomepageReader) StatisticsBoardsCached added in v0.2.0

func (r *HomepageReader) StatisticsBoardsCached(ctx context.Context, site SiteConfigurationResponse, queries []StatisticsQuery) map[int][]StatisticsEntry

StatisticsBoardsCached reads warm cards in one cache batch without starting cold queries or background work. Missing cards load through HTML fragments.

func (*HomepageReader) StatisticsSite added in v0.2.0

func (r *HomepageReader) StatisticsSite(ctx context.Context, host string) (SiteConfigurationResponse, error)

func (*HomepageReader) Top added in v0.2.0

func (r *HomepageReader) Top(ctx context.Context, dataType string, days, limit int) ([]TopEntry, error)

func (*HomepageReader) TopKills added in v0.2.0

func (r *HomepageReader) TopKills(ctx context.Context, kind, dataType string, days, limit int) ([]TopEntry, error)

TopKills and MostValuableKills are the typed reads for /kills/{type} pages. They call the same query helpers as the JSON endpoints and reuse the shared homepage response cache rather than making an internal HTTP request.

func (*HomepageReader) TopKillsCached added in v0.2.0

func (r *HomepageReader) TopKillsCached(ctx context.Context, kind, dataType string, days, limit int) ([]TopEntry, bool)

TopKillsCached is a nonblocking read for page assembly. Cold or expired leaderboards are fetched through their HTML fragments after the main page has rendered; a warm one remains part of the initial HTML.

func (*HomepageReader) UniverseConstellation added in v0.2.0

func (r *HomepageReader) UniverseConstellation(ctx context.Context, id int64) (UniverseConstellationData, bool, error)

func (*HomepageReader) UniverseFitDistributions added in v0.2.0

func (r *HomepageReader) UniverseFitDistributions(ctx context.Context, shipID int64, filters url.Values) (UniverseFitDistributions, error)

func (*HomepageReader) UniverseFitFamilies added in v0.2.0

func (r *HomepageReader) UniverseFitFamilies(ctx context.Context, shipID int64, filters url.Values) (UniverseFitFamilies, error)

func (*HomepageReader) UniverseFitMeta added in v0.2.0

func (r *HomepageReader) UniverseFitMeta(ctx context.Context, shipID int64, filters url.Values) (UniverseFitMeta, error)

func (*HomepageReader) UniverseGroup added in v0.2.0

func (r *HomepageReader) UniverseGroup(ctx context.Context, id int64) (UniverseGroupData, bool, error)

func (*HomepageReader) UniverseGroupKills added in v0.2.0

func (r *HomepageReader) UniverseGroupKills(ctx context.Context, id int64, limit int, after *int64) (KilllistPage, error)

func (*HomepageReader) UniverseItem added in v0.2.0

func (r *HomepageReader) UniverseItem(ctx context.Context, id int64) (UniverseItemData, bool, error)

func (*HomepageReader) UniverseItemKills added in v0.2.0

func (r *HomepageReader) UniverseItemKills(ctx context.Context, id int64, ship bool, limit int, after *int64) (KilllistPage, error)

func (*HomepageReader) UniverseLocationKills added in v0.2.0

func (r *HomepageReader) UniverseLocationKills(ctx context.Context, kind string, id int64, limit int, after *int64) (KilllistPage, error)

func (*HomepageReader) UniverseLocationValuable added in v0.2.0

func (r *HomepageReader) UniverseLocationValuable(ctx context.Context, kind string, id int64, category string) ([]ValuableKill, error)

func (*HomepageReader) UniverseMarketGroupItems added in v0.2.0

func (r *HomepageReader) UniverseMarketGroupItems(ctx context.Context, id int64) ([]UniverseMarketGroupItem, error)

func (*HomepageReader) UniverseMarketHistory added in v0.2.0

func (r *HomepageReader) UniverseMarketHistory(ctx context.Context, id int64, region int32, days int) (UniverseMarketHistory, error)

func (*HomepageReader) UniverseMarketOrders added in v0.2.0

func (r *HomepageReader) UniverseMarketOrders(ctx context.Context, id int64, region int32, security string) (UniverseMarketOrders, error)

func (*HomepageReader) UniverseMarketTree added in v0.2.0

func (r *HomepageReader) UniverseMarketTree(ctx context.Context) ([]UniverseMarketTreeNode, error)

func (*HomepageReader) UniverseRegion added in v0.2.0

func (r *HomepageReader) UniverseRegion(ctx context.Context, id int64) (UniverseRegionData, bool, error)

func (*HomepageReader) UniverseSystem added in v0.2.0

func (r *HomepageReader) UniverseSystem(ctx context.Context, id int64) (UniverseSystemData, bool, error)

func (*HomepageReader) WarDetail added in v0.2.0

func (r *HomepageReader) WarDetail(ctx context.Context, id int64) (WarDetailData, bool, error)

func (*HomepageReader) WarDirectory added in v0.2.0

func (r *HomepageReader) WarDirectory(ctx context.Context, query url.Values, host string) (WarDirectoryData, error)

func (*HomepageReader) WarIntel added in v0.2.0

func (r *HomepageReader) WarIntel(ctx context.Context, id int64) (WarIntelData, error)

func (*HomepageReader) WarKilllist added in v0.2.0

func (r *HomepageReader) WarKilllist(ctx context.Context, id int64, query url.Values) (KilllistPage, error)

func (*HomepageReader) WarMembers added in v0.2.0

func (r *HomepageReader) WarMembers(ctx context.Context, id int64, query url.Values) (WarMembersData, error)

func (*HomepageReader) WarOverview added in v0.2.0

func (r *HomepageReader) WarOverview(ctx context.Context) (WarOverviewData, error)

func (*HomepageReader) WarStats added in v0.2.0

func (r *HomepageReader) WarStats(ctx context.Context, id int64) (WarStatsData, error)

type KilllistPage added in v0.2.0

type KilllistPage struct {
	Kills      []KilllistRow `json:"kills"`
	HasMore    bool          `json:"hasMore"`
	Cursor     *int64        `json:"cursor"`
	TotalPages int           `json:"totalPages"`
}

type KilllistRow added in v0.2.0

type KilllistRow struct {
	KillmailID               int64     `json:"killmail_id"`
	KillmailTime             time.Time `json:"killmail_time"`
	TotalValue               float64   `json:"total_value"`
	AttackerCount            int       `json:"attacker_count"`
	IsNPC                    bool      `json:"is_npc"`
	IsSolo                   bool      `json:"is_solo"`
	ShipTypeID               int64     `json:"ship_type_id"`
	ShipName                 string    `json:"ship_name"`
	ShipGroupID              int64     `json:"ship_group_id"`
	ShipGroupName            string    `json:"ship_group_name"`
	VictimCharacterID        int64     `json:"victim_character_id"`
	VictimCharacterName      string    `json:"victim_character_name"`
	VictimCorporationID      int64     `json:"victim_corporation_id"`
	VictimCorporationName    string    `json:"victim_corporation_name"`
	VictimAllianceID         int64     `json:"victim_alliance_id"`
	VictimAllianceName       string    `json:"victim_alliance_name"`
	FinalBlowCharacterID     int64     `json:"final_blow_character_id"`
	FinalBlowCharacterName   string    `json:"final_blow_character_name"`
	FinalBlowCorporationID   int64     `json:"final_blow_corporation_id"`
	FinalBlowCorporationName string    `json:"final_blow_corporation_name"`
	FinalBlowAllianceID      int64     `json:"final_blow_alliance_id"`
	FinalBlowAllianceName    string    `json:"final_blow_alliance_name"`
	FinalBlowShipTypeID      int64     `json:"final_blow_ship_type_id"`
	FinalBlowShipName        string    `json:"final_blow_ship_name"`
	SolarSystemID            int64     `json:"solar_system_id"`
	SolarSystemName          string    `json:"solar_system_name"`
	SolarSystemSecurity      *float64  `json:"solar_system_security"`
	RegionID                 int64     `json:"region_id"`
	RegionName               string    `json:"region_name"`
}

type KillmailAttacker added in v0.2.0

type KillmailAttacker struct {
	CharacterID     *int64   `json:"character_id"`
	CharacterName   string   `json:"character_name"`
	CorporationID   *int64   `json:"corporation_id"`
	CorporationName string   `json:"corporation_name"`
	AllianceID      *int64   `json:"alliance_id"`
	AllianceName    string   `json:"alliance_name"`
	ShipTypeID      *int64   `json:"ship_type_id"`
	ShipCategoryID  *int64   `json:"ship_category_id"`
	ShipName        string   `json:"ship_name"`
	WeaponTypeID    *int64   `json:"weapon_type_id"`
	WeaponName      string   `json:"weapon_name"`
	DamageDone      int64    `json:"damage_done"`
	FinalBlow       bool     `json:"final_blow"`
	SecurityStatus  *float64 `json:"security_status"`
}

type KillmailItem added in v0.2.0

type KillmailItem struct {
	ItemIndex         int     `json:"item_index"`
	TypeID            int64   `json:"type_id"`
	TypeName          string  `json:"type_name"`
	GroupID           *int64  `json:"group_id"`
	CategoryID        *int64  `json:"category_id"`
	FlagID            int     `json:"flag_id"`
	FlagName          string  `json:"flag_name"`
	QuantityDropped   int64   `json:"quantity_dropped"`
	QuantityDestroyed int64   `json:"quantity_destroyed"`
	ParentIndex       *int    `json:"parent_index"`
	IsContainer       bool    `json:"is_container"`
	Slot              string  `json:"slot"`
	Price             float64 `json:"price"`
	TotalValue        float64 `json:"total_value"`
}

type KillmailLocation added in v0.2.0

type KillmailLocation struct {
	ItemID   int64   `json:"item_id"`
	ItemName string  `json:"item_name"`
	TypeID   *int64  `json:"type_id"`
	GroupID  *int64  `json:"group_id"`
	Distance float64 `json:"distance"`
}

type KillmailPageData added in v0.2.0

type KillmailPageData struct {
	KillmailID          int64              `json:"killmail_id"`
	KillmailHash        string             `json:"killmail_hash"`
	KillmailTime        time.Time          `json:"killmail_time"`
	Victim              KillmailVictim     `json:"victim"`
	SolarSystemID       int64              `json:"solar_system_id"`
	SolarSystemName     string             `json:"solar_system_name"`
	SolarSystemSecurity *float64           `json:"solar_system_security"`
	ConstellationID     *int64             `json:"constellation_id"`
	ConstellationName   string             `json:"constellation_name"`
	RegionID            *int64             `json:"region_id"`
	RegionName          string             `json:"region_name"`
	Location            *KillmailLocation  `json:"location"`
	TotalValue          float64            `json:"total_value"`
	FittedValue         float64            `json:"fitted_value"`
	DroppedValue        float64            `json:"dropped_value"`
	DestroyedValue      float64            `json:"destroyed_value"`
	Points              int64              `json:"points"`
	AttackerCount       int                `json:"attacker_count"`
	IsNPC               bool               `json:"is_npc"`
	IsSolo              bool               `json:"is_solo"`
	TotalDamage         int64              `json:"total_damage"`
	Attackers           []KillmailAttacker `json:"attackers"`
	Items               []KillmailItem     `json:"items"`
	Siblings            []KillmailSibling  `json:"siblings"`
}

KillmailPageData is the public killmail detail read model used by both the JSON API and the Go-rendered page. Keep the field names aligned with the established /api/killmail/{id} response.

type KillmailSibling added in v0.2.0

type KillmailSibling struct {
	KillmailID   int64     `json:"killmail_id"`
	ShipTypeID   *int64    `json:"ship_type_id"`
	ShipGroupID  *int64    `json:"ship_group_id"`
	ShipName     string    `json:"ship_name"`
	TotalValue   float64   `json:"total_value"`
	KillmailTime time.Time `json:"killmail_time"`
}

type KillmailVictim added in v0.2.0

type KillmailVictim struct {
	CharacterID        *int64          `json:"character_id"`
	CharacterName      string          `json:"character_name"`
	CorporationID      *int64          `json:"corporation_id"`
	CorporationName    string          `json:"corporation_name"`
	CorporationPalette json.RawMessage `json:"corporation_palette"`
	AllianceID         *int64          `json:"alliance_id"`
	AllianceName       string          `json:"alliance_name"`
	ShipTypeID         *int64          `json:"ship_type_id"`
	ShipName           string          `json:"ship_name"`
	ShipGroupID        *int64          `json:"ship_group_id"`
	ShipGroupName      string          `json:"ship_group_name"`
	ShipMarketPath     string          `json:"ship_market_path"`
	DamageTaken        int64           `json:"damage_taken"`
	ShipPrice          float64         `json:"ship_price"`
}

type LabelEntry added in v0.2.0

type LabelEntry struct {
	ID            string         `json:"id"`
	Name          string         `json:"name"`
	Description   string         `json:"description"`
	Category      string         `json:"category"`
	Count         int64          `json:"count"`
	ViewURL       string         `json:"view_url"`
	SearchFilters map[string]any `json:"search_filters"`
}

type LegacyArchiveAttacker added in v0.2.0

type LegacyArchiveAttacker struct {
	Name          string `json:"name"`
	Corp          string `json:"corp"`
	Alliance      string `json:"alliance"`
	Ship          string `json:"ship"`
	Weapon        string `json:"weapon"`
	FinalBlow     bool   `json:"final_blow"`
	CharacterID   *int64 `json:"character_id"`
	CorporationID *int64 `json:"corporation_id"`
	AllianceID    *int64 `json:"alliance_id"`
	ShipTypeID    *int64 `json:"ship_type_id"`
	WeaponTypeID  *int64 `json:"weapon_type_id"`
}

type LegacyArchiveItem added in v0.2.0

type LegacyArchiveItem struct {
	ID       int64   `json:"id"`
	Name     string  `json:"name"`
	Location *string `json:"location"`
	TypeID   *int64  `json:"type_id"`
	Quantity int64   `json:"quantity"`
}

type LegacyArchiveKill added in v0.2.0

type LegacyArchiveKill struct {
	KillmailID          int64     `json:"killmail_id"`
	KillmailTime        time.Time `json:"killmail_time"`
	RawText             string    `json:"raw_text"`
	TotalValue          float64   `json:"total_value"`
	Security            *float64  `json:"security"`
	SystemName          string    `json:"system_name"`
	VictimName          string    `json:"victim_name"`
	VictimCorp          string    `json:"victim_corp"`
	VictimAlliance      string    `json:"victim_alliance"`
	VictimShip          string    `json:"victim_ship"`
	VictimShipTypeID    *int64    `json:"victim_ship_type_id"`
	VictimCharacterID   *int64    `json:"victim_character_id"`
	VictimCorporationID *int64    `json:"victim_corporation_id"`
	VictimAllianceID    *int64    `json:"victim_alliance_id"`
}

type LegacyArchiveKillData added in v0.2.0

type LegacyArchiveKillData struct {
	Kill      LegacyArchiveKill       `json:"kill"`
	Attackers []LegacyArchiveAttacker `json:"attackers"`
	Items     []LegacyArchiveItem     `json:"items"`
}

type LegacyArchiveStats added in v0.2.0

type LegacyArchiveStats struct {
	Killmails    int64 `json:"killmails"`
	Characters   int64 `json:"characters"`
	Corporations int64 `json:"corporations"`
	Alliances    int64 `json:"alliances"`
}

type MutationDatabase

type MutationDatabase interface {
	Database
	Exec(context.Context, string, ...any) (pgconn.CommandTag, error)
	Begin(context.Context) (pgx.Tx, error)
}

MutationDatabase is the database contract for API-owned state.

Read-only handlers deliberately depend on the smaller Database interface. The production *pgxpool.Pool satisfies both, while focused tests do not need mutation methods unless the operation they exercise actually writes.

type Options

type Options struct {
	Version string
	Commit  string
	DB      Database
	// Primary is used for mutations and reads that require read-after-write
	// consistency. PrimaryPool is the same connection exposed concretely for
	// River, whose client requires *pgxpool.Pool.
	Primary     MutationDatabase
	PrimaryPool *pgxpool.Pool
	Graph       GraphDatabase
	Feed        *FeedManager
	Cache       *redis.Client
	// ResponseCacheBytes bounds the process-local L1. Cache remains the shared
	// Valkey client used as L2 and by non-response coordination features.
	ResponseCacheBytes int64

	Auth         AuthOptions
	DomainAssets DomainAssetStorage
	Images       *images.Service
	RequestGuard *RequestGuard
	OpenAIAPIKey string
	KlipyAPIKey  string
	// contains filtered or unexported fields
}

Options carries what the surfaces need from the process.

Deliberately not the whole *config.Config: a surface that wants a database pool should be handed a pool, so the dependency shows up in the signature rather than being fished out of a bag at request time.

type Principal

type Principal struct {
	CharacterID            int32
	CharacterName          string
	IsAdmin                bool
	CorporationID          *int32
	CorporationName        *string
	AllianceID             *int32
	AllianceName           *string
	LastSeenNotificationID int64
}

Principal is the small request-time identity. It deliberately excludes user_config and account-detail fields: authorization should be one indexed lookup, not a settings-page query paid by every authenticated request.

type PublicWalletData added in v0.2.0

type PublicWalletData struct {
	Corporation struct {
		ID     int64  `json:"corporation_id"`
		Name   string `json:"name"`
		Ticker string `json:"ticker"`
	} `json:"corporation"`
	TotalBalance string              `json:"totalBalance"`
	LastSynced   *string             `json:"lastSynced"`
	Journal      []PublicWalletEntry `json:"journal"`
	Page         int                 `json:"page"`
	Division     *int                `json:"division"`
	HasMore      bool                `json:"hasMore"`
	PageSize     int                 `json:"pageSize"`
}

PublicWalletData is the public wallet API contract rendered by the Go page. The reader delegates to the same handler as /api/wallet, so pagination, division filtering, and journal ordering stay consistent with API clients.

type PublicWalletEntry added in v0.2.0

type PublicWalletEntry struct {
	Division      int     `json:"division"`
	JournalID     int64   `json:"journal_id"`
	Date          string  `json:"date"`
	RefType       string  `json:"ref_type"`
	Description   string  `json:"description"`
	Amount        *string `json:"amount"`
	Balance       *string `json:"balance"`
	FirstPartyID  *int64  `json:"first_party_id"`
	SecondPartyID *int64  `json:"second_party_id"`
	Reason        *string `json:"reason"`
}

type RankingEntry added in v0.2.0

type RankingEntry struct {
	EntityID          int64  `json:"entity_id"`
	Name              string `json:"name"`
	EveKillRating     int64  `json:"eve_kill_rating"`
	CombatPoints      int64  `json:"combat_points"`
	AchievementPoints int64  `json:"achievement_points"`
	OverallRank       int64  `json:"overall_rank"`
}

type RequestGuard

type RequestGuard struct{}

RequestGuard enforces the public HTTP etiquette documented by the API.

It deliberately wraps /api only. Edge-layer infrastructure owns traffic shaping and rate limiting; the origin only requires clients to identify themselves so operators can contact a misbehaving integration.

func NewRequestGuard

func NewRequestGuard() *RequestGuard

NewRequestGuard returns the production API request policy.

func (*RequestGuard) Wrap

func (g *RequestGuard) Wrap(next http.Handler) http.Handler

Wrap applies the guard without changing handlers for the other same-origin namespaces.

type ResponseCache

type ResponseCache struct {
	// contains filtered or unexported fields
}

ResponseCache is the API response cache.

L1 is a byte-bounded LRU in this process. L2 is the shared Valkey. A read checks L1, promotes an L2 hit into L1 for the L2 entry's remaining lifetime, and otherwise lets the handler load the source. A source response is written through to both tiers.

func NewResponseCache

func NewResponseCache(client *redis.Client, maxBytes int64) *ResponseCache

NewResponseCache builds an L1 cache over a shared Valkey L2.

maxBytes is a hard payload ceiling for this process. Zero disables L1 but leaves L2 enabled. A nil client disables L2 but still permits a local cache, which is useful during a temporary Valkey outage and in focused tests.

func (*ResponseCache) Close added in v0.2.9

func (c *ResponseCache) Close()

Close cancels detached refreshes and drains all registered loaders before their database/cache dependencies can close. Repeated calls are safe.

func (*ResponseCache) DeleteMatching

func (c *ResponseCache) DeleteMatching(ctx context.Context, pattern string)

DeleteMatching invalidates both tiers. The pattern uses the Redis glob syntax needed by the current callers: '*' and '?' wildcards.

func (*ResponseCache) Load

func (c *ResponseCache) Load(
	ctx context.Context,
	key string,
) (cachedResponse, bool)

func (*ResponseCache) LoadMany added in v0.2.0

func (c *ResponseCache) LoadMany(ctx context.Context, keys []string) map[string]cachedResponse

LoadMany reads fresh entries in one shared-cache round trip after checking L1. It never loads the database or starts refresh work on a miss.

func (*ResponseCache) LoadOnce added in v0.1.7

func (c *ResponseCache) LoadOnce(
	ctx context.Context,
	key string,
	load func() (any, error),
) (any, error, bool)

LoadOnce collapses concurrent cache misses for the same key in this process. The shared Valkey cache handles reuse across replicas; this guard prevents a burst inside one replica from running the same expensive database query for every waiting request before the first response reaches Valkey.

func (*ResponseCache) LoadState added in v0.1.9

func (c *ResponseCache) LoadState(
	ctx context.Context,
	key string,
) (cachedResponse, bool, bool)

LoadState returns fresh and stale entries while their retention TTL lasts.

func (*ResponseCache) Refresh added in v0.1.9

func (c *ResponseCache) Refresh(key string, load func() (any, error))

Refresh starts one detached load for a key in this process. Callers use it after serving a stale response, so the client request never owns the refresh.

func (*ResponseCache) RefreshContext added in v0.2.5

func (c *ResponseCache) RefreshContext(ctx context.Context, key string, load func(context.Context) (any, error))

RefreshContext starts a separate background transaction; an already-served HTTP request must not retain spans for a refresh that continues afterwards.

func (*ResponseCache) Store

func (c *ResponseCache) Store(
	ctx context.Context,
	key string,
	entry cachedResponse,
	ttl time.Duration,
)

func (*ResponseCache) StoreStale added in v0.1.9

func (c *ResponseCache) StoreStale(
	ctx context.Context,
	key string,
	entry cachedResponse,
	freshTTL time.Duration,
	staleTTL time.Duration,
)

StoreStale retains an entry after its fresh TTL so a request can serve it while a detached refresh replaces it.

type RoamEngagement added in v0.2.0

type RoamEngagement = roamEngagement

type RoamKillmail added in v0.2.0

type RoamKillmail = roamKillmail

type RoamPilot added in v0.2.0

type RoamPilot = roamPilot

type RoamReport added in v0.2.0

type RoamReport = roamReport

These aliases let the Go frontend share the established report contract. API handlers and page readers share report construction and enrichment.

type RoamShip added in v0.2.0

type RoamShip = roamShip

type RoamSummary added in v0.2.0

type RoamSummary = roamSummary

type RoamSystem added in v0.2.0

type RoamSystem = roamSystem

type RoamTarget added in v0.2.0

type RoamTarget = roamTarget

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service is one API registry exposed through the main-site transport.

func New

func New(opts Options) *Service

New builds the shared API once.

func (*Service) Close added in v0.2.9

func (s *Service) Close()

Close drains work that can outlive an HTTP response. Stop ingress first; close database and shared-cache dependencies only after this returns.

func (*Service) Homepage added in v0.2.0

func (s *Service) Homepage() *HomepageReader

Homepage provides the shared cached reads used by the Go homepage widgets.

func (*Service) OpenAPI

func (s *Service) OpenAPI() *huma.OpenAPI

OpenAPI returns the generated contract owned by this service.

The document is complete immediately after New returns: route registration never invokes a handler or touches its database dependencies, which lets the CLI emit the frontend contract without starting the server.

func (*Service) Session added in v0.2.0

func (s *Service) Session() *SessionPageReader

func (*Service) Site

func (s *Service) Site() http.Handler

Site serves /api, /auth, /images, /health, and /ready on the frontend origin.

type SessionPageReader added in v0.2.0

type SessionPageReader struct {
	// contains filtered or unexported fields
}

SessionPageReader resolves the existing browser session for SSR. It neither creates a session nor refreshes its activity; /auth/me owns that lifecycle.

func (*SessionPageReader) BrowserSession added in v0.2.0

func (r *SessionPageReader) BrowserSession(ctx context.Context, cookie string) (*Principal, error)

type SiteConfigurationResponse

type SiteConfigurationResponse struct {
	Domain       *SiteDomainConfiguration `json:"domain"`
	IsDomainHost bool                     `json:"isDomainHost"`
}

SiteConfigurationResponse is the host-aware bootstrap consumed by Nuxt. Keeping it as a real Huma response makes the generated TypeScript contract authoritative for both SSR and browser rendering.

type SiteDomainConfiguration

type SiteDomainConfiguration struct {
	ID                int32                  `json:"id"`
	Subdomain         string                 `json:"subdomain"`
	CustomHostname    *string                `json:"customHostname"`
	UserID            int32                  `json:"userId"`
	Entities          []SiteDomainEntity     `json:"entities" nullable:"false"`
	EntityIDs         SiteDomainEntityIDs    `json:"entityIds"`
	Theme             SiteDomainTheme        `json:"theme"`
	NavbarLinks       []SiteDomainNavbarLink `json:"navbarLinks" nullable:"false"`
	Widgets           SiteDomainWidgets      `json:"widgets"`
	SiteName          *string                `json:"siteName"`
	SiteDescription   *string                `json:"siteDescription"`
	CampaignPolicy    int16                  `json:"campaignPolicy" enum:"0,1"`
	CampaignIDs       []string               `json:"campaignIds" nullable:"false"`
	PublicCampaignIDs []string               `json:"publicCampaignIds" nullable:"false"`
	Backgrounds       []string               `json:"backgrounds" nullable:"false"`
}

type SiteDomainEntity

type SiteDomainEntity struct {
	Type string `json:"type" enum:"character,corporation,alliance"`
	ID   int32  `json:"id"`
	Name string `json:"name"`
}

type SiteDomainEntityIDs

type SiteDomainEntityIDs struct {
	CharacterIDs   []int32 `json:"characterIds" nullable:"false"`
	CorporationIDs []int32 `json:"corporationIds" nullable:"false"`
	AllianceIDs    []int32 `json:"allianceIds" nullable:"false"`
}

type SiteDomainNavbarGroup

type SiteDomainNavbarGroup struct {
	Label *string                `json:"label,omitempty"`
	Items []SiteDomainNavbarItem `json:"items" nullable:"false"`
}

type SiteDomainNavbarItem

type SiteDomainNavbarItem struct {
	Label    string  `json:"label"`
	Href     string  `json:"href"`
	External *bool   `json:"external,omitempty"`
	Icon     *string `json:"icon,omitempty"`
}
type SiteDomainNavbarLink struct {
	Label    string                  `json:"label"`
	Href     string                  `json:"href"`
	External *bool                   `json:"external,omitempty"`
	Icon     *string                 `json:"icon,omitempty"`
	Children []SiteDomainNavbarGroup `json:"children,omitempty" nullable:"false"`
}

type SiteDomainTheme

type SiteDomainTheme struct {
	PrimaryColor            *string           `json:"primaryColor,omitempty"`
	AccentColor             *string           `json:"accentColor,omitempty"`
	BackgroundColor         *string           `json:"bgColor,omitempty"`
	TextColor               *string           `json:"textColor,omitempty"`
	BannerURL               *string           `json:"bannerUrl,omitempty"`
	LogoURL                 *string           `json:"logoUrl,omitempty"`
	ShowLogoInBanner        *bool             `json:"showLogoInBanner,omitempty"`
	ShowNameInBanner        *bool             `json:"showNameInBanner,omitempty"`
	ShowDescriptionInBanner *bool             `json:"showDescriptionInBanner,omitempty"`
	TransparentBanner       *bool             `json:"transparentBanner,omitempty"`
	ContentOpacity          *float64          `json:"contentOpacity,omitempty"`
	DefaultThemePreset      *string           `json:"defaultThemePreset,omitempty"`
	DefaultThemeOverrides   map[string]string `json:"defaultThemeOverrides,omitempty"`
}

type SiteDomainWidget

type SiteDomainWidget struct {
	Type         string  `` /* 145-byte string literal not displayed */
	Enabled      bool    `json:"enabled"`
	Content      *string `json:"content,omitempty"`
	KilllistType *string `json:"killlistType,omitempty"`
}

type SiteDomainWidgets

type SiteDomainWidgets struct {
	Top         []SiteDomainWidget `json:"top" nullable:"false"`
	Left        []SiteDomainWidget `json:"left" nullable:"false"`
	Right       []SiteDomainWidget `json:"right" nullable:"false"`
	ColumnRatio *string            `json:"columnRatio,omitempty"`
}

type StatisticsEntry added in v0.2.0

type StatisticsEntry struct {
	ID            int64      `json:"id"`
	Name          string     `json:"name"`
	Type          string     `json:"type"`
	Count         float64    `json:"count"`
	ISK           float64    `json:"isk"`
	Security      float64    `json:"sec"`
	Members       int64      `json:"member_count"`
	Delta1        int64      `json:"delta_1d"`
	Delta7        int64      `json:"delta_7d"`
	Delta30       int64      `json:"delta_30d"`
	Delta         int64      `json:"delta"`
	AverageSec    float64    `json:"avg_sec_status"`
	WeightedScore float64    `json:"weighted_score"`
	Founded       *time.Time `json:"date_founded"`
	TotalPoints   float64    `json:"total_points"`
	AveragePoints float64    `json:"avg_points"`
}

StatisticsEntry retains the richer population-ranking fields that are not part of the homepage's TopEntry contract.

type StatisticsQuery added in v0.2.0

type StatisticsQuery struct {
	DataType   string
	Section    string
	EntityType string
	Rank       string
	Direction  string
	Days       float64
}

type TopEntry added in v0.2.0

type TopEntry struct {
	ID      int64       `json:"id"`
	Name    string      `json:"name"`
	Count   float64     `json:"count"`
	Type    string      `json:"type"`
	Palette *TopPalette `json:"palette"`
}

type TopPalette added in v0.2.0

type TopPalette struct {
	MainColor      string `json:"main_color"`
	SecondaryColor string `json:"secondary_color"`
	TertiaryColor  string `json:"tertiary_color"`
}

type UniverseAttribute added in v0.2.0

type UniverseAttribute struct {
	ID    int64   `json:"id"`
	Name  string  `json:"name"`
	Value float64 `json:"value"`
}

type UniverseConstellationData added in v0.2.0

type UniverseConstellationData struct {
	Constellation struct {
		ConstellationID   int64  `json:"constellation_id"`
		ConstellationName string `json:"constellation_name"`
		RegionID          int64  `json:"region_id"`
		RegionName        string `json:"region_name"`
	} `json:"constellation"`
	Systems         []UniverseLocationSystem      `json:"systems"`
	SovDistribution []UniverseLocationSovereignty `json:"sovDistribution"`
	Stats           UniverseLocationStats         `json:"stats"`
}

type UniverseFitAlliance added in v0.2.0

type UniverseFitAlliance struct {
	ID                  int64   `json:"alliance_id"`
	Name                string  `json:"name"`
	Uses                int     `json:"uses"`
	PctOfAllianceLosses float64 `json:"pct_of_alliance_losses"`
}

type UniverseFitContext added in v0.2.0

type UniverseFitContext struct {
	SecurityDistribution []UniverseFitSecurityContext `json:"security_distribution"`
	TopRegion            *UniverseFitRegionContext    `json:"top_region"`
	MedianAttackers      float64                      `json:"median_attackers"`
	MedianLossValue      float64                      `json:"median_loss_value"`
}

type UniverseFitDistributionBucket added in v0.2.0

type UniverseFitDistributionBucket struct {
	Bucket           int     `json:"bucket"`
	LowerBound       float64 `json:"lower_bound"`
	UpperBound       float64 `json:"upper_bound"`
	ObservationCount int64   `json:"observation_count"`
}

type UniverseFitDistributionMetric added in v0.2.0

type UniverseFitDistributionMetric struct {
	Metric           string                          `json:"metric"`
	ObservationCount int64                           `json:"observation_count"`
	Median           float64                         `json:"median"`
	P10              float64                         `json:"p10"`
	P90              float64                         `json:"p90"`
	Buckets          []UniverseFitDistributionBucket `json:"buckets"`
}

type UniverseFitDistributions added in v0.2.0

type UniverseFitDistributions struct {
	ShipTypeID int64                           `json:"ship_type_id"`
	WindowDays int                             `json:"window_days"`
	Metrics    []UniverseFitDistributionMetric `json:"metrics"`
}

type UniverseFitDrone added in v0.2.0

type UniverseFitDrone struct {
	TypeID   int64  `json:"type_id"`
	Name     string `json:"name"`
	Quantity int    `json:"quantity"`
}

type UniverseFitFamilies added in v0.2.0

type UniverseFitFamilies struct {
	ShipTypeID int64               `json:"ship_type_id"`
	WindowDays int                 `json:"window_days"`
	IsRareHull bool                `json:"is_rare_hull"`
	HullCost   *float64            `json:"hull_cost"`
	Families   []UniverseFitFamily `json:"families"`
}

type UniverseFitFamily added in v0.2.0

type UniverseFitFamily struct {
	FamilyHash       string                `json:"family_hash"`
	CanonicalFitHash string                `json:"canonical_fit_hash"`
	TotalUses        int                   `json:"total_uses"`
	CanonicalUses    int                   `json:"canonical_uses"`
	VariantCount     int                   `json:"variant_count"`
	LastUsed         time.Time             `json:"last_used"`
	FitCost          float64               `json:"fit_cost"`
	Modules          []UniverseFitModule   `json:"modules"`
	Drones           []UniverseFitDrone    `json:"drones"`
	TopAlliances     []UniverseFitAlliance `json:"top_alliances"`
	Context          *UniverseFitContext   `json:"context"`
	Stats            *UniverseFitStats     `json:"stats"`
}

type UniverseFitMeta added in v0.2.0

type UniverseFitMeta struct {
	ShipTypeID int64                  `json:"ship_type_id"`
	WindowDays int                    `json:"window_days"`
	TotalKills int64                  `json:"total_kills"`
	Groups     []UniverseFitMetaGroup `json:"groups"`
}

type UniverseFitMetaGroup added in v0.2.0

type UniverseFitMetaGroup struct {
	ID        int64   `json:"group_id"`
	Name      string  `json:"name"`
	KillCount int64   `json:"kill_count"`
	Pct       float64 `json:"pct"`
}

type UniverseFitModule added in v0.2.0

type UniverseFitModule struct {
	SlotGroup    int    `json:"slot_group"`
	Ordinal      int    `json:"ordinal"`
	TypeID       int64  `json:"type_id"`
	Name         string `json:"name"`
	ChargeTypeID int64  `json:"charge_type_id"`
	ChargeName   string `json:"charge_name"`
}

type UniverseFitRegionContext added in v0.2.0

type UniverseFitRegionContext struct {
	ID   int64   `json:"region_id"`
	Name string  `json:"name"`
	Pct  float64 `json:"pct"`
}

type UniverseFitSecurityContext added in v0.2.0

type UniverseFitSecurityContext struct {
	Name string  `json:"name"`
	Pct  float64 `json:"pct"`
}

type UniverseFitStats added in v0.2.0

type UniverseFitStats struct {
	EHP        *float64 `json:"ehp"`
	DPS        *float64 `json:"dps"`
	Alpha      *float64 `json:"alpha"`
	Speed      *float64 `json:"speed"`
	Align      *float64 `json:"align"`
	Repair     *float64 `json:"repair"`
	NPCEHP     *float64 `json:"npc_ehp"`
	NPCProfile string   `json:"npc_profile"`
}

type UniverseGroup added in v0.2.0

type UniverseGroup struct {
	ID                 int64  `json:"group_id"`
	Name               string `json:"name"`
	CategoryID         int64  `json:"category_id"`
	CategoryName       string `json:"category_name"`
	Published          bool   `json:"published"`
	TypeCount          int64  `json:"type_count"`
	PublishedTypeCount int64  `json:"published_type_count"`
}

type UniverseGroupData added in v0.2.0

type UniverseGroupData struct {
	Group UniverseGroup       `json:"group"`
	Types []UniverseGroupType `json:"types"`
}

type UniverseGroupType added in v0.2.0

type UniverseGroupType struct {
	ID            int64  `json:"type_id"`
	Name          string `json:"name"`
	Published     bool   `json:"published"`
	MetaGroupName string `json:"meta_group_name"`
}

type UniverseInsurance added in v0.2.0

type UniverseInsurance struct {
	LevelName string  `json:"level_name"`
	Cost      float64 `json:"cost"`
	Payout    float64 `json:"payout"`
}

type UniverseItem added in v0.2.0

type UniverseItem struct {
	ID             int64   `json:"type_id"`
	Name           string  `json:"name"`
	Description    string  `json:"description"`
	GroupID        int64   `json:"group_id"`
	GroupName      string  `json:"group_name"`
	CategoryID     int64   `json:"category_id"`
	CategoryName   string  `json:"category_name"`
	MetaGroupName  string  `json:"meta_group_name"`
	IsShip         bool    `json:"is_ship"`
	Published      bool    `json:"published"`
	Volume         float64 `json:"volume"`
	PackagedVolume float64 `json:"packaged_volume"`
	Mass           float64 `json:"mass"`
	Capacity       float64 `json:"capacity"`
	BasePrice      float64 `json:"base_price"`
	PortionSize    int64   `json:"portion_size"`
	Radius         float64 `json:"radius"`
	MetaLevel      int64   `json:"meta_level"`
	TechLevel      int64   `json:"tech_level"`
}

type UniverseItemData added in v0.2.0

type UniverseItemData struct {
	Item             UniverseItem                   `json:"item"`
	ShipAttributes   map[string][]UniverseAttribute `json:"shipAttributes"`
	Attributes       []UniverseAttribute            `json:"attributes"`
	RequiredSkills   []UniverseSkill                `json:"requiredSkills"`
	Materials        []UniverseMaterial             `json:"materials"`
	Variations       []UniverseVariation            `json:"variations"`
	MarketBreadcrumb []UniverseMarketCrumb          `json:"marketBreadcrumb"`
	Pricing          struct {
		Summary       *UniversePriceSummary `json:"summary"`
		CustomSummary *UniversePriceSummary `json:"customSummary"`
		History       []UniversePricePoint  `json:"history"`
		CustomHistory []UniversePricePoint  `json:"customHistory"`
		Insurance     []UniverseInsurance   `json:"insurance"`
	} `json:"pricing"`
}

type UniverseLocationSovereignty added in v0.2.0

type UniverseLocationSovereignty struct {
	AllianceID   int64  `json:"alliance_id"`
	AllianceName string `json:"alliance_name"`
	FactionID    int64  `json:"faction_id"`
	FactionName  string `json:"faction_name"`
	SystemCount  int64  `json:"system_count"`
}

type UniverseLocationStats added in v0.2.0

type UniverseLocationStats struct {
	Kills      int64   `json:"kills"`
	NPCKills   int64   `json:"npc_kills"`
	PodKills   int64   `json:"pod_kills"`
	TotalValue float64 `json:"total_value"`
}

type UniverseLocationSystem added in v0.2.0

type UniverseLocationSystem struct {
	SolarSystemID int64    `json:"solar_system_id"`
	SystemName    string   `json:"system_name"`
	Security      *float64 `json:"security"`
	AllianceID    int64    `json:"alliance_id"`
	AllianceName  string   `json:"alliance_name"`
	FactionID     int64    `json:"faction_id"`
	FactionName   string   `json:"faction_name"`
	Kills         int64    `json:"kills"`
	TotalValue    float64  `json:"total_value"`
}

type UniverseMarketCrumb added in v0.2.0

type UniverseMarketCrumb struct {
	ID   int64  `json:"id"`
	Name string `json:"name"`
	Slug string `json:"slug"`
}

type UniverseMarketGroupItem added in v0.2.0

type UniverseMarketGroupItem struct {
	ID              int64    `json:"type_id"`
	Name            string   `json:"name"`
	GroupID         int64    `json:"group_id"`
	MarketGroupID   int64    `json:"market_group_id"`
	CategoryID      int64    `json:"category_id"`
	MetaGroupID     *int64   `json:"meta_group_id"`
	IsShip          bool     `json:"is_ship"`
	UniverseAverage *float64 `json:"universe_average"`
	UniverseVolume  *int64   `json:"universe_volume"`
	JitaSell        *float64 `json:"jita_sell"`
}

type UniverseMarketHistory added in v0.2.0

type UniverseMarketHistory struct {
	RegionID int32                        `json:"region_id"`
	Days     int                          `json:"days"`
	History  []UniverseMarketHistoryPoint `json:"history"`
}

type UniverseMarketHistoryPoint added in v0.2.0

type UniverseMarketHistoryPoint struct {
	Date    time.Time `json:"date"`
	Average *float64  `json:"average"`
	Volume  *int64    `json:"volume"`
}

type UniverseMarketOrder added in v0.2.0

type UniverseMarketOrder struct {
	OrderID      int64     `json:"order_id"`
	VolumeRemain int64     `json:"volume_remain"`
	MinVolume    int64     `json:"min_volume"`
	Price        float64   `json:"price"`
	LocationName string    `json:"location_name"`
	RegionName   string    `json:"region_name"`
	SystemID     int64     `json:"system_id"`
	Security     *float64  `json:"security"`
	ExpiresAt    time.Time `json:"expires_at"`
}

Market page reads share the same order and history handlers as the public API, including its region/security semantics, without an HTTP round trip.

type UniverseMarketOrders added in v0.2.0

type UniverseMarketOrders struct {
	SnapshotAt *time.Time             `json:"snapshot_at"`
	RegionID   int32                  `json:"region_id"`
	Security   []string               `json:"security"`
	Sellers    []UniverseMarketOrder  `json:"sellers"`
	Buyers     []UniverseMarketOrder  `json:"buyers"`
	Regions    []UniverseMarketRegion `json:"regions"`
}

type UniverseMarketRegion added in v0.2.0

type UniverseMarketRegion struct {
	ID   int64  `json:"region_id"`
	Name string `json:"name"`
}

type UniverseMarketTreeNode added in v0.2.0

type UniverseMarketTreeNode struct {
	ID       int64                    `json:"id"`
	Name     string                   `json:"name"`
	Slug     string                   `json:"slug"`
	ParentID *int64                   `json:"parent_id"`
	HasTypes bool                     `json:"has_types"`
	IconID   *int64                   `json:"icon_id"`
	Children []UniverseMarketTreeNode `json:"children"`
}

type UniverseMaterial added in v0.2.0

type UniverseMaterial struct {
	ID       int64  `json:"type_id"`
	Name     string `json:"name"`
	Quantity int64  `json:"quantity"`
}

type UniversePricePoint added in v0.2.0

type UniversePricePoint struct {
	Date    string  `json:"date"`
	Price   float64 `json:"price"`
	Average float64 `json:"average"`
	Volume  int64   `json:"volume"`
}

type UniversePriceSummary added in v0.2.0

type UniversePriceSummary struct {
	Latest       float64 `json:"latest"`
	LatestDate   string  `json:"latest_date"`
	Average90D   float64 `json:"average_90d"`
	Highest90D   float64 `json:"highest_90d"`
	Lowest90D    float64 `json:"lowest_90d"`
	AvgVolume90D int64   `json:"avg_volume_90d"`
}

type UniverseRegionData added in v0.2.0

type UniverseRegionData struct {
	Region struct {
		RegionID           int64  `json:"region_id"`
		Name               string `json:"name"`
		Description        string `json:"description"`
		ConstellationCount int64  `json:"constellation_count"`
		SystemCount        int64  `json:"system_count"`
	} `json:"region"`
	Constellations []struct {
		ConstellationID   int64  `json:"constellation_id"`
		ConstellationName string `json:"constellation_name"`
		SystemCount       int64  `json:"system_count"`
		AllianceID        int64  `json:"alliance_id"`
		AllianceName      string `json:"alliance_name"`
		FactionID         int64  `json:"faction_id"`
		FactionName       string `json:"faction_name"`
	} `json:"constellations"`
	SovDistribution []UniverseLocationSovereignty `json:"sovDistribution"`
	TopSystems      []UniverseLocationSystem      `json:"topSystems"`
	Stats           UniverseLocationStats         `json:"stats"`
}

type UniverseSkill added in v0.2.0

type UniverseSkill struct {
	ID    int64  `json:"type_id"`
	Name  string `json:"name"`
	Level int    `json:"level"`
}

type UniverseSovereignty added in v0.2.0

type UniverseSovereignty struct {
	AllianceID      int64  `json:"alliance_id"`
	AllianceName    string `json:"alliance_name"`
	CorporationID   int64  `json:"corporation_id"`
	CorporationName string `json:"corporation_name"`
	FactionID       int64  `json:"faction_id"`
	FactionName     string `json:"faction_name"`
	Date            string `json:"date"`
}

type UniverseSystemActivity added in v0.2.0

type UniverseSystemActivity struct {
	Timestamp time.Time `json:"timestamp"`
	ShipJumps int64     `json:"ship_jumps"`
	ShipKills int64     `json:"ship_kills"`
	NPCKills  int64     `json:"npc_kills"`
	PodKills  int64     `json:"pod_kills"`
}

type UniverseSystemData added in v0.2.0

type UniverseSystemData struct {
	System struct {
		SolarSystemID     int64    `json:"solar_system_id"`
		SystemName        string   `json:"system_name"`
		Security          *float64 `json:"security"`
		ConstellationID   int64    `json:"constellation_id"`
		ConstellationName string   `json:"constellation_name"`
		RegionID          int64    `json:"region_id"`
		RegionName        string   `json:"region_name"`
		SunTypeName       string   `json:"sun_type_name"`
	} `json:"system"`
	Celestials struct {
		Planets int64 `json:"planets"`
		Belts   int64 `json:"belts"`
	} `json:"celestials"`
	CelestialList []struct {
		ItemID   int64  `json:"item_id"`
		ItemName string `json:"item_name"`
		TypeName string `json:"type_name"`
		Category string `json:"category"`
	} `json:"celestialList"`
	Stations []struct {
		StationID       int64  `json:"station_id"`
		StationName     string `json:"station_name"`
		OperationName   string `json:"operation_name"`
		CorporationID   int64  `json:"corporation_id"`
		CorporationName string `json:"corporation_name"`
	} `json:"stations"`
	Structures []struct {
		StructureID int64  `json:"structure_id"`
		Name        string `json:"name"`
		TypeName    string `json:"type_name"`
		OwnerID     int64  `json:"owner_id"`
		OwnerName   string `json:"owner_name"`
		IsMarket    bool   `json:"is_market"`
	} `json:"structures"`
	Connections []struct {
		ToSolarSystemID int64    `json:"to_solar_system_id"`
		SystemName      string   `json:"system_name"`
		Security        *float64 `json:"security"`
		RegionID        int64    `json:"region_id"`
		IsRegional      bool     `json:"is_regional"`
	} `json:"connections"`
	Sovereignty        *UniverseSovereignty  `json:"sovereignty"`
	SovereigntyHistory []UniverseSovereignty `json:"sovereigntyHistory"`
	Stats              struct {
		Kills      int64   `json:"kills"`
		TotalValue float64 `json:"total_value"`
	} `json:"stats"`
	Activity struct {
		Latest  *UniverseSystemActivity  `json:"latest"`
		History []UniverseSystemActivity `json:"history"`
	} `json:"activity"`
}

type UniverseVariation added in v0.2.0

type UniverseVariation struct {
	ID            int64  `json:"type_id"`
	Name          string `json:"name"`
	MetaGroupName string `json:"meta_group_name"`
}

type ValuableKill added in v0.2.0

type ValuableKill struct {
	KillmailID            int64   `json:"killmail_id"`
	ShipTypeID            int64   `json:"ship_type_id"`
	ShipName              string  `json:"ship_name"`
	TotalValue            float64 `json:"total_value"`
	VictimCharacterName   string  `json:"victim_character_name"`
	VictimCorporationName string  `json:"victim_corporation_name"`
	VictimAllianceName    string  `json:"victim_alliance_name"`
}

type WarAlly added in v0.2.0

type WarAlly struct {
	ID           int64   `json:"id"`
	Name         string  `json:"name"`
	Type         string  `json:"type"`
	Kills        int64   `json:"kills"`
	Losses       int64   `json:"losses"`
	ISKDestroyed float64 `json:"isk_destroyed"`
	ISKLost      float64 `json:"isk_lost"`
}

type WarDetail added in v0.2.0

type WarDetail struct {
	WarID         int64         `json:"war_id"`
	Declared      string        `json:"declared"`
	Started       string        `json:"started"`
	Finished      string        `json:"finished"`
	Mutual        bool          `json:"mutual"`
	OpenForAllies bool          `json:"open_for_allies"`
	Aggressor     EntityWarSide `json:"aggressor"`
	Defender      EntityWarSide `json:"defender"`
	Allies        []WarAlly     `json:"allies"`
}

type WarDetailData added in v0.2.0

type WarDetailData struct {
	War   WarDetail      `json:"war"`
	Stats WarDetailStats `json:"stats"`
}

type WarDetailStats added in v0.2.0

type WarDetailStats struct {
	TotalKills int64        `json:"total_kills"`
	TotalValue float64      `json:"total_value"`
	TopShips   []WarTopShip `json:"top_ships"`
}

type WarDirectoryData added in v0.2.0

type WarDirectoryData struct {
	Wars  []EntityWarEntry `json:"wars"`
	Page  int              `json:"page"`
	Limit int              `json:"limit"`
}

The HTML directory and the public API use the same conflict handlers. Keeping the request host lets custom killboards retain their war scope.

type WarIntelData added in v0.2.0

type WarIntelData struct {
	Summary struct {
		Kills          int64   `json:"kills"`
		ISKDestroyed   float64 `json:"isk_destroyed"`
		Systems        int64   `json:"systems"`
		Constellations int64   `json:"constellations"`
		Regions        int64   `json:"regions"`
	} `json:"summary"`
	TopSystems          []WarIntelSystem    `json:"top_systems"`
	TopConstellations   []WarIntelLocation  `json:"top_constellations"`
	TopRegions          []WarIntelLocation  `json:"top_regions"`
	ShipsDestroyed      []WarIntelShip      `json:"ships_destroyed"`
	ShipsUsed           []WarIntelShip      `json:"ships_used"`
	ShipGroupsDestroyed []WarIntelShipGroup `json:"ship_groups_destroyed"`
	SecurityBreakdown   []WarIntelSecurity  `json:"security_breakdown"`
}

type WarIntelLocation added in v0.2.0

type WarIntelLocation struct {
	ConstellationID   int64   `json:"constellation_id"`
	ConstellationName string  `json:"constellation_name"`
	RegionID          int64   `json:"region_id"`
	RegionName        string  `json:"region_name"`
	Kills             int64   `json:"kills"`
	ISKDestroyed      float64 `json:"isk_destroyed"`
}

type WarIntelSecurity added in v0.2.0

type WarIntelSecurity struct {
	SecClass     string  `json:"sec_class"`
	Kills        int64   `json:"kills"`
	ISKDestroyed float64 `json:"isk_destroyed"`
}

type WarIntelShip added in v0.2.0

type WarIntelShip struct {
	ShipTypeID   int64   `json:"ship_type_id"`
	ShipName     string  `json:"ship_name"`
	GroupID      int64   `json:"group_id"`
	GroupName    string  `json:"group_name"`
	Count        int64   `json:"count"`
	ISKDestroyed float64 `json:"isk_destroyed"`
}

type WarIntelShipGroup added in v0.2.0

type WarIntelShipGroup struct {
	GroupID      int64   `json:"group_id"`
	GroupName    string  `json:"group_name"`
	Count        int64   `json:"count"`
	ISKDestroyed float64 `json:"isk_destroyed"`
}

type WarIntelSystem added in v0.2.0

type WarIntelSystem struct {
	SystemID     int64    `json:"system_id"`
	SystemName   string   `json:"system_name"`
	RegionName   string   `json:"region_name"`
	Security     *float64 `json:"security"`
	Kills        int64    `json:"kills"`
	ISKDestroyed float64  `json:"isk_destroyed"`
}

type WarLeaderboard added in v0.2.0

type WarLeaderboard struct {
	TopCharacters   []WarLeaderboardEntry `json:"topCharacters"`
	TopCorporations []WarLeaderboardEntry `json:"topCorporations"`
	TopAlliances    []WarLeaderboardEntry `json:"topAlliances"`
}

type WarLeaderboardEntry added in v0.2.0

type WarLeaderboardEntry struct {
	ID    int64  `json:"id"`
	Name  string `json:"name"`
	Kills int64  `json:"kills"`
	Side  string `json:"side"`
}

type WarMember added in v0.2.0

type WarMember struct {
	CharacterID     int64   `json:"character_id"`
	CharacterName   string  `json:"character_name"`
	CorporationID   int64   `json:"corporation_id"`
	CorporationName string  `json:"corporation_name"`
	AllianceID      int64   `json:"alliance_id"`
	AllianceName    string  `json:"alliance_name"`
	TopShipTypeID   int64   `json:"top_ship_type_id"`
	TopShipName     string  `json:"top_ship_name"`
	TopShipCount    int64   `json:"top_ship_count"`
	Kills           int64   `json:"kills"`
	Losses          int64   `json:"losses"`
	ISKDestroyed    float64 `json:"isk_destroyed"`
	ISKLost         float64 `json:"isk_lost"`
	Side            string  `json:"side"`
}

type WarMembersData added in v0.2.0

type WarMembersData struct {
	Members []WarMember `json:"members"`
	Count   int64       `json:"count"`
	Limit   int64       `json:"limit"`
}

type WarOverviewData added in v0.2.0

type WarOverviewData struct {
	ActiveWars        int64 `json:"activeWars"`
	FinishedWars      int64 `json:"finishedWars"`
	UpcomingWars      int64 `json:"upcomingWars"`
	EligibleCorps     int64 `json:"eligibleCorps"`
	EligibleAlliances int64 `json:"eligibleAlliances"`
}

type WarStatsData added in v0.2.0

type WarStatsData struct {
	Combined  WarLeaderboard `json:"combined"`
	Aggressor WarLeaderboard `json:"aggressor"`
	Defender  WarLeaderboard `json:"defender"`
	TopShips  []WarTopShip   `json:"topShips"`
}

type WarTopShip added in v0.2.0

type WarTopShip struct {
	ShipTypeID int64  `json:"ship_type_id"`
	ShipName   string `json:"ship_name"`
	Count      int64  `json:"count"`
}

Source Files

Jump to

Keyboard shortcuts

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