尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Logiciel de cabinet dentaire : odontogramme anatomique, charting parodontal avec diagnostic automatique, imagerie, aide à la décision clinique, plans de traitement, agenda, facturation et pilotage. Interface en français, fonctionnement hors ligne, données chiffrées sur le poste. → Galerie complète : 19 captures de tous les modules查看完整 README ↗
Logiciel de cabinet dentaire : odontogramme anatomique, charting parodontal avec diagnostic automatique, imagerie, aide à la décision clinique, plans de traitement, agenda, facturation et pilotage. Interface en français, fonctionnement hors ligne, données chiffrées sur le poste.
→ Galerie complète : 19 captures de tous les modules
| Odontogramme anatomique | Les couronnes ne sont pas des cases : chacune est dessinée à ses dimensions réelles et posée sur la courbe de l'arcade. |
| Diagnostic parodontal automatique | Sondage à six sites par dent, stade et grade selon la classification 2018, avec le raisonnement affiché. |
| Journal inviolable | Chaque modification est tracée. Le schéma dentaire se rejoue à n'importe quelle date, et chaque dent a sa biographie. |
| Aide à la décision explicable | Des règles déterministes croisent traitements, allergies et actes programmés. Jamais de boîte noire. |
| Chiffré au repos | AES-256-GCM, clé dérivée de la phrase secrète du cabinet. Sans elle, le disque est illisible. |
| Hors ligne et installable | Aucune dépendance réseau à l'exécution. S'installe comme une application. |
S saignement, P plaque,
U suppuration, flèches pour naviguer. Profondeurs colorées du vert au rouge sombre.La perte d'attache retenue pour la stadification distingue le sulcus physiologique d'une vraie perte : un parodonte sain n'est pas classé à tort en parodontite. La définition de cas exige deux dents non adjacentes, et les dents absentes sont exclues des indices.
Des règles déterministes, chacune motivée par la donnée qui l'a déclenchée :
Le tableau de bord agrège la vigilance sur l'ensemble du cabinet.
setErreur par fichier : en déposant cinq
documents, un seul était signalé.Le catalogue d'actes n'est pas câblé sur un seul pays. Le cabinet choisit sa nomenclature dans les paramètres, ce qui change d'un coup le catalogue, les régimes proposés et la devise conseillée :
| Nomenclature | Actes | Régimes |
|---|---|---|
| France — CCAM | 23 | Assurance maladie 70 %, CSS 100 %, sans couverture |
| Maroc — NGAP / TNR | 14 | CNSS 70 %, CNOPS 80 %, sans couverture |
Le remboursement se calcule partout de la même façon : tarif de référence × taux du régime du patient. C'est la base de remboursement en France, la Tarification nationale de référence au Maroc. Chaque patient porte son régime, et un dossier dont le régime n'existe pas dans la nomenclature active est signalé plutôt que calculé en silence à zéro.
Encaissements, taux de recouvrement, taux d'acceptation des devis (en nombre et en valeur, calculé sur les seuls devis décidés), taux de rendez-vous non honorés, charge par praticien, répartition des actes, actes réalisés jamais facturés, et moteur de rappels listant les patients à recontacter — les patients déjà reprogrammés étant écartés.
⌘K / Ctrl+K ouvre n'importe quel dossier, écran ou action sans quitter le clavier, avec recherche
insensible aux accents sur nom, téléphone, e-mail, numéro de sécurité sociale et mutuelle.
Registre des cycles, obligation réglementaire en France pour les dispositifs réutilisables. Mais l'enjeu n'est pas de tenir un registre : c'est de pouvoir répondre, un jeudi, à la question « le test biologique du cycle 148 est revenu positif, quels patients ont reçu ces instruments ? ».
muter accepte désormais un lot d'événements.Le journal en ajout seul existait depuis le début, mais n'était affiché nulle part comme suite d'événements : il ne servait qu'à la remontée temporelle et à la biographie d'une dent. Un praticien ne pouvait pas lire ce qui s'était passé dans un dossier, et l'invalidation d'un cycle de stérilisation n'aurait atteint personne.
Un onglet Historique le rend lisible : fil chronologique, filtres par nature, auteur et dent concernée, et un bandeau rouge pour les événements de traçabilité qui demandent une action.
En l'affichant, un défaut est apparu : les écritures nommaient les états par leur clé technique, « Dent 45 : a_extraire ». Corrigé pour les écritures à venir. Les anciennes gardent leur texte, puisque le journal ne se réécrit pas, et c'est précisément le propos.
Un fil embarqué sur les technologies, la recherche et le cadre de remboursement. Il est livré avec le logiciel et daté : l'application ne passe aucun appel réseau, et un fil qui interrogerait un serveur contredirait sa promesse centrale. Il est mis à jour avec les versions, ce qui donne à la maintenance annuelle un contenu tangible.
Trois règles, tenues par les tests plutôt que par la discipline (src/test/veille.test.ts) :
La page avoue son âge : passé six mois sans mise à jour, elle prévient que l'absence de nouvelle est plus probablement un défaut de mise à jour qu'un calme du secteur.
Stock des consommables, seuils de réapprovisionnement et bons de commande imprimables, groupés par fournisseur.
Le catalogue de départ ne nomme aucune marque et aucun fournisseur : ce sont des désignations génériques proposées en autocomplétion, que le cabinet remplace par ses propres références.
Ce n'est pas une place de marché. Il n'y a ni commande en ligne, ni paiement, ni catalogue distant : cela demanderait un serveur, des fournisseurs sous contrat et un prestataire de paiement, c'est-à-dire exactement ce que ce logiciel n'a pas.
Les données ne quittent jamais le poste : aucun serveur, aucun envoi réseau, aucune dépendance CDN.
Le coffre, activable dans les paramètres, chiffre l'intégralité du magasin :
La phrase secrète n'est stockée nulle part. Perdue, les données sont irrécupérables. Exportez une sauvegarde avant d'activer le coffre.
Cette application n'est pas un dispositif médical et n'intègre pas d'authentification multi-postes. Avant tout usage sur des données de santé réelles, prévoyez l'hébergement et les mesures exigés par la réglementation applicable (en France, hébergement de données de santé et RGPD). Les règles d'aide à la décision sont une assistance, jamais une prescription : le praticien reste seul responsable.
npm install
npm run dev # http://localhost:5173
Au premier lancement, un cabinet de démonstration complet est chargé — 8 patients, schémas dentaires renseignés, sondages parodontaux, actes, rendez-vous, factures, devis et journal historique — pour que chaque écran soit immédiatement utilisable. Remplaçable ou effaçable depuis Paramètres → Données.
npm run build # build de production + précache du service worker
npm run preview # sert le build de production
npm run test # 168 tests (Vitest)
npm run lint # vérification TypeScript
Le site porte deux documents distincts, voisins dans le même dossier publié :
| Adresse | Document | Rôle |
|---|---|---|
/ | index.html | Vitrine publique : HTML servi tel quel, indexable |
/app.html (ou /app) | app.html | Poste de travail clinique, React |
La vitrine est écrite à la main, en HTML et CSS, sans React ni Tailwind. Elle pèse une dizaine de kilo-octets de feuille de style et moins d'un kilo-octet de script, et elle ne charge pas le paquet applicatif : une personne qui découvre le produit n'a aucune raison de télécharger le charting parodontal et la visionneuse d'imagerie.
Quelques points qui ne se devinent pas à la lecture des fichiers :
app.html est un fichier voisin de index.html, pas un sous-répertoire.
Toutes les adresses relatives de l'application (./assets, ./sw.js,
./manifest.webmanifest) continuent donc de résoudre, et le service worker
garde la racine pour portée.animation-timeline: view(),
sous @supports). Une version pilotée en JavaScript laissait toute la page
invisible si le script échouait à se charger. Sans le script, et sur les
navigateurs sans défilement animé, le contenu s'affiche simplement./#/patients est redirigé vers /app.html#/patients, et une
application déjà installée, qui démarre en fenêtre autonome, va directement au
poste de travail sans passer par la page de présentation.app.html : on installe un outil de travail, pas
une page de présentation.Les montants vivent en un seul endroit, en tête de src/vitrine/vitrine.ts :
LICENCE, MAINTENANCE et MOIS_COMPARES. Les mêmes chiffres sont écrits en
toutes lettres dans index.html, section #tarif : changer l'un sans l'autre
donnerait une page qui se contredit.
Le comparateur ne contient aucun prix de concurrent. Le visiteur saisit son propre abonnement, et le calcul se fait contre notre coût le plus défavorable, maintenance prise chaque année. Publier le tarif d'un confrère reviendrait à se porter garant d'une information qui vieillit et qu'on ne maîtrise pas.
Le modèle : la licence couvre la première année de mises à jour, la maintenance court à partir de la deuxième. Le mois de bascule est le premier mois où l'abonnement cumulé dépasse la licence cumulée. Quand il n'existe pas sur dix ans, la page le dit et conseille de garder l'abonnement en place.
Les captures de la vitrine sont dérivées de docs/ par
node scripts/vitrine-images.mjs, qui les réduit à la largeur d'affichage et
les convertit en WebP (environ 420 Ko pour l'ensemble, contre 3 Mo en PNG). Les
sorties sont versionnées dans public/vitrine/ : la compilation n'a pas besoin
de sharp.
src/
components/
OdontogrammeArcade.tsx Arcade anatomique (pose, rotation, faces cliquables)
DentalChart.tsx Vue grille
ToothPanel.tsx Dent sélectionnée + biographie
perio/ Grille de sondage, panneau de diagnostic, onglet
OngletImagerie.tsx Import, galerie, visionneuse annotable
OngletDevis.tsx Devis à variantes et comparateur
OngletOrdonnances.tsx Modèles de prescription
PanneauAlertes.tsx Aide à la décision
PanneauRisques.tsx Profils de risque carieux et parodontal
PaletteCommandes.tsx ⌘K
EcranVerrouillage.tsx Déverrouillage du coffre
ui/ Primitives (Button, Card, Modal, Field, Badge…)
pages/ Dashboard, Patients, PatientDetail, Agenda,
Traitements, Facturation, Pilotage, Parametres
data/
teeth.ts Numérotation FDI, anatomie, états cliniques
anatomie.ts Dimensions coronaires, pose sur l'arcade, silhouettes
perio.ts Mesures, indices, classification 2018
actes.ts Catalogue CCAM
medicaments.ts Modèles d'ordonnance et contre-indications
seed.ts Jeu de démonstration
lib/
crypto.ts Coffre AES-GCM / PBKDF2
storage.ts Persistance, migrations, export/import
imagerie.ts IndexedDB, vignettes, chiffrement des binaires
fournitures.ts Seuils, quantités à commander, groupement par fournisseur
veille.ts Fil professionnel daté, sources et niveaux de maturité
sterilisation.ts Statut des cycles, invalidation rétrospective, remontée aux patients
dicom.ts Lecture des DICOM non compressés, fenêtrage, conversion
decision.ts Règles cliniques et profils de risque
historique.ts Rejeu du journal, biographie, activité
finance.ts Totaux, statuts, numérotation
pilotage.ts Indicateurs et moteur de rappels
store/AppContext.tsx État applicatif, journalisation, coffre
types/ Modèle de domaine typé
Pile technique : React 18, TypeScript strict, Vite, Tailwind CSS, React Router, Vitest + Testing Library. Aucune dépendance réseau à l'exécution — polices système, pas de CDN.
Dossier dans localStorage (clé suivi-patient-dentaire:v1), images dans IndexedDB, chiffrés quand
le coffre est actif. Les sauvegardes v1 sont migrées automatiquement en v2.
Pour un usage multi-postes, src/lib/storage.ts est le seul module à réécrire : tout le reste passe
par le magasin src/store/AppContext.tsx.
168 tests couvrent :
npm run test
netlify.toml est fourni et couvre la configuration complète :
sw.js et index.html toujours revalidés — sans quoi un poste resterait
bloqué sur une version périmée ; /assets/* mis en cache définitivement
puisque leurs noms portent un hachage ;manifest.webmanifest servi en application/manifest+json, faute de quoi
l'application cesse d'être installable sans aucun message d'erreur ;script-src reste à
'self' sans unsafe-inline ;X-Robots-Tag: noindex ne porte plus sur tout
le site mais sur /app.html seul, pour que la vitrine soit référençable et
que le poste clinique ne le soit pas. robots.txt et sitemap.xml disent la
même chose ;/app vers /app.html.La CSP a été vérifiée dans un navigateur contre l'application compilée : tous
les écrans, l'import d'images (blob:), la génération de vignettes, le service
worker, l'activation du coffre WebCrypto et l'export de sauvegarde, sans aucune
violation. La vitrine a été éprouvée de la même façon, en bureau et en mobile :
elle ne porte ni script ni style en ligne, et passe donc la politique sans
recourir à unsafe-inline.
Le chiffrement et le service worker exigent un contexte sécurisé : HTTPS est indispensable, sinon les deux se désactivent silencieusement.