Files
nextcloud-sync-cal-time-man…/docs/time-manager-api.md
T
2026-05-20 11:09:57 +02:00

7.9 KiB
Raw Blame History

TimeManager — API publique (résumé d'usage)

Ce document résume l'usage des endpoints exposés par l'app TimeManager (routes dans appinfo/routes.php). Les implémentations serveur se trouvent dans lib/Controller/TApiController.php et la logique de transformation/stockage dans lib/Db/StorageHelper.php.

Authentification

  • L'API est une API Nextcloud : il faut une session authentifiée ou utiliser l'authentification HTTP Basic (utilisateur + mot de passe d'application). Dans les scripts automatisés, préférez un app password.
  • Pour les requêtes JSON, envoyez Content-Type: application/json.

Résumé des endpoints

  • GET /api/items — lecture / recherche d'items (clients / projets / tâches / temps). Usage UI/interop (paramètres de filtrage dépendants de l'implémentation). Le contrôleur TApiController ne contient pas de méthode get explicite dans la version actuelle du dépôt ; ce endpoint peut être géré par un héritage du framework ou un code serveur externe.
  • POST /api/items — création d'un item (implémentation: création d'un client via post($name, $note)). Exemple minimal : envoyer {"name":"Mon client","note":"…"}.
  • POST /api/updateObjects — endpoint principal de synchronisation bidirectionnelle. Accepta un objet JSON contenant lastCommit et data (structure détaillée cidessous). Retourne les objets modifiés depuis le commit fourni plus un nouveau commit si des changements ont été appliqués.
  • POST /api/sync-web — alias/variante utilisée par le client web (updateObjectsFromWeb) ; se comporte comme updateObjects.
  • GET /api/hoursInPeriod — statistique/aggrégation des heures sur une période. Paramètres détaillés cidessous.

Détail : POST /api/updateObjects

Attendu : un JSON avec ces champs racine :

  • lastCommit : string — le commit connu côté client (vide ou absent si première synchronisation).
  • data : objet contenant 4 entités : clients, projects, tasks, times.

Chaque entité doit être un objet contenant trois tableaux : created, updated, deleted.

Exemple minimal :

{
  "lastCommit": "",
  "data": {
    "clients": { "created": [ { "name": "Client A" } ], "updated": [], "deleted": [] },
    "projects": { "created": [], "updated": [], "deleted": [] },
    "tasks": { "created": [], "updated": [], "deleted": [] },
    "times": { "created": [], "updated": [], "deleted": [] }
  }
}

Champs usuels par entité (voir StorageHelper::convertToEntityObject pour la liste complète)

  • clients: name, note, email, phone, city, postcode, street, web, uuid, commit, created, changed.
  • projects: name, client_uuid, note, color, uuid, commit, created, changed.
  • tasks: name, project_uuid, uuid, commit, created, changed.
  • times: start, end, task_uuid, note, uuid, commit, created, changed.

Comportement serveur (synthèse)

  • Le serveur vérifie que chaque entité a bien les trois sous-tableaux created, updated, deleted et renverra une erreur HTTP 406 si la structure est invalide.
  • Pour les objets created, le serveur complète uuid, created, changed si besoin et insère l'objet. Pour updated/deleted, le serveur utilise les champs commit / desiredCommit pour résoudre les conflits selon la stratégie configurée.
  • Le serveur renvoie un objet JSON contenant data (les objets modifiés après le commit fourni) et commit (nouveau commit si des changements ont été appliqués, sinon le dernier commit connu côté serveur).

Exemple de réponse (squelette) :

{
  "data": {
    "clients": [ /* liste d'objets client après commit demandé */ ],
    "projects": [ /* ... */ ],
    "tasks": [ /* ... */ ],
    "times": [ /* ... */ ]
  },
  "commit": "<commit-uuid>"
}

Notes pratiques

  • Le champ commit est central pour la synchronisation incrémentale : envoyez la valeur commit renvoyée par le serveur comme lastCommit lors du prochain appel pour ne recevoir que les changements suivants.
  • Si vous ne souhaitez pousser aucun changement mais uniquement récupérer les nouveautés, envoyez data vide (ou des tableaux vides) et lastCommit égal au dernier commit connu du client : le serveur renverra les objets après ce commit.

/api/sync-web

Equivalent pratique de updateObjects, prévu pour les appels depuis le frontend web. Même payload et même réponse.

GET /api/hoursInPeriod

Signature (d'après TApiController::getHoursInPeriodStats):

  • start (required) — date de début (format attendu par l'app, typiquement YYYY-MM-DD ou une date ISO)
  • end (required) — date de fin
  • group_by (optional) — none | day | week | month | year (par défaut none)
  • clients, projects, tasks (optional) — listes CSV d'UUIDs pour filtrer (client_uuid1,client_uuid2)
  • status (optional) — filtre d'état des temps (ex: active/deleted selon implémentation)
  • shared (optional) — booléen pour inclure les entrées partagées
  • userFilter (optional) — CSV d'IDs utilisateurs pour limiter aux auteurs
  • timezone (optional) — timezone utilisée pour l'agrégation (ex: UTC)

Exemple curl :

curl -u "user:APP_PASSWORD" \
  "https://<nextcloud>/apps/timemanager/api/hoursInPeriod?start=2026-01-01&end=2026-01-31&group_by=day"

Réponse (squelette) :

{
  "total": 123.5,
  "grouped": { "2026-01-01": 8.0, "2026-01-02": 7.5 },
  "js_date_format": "yyyy-MM-dd"
}

GET /api/items et POST /api/items

  • POST /api/items crée un client si on lui fournit name et note (méthode post($name,$note) dans TApiController). Exemple :
curl -u "user:APP_PASSWORD" -H "Content-Type: application/json" \
  -d '{"name":"Nouveau client","note":"créé via API"}' \
  -X POST "https://<nextcloud>/apps/timemanager/api/items"
  • GET /api/items permet de lister / rechercher des éléments exposés par l'API (usage UI). Les filtres exacts sont implémentés dans la méthode get du contrôleur; si vous avez un usage précis je peux extraire la signature exacte et ajouter des exemples d'appel.

Exemple Python de synchronisation updateObjects

import requests
import json
from requests.auth import HTTPBasicAuth

url = "https://<nextcloud>/apps/timemanager/api/updateObjects"
username = "<user>"
password = "<app_password>"

payload = {
    "lastCommit": "",
    "data": {
        "clients": {"created": [{"name": "Client API", "note": "Créé via API"}], "updated": [], "deleted": []},
        "projects": {"created": [], "updated": [], "deleted": []},
        "tasks": {"created": [], "updated": [], "deleted": []},
        "times": {"created": [], "updated": [], "deleted": []}
    }
}

resp = requests.post(url, json=payload, auth=HTTPBasicAuth(username, password))
print(resp.status_code)
print(resp.text)

Références et exploration

Si vous voulez, je peux :

  • ajouter des exemples d'appels curl réels adaptés à votre instance Nextcloud (avec placeholders),
  • extraire la signature exacte de la méthode get pour /api/items et ajouter sa doc précise,
  • générer un petit script Python d'exemple qui synchronise un petit ensemble clients/projects/tasks/times contre votre instance.