Return some killmails with statistics

This commit is contained in:
2026-01-06 11:34:45 +01:00
parent c48e101ccb
commit 5fbb518bde
3 changed files with 49 additions and 8 deletions

18
api.go
View File

@@ -15,10 +15,11 @@ import (
)
type APIStatisticsRequest struct {
Ship *int64 `json:"ship,omitempty"`
Systems []int64 `json:"systems,omitempty"`
Modules []int64 `json:"modules,omitempty"`
Groups []int64 `json:"groups,omitempty"`
Ship *int64 `json:"ship,omitempty"`
Systems []int64 `json:"systems,omitempty"`
Modules []int64 `json:"modules,omitempty"`
Groups []int64 `json:"groups,omitempty"`
KillmailLimit *int `json:"killmailLimit,omitempty"`
}
type APIItemCount struct {
@@ -35,6 +36,7 @@ type APIFitStatistics struct {
LowSlotModules []APIItemCount `json:"lowSlotModules"`
Rigs []APIItemCount `json:"rigs"`
Drones []APIItemCount `json:"drones"`
KillmailIDs []int64 `json:"killmailIds,omitempty"`
}
type APISearchResult struct {
@@ -80,6 +82,7 @@ func convertFitStatistics(stats *FitStatistics) *APIFitStatistics {
LowSlotModules: convertModuleMapToItemCounts(stats.LowSlotModules),
Rigs: convertModuleMapToItemCounts(stats.Rigs),
Drones: convertModuleMapToItemCounts(stats.Drones),
KillmailIDs: stats.KillmailIDs,
}
return api
}
@@ -142,6 +145,13 @@ func handleStatistics(w http.ResponseWriter, r *http.Request) {
if len(params.Groups) > 0 {
flog.Debug("Groups filter: %d groups", len(params.Groups))
}
// Killmail limit defaults to 20 when not provided or invalid
if req.KillmailLimit != nil && *req.KillmailLimit > 0 {
params.KillmailLimit = *req.KillmailLimit
} else {
params.KillmailLimit = 20
}
flog.Debug("Killmail limit: %d", params.KillmailLimit)
db, err := GetDB()
if err != nil {

21
db.go
View File

@@ -18,10 +18,11 @@ import (
)
type QueryParams struct {
Ship int64
Systems []int64
Modules []int64
Groups []int64
Ship int64
Systems []int64
Modules []int64
Groups []int64
KillmailLimit int
}
// CacheEntry stores both statistics (JSON) and images (blobs) in unified cache
@@ -48,6 +49,7 @@ type FitStatistics struct {
LowSlotModules map[int32]ModuleStats // typeID -> {Count, Percentage}
Rigs map[int32]ModuleStats // typeID -> {Count, Percentage}
Drones map[int32]ModuleStats // typeID -> {Count, Percentage}
KillmailIDs []int64
}
type SystemStats struct {
@@ -512,6 +514,7 @@ func (db *DBWrapper) QueryFits(params QueryParams) (*FitStatistics, error) {
LowSlotModules: make(map[int32]ModuleStats),
Rigs: make(map[int32]ModuleStats),
Drones: make(map[int32]ModuleStats),
KillmailIDs: limitKillmails(killmailIDs, params.KillmailLimit),
}
if totalKillmails == 0 {
@@ -944,3 +947,13 @@ func min(a, b int) int {
}
return b
}
func limitKillmails(ids []int64, limit int) []int64 {
if limit <= 0 || len(ids) == 0 {
return nil
}
if limit > len(ids) {
limit = len(ids)
}
return ids[:limit]
}

View File

@@ -128,6 +128,24 @@ func TestQueryFitsModuleFilterKeepsOtherModulesAndSlots(t *testing.T) {
assert.Greater(t, otherSlots, 0, "other slot categories should remain populated")
}
func TestQueryFitsReturnsKillmailIDsWithLimit(t *testing.T) {
dbi, err := GetDB()
require.NoError(t, err)
db := dbi.(*DBWrapper)
shipID := int64(32872)
moduleID := int64(16433)
limit := 5
stats, err := db.QueryFits(QueryParams{Ship: shipID, Modules: []int64{moduleID}, KillmailLimit: limit})
require.NoError(t, err)
require.Greater(t, stats.TotalKillmails, int64(0))
require.NotNil(t, stats.KillmailIDs)
assert.LessOrEqual(t, len(stats.KillmailIDs), limit)
assert.Greater(t, len(stats.KillmailIDs), 0)
}
func pickTopSystemID(stats *FitStatistics) int64 {
var bestID int64
var bestCount int64