A community based topic aggregation platform built on atproto
1package main 2 3import ( 4 "database/sql" 5 "fmt" 6 "log" 7 "net/http" 8 "os" 9 10 "github.com/go-chi/chi/v5" 11 "github.com/go-chi/chi/v5/middleware" 12 _ "github.com/lib/pq" 13 "github.com/pressly/goose/v3" 14 "gorm.io/driver/postgres" 15 "gorm.io/gorm" 16 17 "Coves/internal/api/routes" 18 "Coves/internal/atproto/carstore" 19 "Coves/internal/core/repository" 20 "Coves/internal/core/users" 21 postgresRepo "Coves/internal/db/postgres" 22) 23 24func main() { 25 dbURL := os.Getenv("DATABASE_URL") 26 if dbURL == "" { 27 dbURL = "postgres://postgres:password@localhost:5432/coves?sslmode=disable" 28 } 29 30 db, err := sql.Open("postgres", dbURL) 31 if err != nil { 32 log.Fatal("Failed to connect to database:", err) 33 } 34 defer db.Close() 35 36 if err := db.Ping(); err != nil { 37 log.Fatal("Failed to ping database:", err) 38 } 39 40 if err := goose.SetDialect("postgres"); err != nil { 41 log.Fatal("Failed to set goose dialect:", err) 42 } 43 44 if err := goose.Up(db, "internal/db/migrations"); err != nil { 45 log.Fatal("Failed to run migrations:", err) 46 } 47 48 r := chi.NewRouter() 49 50 r.Use(middleware.Logger) 51 r.Use(middleware.Recoverer) 52 r.Use(middleware.RequestID) 53 54 // Initialize GORM 55 gormDB, err := gorm.Open(postgres.New(postgres.Config{ 56 Conn: db, 57 }), &gorm.Config{ 58 DisableForeignKeyConstraintWhenMigrating: true, 59 PrepareStmt: false, 60 }) 61 if err != nil { 62 log.Fatal("Failed to initialize GORM:", err) 63 } 64 65 // Initialize repositories 66 userRepo := postgresRepo.NewUserRepository(db) 67 _ = users.NewUserService(userRepo) // TODO: Use when UserRoutes is fixed 68 69 // Initialize carstore for ATProto repository storage 70 carDirs := []string{"./data/carstore"} 71 repoStore, err := carstore.NewRepoStore(gormDB, carDirs) 72 if err != nil { 73 log.Fatal("Failed to initialize repo store:", err) 74 } 75 76 repositoryRepo := postgresRepo.NewRepositoryRepo(db) 77 repositoryService := repository.NewService(repositoryRepo, repoStore) 78 79 // Mount routes 80 // TODO: Fix UserRoutes to accept *UserService 81 // r.Mount("/api/users", routes.UserRoutes(userService)) 82 r.Mount("/", routes.RepositoryRoutes(repositoryService)) 83 84 r.Get("/health", func(w http.ResponseWriter, r *http.Request) { 85 w.WriteHeader(http.StatusOK) 86 w.Write([]byte("OK")) 87 }) 88 89 port := os.Getenv("PORT") 90 if port == "" { 91 port = "8080" 92 } 93 94 fmt.Printf("Server starting on port %s\n", port) 95 log.Fatal(http.ListenAndServe(":"+port, r)) 96}