package server import ( "database/sql" "encoding/json" "net/http" ) type insiderTradeRow struct { ID int `json:"id"` Ticker string `json:"ticker"` InsiderName string `json:"insider_name"` InsiderTitle string `json:"insider_title"` TransactionCode string `json:"transaction_code"` Shares float64 `json:"shares"` Price float64 `json:"price"` TotalValue float64 `json:"total_value"` TransactionDate string `json:"transaction_date"` FilingURL string `json:"filing_url"` } func (s *Server) handleGetInsiderTrades(w http.ResponseWriter, r *http.Request) { ticker := r.URL.Query().Get("ticker") base := ` SELECT id, ticker, COALESCE(insider_name,''), COALESCE(insider_title,''), COALESCE(transaction_code,''), COALESCE(shares,0), COALESCE(price,0), COALESCE(total_value,0), COALESCE(transaction_date,''), COALESCE(filing_url,'') FROM insider_trades` var rows *sql.Rows var err error if ticker != "" { rows, err = s.db.Query(base+` WHERE ticker = ? ORDER BY transaction_date DESC LIMIT 100`, ticker) } else { rows, err = s.db.Query(base + ` ORDER BY transaction_date DESC LIMIT 200`) } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer rows.Close() trades := []insiderTradeRow{} for rows.Next() { var t insiderTradeRow if err := rows.Scan( &t.ID, &t.Ticker, &t.InsiderName, &t.InsiderTitle, &t.TransactionCode, &t.Shares, &t.Price, &t.TotalValue, &t.TransactionDate, &t.FilingURL, ); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } trades = append(trades, t) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(trades) } func (s *Server) handleSyncInsider(w http.ResponseWriter, r *http.Request) { go func() { s.edgarPoller.Sync() }() w.Header().Set("Content-Type", "application/json") w.Write([]byte(`{"status":"syncing"}`)) }