Compare commits

...
1 Commits
Author SHA1 Message Date
bruno 10453d8dfe feat: dossier perso (#194) — vaults home-* en tête de l'arborescence, icône maison, compose de test
CI / lint (push) Successful in 3m1s
CI / security (push) Successful in 1m41s
CI / test (push) Successful in 4m37s
CI / build (push) Successful in 1m34s
CI / e2e (push) Successful in 17m40s
- frontend/js/sidebar.js : tri stable _homeFirst appliqué à la source des
  deux listes de vaults (loadVaults + soft refresh) → les vaults home-<user>
  passent en premier, arborescence et sélecteurs cohérents.
- frontend/js/viewer.js : getVaultIcon renvoie l'icône lucide "home" pour
  home-* (même safeCreateIcons / stroke currentColor que les autres).
- docker-compose.test-win.yml : montage test_home:/vaults/Home +
  OBSIGATE_HOME_ROOT=/vaults/Home pour tester la feature en local ;
  test_home/ ajouté au .gitignore.
- Tests : sidebar-filters.test.mjs +2 (icône maison, gemme violette
  inchangée), vérifié live sur l'instance 2020 (ordre + svg.lucide-home).
2026-10-10 16:09:59 -04:00
16 changed files with 84 additions and 14 deletions
+1
View File
@@ -44,6 +44,7 @@ test_dir/video/
test_vault/images/
test_vault/markdown/
test_vault/budget.xlsx
test_home/
# Tauri updater signing keys (private key — never commit)
desktop/*.key
+20 -1
View File
@@ -6,7 +6,7 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/),
et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
> **En cours de développement** : les changements à venir sont listés dans la section
> [Unreleased](#unreleased). La dernière version livrée est **2.64.0**.
> [Unreleased](#unreleased). La dernière version livrée est **2.65.0**.
---
@@ -14,6 +14,25 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
---
## [2.65.0] — 2026-10-10
### Ajouté
- **#194 (UI) — Dossier personnel visible dans l'arborescence**
- Les vaults `home-<user>` s'affichent **en premier** dans l'arborescence de
la barre latérale (tri stable appliqué à la source, `frontend/js/sidebar.js`,
donc aussi les sélecteurs de vault).
- Icône **maison** lucide (`data-lucide="home"`, même style/`stroke:
currentColor` que les autres icônes) via `getVaultIcon()` —
`frontend/js/viewer.js`.
- `docker-compose.test-win.yml` : montage `test_home:/vaults/Home` +
`OBSIGATE_HOME_ROOT=/vaults/Home` pour tester la feature en local
(dossier `test_home/` ignoré par git).
- Tests : `sidebar-filters.test.mjs` +2 (icône maison pour `home-*`,
gemme violette inchangée ailleurs).
---
## [2.64.0] — 2026-10-10
### Ajouté
+3 -3
View File
@@ -4,7 +4,7 @@
**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.
[![Version](https://img.shields.io/badge/Version-2.64.0-blue.svg)]()
[![Version](https://img.shields.io/badge/Version-2.65.0-blue.svg)]()
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/)
[![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/)
@@ -977,8 +977,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l
## 📝 Changelog
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.64.0).
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.65.0).
---
*Projet : ObsiGate | Version : 2.64.0 | Dernière mise à jour : Septembre 2026*
*Projet : ObsiGate | Version : 2.65.0 | Dernière mise à jour : Septembre 2026*
+3 -3
View File
@@ -2,7 +2,7 @@
**Ultra-light web gateway for your Obsidian vaults** — Access, browse, and search all your Obsidian notes from any device via a modern, responsive web interface.
[![Version](https://img.shields.io/badge/Version-2.64.0-blue.svg)]()
[![Version](https://img.shields.io/badge/Version-2.65.0-blue.svg)]()
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/)
[![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/)
@@ -1152,8 +1152,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE)
## 📝 Changelog
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.64.0).
See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.65.0).
---
*Project: ObsiGate | Version: 2.64.0 | Last updated: September 2026*
*Project: ObsiGate | Version: 2.65.0 | Last updated: September 2026*
+1 -1
View File
@@ -1 +1 @@
2.64.0
2.65.0
+1 -1
View File
@@ -2626,7 +2626,7 @@ dependencies = [
[[package]]
name = "obsigate-desktop"
version = "2.64.0"
version = "2.65.0"
dependencies = [
"chrono",
"env_logger",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "obsigate-desktop"
version = "2.64.0"
version = "2.65.0"
description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian"
authors = ["Bruno Charest"]
edition = "2021"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json",
"productName": "ObsiGate",
"version": "2.64.0",
"version": "2.65.0",
"identifier": "com.obsigate.desktop",
"build": {
"frontendDist": "../frontend",
+5
View File
@@ -21,12 +21,17 @@ services:
volumes:
- /c/dev/git/python/ObsiGate/test_vault:/vaults/TestVault
- /c/dev/git/python/ObsiGate/test_dir:/vaults/TestDir
# #194 : racine des dossiers persos — UN seul montage pour tous les
# utilisateurs (dossier hôte : mkdir test_home à côté du dépôt).
- /c/dev/git/python/ObsiGate/test_home:/vaults/Home
- obsigate_data:/app/data
environment:
- VAULT_1_NAME=TestVault
- VAULT_1_PATH=/vaults/TestVault
- DIR_1_NAME=TestDir
- DIR_1_PATH=/vaults/TestDir
# #194 : dossier personnel par utilisateur = <racine>/home-<user>
- OBSIGATE_HOME_ROOT=/vaults/Home
- OBSIGATE_AUTH_ENABLED=true
- OBSIGATE_ADMIN_USER=admin
- OBSIGATE_ADMIN_PASSWORD=test123
+2
View File
@@ -341,6 +341,8 @@ Avant de corriger quoi que ce soit, un agent IA doit :
| 2026-10-09 | #194 | Fonctionnalité | `backend/user_home.py` (nouveau), `backend/indexer.py`, `backend/auth/router.py`, `backend/routers/vaults.py`, `backend/main.py`, `docker-compose.yml`, `tests/test_user_home.py` (nouveau), `tests/test_auth_api.py`, `docs/features/user-home-194.md` (nouveau), `docs/ROADMAP.md`, `CHANGELOG.md`, `README.md`, `README.fr.md` | **#194 — dossier personnel par utilisateur** : chaque compte reçoit `<OBSIGATE_HOME_ROOT>/<user>` monté comme vault propre `home-<user>` (option A validée) — l'isolation s'appuie sur l'ACL par vault **existante** (`check_vault_access`), aucune ACL par chemin inventée. `backend/user_home.py` : `ensure_user_home()` idempotent (mkdir → `add_vault_to_index` → `persist_vault` → watcher → SSE → octroi dans `user.vaults`) appelé à `POST /api/auth/admin/users` **et** au démarrage (`ensure_all_user_homes()` : migration des users existants, réparation des dossiers/registres manquants, sweep des vaults `home-*` orphelins dont l'utilisateur a disparu hors route — garde `Path.parent == racine` pour ne jamais toucher à un vault admin homonyme) ; `release_user_home()` à la suppression (index/watcher/registre refermés, **dossier conservé**). **Blocage levé** : registre persistant `data/vaults.json` fusionné par `load_vault_config()` — avant, tout vault ajouté à la volée (`/api/vaults/add`) disparaissait au premier reindex complet et au redémarrage. Correctif au passage : `reload_single_vault()` remet `vault_config[name]` après `remove_vault_from_index()`. Réponse du POST = vaults réactualisés (l'instantané de `create_user` était antérieur à l'octroi). Déploiement : montage unique `/NFS/OBSIDIAN_DOC/Home:/vaults/Home` + `OBSIGATE_HOME_ROOT` (absente = feature inactive, dev/tests/desktop inchangés). Vérifié : `test_user_home.py` 12/12 (création, idempotence, username invalide, persistance après `load_vault_config`, retrait, isolation `check_vault_access`, orphelins), `test_auth_api.py::TestUserHome` 2/2, suite **1703 passed / 2 skipped**, ruff backend 0, mypy 114 fichiers 0, `validate-imports` 42 modules / 372 exports, `unit.test.mjs` 13/13 | ✅ livré (en attente vérif utilisateur) |
| 2026-10-09 | #194 | Fonctionnalité (UI) | `frontend/js/sidebar.js`, `frontend/js/viewer.js`, `docker-compose.test-win.yml`, `.gitignore`, `tests/frontend/sidebar-filters.test.mjs`, `docs/ROADMAP.md`, `docs/features/user-home-194.md`, `CHANGELOG.md` | **#194 (incrément UI)** : les vaults `home-<user>` s'affichent **en premier** dans l'arborescence de la sidebar — tri stable appliqué à la source (`_homeFirst` dans `loadVaults()` et dans le soft-refresh, donc `state.allVaults`, l'arborescence et les sélecteurs restent cohérents) — et portent l'icône **maison** lucide (`data-lucide="home"` via `getVaultIcon`, même `safeCreateIcons`/`stroke: currentColor` que les autres icônes, thème-aware). Compose de test : `test_home:/vaults/Home` + `OBSIGATE_HOME_ROOT=/vaults/Home` (dossier `test_home/` ignoré par git). Vérifié : `sidebar-filters.test.mjs` 8→**10/10**, `validate-imports` 42 modules / 372 exports, `unit.test.mjs` 13/13, suites voisines (ai-sidebar, toolbar-order, search-facets, pane-manager, editor-inline) vertes, **live Playwright sur l'instance 2020** : ordre `home-admin, home-bruno, TestDir, TestVault` + `svg.lucide-home` rendu (placeholder `<i>` remplacé) | ✅ livré (en attente vérif utilisateur) |
---
## 📜 Historique des bugs résolus
+5 -2
View File
@@ -1,6 +1,6 @@
# ObsiGate — Roadmap
> **Version :** 2.64.0 | **Dernière mise à jour :** 2026-10-10
> **Version :** 2.65.0 | **Dernière mise à jour :** 2026-10-10
> **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact
> vers les fonctionnalités livrées.
> - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)**
@@ -46,7 +46,10 @@
- [x] Service `ensure_user_home()` idempotent : mkdir + vault + octroi, appelé à la création
d'un user et au démarrage (réparation/migration)
- [x] Retrait au suppression de compte (index/watcher/registre) sans supprimer le dossier
- [x] Montage Docker + `OBSIGATE_HOME_ROOT` dans `docker-compose.yml`
- [x] Montage Docker + `OBSIGATE_HOME_ROOT` (prod **et** compose de test
`docker-compose.test-win.yml` → `test_home:/vaults/Home`)
- [x] UI : vaults `home-*` en **premier** dans l'arborescence + icône maison
lucide (`getVaultIcon`), vérifié live sur l'instance 2020
- [x] Tests (création, persistance après rebuild, isolation 403 entre users) + docs
---
+15
View File
@@ -70,6 +70,21 @@ suppression du compte, racine `/NFS/OBSIDIAN_DOC/Home` montée `/vaults/Home`.
→ vault refermé / dossier conservé) + absence de dossier sans
`OBSIGATE_HOME_ROOT`.
## UI — arborescence (incrément)
- **Ordre** : tri stable `home-*` en premier, appliqué à la source
(`frontend/js/sidebar.js::_homeFirst`, sur les deux sites qui alimentent
`state.allVaults`) → arborescence, sélecteurs et refreshs homogènes.
- **Icône** : `getVaultIcon()` (`frontend/js/viewer.js`) renvoie
`icon("home", size)` pour `home-*` → même pipeline lucide que le reste de
l'app (`safeCreateIcons`, `stroke: currentColor`, suit le thème).
- **Test local** : `docker-compose.test-win.yml` monte
`test_home:/vaults/Home` + `OBSIGATE_HOME_ROOT=/vaults/Home`
(`test_home/` est dans `.gitignore`).
- **Vérifié live** (instance 2020, Playwright) : ordre
`home-admin, home-bruno, TestDir, TestVault`, `svg.lucide-home` rendu,
placeholder `<i>` remplacé.
## Impact utilisateur
Aucune nouvelle chaîne i18n : les noms de vault sont des données, la liste
+8
View File
@@ -220,8 +220,15 @@ async function loadVaultSettings() {
// ---------------------------------------------------------------------------
// Sidebar — Vault tree
// ---------------------------------------------------------------------------
// #194 : le dossier personnel (vault « home-<user> ») s'affiche en premier
// dans l'arborescence. Tri stable fait sur place, à la source de toutes les
// listes (arborescence, sélecteurs, state.allVaults).
const _homeFirst = (a, b) =>
(String(b?.name).startsWith("home-") ? 1 : 0) - (String(a?.name).startsWith("home-") ? 1 : 0);
async function loadVaults() {
const vaults = await api("/api/vaults");
vaults.sort(_homeFirst);
state.allVaults = vaults;
const container = document.getElementById("vault-tree");
container.innerHTML = "";
@@ -426,6 +433,7 @@ export async function refreshSidebarTreePreservingState() {
// 2. Soft update: vault names/counts without wiping the tree
try {
const vaults = await api("/api/vaults");
vaults.sort(_homeFirst);
state.allVaults = vaults;
vaults.forEach((v) => {
const vItem = document.querySelector(`.vault-item[data-vault="${CSS.escape(v.name)}"]`);
+4
View File
@@ -7579,6 +7579,10 @@ export function attachTreeItemLongPress(itemEl, getMenuData) {
}
export function getVaultIcon(vaultName, size = 16) {
// Dossier personnel (#194) : icône maison, même style lucide que le reste.
if (typeof vaultName === "string" && vaultName.startsWith("home-")) {
return icon("home", size);
}
const v = state.allVaults.find((val) => val.name === vaultName);
const type = v ? v.type : "VAULT";
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "obsigate",
"version": "2.64.0",
"version": "2.65.0",
"description": "**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.",
"main": "patch.js",
"directories": {
+13
View File
@@ -176,6 +176,19 @@ await test("filterSavedSearches combines with the type pills", async () => {
assert.equal(visibleSaved(), 3, "clearing both filters restores everything");
});
// ── #194 : icône du dossier personnel ──
await test("getVaultIcon returns the lucide house icon for home-* vaults", async () => {
const homeIcon = viewerMod.getVaultIcon("home-bruno", 16);
assert.equal(homeIcon.tagName.toLowerCase(), "i", "placeholder lucide (comme les autres icônes)");
assert.equal(homeIcon.getAttribute("data-lucide"), "home", "icône maison lucide");
assert.equal(homeIcon.style.width, "16px", "taille demandée respectée");
});
await test("getVaultIcon is unchanged for regular vaults", async () => {
const vaultIcon = viewerMod.getVaultIcon("Recettes", 16);
assert.equal(vaultIcon.tagName.toLowerCase(), "svg", "gemme violette SVG d'origine");
});
// ── Summary ──
console.log(`\n${passCount}/${testCount} tests passed`);
if (passCount !== testCount) {