feat: create_category + delete_category tools (v0.4.11)

Verified via systematic FW_DEBUG=1 probing:
- taskcategoryput: requires 'name'; optional 'emoji' (Unicode or string code)
  accepted as-is. 'listId' param has no per-list effect — categories are
  family-wide.
- taskcategorydelete: uses 'id' param (not 'metaId'), returns r='true'.

Changes:
- create_category(list_id, name, icon=None): creates custom category via
  taskcategoryput; icon maps to 'emoji' API param
- delete_category(category_id): safety check via accgetallfamily looks up
  rights.canDelete='true'; system categories (rights.canDelete=null) are
  refused with a clear error
- get_categories: now exposes 'custom' bool field (rights.canDelete='true')
  so callers can identify deletable categories
- SPEC.md: document taskcategoryput + taskcategorydelete params, responses,
  error formats, and system-category protection behaviour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-16 07:43:54 +02:00
parent a76dc0fd51
commit 5698196c43
5 changed files with 205 additions and 8 deletions
+62 -1
View File
@@ -331,6 +331,65 @@ mit `{"a00": {"un": {"un": {"message": "missing value in: id"}}}}` auf Top-Level
→ wird vom fw_client fälschlich als Erfolg interpretiert. Daher ist der korrekte Parameter-Name
kritisch.
### `taskcategoryput` Kategorie erstellen
POST https://api.familywall.com/api/taskcategoryput
Content-Type: application/x-www-form-urlencoded
**Body-Parameter (verifiziert via FW_DEBUG=1):**
| Parameter | Pflicht | Wert |
|---|---|---|
| `name` | ja | Kategorie-Name (beliebiger String) |
| `emoji` | nein | Icon: Unicode-Emoji-Zeichen (z.B. `🌿`) oder beliebiger String-Code (z.B. `"FOOD"`) — wird as-is gespeichert |
Hinweise:
- Die neue Kategorie wird **allen** Listen der Familie zugeordnet — es gibt keine per-Liste-Einschränkung.
- Benutzerdefinierte Kategorien haben `systemCategoryId=null` und `rights.canDelete='true'`.
- System-Kategorien haben `rights.canDelete=null` — API erlaubt Löschen, aber `delete_category` Tool verweigert es.
**Response-Struktur (verifiziert):**
```
a00.r.r → vollständiges Kategorie-Objekt
.metaId → neue Kategorie-ID (z.B. "taskCategory/23431854_4956637")
.name → Kategorie-Name
.taskListType → "SHOPPING_LIST" (automatisch gesetzt)
.familyId → Familien-ID
.accountId → Account-ID des Erstellers
.rights.canDelete → "true" (custom Kategorien)
.rights.canUpdate → "true" (custom Kategorien)
.emoji → gespeicherter Icon-Wert (falls übergeben)
```
**Fehlerverhalten:** Ohne `name`-Parameter:
```json
{"a00": {"un": {"un": {"FiZClassId": "502", "message": "cat without a name ..."}}}}
```
### `taskcategorydelete` Kategorie löschen
POST https://api.familywall.com/api/taskcategorydelete
Content-Type: application/x-www-form-urlencoded
**Body-Parameter (verifiziert via FW_DEBUG=1):**
| Parameter | Pflicht | Wert |
|---|---|---|
| `id` | ja | Kategorie-MetaId aus `get_categories` (**WICHTIG: `id`, nicht `metaId`!**) |
**Achtung:** Falscher Parameter-Name `metaId` führt zu:
```json
{"a00": {"un": {"un": {"FiZClassId": "502", "message": "In request, missing value in : id"}}}}
```
**Response-Struktur (verifiziert):**
```
a00.r.r → "true" (String)
```
**Wichtig System-Kategorien:** Die API erlaubt technisch das Löschen von System-Kategorien
(`taskCategory/<familyId>_200` etc.), entfernt sie aber nur aus der Familie — nicht global.
Das `delete_category`-MCP-Tool verweigert dies (Schutz via `rights.canDelete`-Check).
Erkennung: custom Kategorien haben `rights.canDelete='true'`; System-Kategorien haben `rights.canDelete=null`.
### `wallmood` Wall-Post liken
POST https://api.familywall.com/api/wallmood
Content-Type: application/x-www-form-urlencoded
@@ -426,4 +485,6 @@ AND `moodStarShortcut: false` AND `moodMap: {}`.
- ~~`wallmood`: Parameter-Name `wallId`~~ → **`wall_message_id`** (verifiziert via API-Fehlermeldung)
- ~~`wallmood`: `moodType`-Werte, Toggle vs. explizit, Response-Struktur~~ → verifiziert: idempotentes SET mit `"STAR"`, kein Toggle (siehe oben)
- `wallmood` Unlike: Mechanismus unbekannt — Service Worker verhindert Browser-Inspektion; alle getesteten Ansätze fehlgeschlagen (siehe oben)
- ~~`taskcreate2` / `taskupdate2`: Kategorie-Paramter-Name~~**`taskCategoryId`**, Wert = vollständige metaId (verifiziert)
- ~~`taskcreate2` / `taskupdate2`: Kategorie-Paramter-Name~~ → **`taskCategoryId`**, Wert = vollständige metaId (verifiziert)
- ~~`taskcategoryput`: Body-Parameter, Response-Struktur~~ → `name` (Pflicht), `emoji` (optional), Response = neues Kategorie-Objekt (verifiziert)
- ~~`taskcategorydelete`: Body-Parameter~~**`id`** (nicht `metaId`!), Response = `"true"` (verifiziert)