feat: Go backend, enhanced search, new widgets, Docker deploy
Major changes: - Add Go backend (backend/) with microservices architecture - Enhanced master-agents-svc: reranker, content-classifier, stealth-crawler, proxy-manager, media-search, fastClassifier, language detection - New web-svc widgets: KnowledgeCard, ProductCard, ProfileCard, VideoCard, UnifiedCard, CardGallery, InlineImageGallery, SourcesPanel, RelatedQuestions - Improved discover-svc with discover-db integration - Docker deployment improvements (Caddyfile, vendor.sh, BUILD.md) - Library-svc: project_id schema migration - Remove deprecated finance-svc and travel-svc - Localization improvements across services Made-with: Cursor
This commit is contained in:
139
backend/cmd/finance-heatmap-svc/main.go
Normal file
139
backend/cmd/finance-heatmap-svc/main.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/gooseek/backend/internal/finance"
|
||||
)
|
||||
|
||||
func main() {
|
||||
heatmapSvc := finance.NewHeatmapService(finance.HeatmapConfig{
|
||||
CacheTTL: 5 * time.Minute,
|
||||
RefreshInterval: time.Minute,
|
||||
})
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
ReadTimeout: 30 * time.Second,
|
||||
WriteTimeout: 30 * time.Second,
|
||||
})
|
||||
|
||||
app.Use(logger.New())
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Get("/health", func(c *fiber.Ctx) error {
|
||||
return c.JSON(fiber.Map{"status": "ok"})
|
||||
})
|
||||
|
||||
app.Get("/api/v1/heatmap/:market", func(c *fiber.Ctx) error {
|
||||
market := c.Params("market")
|
||||
timeRange := c.Query("range", "1d")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
heatmap, err := heatmapSvc.GetMarketHeatmap(ctx, market, timeRange)
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
return c.JSON(heatmap)
|
||||
})
|
||||
|
||||
app.Get("/api/v1/heatmap/:market/treemap", func(c *fiber.Ctx) error {
|
||||
market := c.Params("market")
|
||||
timeRange := c.Query("range", "1d")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
heatmap, err := heatmapSvc.GetMarketHeatmap(ctx, market, timeRange)
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
treemapData := heatmapSvc.GenerateTreemapData(heatmap)
|
||||
return c.JSON(treemapData)
|
||||
})
|
||||
|
||||
app.Get("/api/v1/heatmap/:market/grid", func(c *fiber.Ctx) error {
|
||||
market := c.Params("market")
|
||||
timeRange := c.Query("range", "1d")
|
||||
rows := c.QueryInt("rows", 5)
|
||||
cols := c.QueryInt("cols", 10)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
heatmap, err := heatmapSvc.GetMarketHeatmap(ctx, market, timeRange)
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
gridData := heatmapSvc.GenerateGridData(heatmap, rows, cols)
|
||||
return c.JSON(fiber.Map{"grid": gridData, "rows": rows, "cols": cols})
|
||||
})
|
||||
|
||||
app.Get("/api/v1/heatmap/:market/sector/:sector", func(c *fiber.Ctx) error {
|
||||
market := c.Params("market")
|
||||
sector := c.Params("sector")
|
||||
timeRange := c.Query("range", "1d")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
heatmap, err := heatmapSvc.GetSectorHeatmap(ctx, market, sector, timeRange)
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
return c.JSON(heatmap)
|
||||
})
|
||||
|
||||
app.Get("/api/v1/movers/:market", func(c *fiber.Ctx) error {
|
||||
market := c.Params("market")
|
||||
count := c.QueryInt("count", 10)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
movers, err := heatmapSvc.GetTopMovers(ctx, market, count)
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
return c.JSON(movers)
|
||||
})
|
||||
|
||||
app.Get("/api/v1/markets", func(c *fiber.Ctx) error {
|
||||
markets := []map[string]interface{}{
|
||||
{"id": "sp500", "name": "S&P 500", "region": "us"},
|
||||
{"id": "nasdaq", "name": "NASDAQ", "region": "us"},
|
||||
{"id": "dow", "name": "Dow Jones", "region": "us"},
|
||||
{"id": "moex", "name": "MOEX", "region": "ru"},
|
||||
{"id": "crypto", "name": "Cryptocurrency", "region": "global"},
|
||||
{"id": "forex", "name": "Forex", "region": "global"},
|
||||
}
|
||||
return c.JSON(fiber.Map{"markets": markets})
|
||||
})
|
||||
|
||||
port := getEnvInt("PORT", 3033)
|
||||
log.Printf("finance-heatmap-svc listening on :%d", port)
|
||||
log.Fatal(app.Listen(fmt.Sprintf(":%d", port)))
|
||||
}
|
||||
|
||||
func getEnvInt(key string, defaultValue int) int {
|
||||
if val := os.Getenv(key); val != "" {
|
||||
var result int
|
||||
if _, err := fmt.Sscanf(val, "%d", &result); err == nil {
|
||||
return result
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
Reference in New Issue
Block a user