Skip to content

fix: persist add-reminder under the reminder API field (re-implements upstream #58 by @nico-fioretti) - #4

Merged
netadvanced merged 2 commits into
mainfrom
upstream-58-reminder-date-fix
Jul 17, 2026
Merged

fix: persist add-reminder under the reminder API field (re-implements upstream #58 by @nico-fioretti)#4
netadvanced merged 2 commits into
mainfrom
upstream-58-reminder-date-fix

Conversation

@netadvanced

Copy link
Copy Markdown
Owner

Re-implements upstream PR #58 by @nico-fioretti (democratize-technology#58) — "fix: persist add-reminder date (send under reminder, not reminder_date)" — as a fork PR. Full credit for the fix goes to the original author.

What this fixes

An absolute reminder must be sent to Vikunja under the reminder key. node-vikunja's typed TaskReminder model calls the field reminder_date, so sending that key makes Vikunja (v2.3.0) silently store a zero (0001-01-01) reminder that never fires. This change reads and writes the actual API reminder field and preserves any existing reminders (absolute or relative) verbatim.

Changes

  • src/tools/tasks/reminders.ts — cherry-picked verbatim from upstream PR Wave D: direct project sharing with users & teams + link-share REST migration #58 (@nico-fioretti). addReminder now maps existing reminders through the real reminder field and appends the new reminder as { reminder: <date> }.
  • tests/reminder-persistence.test.ts — new test from the upstream PR verifying the persisted payload uses reminder (passing).
  • tests/tools/tasks-reminders.test.ts — follow-up commit updating the two existing add-reminder unit tests to assert the new reminder payload shape and to model existing reminders the way Vikunja v2.3.0 returns them. These two tests were the only net-new failures introduced by the field rename.

Verification

  • npm run lint — passes
  • npm run typecheck — passes
  • Reminder suites (tasks-reminders.test.ts + reminder-persistence.test.ts) — 22/22 passing
  • Full-suite delta: this branch has exactly the same failing set as main (24 suites / 227 tests). The fix introduces zero net-new failures / zero regressions.

Known limitation (pre-existing, out of scope)

npm run test:coverage does not pass repo-wide because main itself currently has ~227 failing tests with coverage below the configured thresholds, from long-standing source-vs-test drift unrelated to reminders (e.g. SecureErrorHandler string handling, removed default-subcommand branches, circuit-breaker test isolation). This drift predates PR #58 and is tracked separately in the upstream-adoption triage. This PR is intentionally scoped to the reminder fix only and does not attempt to repair that unrelated debt.

nicoferfio and others added 2 commits July 16, 2026 16:16
An absolute reminder must be sent under the reminder key. The TaskReminder type calls it reminder_date, but the server expects reminder and otherwise stores a zero (0001-01-01) reminder that never fires. Reads/writes the reminder field and preserves existing reminders.
PR #58 changes add-reminder to persist under the 'reminder' API field
instead of 'reminder_date'. Update the two existing add-reminder unit
tests in tasks-reminders.test.ts to assert the new payload shape and to
model existing reminders as Vikunja v2.3.0 returns them (reminder field).

These two tests were the only net-new failures introduced by the field
change; with them updated the branch matches main's test baseline exactly
(no regressions).
@netadvanced
netadvanced merged commit c8cd67f into main Jul 17, 2026
netadvanced added a commit that referenced this pull request Jul 18, 2026
Battle-campaign friction #4 (q3-offsite-kanban / subtask-breakdown
transcripts): agents made 6 one-by-one set-bucket calls and 3 one-by-one
create-subtask calls despite readily using bulk-create/bulk-update
elsewhere in the same run. Adds two composite-first (docs/ROADMAP.md
decision 4) subcommands on vikunja_tasks, following PR #95's honest
partial-reporting shape:

- bulk-set-bucket (also exposed on vikunja_task_bulk, mirroring the
  existing bulk-create/update/delete dual registration): resolves the
  project + Kanban view ONCE, then applies the per-task bucket move
  sequentially (SQLite lock discipline), collecting failedIds on a
  partial result instead of aborting the whole batch.
- bulk-create-subtasks: resolves the parent's project ONCE, then reuses
  create-subtask's own create -> label -> assign -> relate -> bucket ->
  verify CompositeOperation sequence per subtask spec, sequentially, each
  with its own independent rollback scope. atomic:true rolls back only
  the failing subtask, never earlier successes. Response lists which
  subtasks were created/related/failed.

Both subcommands are classified 'write' in the global read-only
classification table and covered by tool annotations. Updates the
hard-coded vikunja_tasks/vikunja_task_bulk description-string assertions,
docs/TOOLS.md, and adds mcp-e2e.ts checks (not run live).

Gates: lint clean, typecheck clean, test:coverage 145 suites / 3148 tests
passing (up from 143/3123 on unmodified main — zero net new regressions),
aggregate coverage 89.84/80.81/78.45/90.13 (stmts/branches/funcs/lines),
above the 89/80/77/89 ratcheted gate.

Claude-Session: https://claude.ai/code/session_01Jn8SF2doyvho8vM9fwwFeJ
netadvanced added a commit that referenced this pull request Jul 22, 2026
…overage (#159)

Adds an `ensure` subcommand to vikunja_labels that get-or-creates a label by
title in one idempotent call: GET /labels?s=<title> narrows candidates, a
case-insensitive exact-title match is picked client-side (first match wins on
duplicates), and only on a miss does it fall through to the same PUT /labels
`create` uses. Reports clearly whether the label was reused or created,
mirroring applyLabels' idempotent messaging style.

Campaign evidence (tracking issue #28, friction #4): with no create-or-reuse
primitive, agents were listing all labels, matching by title, then creating —
costing both models 6 calls vs an optimal 3 (2x overage) for "attach a label
by name". This collapses that flow to ensure + apply-label (2 calls).

Also points vikunja_labels' and vikunja_task_labels' tool descriptions at the
new ensure subcommand for the by-name-attach flow, classifies `ensure` as a
'write' subcommand in the read-only gate, documents the composite in
docs/API-COVERAGE.md, and adds an mcp-e2e check that ensures the same label
twice (plus a third differently-cased call) and confirms every call reuses
the same id after the first create.

Unit tests cover reuse-hit, create-miss, case-insensitive match, dedupe
against multiple/substring search candidates, a null search response, and
read-only-mode rejection.

Gates: lint clean, typecheck clean, test:coverage 147/147 suites passing,
3324/3324 tests passing (net +7 vs the 3317-test unmodified base, 0 new
failures).

Claude-Session: https://claude.ai/code/session_014BfGcJGUddi6mnTe6QYLgs
netadvanced added a commit that referenced this pull request Jul 23, 2026
PR #159's `vikunja_labels ensure` subcommand cut existing-label-reuse
friction (#28 #4) but a battle re-check showed
weak agents still didn't adopt it: discovering `ensure`, calling it,
then threading its id into a *separate* apply-label call was too many
hops. This folds get-or-create directly into `vikunja_task_labels
apply-label` via an optional `labelTitles: string[]` field, alongside
the existing numeric `labels` field — either or both may be given.

- Extract the get-or-create-by-title logic out of `ensure` into a
  shared `ensureLabelByTitle` helper (src/utils/label-ensure.ts).
  `ensure` now calls the helper instead of duplicating the logic;
  its existing test suite passes unchanged.
- `applyLabels` resolves each `labelTitles` entry via the helper
  (case-insensitive title cache to avoid redundant lookups), merges
  the resolved ids with `labels`, dedupes, and attaches all of them
  through the existing idempotent apply path. The response reports
  which titles were created vs reused, alongside the pre-existing
  "already present" messaging.
- Updated `vikunja_task_labels`/`vikunja_labels` tool descriptions and
  docs/TOOLS.md to point agents at the one-call `labelTitles` path;
  `ensure` remains documented for get-or-create-without-attaching.
- Added a live labelTitles create/reuse/attach check to
  scripts/mcp-e2e.ts (not run — shared local stack is in use).

Gates: lint clean, typecheck clean, test:coverage 149/149 suites,
3341/3341 tests (baseline origin/main: 147/147, 3324/3324 — net +2
suites/+17 tests, zero regressions).

Claude-Session: https://claude.ai/code/session_014BfGcJGUddi6mnTe6QYLgs
@netadvanced
netadvanced deleted the upstream-58-reminder-date-fix branch August 3, 2026 00:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants