-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
122 lines (96 loc) · 3.93 KB
/
main.go
File metadata and controls
122 lines (96 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package main
import (
"log/slog"
"net/http"
"os"
"time"
"knowledge-capsule/app/handlers"
"knowledge-capsule/app/middleware"
_ "knowledge-capsule/docs"
"knowledge-capsule/pkg/config"
"knowledge-capsule/pkg/db"
"knowledge-capsule/pkg/utils"
httpSwagger "github.com/swaggo/http-swagger"
)
// @title Knowledge Capsule
// @version 1.0
// @description Knowledge Capsule - knowledge management backend.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @description Enter your JWT token (or "Bearer <token>" for clarity). Get token from POST /api/auth/login.
// @BasePath /
func main() {
// Load env variables first (for log level)
cfg, err := config.Load()
if err != nil {
slog.Error("Failed to load environment variables", "error", err)
os.Exit(1)
}
// Set log level based on environment
var level slog.Level
if cfg.Env == "development" {
level = slog.LevelDebug
} else {
level = slog.LevelInfo
}
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: level})))
database, err := db.Open(cfg.DatabaseURL)
if err != nil {
slog.Error("Failed to connect to database", "error", err)
os.Exit(1)
}
handlers.InitStores(database)
if err := db.SeedSuperAdmin(database, cfg.SuperAdminEmail, cfg.SuperAdminPassword, cfg.SuperAdminName); err != nil {
slog.Error("Failed to seed superadmin", "error", err)
os.Exit(1)
}
handlers.InitChat(cfg.CORSOrigins)
mux := http.NewServeMux()
// Default routes
mux.HandleFunc("/", handlers.RootHandler)
mux.HandleFunc("/api", handlers.ApiRootHandler)
mux.HandleFunc("/health", handlers.HealthHandler)
mux.HandleFunc("/test-ws", handlers.TestChatHandler)
// Swagger
mux.HandleFunc("/docs/", httpSwagger.WrapHandler)
// Public routes
mux.HandleFunc("/api/auth/register", handlers.RegisterHandler)
mux.HandleFunc("/api/auth/login", handlers.LoginHandler)
// User routes
mux.Handle("/api/users", middleware.AuthMiddleware(middleware.RequireAdmin(http.HandlerFunc(handlers.ListUsers))))
mux.Handle("/api/users/", middleware.AuthMiddleware(http.HandlerFunc(handlers.UserHandler)))
// Admin routes
mux.Handle("/api/admin/search", middleware.AuthMiddleware(middleware.RequireAdmin(http.HandlerFunc(handlers.GlobalSearch))))
mux.Handle("/api/admin/admins", middleware.AuthMiddleware(middleware.RequireSuperAdmin(http.HandlerFunc(handlers.ListAdmins))))
mux.Handle("/api/admin/users/", middleware.AuthMiddleware(middleware.RequireSuperAdmin(http.HandlerFunc(handlers.AdminUsersHandler))))
// Protected routes
mux.Handle("/api/topics", middleware.AuthMiddleware(http.HandlerFunc(handlers.TopicHandler)))
mux.Handle("/api/topics/", middleware.AuthMiddleware(http.HandlerFunc(handlers.TopicByIDHandler)))
mux.Handle("/api/capsules", middleware.AuthMiddleware(http.HandlerFunc(handlers.CapsuleHandler)))
mux.Handle("/api/capsules/", middleware.AuthMiddleware(http.HandlerFunc(handlers.CapsuleByIDHandler)))
// Chat & File Upload
mux.Handle("/ws/chat", middleware.AuthMiddleware(http.HandlerFunc(handlers.ChatWebSocketHandler)))
mux.Handle("/api/upload", middleware.AuthMiddleware(http.HandlerFunc(handlers.UploadHandler)))
mux.Handle("/uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir("uploads"))))
// Wrap with CORS, logger, recover
handler := middleware.CORS(cfg.CORSOrigins)(middleware.Recover(middleware.Logger(mux)))
utils.InitJWTSecret(cfg.JWTSecret)
server := &http.Server{
Addr: ":" + cfg.Port,
Handler: handler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
slog.Info("Server starting", "env", cfg.Env, "port", cfg.Port)
if err := server.ListenAndServe(); err != nil {
slog.Error("Server failed", "error", err)
os.Exit(1)
}
}