This commit is contained in:
2026-10-05 07:40:34 +08:00
parent 5a7ac2e5d9
commit d13088bfd5
22 changed files with 1369 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
package main
import (
"context"
"io/fs"
"log"
"net/http"
"os"
"nestly/internal/auth"
"nestly/internal/handlers"
"nestly/internal/models"
"nestly/internal/storage"
"nestly/internal/templates"
"nestly/web"
)
const demoEmail = "demo@nestly.test"
func envOr(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}
func main() {
port := envOr("PORT", "3000")
dsn := envOr("DB_DSN", "nestly.db")
secret := os.Getenv("SESSION_SECRET")
if secret == "" {
secret = "nestly-dev-secret"
log.Println("警告:未設定 SESSION_SECRET,使用開發用預設值,正式環境務必指定")
}
ctx := context.Background()
db, err := storage.Open(dsn)
if err != nil {
log.Fatal(err)
}
accounts := models.NewAccountStore(db)
if err := accounts.AutoMigrate(ctx); err != nil {
log.Fatal(err)
}
seedDemoAccount(ctx, accounts)
templateFS, err := fs.Sub(web.TemplatesFS, "templates")
if err != nil {
log.Fatal(err)
}
engine, err := templates.New(templateFS)
if err != nil {
log.Fatal(err)
}
router := handlers.NewRouter(handlers.Dependencies{
Templates: engine,
Accounts: accounts,
Sessions: auth.NewSessionManager(secret, os.Getenv("COOKIE_SECURE") == "true"),
})
log.Printf("Nestly 啟動於 http://localhost:%s", port)
if err := http.ListenAndServe(":"+port, router); err != nil {
log.Fatal(err)
}
}
// seedDemoAccount 於資料庫無此帳號時建立示範帳號,方便本地試用登入流程。
func seedDemoAccount(ctx context.Context, accounts *models.AccountStore) {
if _, err := accounts.FindByEmail(ctx, demoEmail); err == nil {
return
} else if err != models.ErrNotFound {
log.Fatal(err)
}
acct := &models.Account{Email: demoEmail, Name: "示範帳號", Role: models.RoleMember}
if err := acct.SetPassword("nestly1234"); err != nil {
log.Fatal(err)
}
if err := accounts.Create(ctx, acct); err != nil {
log.Fatal(err)
}
log.Printf("已建立示範帳號 %s(密碼:nestly1234)", demoEmail)
}