Add workspace management and isolated worktree environments

This commit is contained in:
Jiayuan Zhang 2026-03-23 18:12:11 +08:00
parent e9555b8a22
commit 81e64e9fce
32 changed files with 1462 additions and 200 deletions

View file

@ -59,7 +59,8 @@ func TestMain(m *testing.M) {
hub := realtime.NewHub()
go hub.Run()
router := NewRouter(queries, hub)
_ = queries
router := NewRouter(pool, hub)
testServer = httptest.NewServer(router)
defer testServer.Close()

View file

@ -12,7 +12,6 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
"github.com/multica-ai/multica/server/internal/realtime"
db "github.com/multica-ai/multica/server/pkg/db/generated"
)
func main() {
@ -39,11 +38,10 @@ func main() {
}
log.Println("Connected to database")
queries := db.New(pool)
hub := realtime.NewHub()
go hub.Run()
r := NewRouter(queries, hub)
r := NewRouter(pool, hub)
srv := &http.Server{
Addr: ":" + port,

View file

@ -2,10 +2,13 @@ package main
import (
"net/http"
"os"
"strings"
"github.com/go-chi/chi/v5"
chimw "github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/multica-ai/multica/server/internal/handler"
"github.com/multica-ai/multica/server/internal/middleware"
@ -13,9 +16,33 @@ import (
db "github.com/multica-ai/multica/server/pkg/db/generated"
)
func allowedOrigins() []string {
raw := strings.TrimSpace(os.Getenv("CORS_ALLOWED_ORIGINS"))
if raw == "" {
raw = strings.TrimSpace(os.Getenv("FRONTEND_ORIGIN"))
}
if raw == "" {
return []string{"http://localhost:3000"}
}
parts := strings.Split(raw, ",")
origins := make([]string, 0, len(parts))
for _, part := range parts {
origin := strings.TrimSpace(part)
if origin != "" {
origins = append(origins, origin)
}
}
if len(origins) == 0 {
return []string{"http://localhost:3000"}
}
return origins
}
// NewRouter creates the fully-configured Chi router with all middleware and routes.
func NewRouter(queries *db.Queries, hub *realtime.Hub) chi.Router {
h := handler.New(queries, hub)
func NewRouter(pool *pgxpool.Pool, hub *realtime.Hub) chi.Router {
queries := db.New(pool)
h := handler.New(queries, pool, hub)
r := chi.NewRouter()
@ -24,7 +51,7 @@ func NewRouter(queries *db.Queries, hub *realtime.Hub) chi.Router {
r.Use(chimw.Recoverer)
r.Use(chimw.RequestID)
r.Use(cors.Handler(cors.Options{
AllowedOrigins: []string{"http://localhost:3000"},
AllowedOrigins: allowedOrigins(),
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-Workspace-ID"},
AllowCredentials: true,
@ -51,6 +78,7 @@ func NewRouter(queries *db.Queries, hub *realtime.Hub) chi.Router {
// Auth
r.Get("/api/me", h.GetMe)
r.Patch("/api/me", h.UpdateMe)
// Issues
r.Route("/api/issues", func(r chi.Router) {
@ -89,7 +117,15 @@ func NewRouter(queries *db.Queries, hub *realtime.Hub) chi.Router {
r.Route("/{id}", func(r chi.Router) {
r.Get("/", h.GetWorkspace)
r.Put("/", h.UpdateWorkspace)
r.Patch("/", h.UpdateWorkspace)
r.Delete("/", h.DeleteWorkspace)
r.Get("/members", h.ListMembersWithUser)
r.Post("/members", h.CreateMember)
r.Post("/leave", h.LeaveWorkspace)
r.Route("/members/{memberId}", func(r chi.Router) {
r.Patch("/", h.UpdateMember)
r.Delete("/", h.DeleteMember)
})
})
})
})