Files
rikkei_simple_care/server/main.go
2026-06-30 10:39:29 +07:00

168 lines
6.9 KiB
Go

package main
import (
"log"
"os"
"server/internal/db"
"server/internal/handlers"
"server/internal/mail"
"server/internal/middleware"
"server/internal/qldt"
"server/internal/syncjobs"
internalWs "server/internal/websocket"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
gofiberWs "github.com/gofiber/websocket/v2"
"github.com/joho/godotenv"
)
func main() {
if err := godotenv.Load(); err != nil {
log.Println("Note: .env file not found or couldn't be loaded, using system environments.")
}
dbHost := getEnv("DB_HOST", "127.0.0.1")
dbPort := getEnv("DB_PORT", "3306")
dbUser := getEnv("DB_USER", "naruto")
dbPass := getEnv("DB_PASSWORD", "29121999aA@")
dbName := getEnv("DB_NAME", "simple_care")
qldtToken := getEnv("QLDT_TOKEN", "")
qldtBaseURL := getEnv("QLDT_BASE_URL", "https://apiportal.rikkei.edu.vn")
qldtOrigin := getEnv("QLDT_ORIGIN", "https://qldt.rikkei.edu.vn")
if qldtToken == "" {
log.Println("WARNING: QLDT_TOKEN is empty! Sync features will fail until QLDT_TOKEN is configured in environment.")
}
gormDB, err := db.ConnectDB(dbHost, dbPort, dbUser, dbPass, dbName)
if err != nil {
log.Fatalf("Database connection failed: %v", err)
}
if err := db.AutoMigrate(gormDB); err != nil {
log.Fatalf("Database migration failed: %v", err)
}
qldtClient := qldt.NewClient(qldtBaseURL, qldtOrigin)
classesJob := syncjobs.NewClassesSyncJob()
studentsJob := syncjobs.NewStudentsSyncJob()
mailer := mail.LoadConfigFromEnv()
app := fiber.New(fiber.Config{
AppName: "Simple Care Sync Backend",
})
app.Use(cors.New(cors.Config{
AllowOrigins: "*",
AllowHeaders: "Origin, Content-Type, Accept, Authorization",
AllowMethods: "GET, POST, PATCH, PUT, DELETE, OPTIONS",
}))
// WebSocket Upgrade Check
app.Use("/ws", func(c *fiber.Ctx) error {
if gofiberWs.IsWebSocketUpgrade(c) {
c.Locals("allowed", true)
return c.Next()
}
return fiber.ErrUpgradeRequired
})
// WebSocket Route
app.Get("/ws", gofiberWs.New(internalWs.WebSocketHandler(gormDB)))
api := app.Group("/api")
// Auth công khai (management)
api.Post("/auth/provision", handlers.ProvisionStaffHandler(gormDB, mailer))
api.Post("/auth/login", handlers.LoginStaffHandler(gormDB))
api.Post("/auth/forgot-password", handlers.ForgotPasswordHandler(gormDB, mailer))
api.Post("/auth/reset-password", handlers.ResetPasswordHandler(gormDB))
// Student client (không cần JWT staff)
api.Post("/student/sync-log", handlers.SyncStudentSessionLogHandler(gormDB))
api.Get("/student/status", handlers.GetStudentStatusHandler(gormDB))
api.Get("/student/wifi-policy", handlers.GetStudentWifiPolicyHandler(gormDB))
api.Post("/student/report-wifi", handlers.ReportWifiHandler(gormDB))
api.Post("/student/report-blocked-app", handlers.ReportBlockedAppHandler(gormDB))
api.Get("/student/chat/messages", handlers.StudentListChatHandler(gormDB))
api.Get("/student/chat/conversations", handlers.StudentListChatConversationsHandler(gormDB))
api.Post("/student/chat/messages", handlers.StudentSendChatHandler(gormDB))
// Health check (public)
api.Get("/health", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"ok": true})
})
// Management — yêu cầu đăng nhập staff
staff := api.Group("", middleware.RequireStaff())
staff.Get("/auth/me", handlers.MeStaffHandler(gormDB))
staff.Post("/auth/change-password", handlers.ChangePasswordHandler(gormDB))
staff.Get("/stats", handlers.GetStatsHandler(gormDB))
// Classes endpoints
staff.Get("/classes", handlers.ListClassesHandler(gormDB))
staff.Get("/classes/schedules", handlers.ListActiveSchedulesHandler(gormDB))
staff.Get("/classes/:rkId", handlers.GetClassHandler(gormDB))
staff.Patch("/classes/:rkId/studying", handlers.PatchClassStudyingHandler(gormDB))
staff.Get("/classes/:rkId/students", handlers.ListClassStudentsHandler(gormDB))
// Students endpoints
staff.Get("/students", handlers.ListAllStudentsHandler(gormDB))
// Sync endpoints
staff.Post("/sync/classes/start", handlers.StartClassesSyncHandler(gormDB, qldtClient, classesJob, qldtToken))
staff.Get("/sync/classes/status", handlers.GetClassesSyncStatusHandler(classesJob))
staff.Post("/sync/students/start", handlers.StartStudentsSyncHandler(gormDB, qldtClient, studentsJob, qldtToken))
staff.Get("/sync/students/status", handlers.GetStudentsSyncStatusHandler(studentsJob))
// Learning Management endpoints
staff.Get("/classes/:rkId/schedule", handlers.GetClassScheduleHandler(gormDB))
staff.Post("/classes/:rkId/schedule", handlers.SaveClassScheduleHandler(gormDB))
staff.Delete("/classes/:rkId/schedule", handlers.DeleteClassScheduleHandler(gormDB))
staff.Get("/classes/:rkId/allowed-apps", handlers.GetAllowedAppsHandler(gormDB))
staff.Post("/classes/:rkId/allowed-apps", handlers.SaveAllowedAppsHandler(gormDB))
staff.Get("/app-pool", handlers.ListAppPoolHandler(gormDB))
staff.Get("/wifi-pool", handlers.ListWifiPoolHandler(gormDB))
staff.Get("/network/accepted-wifis", handlers.ListAcceptedWifisHandler(gormDB))
staff.Post("/network/accepted-wifis", handlers.SaveAcceptedWifisHandler(gormDB))
staff.Post("/network/accepted-wifis/add", handlers.AddAcceptedWifiHandler(gormDB))
staff.Delete("/network/accepted-wifis/:id", handlers.DeleteAcceptedWifiHandler(gormDB))
staff.Get("/classes/:rkId/session-logs", handlers.ListClassSessionLogsHandler(gormDB))
staff.Get("/classes/:rkId/online-students", handlers.GetOnlineStudentsHandler(gormDB))
staff.Get("/classes/:rkId/courses", handlers.GetClassCoursesHandler(gormDB, qldtClient, qldtToken))
staff.Post("/classes/:rkId/schedule/apply-template", handlers.ApplyScheduleTemplateHandler(gormDB))
staff.Get("/classes/:rkId/attendance", handlers.GetClassAttendanceHandler(gormDB))
staff.Get("/classes/:rkId/attendance/shifts", handlers.ListAttendanceShiftsHandler(gormDB))
staff.Put("/classes/:rkId/attendance/status", handlers.UpdateAttendanceStatusHandler(gormDB))
staff.Post("/classes/:rkId/attendance/push-qldt", handlers.PushAttendanceToQLDTHandler(gormDB, qldtClient, qldtToken))
// Chat & quản lý tài khoản
staff.Get("/chat/students", handlers.SearchChatStudentsHandler(gormDB))
staff.Get("/chat/conversations", handlers.ListChatConversationsHandler(gormDB))
staff.Get("/chat/messages/:studentRkId", handlers.ListChatMessagesHandler(gormDB))
staff.Post("/chat/messages", handlers.SendChatMessageHandler(gormDB))
staff.Get("/admin/email-domains", handlers.ListEmailDomainsHandler(gormDB))
staff.Post("/admin/email-domains", handlers.AddEmailDomainHandler(gormDB))
staff.Delete("/admin/email-domains/:id", handlers.DeleteEmailDomainHandler(gormDB))
staff.Get("/admin/staff", handlers.ListStaffHandler(gormDB))
port := getEnv("PORT", "8080")
log.Printf("Server starting on port %s...", port)
if err := app.Listen(":" + port); err != nil {
log.Fatalf("Failed to start web server: %v", err)
}
}
func getEnv(key, defaultVal string) string {
if val := os.Getenv(key); val != "" {
return val
}
return defaultVal
}