feat: initialize project skeleton with Go backend, database, and config
- Go module with standard library + gorilla/sessions + mysql driver - Config: env-based configuration with .env file support - Database: MySQL connection with auto-migration for 6 tables - Seed data: 12 system tags with options, 8 system snippets - Auth: session cookie middleware - Handlers: auth, tags, snippets, builder, claude, dashboard, suggestions, settings - LLM: OpenAI-compatible client with 30s timeout - Docker: Dockerfile + docker-compose.yml - .env.example with all configuration options Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
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)
|
||||
|
||||
// Setup routes
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// Static files (frontend)
|
||||
fs := http.FileServer(http.Dir("frontend"))
|
||||
mux.Handle("/", fs)
|
||||
|
||||
// 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/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
|
||||
}
|
||||
Reference in New Issue
Block a user