# Project Notes REST API Documentation

Version: **v1**
Base URL: `http://localhost:8080/api/v1`

## Table des matières

- [Vue d'ensemble](#vue-densemble)
- [Authentification](#authentification)
- [Formats de données](#formats-de-données)
- [Endpoints](#endpoints)
  - [Lister les notes](#lister-les-notes)
  - [Récupérer une note](#récupérer-une-note)
  - [Créer/Mettre à jour une note](#créermettre-à-jour-une-note)
  - [Supprimer une note](#supprimer-une-note)
- [Codes de statut HTTP](#codes-de-statut-http)
- [Exemples d'utilisation](#exemples-dutilisation)

---

## Vue d'ensemble

L'API REST de Project Notes permet de gérer vos notes Markdown via HTTP. Elle supporte :

- **Listage** : Récupérer la liste de toutes les notes avec métadonnées
- **Lecture** : Télécharger une note en JSON ou Markdown brut
- **Écriture** : Créer ou mettre à jour une note
- **Suppression** : Supprimer une note définitivement

### Caractéristiques

- ✅ **Versionnée** : `/api/v1` pour assurer la compatibilité future
- ✅ **Content Negotiation** : Support JSON et Markdown selon le header `Accept`
- ✅ **Idempotence** : PUT crée ou met à jour (idempotent)
- ✅ **Automatisation** : Front matter géré automatiquement
- ✅ **Ré-indexation** : Recherche mise à jour automatiquement après chaque modification
- ✅ **Support sous-dossiers** : Organisation hiérarchique native

---

## Authentification

**Version actuelle : Aucune authentification requise**

⚠️ **IMPORTANT** : L'API n'a pas d'authentification. Si vous exposez le serveur publiquement :
1. Utilisez un reverse proxy (nginx, Caddy) avec authentification
2. Implémentez Basic Auth ou API Key
3. Utilisez un VPN ou tunnel SSH

---

## Formats de données

### Note complète (NoteResponse)

```json
{
  "path": "projet/backend.md",
  "title": "Backend API",
  "content": "---\ntitle: Backend API\n...\n---\n\n# Content",
  "body": "\n# Content",
  "frontMatter": {
    "title": "Backend API",
    "date": "10-11-2025",
    "last_modified": "10-11-2025:14:30",
    "tags": ["projet", "backend"]
  },
  "lastModified": "10-11-2025:14:30",
  "size": 1024
}
```

### Métadonnées de note (NoteMetadata)

```json
{
  "path": "projet/backend.md",
  "title": "Backend API",
  "tags": ["projet", "backend"],
  "lastModified": "10-11-2025:14:30",
  "date": "10-11-2025",
  "size": 1024
}
```

### Requête de création/modification (NoteRequest)

Deux options :

**Option 1 : Content complet** (recommandé pour migration)
```json
{
  "content": "---\ntitle: Ma note\ntags: [test]\n---\n\n# Contenu"
}
```

**Option 2 : Body + FrontMatter séparés** (recommandé pour création)
```json
{
  "body": "\n# Mon contenu\n\nTexte ici...",
  "frontMatter": {
    "title": "Ma note",
    "tags": ["test", "exemple"]
  }
}
```

### Erreur (ErrorResponse)

```json
{
  "error": "Bad Request",
  "message": "Invalid path",
  "code": 400
}
```

---

## Endpoints

### Lister les notes

Récupère la liste de toutes les notes avec leurs métadonnées.

**Endpoint** : `GET /api/v1/notes`

**Paramètres** : Aucun

**Réponse** : `200 OK`

```json
{
  "notes": [
    {
      "path": "projet/backend.md",
      "title": "Backend API",
      "tags": ["projet", "backend"],
      "lastModified": "10-11-2025:14:30",
      "date": "10-11-2025",
      "size": 1024
    },
    {
      "path": "daily/2025-11-10.md",
      "title": "Notes du 10 novembre",
      "tags": ["daily"],
      "lastModified": "10-11-2025:09:15",
      "date": "10-11-2025",
      "size": 2048
    }
  ],
  "total": 2
}
```

**Exemple curl** :

```bash
curl http://localhost:8080/api/v1/notes
```

---

### Récupérer une note

Télécharge une note spécifique. Le format dépend du header `Accept`.

**Endpoint** : `GET /api/v1/notes/{path}`

**Paramètres** :
- `{path}` : Chemin relatif de la note (ex: `projet/backend.md`)

**Headers** :
- `Accept: application/json` (défaut) : Retourne JSON avec métadonnées
- `Accept: text/markdown` : Retourne Markdown brut
- `Accept: text/plain` : Retourne Markdown brut

**Réponse JSON** : `200 OK`

```json
{
  "path": "projet/backend.md",
  "title": "Backend API",
  "content": "---\ntitle: Backend API\ndate: 10-11-2025\nlast_modified: 10-11-2025:14:30\ntags:\n  - projet\n  - backend\n---\n\n# Backend API\n\nContenu de la note...",
  "body": "\n# Backend API\n\nContenu de la note...",
  "frontMatter": {
    "title": "Backend API",
    "date": "10-11-2025",
    "last_modified": "10-11-2025:14:30",
    "tags": ["projet", "backend"]
  },
  "lastModified": "10-11-2025:14:30",
  "size": 1024
}
```

**Réponse Markdown** : `200 OK`

```markdown
---
title: Backend API
date: 10-11-2025
last_modified: 10-11-2025:14:30
tags:
  - projet
  - backend
---

# Backend API

Contenu de la note...
```

**Erreurs** :
- `404 Not Found` : Note inexistante

**Exemples curl** :

```bash
# Récupérer en JSON
curl http://localhost:8080/api/v1/notes/projet/backend.md \
  -H "Accept: application/json"

# Récupérer en Markdown brut
curl http://localhost:8080/api/v1/notes/projet/backend.md \
  -H "Accept: text/markdown"

# Sauvegarder dans un fichier
curl http://localhost:8080/api/v1/notes/projet/backend.md \
  -H "Accept: text/markdown" \
  -o backend.md
```

---

### Créer/Mettre à jour une note

Crée une nouvelle note ou met à jour une note existante (idempotent).

**Endpoint** : `PUT /api/v1/notes/{path}`

**Paramètres** :
- `{path}` : Chemin relatif de la note (ex: `projet/nouvelle-note.md`)

**Headers** :
- `Content-Type: application/json` : Envoyer du JSON
- `Content-Type: text/markdown` : Envoyer du Markdown brut

**Body JSON** :

```json
{
  "body": "\n# Ma nouvelle note\n\nContenu ici...",
  "frontMatter": {
    "title": "Ma nouvelle note",
    "tags": ["test", "exemple"]
  }
}
```

Ou avec `content` complet :

```json
{
  "content": "---\ntitle: Ma note\ntags: [test]\n---\n\n# Contenu"
}
```

**Body Markdown brut** :

```markdown
# Ma nouvelle note

Contenu ici...
```

**Réponse** : `201 Created` (nouvelle note) ou `200 OK` (mise à jour)

```json
{
  "path": "projet/nouvelle-note.md",
  "title": "Ma nouvelle note",
  "content": "---\ntitle: Ma nouvelle note\n...",
  "body": "\n# Ma nouvelle note\n\nContenu ici...",
  "frontMatter": {
    "title": "Ma nouvelle note",
    "date": "10-11-2025",
    "last_modified": "10-11-2025:14:35",
    "tags": ["test", "exemple"]
  },
  "lastModified": "10-11-2025:14:35",
  "size": 256
}
```

**Comportement** :
- ✅ Crée automatiquement les dossiers parents
- ✅ Génère le front matter si absent
- ✅ Met à jour `last_modified` automatiquement
- ✅ Préserve `date` pour notes existantes
- ✅ Ré-indexe automatiquement pour la recherche

**Erreurs** :
- `400 Bad Request` : Chemin invalide ou JSON malformé
- `415 Unsupported Media Type` : Content-Type non supporté
- `500 Internal Server Error` : Erreur d'écriture

**Exemples curl** :

```bash
# Créer avec JSON
curl -X PUT http://localhost:8080/api/v1/notes/projet/test.md \
  -H "Content-Type: application/json" \
  -d '{
    "body": "\n# Test\n\nCeci est un test.",
    "frontMatter": {
      "title": "Note de test",
      "tags": ["test"]
    }
  }'

# Créer avec Markdown brut
curl -X PUT http://localhost:8080/api/v1/notes/projet/simple.md \
  -H "Content-Type: text/markdown" \
  -d "# Simple note

Contenu simple sans front matter."

# Upload depuis un fichier
curl -X PUT http://localhost:8080/api/v1/notes/projet/from-file.md \
  -H "Content-Type: text/markdown" \
  --data-binary @local-file.md
```

---

### Supprimer une note

Supprime définitivement une note.

**Endpoint** : `DELETE /api/v1/notes/{path}`

**Paramètres** :
- `{path}` : Chemin relatif de la note (ex: `projet/old-note.md`)

**Réponse** : `200 OK`

```json
{
  "message": "Note deleted successfully",
  "path": "projet/old-note.md"
}
```

**Erreurs** :
- `404 Not Found` : Note inexistante
- `500 Internal Server Error` : Erreur de suppression

**Exemple curl** :

```bash
curl -X DELETE http://localhost:8080/api/v1/notes/projet/old-note.md
```

---

## Codes de statut HTTP

| Code | Signification | Description |
|------|---------------|-------------|
| `200` | OK | Requête réussie |
| `201` | Created | Note créée avec succès |
| `400` | Bad Request | Requête invalide (chemin, JSON, etc.) |
| `404` | Not Found | Note inexistante |
| `405` | Method Not Allowed | Méthode HTTP non supportée |
| `415` | Unsupported Media Type | Content-Type non supporté |
| `500` | Internal Server Error | Erreur serveur |

---

## Exemples d'utilisation

### Synchronisation de notes

**Télécharger toutes les notes** :

```bash
#!/bin/bash
# Télécharger toutes les notes localement

mkdir -p notes-backup

# Récupérer la liste
curl -s http://localhost:8080/api/v1/notes | jq -r '.notes[].path' | while read path; do
    # Créer les dossiers parents
    mkdir -p "notes-backup/$(dirname "$path")"

    # Télécharger la note
    curl -s http://localhost:8080/api/v1/notes/"$path" \
        -H "Accept: text/markdown" \
        -o "notes-backup/$path"

    echo "✓ Downloaded: $path"
done

echo "Backup terminé!"
```

**Uploader un dossier de notes** :

```bash
#!/bin/bash
# Uploader toutes les notes .md d'un dossier

find ./my-notes -name "*.md" | while read file; do
    # Calculer le chemin relatif
    relpath="${file#./my-notes/}"

    # Upload
    curl -X PUT http://localhost:8080/api/v1/notes/"$relpath" \
        -H "Content-Type: text/markdown" \
        --data-binary @"$file"

    echo "✓ Uploaded: $relpath"
done

echo "Upload terminé!"
```

### Recherche et filtrage

**Lister toutes les notes avec un tag spécifique** :

```bash
curl -s http://localhost:8080/api/v1/notes | \
  jq '.notes[] | select(.tags | contains(["projet"])) | .path'
```

**Compter les notes par dossier** :

```bash
curl -s http://localhost:8080/api/v1/notes | \
  jq -r '.notes[].path' | \
  xargs -n1 dirname | \
  sort | uniq -c
```

### Création automatique de notes

**Note quotidienne** :

```bash
#!/bin/bash
# Créer une note quotidienne

TODAY=$(date +%Y-%m-%d)
TITLE="Notes du $(date +%d/%m/%Y)"

curl -X PUT http://localhost:8080/api/v1/notes/daily/${TODAY}.md \
  -H "Content-Type: application/json" \
  -d "{
    \"body\": \"\\n# ${TITLE}\\n\\n## Tasks\\n- [ ] TODO\\n\\n## Notes\\n\",
    \"frontMatter\": {
      \"title\": \"${TITLE}\",
      \"tags\": [\"daily\"]
    }
  }"

echo "Note quotidienne créée: daily/${TODAY}.md"
```

### Intégration avec d'autres outils

**Exporter en HTML avec Pandoc** :

```bash
curl -s http://localhost:8080/api/v1/notes/projet/doc.md \
  -H "Accept: text/markdown" | \
  pandoc -f markdown -t html -o doc.html

echo "Exporté en HTML: doc.html"
```

**Recherche full-text avec jq** :

```bash
# Chercher "API" dans tous les titres
curl -s http://localhost:8080/api/v1/notes | \
  jq '.notes[] | select(.title | contains("API"))'
```

### Script de maintenance

**Vérifier les notes sans tags** :

```bash
curl -s http://localhost:8080/api/v1/notes | \
  jq -r '.notes[] | select(.tags | length == 0) | .path'
```

**Statistiques** :

```bash
#!/bin/bash
# Afficher des statistiques sur les notes

STATS=$(curl -s http://localhost:8080/api/v1/notes)

TOTAL=$(echo "$STATS" | jq '.total')
TOTAL_SIZE=$(echo "$STATS" | jq '[.notes[].size] | add')
AVG_SIZE=$(echo "$STATS" | jq '[.notes[].size] | add / length | floor')

echo "📊 Statistiques des notes"
echo "========================"
echo "Total de notes: $TOTAL"
echo "Taille totale: $(numfmt --to=iec-i --suffix=B $TOTAL_SIZE)"
echo "Taille moyenne: $(numfmt --to=iec-i --suffix=B $AVG_SIZE)"
echo ""
echo "Top 5 tags:"
echo "$STATS" | jq -r '.notes[].tags[]' | sort | uniq -c | sort -rn | head -5
```

---

## Bonnes pratiques

### Sécurité

1. **Ne pas exposer publiquement sans authentification**
2. **Utiliser HTTPS en production**
3. **Valider les chemins côté client** (éviter `../` malveillants)
4. **Limiter la taille des uploads** (si nécessaire, ajouter un middleware)

### Performance

1. **Pagination** : L'API liste ne pagine pas actuellement (toutes les notes en une requête). Pour beaucoup de notes (>1000), envisager d'ajouter `?limit=` et `?offset=`
2. **Cache** : Utiliser un proxy cache (Varnish, nginx) pour GET
3. **Compression** : Activer gzip sur le reverse proxy

### Workflow recommandé

1. **Backup régulier** : Script cron qui télécharge toutes les notes
2. **Versioning Git** : Synchroniser le dossier de notes avec Git
3. **CI/CD** : Valider le format Markdown avec des linters
4. **Monitoring** : Logger les accès API pour audit

---

## Support et contribution

- **Issues** : Rapporter les bugs sur GitHub
- **Documentation** : Ce fichier (`API.md`)
- **Code source** : `internal/api/rest_handler.go`

---

## Changelog

### v1 (2025-11-10)
- ✨ Première version de l'API REST
- ✅ Endpoints: LIST, GET, PUT, DELETE
- ✅ Content negotiation JSON/Markdown
- ✅ Support sous-dossiers
- ✅ Gestion automatique du front matter
- ✅ Ré-indexation automatique

---

**Note** : Cette API coexiste avec l'interface web HTML. Les deux peuvent être utilisées simultanément sans conflit.
