fix: UpdateEntry preserves existing parent/type/depth; import list sort_order; CreateSection dynamic depth

This commit is contained in:
James 2026-03-14 23:44:34 -04:00
parent 1645061932
commit e146deb517
1 changed files with 34 additions and 21 deletions

View File

@ -128,14 +128,10 @@ func (h *Handlers) UpdateEntry(w http.ResponseWriter, r *http.Request) {
entryID := chi.URLParam(r, "entryID")
var req struct {
ProjectID string `json:"project_id"`
ParentID string `json:"parent_id"`
Type string `json:"type"`
Depth int `json:"depth"`
Summary string `json:"summary"`
Data string `json:"data"`
Stage string `json:"stage"`
Summary string `json:"summary"`
AssigneeID string `json:"assignee_id"`
Stage string `json:"stage"`
Version int `json:"version"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@ -143,20 +139,29 @@ func (h *Handlers) UpdateEntry(w http.ResponseWriter, r *http.Request) {
return
}
entry := &lib.Entry{
EntryID: entryID,
ProjectID: req.ProjectID,
ParentID: req.ParentID,
Type: req.Type,
Depth: req.Depth,
SummaryText: req.Summary,
DataText: req.Data,
Stage: req.Stage,
AssigneeID: req.AssigneeID,
Version: req.Version,
// Load the existing entry so we preserve project_id, parent_id, type, depth, sort_order
existing, err := lib.EntryByID(h.DB, h.Cfg, entryID)
if err != nil || existing == nil {
ErrorResponse(w, http.StatusNotFound, "not_found", "Entry not found")
return
}
if err := lib.EntryWrite(h.DB, h.Cfg, actorID, entry); err != nil {
// Only update the fields the client is allowed to change
if req.Data != "" {
existing.DataText = req.Data
}
if req.Summary != "" {
existing.SummaryText = req.Summary
}
if req.AssigneeID != "" {
existing.AssigneeID = req.AssigneeID
}
if req.Stage != "" {
existing.Stage = req.Stage
}
existing.Version = req.Version
if err := lib.EntryWrite(h.DB, h.Cfg, actorID, existing); err != nil {
if err == lib.ErrAccessDenied {
ErrorResponse(w, http.StatusForbidden, "access_denied", "Access denied")
return
@ -169,7 +174,7 @@ func (h *Handlers) UpdateEntry(w http.ResponseWriter, r *http.Request) {
return
}
JSONResponse(w, http.StatusOK, entry)
JSONResponse(w, http.StatusOK, map[string]any{"entry_id": existing.EntryID, "version": existing.Version})
}
// DeleteEntry soft-deletes an entry.
@ -1950,6 +1955,8 @@ func (h *Handlers) CreateSection(w http.ResponseWriter, r *http.Request) {
projectKey, err := lib.DeriveProjectKey(h.Cfg.MasterKey, projectID)
if err != nil { ErrorResponse(w, http.StatusInternalServerError, "internal", "key error"); return }
var parentDepth int
h.DB.Conn.QueryRow(`SELECT depth FROM entries WHERE entry_id=?`, body.ParentID).Scan(&parentDepth)
var maxSort int
h.DB.Conn.QueryRow(
`SELECT COALESCE(MAX(sort_order),0) FROM entries WHERE parent_id=? AND deleted_at IS NULL`, body.ParentID,
@ -1968,7 +1975,7 @@ func (h *Handlers) CreateSection(w http.ResponseWriter, r *http.Request) {
search_key, search_key2, summary, data, stage,
assignee_id, return_to_id, origin_id, version, deleted_at, deleted_by, key_version, created_at, updated_at, created_by)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,
secID, projectID, body.ParentID, lib.TypeSection, 2, maxSort+1000,
secID, projectID, body.ParentID, lib.TypeSection, parentDepth+1, maxSort+1000,
nil, nil, sumPacked, dataPacked, lib.StagePreDataroom,
"", "", "", 1, nil, nil, 1, now, now, actorID,
)
@ -2361,6 +2368,12 @@ func (h *Handlers) ImportRequests(w http.ResponseWriter, r *http.Request) {
rlSummaryPacked, _ := lib.Pack(projectKey, listName)
rlDataPacked, _ := lib.Pack(projectKey, string(rlDataJSON))
var importMaxSort int
h.DB.Conn.QueryRow(
`SELECT COALESCE(MAX(sort_order),0) FROM entries WHERE project_id=? AND type='request_list' AND deleted_at IS NULL`, projectID,
).Scan(&importMaxSort)
rlSortOrder := importMaxSort + 1000
h.DB.Conn.Exec(
`INSERT INTO entries (entry_id, project_id, parent_id, type, depth, sort_order,
search_key, search_key2, summary, data, stage,
@ -2368,7 +2381,7 @@ func (h *Handlers) ImportRequests(w http.ResponseWriter, r *http.Request) {
version, deleted_at, deleted_by, key_version,
created_at, updated_at, created_by)
VALUES (?,?,?,?,?,?, ?,?,?,?,?, ?,?,?, ?,?,?,?, ?,?,?)`,
requestListID, projectID, projectID, lib.TypeRequestList, 1, 0,
requestListID, projectID, projectID, lib.TypeRequestList, 1, rlSortOrder,
nil, nil, rlSummaryPacked, rlDataPacked, lib.StagePreDataroom,
"", "", "",
1, nil, nil, 1,