Files
prompt-generator/main.go
T

154 lines
4.4 KiB
Go
Raw Normal View History

package main
import (
"log"
"net/http"
"os"
"prompt-generator/internal/auth"
"prompt-generator/internal/config"
"prompt-generator/internal/db"
"prompt-generator/internal/handlers"
)
func main() {
// Load .env file if exists
loadEnvFile(".env")
cfg := config.Load()
// Initialize database
if err := db.Init(cfg); err != nil {
log.Fatalf("Failed to initialize database: %v", err)
}
// Auto migrate
if err := db.AutoMigrate(); err != nil {
log.Fatalf("Failed to migrate database: %v", err)
}
// Seed data
if err := db.SeedData(); err != nil {
log.Fatalf("Failed to seed data: %v", err)
}
// Initialize auth
auth.Init(cfg.SessionSecret)
// Initialize handlers
handlers.Init(cfg)
2026-06-26 15:08:12 +08:00
// Ensure prompts table exists for dev environments
db.EnsurePromptsTable()
// Load persisted settings from database
db.LoadSettings(cfg)
// Setup routes
mux := http.NewServeMux()
2026-06-26 15:08:12 +08:00
// Static files with SPA-style routing for HTML pages
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
// Map clean URLs to .html files
switch path {
case "/dashboard":
http.ServeFile(w, r, "frontend/dashboard.html")
return
case "/settings":
http.ServeFile(w, r, "frontend/settings.html")
return
}
// Default file server
fs := http.FileServer(http.Dir("frontend"))
fs.ServeHTTP(w, r)
})
// Auth routes (no auth required)
mux.HandleFunc("POST /api/auth/login", handlers.Login)
mux.HandleFunc("POST /api/auth/logout", handlers.Logout)
mux.HandleFunc("GET /api/auth/check", handlers.AuthCheck)
// Protected API routes
apiMux := http.NewServeMux()
apiMux.HandleFunc("GET /api/tags", handlers.GetTags)
apiMux.HandleFunc("POST /api/tags", handlers.CreateTag)
apiMux.HandleFunc("PUT /api/tags/{id}", handlers.UpdateTag)
apiMux.HandleFunc("DELETE /api/tags/{id}", handlers.DeleteTag)
apiMux.HandleFunc("POST /api/tags/{id}/options", handlers.CreateTagOption)
apiMux.HandleFunc("PUT /api/tag-options/{id}", handlers.UpdateTagOption)
apiMux.HandleFunc("DELETE /api/tag-options/{id}", handlers.DeleteTagOption)
apiMux.HandleFunc("GET /api/snippets", handlers.GetSnippets)
apiMux.HandleFunc("POST /api/snippets", handlers.CreateSnippet)
apiMux.HandleFunc("PUT /api/snippets/{id}", handlers.UpdateSnippet)
apiMux.HandleFunc("DELETE /api/snippets/{id}", handlers.DeleteSnippet)
apiMux.HandleFunc("GET /api/builder/sessions", handlers.GetBuilderSessions)
apiMux.HandleFunc("POST /api/builder/sessions", handlers.CreateBuilderSession)
apiMux.HandleFunc("GET /api/builder/sessions/{id}", handlers.GetBuilderSession)
apiMux.HandleFunc("PUT /api/builder/sessions/{id}", handlers.UpdateBuilderSession)
apiMux.HandleFunc("DELETE /api/builder/sessions/{id}", handlers.DeleteBuilderSession)
apiMux.HandleFunc("GET /api/claude/sessions", handlers.GetClaudeSessions)
apiMux.HandleFunc("GET /api/claude/sessions/{session_id}/prompts", handlers.GetClaudePrompts)
apiMux.HandleFunc("GET /api/claude/sessions/{session_id}/builder", handlers.GetBuilderSessionByClaudeSession)
apiMux.HandleFunc("GET /api/dashboard/projects", handlers.GetDashboardProjects)
apiMux.HandleFunc("GET /api/dashboard/projects/{name}/sessions", handlers.GetDashboardSessions)
apiMux.HandleFunc("GET /api/dashboard/prompts", handlers.GetDashboardPrompts)
apiMux.HandleFunc("POST /api/suggestions", handlers.GetSuggestions)
apiMux.HandleFunc("GET /api/settings", handlers.GetSettings)
apiMux.HandleFunc("PUT /api/settings", handlers.UpdateSettings)
// Wrap API routes with auth middleware
mux.Handle("/api/", auth.AuthMiddleware(apiMux))
log.Printf("Server starting on :%s", cfg.ServerPort)
if err := http.ListenAndServe(":"+cfg.ServerPort, mux); err != nil {
log.Fatalf("Server failed: %v", err)
}
}
func loadEnvFile(path string) {
data, err := os.ReadFile(path)
if err != nil {
return // .env file is optional
}
lines := splitLines(string(data))
for _, line := range lines {
if len(line) == 0 || line[0] == '#' {
continue
}
for i := 0; i < len(line); i++ {
if line[i] == '=' {
key := line[:i]
value := line[i+1:]
// Remove quotes
if len(value) >= 2 && (value[0] == '"' && value[len(value)-1] == '"') {
value = value[1 : len(value)-1]
}
os.Setenv(key, value)
break
}
}
}
}
func splitLines(s string) []string {
var lines []string
start := 0
for i := 0; i < len(s); i++ {
if s[i] == '\n' {
lines = append(lines, s[start:i])
start = i + 1
}
}
if start < len(s) {
lines = append(lines, s[start:])
}
return lines
}