fix: transaction-safe AcceptSuggestionWith + safe eventIds fallback + debug logging

Root cause: s.eventIds may be undefined in JavaScript even when s.events
has data (Wails v2 marshalling of []string in nested struct response).
On calling AcceptSuggestionWith(eventIDs []string), empty array reached Go,
no INSERTs executed, events silently lost.

Changes:
- Frontend: extractEventIds() fallback — s.eventIds || s.events[].id || []
- Frontend: console.log debug for eventIds/events in accept handler
- Backend: AcceptSuggestionWith wrapped in tx (Begin/Commit/Rollback) so
  entry creation + event linking is atomic
- Backend: AddWithSourceTx method for transaction-aware insert
- Backend: buildEntry helper extracted
- Backend: fmt.Printf debug logging for received eventIDs + link count
- Backend: verification query after commit
- Cleanup: removed stale frontend-dist assets, .gitignore build.log
This commit is contained in:
2026-06-03 15:10:25 +08:00
parent 7076980954
commit 21a595c3ce
26 changed files with 100 additions and 66 deletions
+46 -14
View File
@@ -50,7 +50,7 @@ func (s *Service) Add(nodeID, summary, details string, minutes int, approximate,
return s.AddWithSource(nodeID, summary, details, date, minutes, approximate, billable, SourceManual)
}
// Add inserts a new worklog entry.
// AddWithSource inserts a new worklog entry with an explicit source.
func (s *Service) AddWithSource(nodeID, summary, details, date string, minutes int, approximate, billable bool, source string) (*Entry, error) {
if nodeID == "" {
return nil, fmt.Errorf("node_id required")
@@ -62,19 +62,7 @@ func (s *Service) AddWithSource(nodeID, summary, details, date string, minutes i
date = time.Now().Format("2006-01-02")
}
e := &Entry{
ID: util.UUID7(),
NodeID: nodeID,
Summary: summary,
Details: details,
Date: date,
Minutes: &minutes,
Approximate: approximate,
Billable: billable,
Source: source,
CreatedAt: time.Now().UTC(),
UpdatedAt: time.Now().UTC(),
}
e := buildEntry(nodeID, summary, details, date, minutes, approximate, billable, source)
_, err := s.db.Exec(
`INSERT INTO worklog_entries (id,node_id,date,minutes,approximate,billable,
@@ -90,6 +78,50 @@ func (s *Service) AddWithSource(nodeID, summary, details, date string, minutes i
return e, nil
}
// AddWithSourceTx inserts a new worklog entry within an existing transaction.
func (s *Service) AddWithSourceTx(tx *sql.Tx, nodeID, summary, details, date string, minutes int, approximate, billable bool, source string) (*Entry, error) {
if nodeID == "" {
return nil, fmt.Errorf("node_id required")
}
if summary == "" {
return nil, fmt.Errorf("summary required")
}
if date == "" {
date = time.Now().Format("2006-01-02")
}
e := buildEntry(nodeID, summary, details, date, minutes, approximate, billable, source)
_, err := tx.Exec(
`INSERT INTO worklog_entries (id,node_id,date,minutes,approximate,billable,
summary,details,source,created_at,updated_at)
VALUES (?,?,?,?,?,?,?,?,?,?,?)`,
e.ID, e.NodeID, e.Date, e.Minutes, boolInt(e.Approximate),
boolInt(e.Billable), e.Summary, e.Details, e.Source,
e.CreatedAt.Format(time.RFC3339), e.UpdatedAt.Format(time.RFC3339),
)
if err != nil {
return nil, err
}
return e, nil
}
func buildEntry(nodeID, summary, details, date string, minutes int, approximate, billable bool, source string) *Entry {
return &Entry{
ID: util.UUID7(),
NodeID: nodeID,
Summary: summary,
Details: details,
Date: date,
Minutes: &minutes,
Approximate: approximate,
Billable: billable,
Source: source,
CreatedAt: time.Now().UTC(),
UpdatedAt: time.Now().UTC(),
}
}
// Update modifies an existing entry.
func (s *Service) Update(id, summary, details string, minutes int, approximate, billable bool) error {
t := time.Now().UTC().Format(time.RFC3339)