refactor(backend): trim kanban_web bloat (auth/chat/stickers/mcp) — keep sync layer + cards core
This commit is contained in:
+15
-131
@@ -44,7 +44,9 @@ func handleGetBoard(db *DB) http.HandlerFunc {
|
||||
// POST /api/columns { name }
|
||||
func handleCreateColumn(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var body struct{ Name string `json:"name"` }
|
||||
var body struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
if err := infra.HTTPParseBody(r, &body, maxBodyBytes); err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
@@ -101,7 +103,9 @@ func handleDeleteColumn(db *DB) http.HandlerFunc {
|
||||
// POST /api/columns/reorder { ids: [...] }
|
||||
func handleReorderColumns(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var body struct{ IDs []string `json:"ids"` }
|
||||
var body struct {
|
||||
IDs []string `json:"ids"`
|
||||
}
|
||||
if err := infra.HTTPParseBody(r, &body, maxBodyBytes); err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
@@ -133,17 +137,16 @@ func handleCreateCard(db *DB) http.HandlerFunc {
|
||||
badRequest(w, "column_id and title required")
|
||||
return
|
||||
}
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
c, err := db.CreateCard(body.ColumnID, body.Requester, body.Title, body.Description, actor)
|
||||
c, err := db.CreateCard(body.ColumnID, body.Requester, body.Title, body.Description, "")
|
||||
if err == nil && body.AssigneeID != nil && *body.AssigneeID != "" {
|
||||
err = db.UpdateCardWithActor(c.ID, CardPatch{AssigneeID: body.AssigneeID, HasAssignee: true}, actor)
|
||||
err = db.UpdateCardWithActor(c.ID, CardPatch{AssigneeID: body.AssigneeID, HasAssignee: true}, "")
|
||||
if err == nil {
|
||||
c.AssigneeID = body.AssigneeID
|
||||
}
|
||||
}
|
||||
if err == nil && len(body.Tags) > 0 {
|
||||
tags := body.Tags
|
||||
err = db.UpdateCardWithActor(c.ID, CardPatch{Tags: &tags}, actor)
|
||||
err = db.UpdateCardWithActor(c.ID, CardPatch{Tags: &tags}, "")
|
||||
if err == nil {
|
||||
c.Tags = tags
|
||||
}
|
||||
@@ -210,27 +213,7 @@ func handleUpdateCard(db *DB) http.HandlerFunc {
|
||||
}
|
||||
patch.Tags = &tags
|
||||
}
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
if err := db.UpdateCardWithActor(id, patch, actor); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
// PUT /api/cards/{id}/stickers { stickers: [{emoji,x,y}, ...] }
|
||||
func handleUpdateCardStickers(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
var body struct {
|
||||
Stickers []Sticker `json:"stickers"`
|
||||
}
|
||||
if err := infra.HTTPParseBody(r, &body, maxBodyBytes); err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
}
|
||||
if err := db.UpdateStickers(id, body.Stickers); err != nil {
|
||||
if err := db.UpdateCardWithActor(id, patch, ""); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
@@ -242,8 +225,7 @@ func handleUpdateCardStickers(db *DB) http.HandlerFunc {
|
||||
func handleDeleteCard(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
if err := db.DeleteCardWithActor(id, actor); err != nil {
|
||||
if err := db.DeleteCardWithActor(id, ""); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
@@ -267,8 +249,7 @@ func handleMoveCard(db *DB) http.HandlerFunc {
|
||||
badRequest(w, "column_id required")
|
||||
return
|
||||
}
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
if err := db.MoveCard(id, body.ColumnID, body.OrderedIDs, actor); err != nil {
|
||||
if err := db.MoveCard(id, body.ColumnID, body.OrderedIDs, ""); err != nil {
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
notFound(w, "card not found")
|
||||
return
|
||||
@@ -280,79 +261,11 @@ func handleMoveCard(db *DB) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/cards/{id}/messages → [CardMessage, ...]
|
||||
func handleListCardMessages(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
msgs, err := db.ListCardMessages(id)
|
||||
if err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
infra.HTTPJSONResponse(w, http.StatusOK, msgs)
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/cards/{id}/messages { body }
|
||||
func handleCreateCardMessage(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
var body struct {
|
||||
Body string `json:"body"`
|
||||
}
|
||||
if err := infra.HTTPParseBody(r, &body, maxBodyBytes); err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(body.Body) == "" {
|
||||
badRequest(w, "body required")
|
||||
return
|
||||
}
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
if actor == "" {
|
||||
infra.HTTPErrorResponse(w, infra.HTTPError{Status: http.StatusUnauthorized, Code: "unauthorized", Message: "session required"})
|
||||
return
|
||||
}
|
||||
m, err := db.CreateCardMessage(id, actor, body.Body)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
notFound(w, err.Error())
|
||||
return
|
||||
}
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
infra.HTTPJSONResponse(w, http.StatusCreated, m)
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/cards/{cid}/messages/{mid}
|
||||
func handleDeleteCardMessage(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
mid := r.PathValue("mid")
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
if actor == "" {
|
||||
infra.HTTPErrorResponse(w, infra.HTTPError{Status: http.StatusUnauthorized, Code: "unauthorized", Message: "session required"})
|
||||
return
|
||||
}
|
||||
if err := db.DeleteCardMessage(mid, actor); err != nil {
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
notFound(w, err.Error())
|
||||
return
|
||||
}
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/cards/{id}/duplicate
|
||||
func handleDuplicateCard(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
c, err := db.DuplicateCard(id, actor)
|
||||
c, err := db.DuplicateCard(id, "")
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
notFound(w, "card not found")
|
||||
@@ -365,19 +278,6 @@ func handleDuplicateCard(db *DB) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/cards/{id}/history → [HistoryEntry, ...]
|
||||
func handleCardHistory(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
entries, err := db.CardHistory(id)
|
||||
if err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
infra.HTTPJSONResponse(w, http.StatusOK, entries)
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/trash
|
||||
func handleListTrash(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -394,8 +294,7 @@ func handleListTrash(db *DB) http.HandlerFunc {
|
||||
func handleRestoreCard(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
if err := db.RestoreCardWithActor(id, actor); err != nil {
|
||||
if err := db.RestoreCardWithActor(id, ""); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
@@ -415,15 +314,9 @@ func handlePurgeCard(db *DB) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func apiRoutes(db *DB, chatWorkdir string, logger *ChatLogger, internalToken string, flags *FeatureFlags) []infra.Route {
|
||||
func apiRoutes(db *DB, flags *FeatureFlags) []infra.Route {
|
||||
routes := []infra.Route{
|
||||
{Method: "GET", Path: "/api/flags", Handler: handleListFlags(flags)},
|
||||
{Method: "POST", Path: "/api/auth/register", Handler: handleRegister(db, flags)},
|
||||
{Method: "POST", Path: "/api/auth/login", Handler: handleLogin(db)},
|
||||
{Method: "POST", Path: "/api/auth/logout", Handler: handleLogout(db)},
|
||||
{Method: "GET", Path: "/api/me", Handler: handleMe(db)},
|
||||
{Method: "PATCH", Path: "/api/me", Handler: handlePatchMe(db)},
|
||||
{Method: "GET", Path: "/api/users", Handler: handleListUsers(db)},
|
||||
{Method: "GET", Path: "/api/board", Handler: handleGetBoard(db)},
|
||||
{Method: "POST", Path: "/api/columns", Handler: handleCreateColumn(db)},
|
||||
{Method: "POST", Path: "/api/columns/reorder", Handler: handleReorderColumns(db)},
|
||||
@@ -431,21 +324,12 @@ func apiRoutes(db *DB, chatWorkdir string, logger *ChatLogger, internalToken str
|
||||
{Method: "DELETE", Path: "/api/columns/{id}", Handler: handleDeleteColumn(db)},
|
||||
{Method: "POST", Path: "/api/cards", Handler: handleCreateCard(db)},
|
||||
{Method: "PATCH", Path: "/api/cards/{id}", Handler: handleUpdateCard(db)},
|
||||
{Method: "PUT", Path: "/api/cards/{id}/stickers", Handler: handleUpdateCardStickers(db)},
|
||||
{Method: "DELETE", Path: "/api/cards/{id}", Handler: handleDeleteCard(db)},
|
||||
{Method: "POST", Path: "/api/cards/{id}/move", Handler: handleMoveCard(db)},
|
||||
{Method: "POST", Path: "/api/cards/{id}/duplicate", Handler: handleDuplicateCard(db)},
|
||||
{Method: "GET", Path: "/api/cards/{id}/messages", Handler: handleListCardMessages(db)},
|
||||
{Method: "POST", Path: "/api/cards/{id}/messages", Handler: handleCreateCardMessage(db)},
|
||||
{Method: "DELETE", Path: "/api/cards/{id}/messages/{mid}", Handler: handleDeleteCardMessage(db)},
|
||||
{Method: "GET", Path: "/api/cards/{id}/history", Handler: handleCardHistory(db)},
|
||||
{Method: "GET", Path: "/api/trash", Handler: handleListTrash(db)},
|
||||
{Method: "POST", Path: "/api/cards/{id}/restore", Handler: handleRestoreCard(db)},
|
||||
{Method: "DELETE", Path: "/api/cards/{id}/purge", Handler: handlePurgeCard(db)},
|
||||
{Method: "POST", Path: "/api/chat", Handler: handleChat(db, chatWorkdir, logger)},
|
||||
{Method: "GET", Path: "/api/chat/ws", Handler: handleChatWS(db, chatWorkdir, logger, internalToken)},
|
||||
{Method: "POST", Path: "/api/tool/{name}", Handler: handleInternalTool(db, internalToken, logger)},
|
||||
{Method: "GET", Path: "/api/metrics", Handler: handleMetrics(db)},
|
||||
{Method: "GET", Path: "/api/tags", Handler: handleListTags(db)},
|
||||
{Method: "GET", Path: "/api/requesters", Handler: handleListRequesters(db)},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user