chore: auto-commit (28 archivos)
- app.md - auth.go - chat.go - chat.log - db.go - frontend/package.json - frontend/pnpm-lock.yaml - frontend/src/App.tsx - frontend/src/Root.tsx - frontend/src/api.ts - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+92
-15
@@ -71,12 +71,14 @@ func handleUpdateColumn(db *DB) http.HandlerFunc {
|
||||
Position *int `json:"position"`
|
||||
Location *string `json:"location"`
|
||||
Width *int `json:"width"`
|
||||
WIPLimit *int `json:"wip_limit"`
|
||||
IsDone *bool `json:"is_done"`
|
||||
}
|
||||
if err := infra.HTTPParseBody(r, &body, maxBodyBytes); err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
}
|
||||
if err := db.UpdateColumn(id, ColumnPatch{Name: body.Name, Position: body.Position, Location: body.Location, Width: body.Width}); err != nil {
|
||||
if err := db.UpdateColumn(id, ColumnPatch{Name: body.Name, Position: body.Position, Location: body.Location, Width: body.Width, WIPLimit: body.WIPLimit, IsDone: body.IsDone}); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
@@ -116,10 +118,11 @@ func handleReorderColumns(db *DB) http.HandlerFunc {
|
||||
func handleCreateCard(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var body struct {
|
||||
ColumnID string `json:"column_id"`
|
||||
Requester string `json:"requester"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
ColumnID string `json:"column_id"`
|
||||
Requester string `json:"requester"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
AssigneeID *string `json:"assignee_id"`
|
||||
}
|
||||
if err := infra.HTTPParseBody(r, &body, maxBodyBytes); err != nil {
|
||||
badRequest(w, err.Error())
|
||||
@@ -129,7 +132,14 @@ func handleCreateCard(db *DB) http.HandlerFunc {
|
||||
badRequest(w, "column_id and title required")
|
||||
return
|
||||
}
|
||||
c, err := db.CreateCard(body.ColumnID, body.Requester, body.Title, body.Description)
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
c, err := db.CreateCard(body.ColumnID, body.Requester, body.Title, body.Description, actor)
|
||||
if err == nil && body.AssigneeID != nil && *body.AssigneeID != "" {
|
||||
err = db.UpdateCardWithActor(c.ID, CardPatch{AssigneeID: body.AssigneeID, HasAssignee: true}, actor)
|
||||
if err == nil {
|
||||
c.AssigneeID = body.AssigneeID
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
@@ -142,17 +152,38 @@ func handleCreateCard(db *DB) http.HandlerFunc {
|
||||
func handleUpdateCard(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
var body struct {
|
||||
Requester *string `json:"requester"`
|
||||
Title *string `json:"title"`
|
||||
Description *string `json:"description"`
|
||||
Color *string `json:"color"`
|
||||
}
|
||||
if err := infra.HTTPParseBody(r, &body, maxBodyBytes); err != nil {
|
||||
var raw map[string]any
|
||||
if err := infra.HTTPParseBody(r, &raw, maxBodyBytes); err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
}
|
||||
if err := db.UpdateCard(id, CardPatch{Requester: body.Requester, Title: body.Title, Description: body.Description, Color: body.Color}); err != nil {
|
||||
patch := CardPatch{}
|
||||
if v, ok := raw["requester"].(string); ok {
|
||||
patch.Requester = &v
|
||||
}
|
||||
if v, ok := raw["title"].(string); ok {
|
||||
patch.Title = &v
|
||||
}
|
||||
if v, ok := raw["description"].(string); ok {
|
||||
patch.Description = &v
|
||||
}
|
||||
if v, ok := raw["color"].(string); ok {
|
||||
patch.Color = &v
|
||||
}
|
||||
if v, ok := raw["locked"].(bool); ok {
|
||||
patch.Locked = &v
|
||||
}
|
||||
if v, present := raw["assignee_id"]; present {
|
||||
patch.HasAssignee = true
|
||||
if v == nil {
|
||||
empty := ""
|
||||
patch.AssigneeID = &empty
|
||||
} else if s, ok := v.(string); ok {
|
||||
patch.AssigneeID = &s
|
||||
}
|
||||
}
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
if err := db.UpdateCardWithActor(id, patch, actor); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
@@ -188,7 +219,8 @@ func handleMoveCard(db *DB) http.HandlerFunc {
|
||||
badRequest(w, "column_id required")
|
||||
return
|
||||
}
|
||||
if err := db.MoveCard(id, body.ColumnID, body.OrderedIDs); err != nil {
|
||||
actor, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
|
||||
if err := db.MoveCard(id, body.ColumnID, body.OrderedIDs, actor); err != nil {
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
notFound(w, "card not found")
|
||||
return
|
||||
@@ -213,8 +245,49 @@ func handleCardHistory(db *DB) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/trash
|
||||
func handleListTrash(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
cards, err := db.ListDeletedCards()
|
||||
if err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
infra.HTTPJSONResponse(w, http.StatusOK, cards)
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/cards/{id}/restore
|
||||
func handleRestoreCard(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
if err := db.RestoreCard(id); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/cards/{id}/purge
|
||||
func handlePurgeCard(db *DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.PathValue("id")
|
||||
if err := db.PurgeCard(id); err != nil {
|
||||
serverError(w, err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
func apiRoutes(db *DB, chatWorkdir string, logger *ChatLogger) []infra.Route {
|
||||
return []infra.Route{
|
||||
{Method: "POST", Path: "/api/auth/register", Handler: handleRegister(db)},
|
||||
{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: "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)},
|
||||
@@ -225,6 +298,10 @@ func apiRoutes(db *DB, chatWorkdir string, logger *ChatLogger) []infra.Route {
|
||||
{Method: "DELETE", Path: "/api/cards/{id}", Handler: handleDeleteCard(db)},
|
||||
{Method: "POST", Path: "/api/cards/{id}/move", Handler: handleMoveCard(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/metrics", Handler: handleMetrics(db)},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user