Repository navigation
fix: journal entry update fails when the day has planned tasks - #224
Merged
Merged
Conversation
JournalEntryRepository.UpdateAsync passed the detached graph returned by
GetByIdAsync (entry + todos + subtasks + log entries) to DbSet.Update().
EF then re-inserted the todo join rows, so PUT /JournalEntries/{id}
returned 500 (UNIQUE constraint failed: JournalEntryTaskItem) whenever the
entry had planned tasks; it also marked every loaded task and log row as
modified, writing back whatever values were loaded.
Copy only Title, Summary and UpdatedAt onto the tracked row instead. Date
and CreatedAt are never changed by an update. A missing entry now throws
KeyNotFoundException (the controller checks existence first).
Adds regression tests that reproduce the failure with real SQLite: a
single planned task, parent + subtask, stale child/log values not written
back, Date/CreatedAt preserved, UpdatedAt set on the returned instance.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
nevridge
force-pushed
the
bugfix/journal-entry-update-with-todos
branch
from
October 9, 2026 19:08
cfdf772 to
07fb449
Compare
nevridge
added a commit
that referenced
this pull request
Nov 5, 2026
* feat: add TaskFlow MCP server and Claude Code plugin - TaskFlow.Mcp: stdio MCP server (C# / .NET 10, ModelContextProtocol 2.2.0) wrapping the TaskFlow REST API with 14 workflow-oriented tools: projects, tasks (list views, batch create, merge-update), journal and weekly review - API errors are translated to McpException so Claude sees actionable code/message text; 5xx responses never leak stack traces - Plugin (plugin/): work-task-assistant agent and four user-invoked skills (plan-my-day, capture-tasks, weekly-review, journal-log); marketplace manifest at the repo root for local-path install - 101 unit tests with a stubbed HTTP layer, including a tool-surface guard - build.ps1 publishes the server into plugin/bin; README documents install, design choices and the doc sources used Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * feat: add Claude Desktop (Chat) setup A Claude Code plugin does not load in Claude Desktop's Chat (local MCP servers, agents and bin/ are ignored there), so add a separate path: - scripts/install-claude-desktop.ps1 merges the taskflow server into claude_desktop_config.json with a backup, refuses while the app runs, and supports -DryRun and -Uninstall - chat/taskflow-assistant: one Chat skill (SKILL.md + four workflow references) restricted to the frontmatter keys Chat accepts - scripts/package-chat-skill.ps1 validates the frontmatter and zips the skill for upload - README: explain the two surfaces and correct the earlier claim that the plugin works in the desktop app Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * docs: correct Claude Desktop troubleshooting hint for the Store version Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * docs: journal summary updates now work (#224) The TaskFlow API bug that made PUT /JournalEntries/{id} fail on days with planned tasks is fixed and merged. Remove the known-issue entry and the "prefer notes" workaround from the Chat skill, and note the required TaskFlow PRs in the README. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * feat(skills): add feature-factory skill, agents and CLAUDE.md Adds a feature-factory skill adapted from TaskFlow for the MCP server, plugin and chat content, with project agents (builder, test-verifier, validator) and documentation advisors for MCP, Claude plugin and .NET work. Adds a short CLAUDE.md and a README note. * fix(skills): cap feature-factory correction loops and tighten issue detection - Share one correction_cycles budget (cap 2) across Steps 8, 10 and 11 - Stop with no PR when the Step 11 pass leaves a failing gate or Critical findings - Take the issue number from a leading number after feature/ or bugfix/ only - Match owner/repo#N and GitHub URLs in the dependency scan, not path fragments - Allow claude plugin validate in the feature-builder Bash rule - Say in the README that main gets a branch created automatically * fix(skills): close remaining feature-factory review gaps - Dependency scan: reject only path and domain characters before owner/repo#N, so references after markdown punctuation are no longer missed; strip indented code fences - Allow one format-only fix per verifier run before treating it as a code failure - Handle verifier results and commit new tests after the verifier re-runs in Steps 10 and 11 - Require digits followed by a hyphen when taking the issue number from the branch name - Send a rewritten groomed story back through the story approval stop - Let the builder edit CLAUDE.md when the brief names it * refactor(skills): centralize feature-factory rework in one Correction Loop - Add a Correction Loop section that owns correction_cycles (cap 2), checks the budget before the builder runs, and commits tests the verifier adds - Add a Halt section; Steps 8, 10 and 11 now call the loop instead of counting cycles themselves - Define verifier outcomes once in Step 8 and reuse them in the loop - Make the verifier fix its own wrong tests and report only real code failures - Stop when the issue lookup fails instead of continuing with an empty body * fix(agents): quote descriptions so feature-factory agents load The feature-builder, test-verifier and implementation-validator descriptions contained an unquoted ': ', which is invalid YAML. Claude Code silently skipped the agents, so feature-factory could not invoke them. Wrap the three descriptions in double quotes. * feat(journal): send timezone offset when creating journal entries * fix(journal): address important/minor validator findings for journal-offset * feat(tasks): support Blocked task status * fix(tasks): address important/minor validator findings for blocked-status * feat(journal): list open subtasks under planned tasks in get_journal * fix(journal): address important/minor validator findings for journal-subtasks * fix(journal): degrade gracefully when subtasks fail to load and point to list_tasks get_journal now returns the journal without nested subtasks and a Note line when GET TaskItems fails, instead of failing the tool. Cancellation and todos/notes failures still propagate. The tool description and plan-my-day docs point to list_tasks for subtasks of unplanned parents. * fix(journal): degrade gracefully on subtask fetch timeout or unreadable body Address review findings on nevridge/taskflow-assistant#15: LoadAllTasksAsync now also degrades on an HttpClient timeout (TaskCanceledException without caller cancellation) and on JsonException from an unreadable TaskItems body. * docs(skills): stop only on explicit blockers and run advisors before the brief stop Step 0.5 now stops only when the issue explicitly states an unfinished blocker. The documentation advisors move to Step 4.5, before Approval Stop 2, with one spec-writer revision pass and an Advisor input block at the stop. * docs(skills): address review findings on nevridge/taskflow-assistant#16 - re-run advisors when Stop 2 changes the brief's file list - reword the advisor invariant so it covers Step 4.5 re-runs - update the advisor agent descriptions to say they run before Approval Stop 2 * feat(journal): add project and priority to log lines and completed/planned filters to list_tasks * test(journal): acceptance tests for journal-log-project-priority-and-list-filters * fix(journal): address important/minor validator findings for journal-log-project-priority-and-list-filters * test(journal): update acceptance tests for journal-log-project-priority-and-list-filters * docs(skills): address review findings on nevridge/taskflow-assistant#18 - feature-factory blocker check: treat an unreachable explicit blocker as unfinished * feat(tasks): journal append, update_tasks batch and duplicate-title warning * test(tasks): acceptance tests for journal append, update_tasks and duplicate warning * fix(tasks): address important/minor validator findings for journal-append-batch-update-duplicate-warning * feat(tasks): read local date and offset from one clock snapshot per call * fix(tasks): address important/minor validator findings for single-clock-read-tasks * fix(build): make build.ps1 safe when the MCP server is running * fix(build): address important/minor validator findings for build-ps1-safe-swap * feat(skills): add weekday stand-up workflow * fix(skills): address important/minor validator findings for standup * feat(tasks): send due date as a date-only value * fix(tasks): address important/minor validator findings for date-only-due-date * feat(tasks): support the InProgress status and StartedAt * fix(tasks): address important/minor validator findings for inprogress-status * feat(tasks): remove the stale IsComplete field * fix(tasks): address important/minor validator findings for remove-iscomplete * feat(tasks): plan a task from update_task with journalDate * fix(tasks): address important/minor validator findings for journaldate * Address review findings on nevridge/taskflow-assistant#36 - Make the past-day guidance neutral so it also reads correctly for create_tasks - Re-read the task after a project change outside the partial-success handling * fix(tasks): resolve the project before saving task fields in update_task and update_tasks * test(tasks): acceptance tests for resolve-project-before-save * fix(tasks): address important/minor validator findings for resolve-project-before-save * feat(journal): handle #387 planning rule and journal row shape * fix(journal): address important/minor validator findings for journal-planning-rule * chore(plugin): bump plugin version to 0.4.0 * chore(assistant): run Mcp.Tests on Microsoft.Testing.Platform only * ci: cover assistant/ in CI and Dependabot, skip deploy for assistant-only pushes * docs(assistant): update paths and commands for the monorepo * chore(assistant): replace FluentAssertions with AwesomeAssertions --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
PUT /api/v1/JournalEntries/{id}returned 500 (UNIQUE constraint failed: JournalEntryTaskItem.JournalEntryId, JournalEntryTaskItem.TodosId) whenever the entry had planned tasks, so a journal summary or title could not be saved once a day had todos.Cause
JournalEntryRepository.UpdateAsynccalledDbSet.Update()on the detached graph returned byGetByIdAsync(entry + todos + subtasks + log entries). EF re-inserted the todo join rows, and it also marked every loaded task and log row as modified, so stale loaded values would have been written back.Fix
UpdateAsyncnow copies onlyTitle,SummaryandUpdatedAtonto the tracked row (found withFindAsync) and setsUpdatedAton the instance passed in, which the controller returns.DateandCreatedAtare never changed by an update. A missing entry throwsKeyNotFoundException(the controller already returns 404 before reaching this).Tests
New
JournalEntryRepositoryUpdateTests(real in-memory SQLite, one context per request as in production). They failed before the fix and pass now:a single planned task (reproduces the exact production error)
a parent with a subtask
stale task / log values on the loaded graph are not written back, and todos stay linked
Date/CreatedAtpreserved,UpdatedAtset on the returned instancean entry tracked by the same context still works; a missing entry throws
dotnet test(325 passing),dotnet format --verify-no-changesRebuilt the local Docker stack and repeated the failing flow against the live API: plan two tasks, update the summary twice, tasks stay planned
CI
Found while testing the TaskFlow assistant (MCP server), which edits the journal summary.
🤖 Generated with Claude Code