{"id":49914507,"url":"https://github.com/guycorbaz/kesh","last_synced_at":"2026-05-16T15:09:00.766Z","repository":{"id":351774543,"uuid":"1209581976","full_name":"guycorbaz/kesh","owner":"guycorbaz","description":"Open source tiny erp","archived":false,"fork":false,"pushed_at":"2026-05-08T15:39:52.000Z","size":10307,"stargazers_count":1,"open_issues_count":17,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-08T17:30:28.693Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"eupl-1.2","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/guycorbaz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-13T15:14:07.000Z","updated_at":"2026-05-08T15:39:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/guycorbaz/kesh","commit_stats":null,"previous_names":["guycorbaz/kesh"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/guycorbaz/kesh","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guycorbaz%2Fkesh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guycorbaz%2Fkesh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guycorbaz%2Fkesh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guycorbaz%2Fkesh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guycorbaz","download_url":"https://codeload.github.com/guycorbaz/kesh/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guycorbaz%2Fkesh/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33107618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T04:41:52.686Z","status":"ssl_error","status_checked_at":"2026-05-16T04:41:52.009Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-16T15:08:56.414Z","updated_at":"2026-05-16T15:09:00.750Z","avatar_url":"https://github.com/guycorbaz.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kesh\n\n[![CI](https://github.com/guycorbaz/kesh/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/guycorbaz/kesh/actions/workflows/ci.yml)\n[![Release](https://github.com/guycorbaz/kesh/actions/workflows/release.yml/badge.svg)](https://github.com/guycorbaz/kesh/actions/workflows/release.yml)\n[![License: EUPL 1.2](https://img.shields.io/badge/license-EUPL--1.2-blue.svg)](https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12)\n[![Rust](https://img.shields.io/badge/rust-1.85-orange.svg)](https://www.rust-lang.org/)\n[![SvelteKit](https://img.shields.io/badge/svelte-5-ff3e00.svg)](https://svelte.dev/)\n\n**Kesh** est un logiciel de comptabilité et de gestion pour indépendants, TPE et associations en Suisse. Gratuit, open source, auto-hébergé.\n\n## Table des matières\n\n- [Fonctionnalités](#fonctionnalités)\n- [Pile technique](#pile-technique)\n- [Démarrage rapide](#démarrage-rapide)\n- [Structure du projet](#structure-du-projet)\n- [Développement](#développement)\n- [Tests](#tests)\n- [Feuille de route](#feuille-de-route)\n- [Contribuer](#contribuer)\n- [Licence](#licence)\n\n## Fonctionnalités\n\n- **Comptabilité en partie double** — plan comptable suisse, écritures validées, audit log\n- **Carnet d'adresses \u0026 catalogue produits** — contacts, conditions de paiement, TVA\n- **Facturation QR Bill 2.2** — génération PDF conforme au standard suisse\n- **Import bancaire CAMT.053 + CSV multi-encodage** — parser + persistance + UI ✓, profils banque réutilisables ✓, réconciliation automatique avec score ✓, réconciliation manuelle ✓, éclatement de transaction agrégée ✓ et règles d'affectation automatique ✓\n- **Paiements pain.001.001.03** — fichiers de paiement ISO 20022 *(à venir)*\n- **TVA suisse** — calcul et rapports par période *(à venir)*\n- **Multilingue** — FR, DE, IT, EN\n- **Multi-utilisateurs** — RBAC avec rôles, JWT + refresh tokens, isolation multi-tenant par `company_id`\n\n## Pile technique\n\n- **Backend** : Rust 1.85 (édition 2024), Axum, SQLx\n- **Frontend** : SvelteKit 2 + Svelte 5, TypeScript, Tailwind CSS 4\n- **Base de données** : MariaDB 11.4\n- **Déploiement** : Docker Compose (web app uniquement)\n- **Tests** : `cargo test`, Vitest, Playwright\n\n## Démarrage rapide\n\n### Prérequis\n\n- Rust ≥ 1.85 (installé automatiquement via `rust-toolchain.toml`)\n- Node.js ≥ 20\n- Docker + Docker Compose\n\n### Installation\n\n```bash\n# 1. Cloner le repo\ngit clone https://github.com/guycorbaz/kesh.git\ncd kesh\n\n# 2. Démarrer MariaDB + backend (mode dev complet)\ndocker compose -f docker-compose.dev.yml up -d\n\n# 3. Configurer l'environnement\ncp .env.example .env\n# Adapter les valeurs dans .env\n\n# 4. Frontend (hot reload)\ncd frontend\nnpm install\nnpm run dev\n```\n\nL'application est accessible sur http://localhost:5173 (frontend dev) et http://localhost:3000 (API).\n\n### Image Docker (production)\n\nLes images officielles sont publiées sur Docker Hub à chaque tag `v*.*.*` :\n\n```bash\ndocker pull guycorbaz/kesh:latest\n```\n\n## Structure du projet\n\n```\nkesh/\n├── crates/                  # Backend Rust (workspace multi-crates)\n│   ├── kesh-core/           # Logique métier pure (types, validation)\n│   ├── kesh-db/             # Persistance MariaDB, migrations\n│   ├── kesh-api/            # Serveur HTTP Axum\n│   ├── kesh-i18n/           # Internationalisation (Fluent)\n│   ├── kesh-qrbill/         # Génération QR Bill 2.2\n│   ├── kesh-payment/        # Fichiers pain.001\n│   ├── kesh-import/         # Parseurs CAMT.053, CSV\n│   ├── kesh-reconciliation/ # Rapprochement bancaire\n│   ├── kesh-report/         # Bilan, résultat, balance\n│   └── kesh-seed/           # Données d'amorçage\n├── frontend/                # SvelteKit SPA\n├── charts/                  # Plans comptables suisses\n├── docs/                    # Documentation technique\n└── .github/workflows/       # Pipelines CI/CD\n```\n\n## Architecture\n\n### Multi-tenant (Story 6.2)\n\nKesh supporte plusieurs sociétés par instance via un modèle multi-tenant :\n\n- **JWT claims** : chaque token contient `user_id`, `role`, et **`company_id`**\n- **Scoping** : toutes les requêtes filtrent par `company_id` du JWT (défense en profondeur contre IDOR)\n- **Onboarding** : création de la company lors de l'inscription (contrat Story 6.1)\n- **Foreign Key** : `users.company_id` NOT NULL, FK vers `companies.id`\n\nChaque user est assigné à exactement une company. Le `company_id` est inclus au JWT à la connexion (story 1.5) et utilisé pour scoper tous les accès aux ressources (comptes, contacts, factures, écritures comptables, etc.).\n\n### Recherche full-text (Story 7.4)\n\nLes recherches sur les colonnes texte longues utilisent un index `FULLTEXT` MariaDB avec `MATCH AGAINST IN BOOLEAN MODE` (10×+ speedup vs `LIKE '%query%'` au-delà de ~50k lignes) :\n\n- **4 colonnes indexées** : `contacts.name`, `products.name`, `products.description`, `journal_entries.description`.\n- **LIKE conservé** sur les colonnes structurées courtes (`email`, `invoice_number`, `payment_terms`).\n- **UX prefix-search** préservée via auto-append `*` côté repository (`Mar*` matche `Marie`).\n- **Régression v0.1 documentée** : perte du mid-word search (`argo` ne matche plus `Camargo`) — accepté pour v0.1, traçable via 3 régression detectors actifs.\n\nDétails du pattern, limitations BOOLEAN MODE, runbook récupération échec migration : [docs/search-patterns.md](docs/search-patterns.md).\n\n## Développement\n\n### Commandes utiles\n\n```bash\n# Backend\ncargo build --workspace\ncargo clippy --workspace --all-targets -- -D warnings\ncargo fmt --all\n\n# Frontend\ncd frontend\nnpm run check          # svelte-check\nnpm run build          # build production\n```\n\n### Workflow Git\n\n- Branche principale : `main`\n- Les commits sur `main` déclenchent le pipeline CI (tests + build).\n- Les tags `v*.*.*` déclenchent le pipeline Release (build et push Docker Hub).\n\n## Tests\n\n```bash\n# Tests unitaires + intégration backend\nDATABASE_URL='mysql://root:...@127.0.0.1:3306/kesh' \\\n  cargo test --workspace -- --test-threads=1\n\n# Tests unitaires frontend\ncd frontend \u0026\u0026 npm run test:unit\n\n# Tests E2E Playwright\ncd frontend \u0026\u0026 npm run test:e2e\n```\n\n\u003e **Note** : les tests d'intégration SQLx créent des bases éphémères `_sqlx_test_*`. L'utilisateur DB doit avoir les droits `CREATE/DROP` sur `*.*` (en local, utiliser `root`).\n\n## Feuille de route\n\nLe projet suit une approche **BMAD** (Breakthrough Method of Agile AI-driven Development) avec une feuille de route structurée en epics :\n\n| Version | Epics | Statut |\n|---------|-------|--------|\n| v0.1 | E1 Fondations \u0026 Authentification, E2 Onboarding \u0026 Configuration, E3 Plan comptable \u0026 Écritures, E4 Carnet d'adresses \u0026 Catalogue, E5 Facturation QR Bill, E6 Qualité \u0026 CI/CD, E7 Technical Debt Closure, E8 Import bancaire \u0026 Réconciliation | ✅ Done |\n| v0.1 | E9 Rapports \u0026 Exports, E10 Déploiement \u0026 Opérations | 📋 Backlog |\n| v0.2 | E11 TVA Suisse, E12 Avoirs \u0026 Paiements (pain.001), E13 Budgets, E14 Clôture d'exercice, E15 Justificatifs, Lettrage \u0026 Compléments (inc. journaux personnalisables) | 📋 Backlog |\n\nDétails : [PRD complet](_bmad-output/planning-artifacts/prd.md).\n\n## Contribuer\n\nLes contributions sont les bienvenues. Merci d'ouvrir une issue avant tout changement significatif pour en discuter.\n\n- Respecter les règles de qualité du code (`CLAUDE.md`)\n- Ajouter des tests pour toute nouvelle logique métier\n- `cargo fmt` + `cargo clippy` doivent passer sans warning\n\n## Licence\n\nDistribué sous licence [EUPL 1.2](https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguycorbaz%2Fkesh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguycorbaz%2Fkesh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguycorbaz%2Fkesh/lists"}