feat: expose file attachment stats as item properties (#37)

Add file_count and files_total_size to item API responses, computed
via batch query on item_files table (no migration needed).

- Add BatchGetFileStats() to audit_queries.go (follows BatchCheckBOM pattern)
- Add file stats to ItemResponse, HandleListItems, HandleGetItem, HandleGetItemByUUID
- Add 'Files' column to ItemTable (default visible in vertical mode)
- Add has_files computed field to audit completeness scoring (weight 1 for manufactured)
This commit is contained in:
Forbes
2026-02-08 19:25:46 -06:00
parent 9be6f45f09
commit 50985ed805
5 changed files with 118 additions and 3 deletions

View File

@@ -260,6 +260,8 @@ type ItemResponse struct {
LongDescription *string `json:"long_description,omitempty"`
StandardCost *float64 `json:"standard_cost,omitempty"`
ThumbnailKey *string `json:"thumbnail_key,omitempty"`
FileCount int `json:"file_count"`
FilesTotalSize int64 `json:"files_total_size"`
Properties map[string]any `json:"properties,omitempty"`
}
@@ -304,9 +306,20 @@ func (s *Server) HandleListItems(w http.ResponseWriter, r *http.Request) {
return
}
// Batch-fetch file attachment stats
ids := make([]string, len(items))
for i, item := range items {
ids[i] = item.ID
}
fileStats, _ := s.items.BatchGetFileStats(ctx, ids)
response := make([]ItemResponse, len(items))
for i, item := range items {
response[i] = itemToResponse(item)
if fs, ok := fileStats[item.ID]; ok {
response[i].FileCount = fs.Count
response[i].FilesTotalSize = fs.TotalSize
}
}
writeJSON(w, http.StatusOK, response)
@@ -482,7 +495,15 @@ func (s *Server) HandleGetItemByUUID(w http.ResponseWriter, r *http.Request) {
return
}
writeJSON(w, http.StatusOK, itemToResponse(item))
response := itemToResponse(item)
if fileStats, err := s.items.BatchGetFileStats(ctx, []string{item.ID}); err == nil {
if fs, ok := fileStats[item.ID]; ok {
response.FileCount = fs.Count
response.FilesTotalSize = fs.TotalSize
}
}
writeJSON(w, http.StatusOK, response)
}
// HandleGetItem retrieves an item by part number.
@@ -504,6 +525,14 @@ func (s *Server) HandleGetItem(w http.ResponseWriter, r *http.Request) {
response := itemToResponse(item)
// File attachment stats
if fileStats, err := s.items.BatchGetFileStats(ctx, []string{item.ID}); err == nil {
if fs, ok := fileStats[item.ID]; ok {
response.FileCount = fs.Count
response.FilesTotalSize = fs.TotalSize
}
}
// Include properties from current revision if requested
if r.URL.Query().Get("include") == "properties" {
revisions, err := s.items.GetRevisions(ctx, item.ID)