feat(tasks): support reminder write via dot-notation (v1.2.0)
- Add reminder_unit, reminder_value to create_task - Add reminder_unit, reminder_value, clear_reminder to update_task - Wire format verified: reminder.reminderUnit / .reminderValue / .reminderType (SNOOZE=active, NONE=clear) / .localId (optional) - Valid units: MINUTE, HOUR, DAY (WEEK rejected by enum decoder) - Clear requires full inactive block; partial updates reject with "task reminder invalid" - Flat top-level keys, JSON string and bracket notation are silently ignored by the server — confirmed via isolated fuzz per variant - Update SPEC.md, CLAUDE.md, README.md, CHANGELOG.md - Remove outdated "not supported" warning in update_task docstring
This commit is contained in:
@@ -213,15 +213,28 @@ POST https://api.familywall.com/api/taskupdate2
|
||||
**⚠️ Encoding:** Der FiZ-`Ai()`-Encoder serialisiert alle Felder **flach** als Top-Level-Form-Parameter.
|
||||
Recurrency-Felder werden direkt auf Top-Level gesendet (verifiziert via xb-Encoder im JS-Bundle).
|
||||
|
||||
**⚠️ Reminder-Schreibzugriff nicht möglich:**
|
||||
Alle Versuche, `reminderUnit`, `reminderValue`, `reminderType`, `localId` via `taskupdate2`
|
||||
zu setzen, wurden ignoriert — die API antwortet mit HTTP 200 und `lastAction: UPDATED`,
|
||||
aber `reminder` bleibt unverändert auf dem Default-Wert `{reminderUnit: MINUTE, reminderType: NONE, reminderValue: 0}`.
|
||||
Auch alternative Encodings (JSON-String, PHP-Bracket, verschachtelt) und alternative Endpoints
|
||||
(`tasksetalert`, `taskalertput` etc.) wurden erprobt — alle Endpoints sind nicht registriert.
|
||||
**Ursache:** Reminder-Updates werden vom Service Worker der mobilen App abgefangen und transformiert.
|
||||
Diese Transformation ist nicht reproduzierbar ohne den Service Worker.
|
||||
Reminder sind daher **read-only** (wie in v0.9 dokumentiert).
|
||||
**Reminder-Schreibzugriff (verifiziert 2026-04-17):**
|
||||
|
||||
Reminder werden via Dot-Notation als Unterfelder gesendet:
|
||||
|
||||
| Parameter | Wert |
|
||||
|---|---|
|
||||
| `reminder.reminderUnit` | `"MINUTE"` \| `"HOUR"` \| `"DAY"` (WEEK wird abgelehnt) |
|
||||
| `reminder.reminderValue` | nicht-negativer Integer als String (z.B. `"30"`) |
|
||||
| `reminder.reminderType` | `"SNOOZE"` (aktiv) oder `"NONE"` (Reminder entfernen) |
|
||||
| `reminder.localId` | optional; `"0"` akzeptiert |
|
||||
|
||||
**Wichtig:**
|
||||
- Nur Dot-Notation funktioniert. Flache Top-Level-Keys (`reminderUnit`, `reminderValue`, …),
|
||||
JSON-String (`reminder={…}`) und Bracket-Notation (`reminder[reminderUnit]`) werden
|
||||
**silent-ignored** (HTTP 200, Reminder unverändert).
|
||||
- Partielle Reminder-Updates (z.B. nur `reminder.reminderType=NONE`) liefern
|
||||
`task reminder invalid` — immer vollständigen Block senden.
|
||||
- `reminder=$empty` wird silent-ignored; zum Entfernen muss `reminder.reminderType=NONE`
|
||||
mit `reminder.reminderValue=0` und `reminder.reminderUnit=MINUTE` gesendet werden.
|
||||
- Reminder-Felder lassen sich in einem einzigen `taskupdate2`-Call gemeinsam mit
|
||||
`recurrency`/`dueDate`/`text` setzen — keine Interferenz.
|
||||
- `$empty` auf Unterfelder (`reminder.reminderValue=$empty`) führt zu Parse-Fehlern.
|
||||
|
||||
**Response:**
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user