API docs et Dockerfile for dev
This commit is contained in:
1 parent
01fd72d31e
commit
afcbb87063
4 files changed
+232
No files matched your search
@@ -0,0 +1,158 @@
|
|||||||
|
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](https://github.com/te-online/timemanager/blob/main/appinfo/routes.php)). Les implémentations serveur se trouvent dans [lib/Controller/TApiController.php](https://github.com/te-online/timemanager/blob/main/lib/Controller/TApiController.php) et la logique de transformation/stockage dans [lib/Db/StorageHelper.php](https://github.com/te-online/timemanager/blob/main/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 ci‑dessous). 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 ci‑dessous.
|
||||||
|
|
||||||
|
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 front‑end 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 :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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 :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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`
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
```python
|
||||||
|
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
|
||||||
|
-------------------------
|
||||||
|
- Code source des routes : https://github.com/te-online/timemanager/blob/main/appinfo/routes.php
|
||||||
|
- Contrôleur API : https://github.com/te-online/timemanager/blob/main/lib/Controller/TApiController.php
|
||||||
|
- Conversion JSON → entités : https://github.com/te-online/timemanager/blob/main/lib/Db/StorageHelper.php
|
||||||
|
|
||||||
|
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.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
env
|
||||||
|
__pycache__
|
||||||
|
.git
|
||||||
|
.venv
|
||||||
|
/*.pyc
|
||||||
|
*.egg-info
|
||||||
|
dist
|
||||||
|
build
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
FROM python:3.9.2-slim
|
||||||
|
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Install minimal build deps (kept small). Adjust if your requirements need additional system packages.
|
||||||
|
RUN sed -i 's|http://deb.debian.org/debian|http://archive.debian.org/debian|g' /etc/apt/sources.list \
|
||||||
|
|| true \
|
||||||
|
&& sed -i 's|http://security.debian.org/debian-security|http://archive.debian.org/debian-security|g' /etc/apt/sources.list \
|
||||||
|
|| true \
|
||||||
|
&& echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/99no-check-valid-until \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends gcc ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy only requirements first to leverage Docker cache
|
||||||
|
COPY requirements.txt /app/requirements.txt
|
||||||
|
|
||||||
|
RUN pip install --upgrade pip \
|
||||||
|
&& pip install --no-cache-dir -r /app/requirements.txt
|
||||||
|
|
||||||
|
# By default the container runs Python; pass a script name or `-m` args after the image name.
|
||||||
|
ENTRYPOINT ["python3"]
|
||||||
|
|
||||||
|
# Recommended working directory for runs
|
||||||
|
CMD ["-V"]
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
Image Docker de développement pour exécuter les scripts Python du projet
|
||||||
|
|
||||||
|
This image provides a lightweight Python 3.9.2 environment with the project `requirements.txt` installed.
|
||||||
|
|
||||||
|
Build
|
||||||
|
-----
|
||||||
|
|
||||||
|
From the repository root (where `requirements.txt` sits) run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t cal-to-time-manager:dev -f support/docker-dev/Dockerfile .
|
||||||
|
```
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
Run a script from the project root by mounting the repo into `/app`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# run csv-to-timemanager.py
|
||||||
|
docker run --rm -v "$(pwd)":/app -w /app cal-to-time-manager:dev csv-to-timemanager.py
|
||||||
|
|
||||||
|
# run with arguments
|
||||||
|
docker run --rm -v "$(pwd)":/app -w /app cal-to-time-manager:dev csv-to-timemanager.py arg1 arg2
|
||||||
|
```
|
||||||
|
|
||||||
|
Open an interactive shell (override the image entrypoint):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm -it --entrypoint bash -v "$(pwd)":/app -w /app cal-to-time-manager:dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
- The container uses Python 3.9.2 (slim). If your `requirements.txt` needs system packages, adapt the `Dockerfile` to install them.
|
||||||
|
- The scripts expect `config.json` and CSV files to be present in the mounted workspace path.
|
||||||
|
- If your scripts connect to services (MySQL, Nextcloud API), ensure the container can reach those hosts (network, VPN, or expose host ports).
|
||||||
|
- To pass secret credentials, prefer using environment variables or Docker secrets rather than baking them in `config.json` inside the image.
|
||||||
Reference in new issue
Block a user