Extract shared code that was duplicated across functions:
- taskJSON struct (MarshalJSON/UnmarshalJSON) to package-level type
- scanTask(scanner) helper for GetTask/GetTasks (~70 identical lines)
- monthNames map for parseMonthName/parseDayAndMonth
- applyNonDateAttribute helper for Apply/ApplyToNew
- resolveDisplayID calls replace inline loops in FormatTaskListWithFormat
Replace O(n²) bubble sorts with sort.Slice in all four report sort
functions (sortByUrgency, NewestReport, NextReport, OldestReport).
Remove dead code: formatTimeWithColor (unused, also used time.Now()
instead of timeNow()), getCurrentTimestamp (unnecessary wrapper).
Remove ~20 comments that restated the next line of code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement complete key:value format parsing for change log entries and fix
critical tag synchronization issue from server to client.
Key Changes:
1. Shared Key:Value Parser (NEW: internal/engine/parser.go)
- Created ParseKeyValueFormat() for both edit and sync operations
- Supports flexible whitespace: 'key:value' and 'key: value'
- Handles comment skipping for edit files
- Consolidates parsing logic (DRY principle)
2. Database Triggers - Tags Support (internal/engine/database.go)
- Added tags to track_task_create trigger
- Added tags to track_task_update trigger
- Tags sorted alphabetically via SQL ORDER BY
- Format: 'tags: alpha,bravo,charlie'
3. Task Creation - Tag Update Fix (internal/engine/task.go)
- CreateTaskWithModifier() now triggers update after adding tags
- Ensures tags appear in change log (UPDATE entry)
- Fixes missing tags in initial CREATE entries
4. Edit Command - Use Shared Parser (cmd/edit.go)
- Replaced custom parseEditedFile() with shared ParseKeyValueFormat()
- Added tag sorting in parseTags()
- Removed ~30 lines, improved maintainability
5. Sync Client - Complete Implementation (internal/sync/client.go)
- NEW: applyChangeDataToTask() - parses all fields from change log
- NEW: Helper functions for status, priority, tag parsing
- FIXED: parseChanges() - sort by timestamp+ID before grouping
- Added parent/child task ordering (prevents FK violations)
- Enhanced tag sync in merge loop with task reload
- Specific validation error messages per field
Critical Bug Fix:
- When CREATE and UPDATE have same timestamp, old code kept CREATE (no tags)
- New code sorts by ID as tiebreaker, ensuring UPDATE (with tags) is used
- Verified: Server->client tag sync now works correctly
Validation:
- Description must not be empty (both edit and sync)
- Recurrence validated (not negative, max 100 years)
- All timestamps parsed correctly (Unix epoch)
- Tags sorted alphabetically in all contexts
Testing:
- Fresh pull from server: ✅ All tags present
- API-created tasks: ✅ Tags sync correctly
- Local->server->client round-trip: ✅ No data loss
- Same-second CREATE+UPDATE: ✅ Correct entry processed
- Parent/child tasks: ✅ Correct ordering
Files Changed:
- NEW: internal/engine/parser.go (+44 lines)
- Modified: internal/engine/database.go (+10 lines)
- Modified: internal/engine/task.go (+8 lines)
- Modified: cmd/edit.go (-25 lines net)
- Modified: internal/sync/client.go (+280 lines)
- Modified: srv/README.md (+1 line)
Total: +318 lines added, -25 removed, net +293 lines
This completes Phase 6: Full bidirectional sync with complete tag support.