api: add /api/currencies endpoint for currency dropdown
Implements currency API per issue #11 requirements: - Returns top 10 currencies (USD, EUR, GBP, JPY, CAD, AUD, CHF, SEK, NOK, NZD) - Returns all remaining active currencies alphabetically - Queries corporate.db currencies table - Proper error handling with unique error codes (ERR-ADMIN-001, ERR-ADMIN-002) - CORS enabled for frontend access fixes #11 Author: Emma <emma-20250409-001>
This commit is contained in:
parent
fe9f98a69e
commit
12824ddbef
|
|
@ -1104,6 +1104,75 @@ Entries:
|
|||
w.Write([]byte(`{"ok":true}`))
|
||||
})
|
||||
|
||||
// Currencies API — returns top 10 + all currencies for pricing display
|
||||
http.HandleFunc("/api/currencies", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
|
||||
if corpDB == nil {
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"error": "ERR-ADMIN-001: Currency data unavailable — corporate DB not connected",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Top currencies to display first
|
||||
topCodes := []string{"USD", "EUR", "GBP", "JPY", "CAD", "AUD", "CHF", "SEK", "NOK", "NZD"}
|
||||
topMap := make(map[string]bool)
|
||||
for _, code := range topCodes {
|
||||
topMap[code] = true
|
||||
}
|
||||
|
||||
rows, err := corpDB.Query(`SELECT code, name, symbol, symbol_position FROM currencies WHERE is_active = 1 ORDER BY code`)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"error": "ERR-ADMIN-002: Failed to query currencies — " + err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
type Currency struct {
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
Symbol string `json:"symbol"`
|
||||
SymbolPosition string `json:"symbol_position"`
|
||||
}
|
||||
|
||||
var top []Currency
|
||||
var all []Currency
|
||||
|
||||
for rows.Next() {
|
||||
var c Currency
|
||||
if err := rows.Scan(&c.Code, &c.Name, &c.Symbol, &c.SymbolPosition); err != nil {
|
||||
continue // Skip malformed rows
|
||||
}
|
||||
if topMap[c.Code] {
|
||||
top = append(top, c)
|
||||
} else {
|
||||
all = append(all, c)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure top currencies are in the defined order
|
||||
orderedTop := make([]Currency, 0, len(topCodes))
|
||||
for _, code := range topCodes {
|
||||
for _, c := range top {
|
||||
if c.Code == code {
|
||||
orderedTop = append(orderedTop, c)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"top": orderedTop,
|
||||
"all": all,
|
||||
})
|
||||
})
|
||||
|
||||
// NOC API — latest telemetry per node
|
||||
nocPin := func(r *http.Request) bool { return r.URL.Query().Get("pin") == "250365" }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue