feat: add Citations and WatchlistChat components, integrate with API
- Implemented Citations component to display citation data. - Created WatchlistDrawer and ChatSidebar components for managing watchlists and AI chat functionality. - Integrated API calls for watchlist management and chat interactions. - Updated index.tsx to include new components in the main application layout. - Added API client in lib/api.ts for structured API interactions. - Developed Alerts, Dashboard, Portfolio, Routines, Screener, and Report pages with relevant data fetching and UI components. - Introduced styles in tokens.css for consistent theming across the application. - Configured TypeScript and Vite for project setup and development.
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
// Package config loads FlowSight runtime configuration from the environment.
|
||||
// Secrets come only from env vars, never from files.
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
// Config holds all runtime settings for the FlowSight backend.
|
||||
type Config struct {
|
||||
Port string
|
||||
SectorsAPIKey string
|
||||
SectorsBaseURL string
|
||||
DBPath string
|
||||
RedisURL string
|
||||
DemoUserKey string
|
||||
LLMBaseURL string
|
||||
LLMAPIKey string
|
||||
LLMTriage string
|
||||
LLMSynth string
|
||||
TelegramBotToken string
|
||||
TelegramChatID string
|
||||
DiscordWebhookURL string
|
||||
CreditCapPerCycle int
|
||||
Watchlist []string
|
||||
}
|
||||
|
||||
// HasSectorsKey reports whether live Sectors API calls are possible.
|
||||
// Without a key the server runs in offline/seed mode.
|
||||
func (c Config) HasSectorsKey() bool { return strings.TrimSpace(c.SectorsAPIKey) != "" }
|
||||
|
||||
// HasLLM reports whether LLM-backed refinement is available.
|
||||
func (c Config) HasLLM() bool {
|
||||
return strings.TrimSpace(c.LLMBaseURL) != "" && strings.TrimSpace(c.LLMAPIKey) != ""
|
||||
}
|
||||
|
||||
func getenv(key, def string) string {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
return v
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func getenvInt(key string, def int) int {
|
||||
v := os.Getenv(key)
|
||||
if v == "" {
|
||||
return def
|
||||
}
|
||||
n, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return def
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Load reads configuration from the environment (.env supported for dev).
|
||||
func Load() Config {
|
||||
_ = godotenv.Load()
|
||||
watch := getenv("WATCHLIST", "BBCA,BBRI,BMRI,TLKM,ASII")
|
||||
tickers := make([]string, 0, 8)
|
||||
for _, t := range strings.Split(watch, ",") {
|
||||
if t = strings.ToUpper(strings.TrimSpace(t)); t != "" {
|
||||
tickers = append(tickers, t)
|
||||
}
|
||||
}
|
||||
return Config{
|
||||
Port: getenv("PORT", "8080"),
|
||||
SectorsAPIKey: os.Getenv("SECTORS_API_KEY"),
|
||||
SectorsBaseURL: getenv("SECTORS_BASE_URL", "https://api.sectors.app/v2/"),
|
||||
DBPath: getenv("DB_PATH", "data/flowsight.db"),
|
||||
RedisURL: os.Getenv("REDIS_URL"),
|
||||
DemoUserKey: getenv("DEMO_USER_KEY", "demo"),
|
||||
LLMBaseURL: os.Getenv("LLM_BASE_URL"),
|
||||
LLMAPIKey: os.Getenv("LLM_API_KEY"),
|
||||
LLMTriage: getenv("LLM_MODEL_TRIAGE", "gpt-4o-mini"),
|
||||
LLMSynth: getenv("LLM_MODEL_SYNTH", "gpt-4o"),
|
||||
TelegramBotToken: os.Getenv("TELEGRAM_BOT_TOKEN"),
|
||||
TelegramChatID: os.Getenv("TELEGRAM_CHAT_ID"),
|
||||
DiscordWebhookURL: os.Getenv("DISCORD_WEBHOOK_URL"),
|
||||
CreditCapPerCycle: getenvInt("CREDIT_CAP_PER_CYCLE", 120),
|
||||
Watchlist: tickers,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user