Second Brain documentation

Architecture

Un moteur générique, un domaine en YAML, une seule image Docker.

Vue d’ensemble

navigateur ──► Spring Boot (BFF, API REST, fichiers statiques Angular) ──► PostgreSQL 17
                    │                                                  └─► disque /data/files
                    └─► config/ (YAML lus au démarrage)
Dossier Contenu
config/ le domaine : aspects, types, liens, modèles, vues, dashboards, revues
backend/ Spring Boot 4 (Java 25) : API REST, moteur de définitions, moteur de vues, PostgreSQL par jOOQ
frontend/ Angular 22 (composants autonomes, signals, sans zone.js) : Material, Formly, AG Grid, Tiptap
backup/ service de sauvegarde (scripts sh dans un conteneur PostgreSQL)
deploy/ Caddy et essai de déploiement
docs/ cahier des fonctionnalités, ADR, backlog, ce site (docs/site)

Une seule image Docker : le build Angular est servi comme ressources statiques par Spring Boot.

Le moteur générique

Le code ne connaît aucun type métier (pas de if (aspect == "facture")). Le moteur de définitions lit config/ au démarrage, valide chaque fichier contre un méta-schéma (backend/src/main/resources/definitions/meta/), contrôle les références croisées (un type qui cite un aspect inconnu est ignoré) et expose les définitions à l’API. Un fichier invalide est ignoré et signalé ; il ne fait jamais tomber l’application, et la version précédente reste en service quand elle existe (voir la santé de la configuration, GET /api/definitions/status).

Un comportement spécifique passe par une définition YAML : workflow, report rapide, valeurs par défaut, prochaine action, masquage jusqu’à une date… Les actions et règles du jalon 3 pourront appeler un handler Java référencé depuis le YAML.

Données

Table Rôle
node titre, type, corps Markdown, parent, dates, inbox, corbeille, recherche plein texte
node_aspect un JSONB par aspect porté, avec la version de l’aspect
node_link liens typés, liens wiki (wiki)
node_tag tags, avec leur origine (saisie ou corps)
node_file, file_blob fichiers rattachés, contenus adressés par SHA-256
node_event journal de toutes les modifications (avant / après)

Règles :

  • Valider à l’écriture, tolérer à la lecture : les données d’aspect sont validées contre le JSON Schema à l’écriture ; une donnée ancienne non conforme reste lisible, et une valeur inchangée ne bloque pas l’écriture des autres champs.
  • Toute modification écrit un node_event dans la même transaction.
  • Schéma : uniquement par migrations Flyway V<n>__<description>.sql, jamais modifiées après coup.
  • Accès : jOOQ partout, sans JPA ni génération de code (ADR 0003).

Moteur de vues

Une vue (config/views/) est traduite en SQL paramétré : aspects joints une fois chacun, condition where dans un langage fermé (pas de SpEL), tri avec les vides en dernier. Les champs calculés (unblockedAt, prochaine action) sont des sous-requêtes construites depuis les définitions, valeurs liées.

Sécurité

Modèle BFF : Spring Boot est le client OIDC (Authentik en production) ; le navigateur n’a qu’un cookie de session et le cookie CSRF XSRF-TOKEN, renvoyé dans l’en-tête X-XSRF-TOKEN. Le profil dev désactive la sécurité. Les fichiers déposés sont servis avec une liste blanche de types affichables, nosniff et une CSP stricte.

Contrat API

Le backend publie son contrat OpenAPI (Swagger UI en dev : /swagger-ui.html). Le front utilise un client généré (frontend/src/app/api/), jamais de DTO écrit à la main ; frontend/openapi.json est l’instantané versionné du contrat.