Centralise la réserve via ai-quota, corrige admin unavailable (-1), brancher les routes sans quota et le host-pays brainstorm, avec usage-meter élargi, noms de clusters, MCP et ajustements dashboard/insights. Co-authored-by: Cursor <cursoragent@cursor.com>
20 KiB
20 KiB
Agent memory (Memento)
Learned User Preferences
- Préfère les échanges en français, avec des explications détaillées et claires (éviter le jargon flou) ; nom produit : Memento (jamais « Momento ») — libellés, metadata, pages publiques, docs.
- Interface : tout libellé via i18n dans les 15 fichiers
memento-note/locales/*.json(FR et EN comme références de contenu) ; éviter le texte en dur ; traductions contextuelles (sens produit, pas mot à mot — ex. « connecter votre propre fournisseur ») ; libellés FR lisibles (éviter jargon non expliqué : « wiki », « embed », etc.) et aide contextuelle où l'UX l'exige ; lors d'une traduction complète, mettre à jour toutes les locales concernées ; si l'utilisateur demande seulement les clés i18n, ajouter les clés (souvent EN/FR) sans remplir les 15 locales — il traduit souvent avec un autre modèle ; insights Memory Echo (texte généré/stocké) : langue utilisateur à la génération + fallback i18n à l'affichage (memoryEcho.defaultInsight) — jamais d'anglais en dur quand l'UI est FR. - Base de données : INTERDIT TOTALEMENT de lancer
prisma db push --force-reset,prisma migrate reset,DROP TABLE,TRUNCATE,pg_restoreavec clean, ou TOUTE commande qui vide/supprime des données — MÊME SI l'utilisateur est d'accord — sans avoir d'abord : (1) dumpé la base avecbash /home/devparsa/dev/Memento/dump-db.sh, (2) vérifié le dump fait au moins 1Mo, (3) obtenu un "OUI" explicite de l'utilisateur. 4 incidents de perte de données documentés (14/05, 15/05 x2, 16/05). NE JAMAIS REFAIRE ÇA. - Design produit : migration depuis
architectural-grid1(base) etarchitectural-grid(prototype UI courant) ; consulter le prototype avant toute implémentation UI ; logique liste/carte puis contenu au clic ; parité actions liste/carte (menus « … », déplacer, génération SVG, etc.) ; contraste éditeur clair / sidebar sombre ; retirer thèmes obsolètes ; pas de refresh/revalidation complets inutiles (aligné prototype — mutations optimistes, pas derevalidatePathsystématique ni resync depuisinitialNotes) ; Memory Echo en section inline dans l'éditeur (pas l'ancienne modale) — similarité sur contenu représentatif (pas de troncature arbitraire type 200/800 car.) ; recherche (sidebar / résultats, ex. flux « ouvrir la note ») et navigation liste des notes (modes affichage, icônes vs initiales…) : suivreSearchModalet les patterns actuels dansarchitectural-grid, pas une approximation ou un ancien flux ; sidebar rail (sidebar.tsx) : une seule icône active ; largeur sidebar (components/sidebar.tsx) — redimensionnement utilisateur par poignée sur le bord droit (desktopmd+, 280–560px, persistélocalStoragememento-sidebar-width) ; défaut responsivew-80puis plus large enxl/2xlsi aucune valeur stockée ; hauteur zone carnets ajustable via poignée horizontale (memento-sidebar-notebooks-height, min 120px) ; fallbackSuspensedeapp/(main)/layout.tsxaligné sur les largeurs par défaut (rail fixe 54px) ; pas de bouton « Note du jour » dans la sidebar (retiré volontairement) ; dashboard Second Brain (/home,dashboard-view.tsx) : vue d'ensemble interactive (pas dashboard statique/mort) — layout v5 configurable (catalogue ~15 widgets, persisté/api/dashboard/layout) ; widget « Prochaines pistes » (next-paths) = recommandations actionnables depuis la dernière note éditée (fast paths briefing puis enrichissement async/api/briefing/paths) ; widget « Revue quotidienne » = checklist matinale interactive (inbox, découvertes IA, connexion, flashcards) — pas une revue automatique de contenu ; cartes cliquables, section Memory Echo « L'IA a trouvé » exploitable (pas vide après 1ère visite), consentement/provider IA + quotas vérifiés sur chaque action IA (dashboard et agents) ; icônes Lucide (pas emojis système type 🎯) ;MindMapCardremplace l'ancienMiniResonanceGraphD3 (graphe décoratif qui débordait) ; navigation sidebar alignée sur/home;activeViewsynchronisé avec pathname et query (/insights,/revision,/home?reminders=1) ; panneau latéral contextuel par route (pas la liste carnets sur/insightsou Rappels) ;/insights(insights sémantiques) : suivreInsightsView.tsx+ graphe réseau associé dans le prototype (ex. composition typeNetworkGraph.tsx) ; distincte de/graph; ne pas substituer par une UX « géométrique » décorative ou un regroupement par carnet hors spec prototype ; lorsque données clusters en retard ou partiellement périmées, montrer l’état dégradé exploitable plutôt qu’une page vide ; bouton Menu immersif/insights: cacher la sidebar ET agrandir le contenu principal (pas de bandeau beige vide — attentiontwMergequi peut faire perdrefixedau profit derelative) ; si l'utilisateur hésite entre variantes UX, trancher pour le design prototype plutôt que multiplier les toggles. - Locale persane : dates en calendrier iranien (conversion), chiffres persans, et vérification RTL/positionnement global (app et extension Web Clipper) ; Memory Echo et recherche sémantique doivent fonctionner en persan (RTL, embeddings — pas de contournement « EN only ») ; attention à ne pas confondre un nom de carnet (ex. « Persan ») avec le libellé de langue.
- Flux Excalidraw / diagrammes générés : accès via notification en plus d'une simple redirection ; priorité à la mise en page et au texte contenu dans les formes ; proposer des modes visuels (ex. coloré vs plus austère) tout en visant un rendu proche du style Excalidraw (polices, look).
- Interdiction d'écrire des tests sauf demande explicite ; en CI, seul
npm run test:unit(tests/unit/**) — pastests/migration/; ne jamais générer de code superflu. - Déploiement : privilégier le chemin rapide (artifact Next.js en CI +
Dockerfile.prebuilt) ; CI/CD très robuste (pas d'image Docker obsolète en prod, pas de migrations/schéma DB via le workflow deploy) ; éviter les rebuild Docker complets inutiles (~15 min par itération) ; ne pas pousser un déploiement quand des features clés sont inachevées ; ne pas insister sur le déploiement tant que le produit n'est pas fini ou meilleur ; ne jamais hardcoder d'IP/URL dans le repo ou les défauts CI — uniquement variables d'env (ex.GRAFANA_BIND,GRAFANA_URL) ; la config runtime reste sur le serveur dans.env.docker. Machines : agent/dev = 192.168.1.83 (devSanbox) ; prod = 192.168.1.190 (/opt/memento) — ne jamais confondre les deux au diagnostic services. CI/CD Gitea spécifique : (1) CIubuntu-24.04= lint + tests + build (validation) ; deploydocker-host= build sur le serveur →/tmp/web-artifact.tgz→deploy-prod.sh— sans upload/download-artifact inter-runners (stockage Gitea instable ; si artifacts utilisés, @v3 uniquement — @v4 →GHESNotSupportedError) ; (2)Dockerfile.socket.prebuiltdoit utiliser--legacy-peer-depsdansnpm install(conflit TipTap 3.22.5 vs 3.23.6) ; (3) le serveur de prod (192.168.1.190) ne peut pas pull Docker Hub (DNS cassé) — le build Docker complet échoue, seul le chemin prebuilt artifact fonctionne ; (4)docker-entrypoint.shapplique les migrations Prisma avant de démarrer le serveur Next.js (ordre correct) ; (5) rollback d'urgence :docker tag memento-memento-note:rollback memento-memento-note:latest && docker compose up -d --force-recreate memento-note; (6)scripts/deploy-prod.shcharge/opt/memento/.env.dockervia un parseur robuste ligne-par-ligne (jamaissource— crashunexpected EOFsur guillemet non fermé) et teste Postgres avecpg_isready+ credentials du conteneur ($POSTGRES_USERinterne) ; (7) lint CI =eslint --max-warnings 9999: les warnings ne bloquent pas, seules les erreurs bloquent (ex.no-html-link-for-pages→<Link>obligatoire pour la navigation interne, pas<a href="/">) ; TRAVAILLER SUR UNE BRANCHE pendant le dev, ne push surmainque quand le code est testé et fonctionnel — avant pushmain: exécuter localementnpm run lint,npm run test:unit,npm run build(même enchaînement que CI) ; chaque push surmaindéclenche un déploiement automatique en production. - Authentification : priorité à l'inscription/connexion via Google OAuth (plutôt qu'un compte email/mot de passe) ; exiger une vraie déconnexion (invalidation session/cookies — pas de reconnexion implicite, y compris en navigation privée) ; prod :
AUTH_GOOGLE_ID/AUTH_GOOGLE_SECRETdans/opt/memento/.env.dockeret variables/secrets Gitea Actions (workflow deploy n'écrit pas les valeurs vides) — absence →invalid_client; redirect URI exactehttps://memento-note.com/api/auth/callback/google; config via Google Auth Platform (Branding → Audience In production, pas Testing → Clients Web) ;ALLOW_REGISTRATION=truerequis pour inscription email (env ouSystemConfigen base — la DB peut primer sur l'env). - Priorité absolue à la qualité UX, même si l'implémentation est complexe (« je m'en fous si c'est complexe ») ; pour les tâches ops (config OAuth prod, serveur), préfère un guidage interactif étape par étape plutôt qu'un bloc d'instructions monolithique ; ne jamais affirmer qu'un correctif ou une feature est fait sans vérification réelle (app, prototype
architectural-grid, ou test), notamment navigation recherche/liste notes et vue/insightsvs fichiers prototype — l'utilisateur sanctionne fermement les fausses déclarations ; ouverture note liée depuis l'éditeur (ex. bloc live « Ouvrir ») : split peek inline animé (lib/note-peek-sync.ts,note-editor-split-peek.tsx— éditeur courant à gauche, note liée en lecture seule à droite en LTR ; inversé en RTLfa/ar), pas nouvel onglet ; ne jamais annuler du code non commité (git checkout, reset fichier) sans demande explicite (perte de travail documentée, ex. drag handle éditeur) ; ne jamais remettre du code que l'utilisateur a explicitement retiré sans demander d'abord (ex.reserveUsageOrThrowretiré intentionnellement deorganize-notebook.ts— agent l'a remis sans demander → user mécontent) ; correction i18n ou spec doc : ne pas refondre logique/UI hors scope (ex. US-4structuredViewBlock— garder le dual-mode base locale + lien carnet, pas de suppression du mode local) ; en frustration ou pour déléguer, prévoir des prompts / briefs d'implémentation détaillés (autre modèle ou dev), en plus des briefs outil de design. - Livraison : une user story à la fois, tester et valider avec l'utilisateur avant la suivante (pas d'auto-validation ni d'enchaînement de code non demandé) ; suivi dans
docs/user-stories.md; briefs pour outil de design externe sur demande ; avant de développer une story, vérifier d'abord dans le code si la feature existe déjà — les docs de stories (docs/story-nextgen-editor.md,docs/user-stories.md) sont souvent périmés (features livrées mais marquées « à faire ») ; dashboard Second Brain : même rythme — une feature à la fois, validation explicite avant la suivante. - Facturation & quotas IA : limites mensuelles, tiers (BASIC/PRO/BUSINESS/ENTERPRISE) et Price IDs Stripe via Admin > Facturation & quotas (
/admin/billing) — pas via.envpour le métier ; secrets Stripe (STRIPE_SECRET_KEY, webhook) restent en env serveur ; docmemento-note/docs/admin-billing-quotas-guide.md; tier BASIC sans accès MCP ; chaque usage IA (dashboard, agents, MCP si autorisé, etc.) doit décompter le quota — ne pas affirmer un déploiement prod sans vérif réelle (ex. travail MCP/quotas encore local).
Learned Workspace Facts
- Application Next.js principalement sous
memento-note/. - Référentiels design du workspace :
architectural-grid1/etarchitectural-grid/à la racine du repo Memento. - i18n : 15 fichiers sous
memento-note/locales/(de, en, es, fr, it, pt, nl, pl, ru, zh, ja, ko, ar, fa, hi) ; logique sousmemento-note/lib/i18n/; référenceen.json(~2218 clés) ; auditer les « non traduits » par flatten EN vs locale (souvent valeurs identiques à l'EN). - Workflow BMad : stories sous
docs/(ex.3-4-host-pays-session-logic.md), suivi sprint dansdocs/sprint-status.yamlet stories courantes dansdocs/user-stories.md; skills sous.claude/skills/bmad-*;_bmad-output/planning-artifactssouvent vide — planification de référence dansdocs/; préférer une user story par feature (pas de stories groupées). - PostgreSQL Docker (
memento-postgres) port 5433 ; Redis (memento-redis) port 6379 ; règles Prisma/DB dansCLAUDE.md. - Admin facturation : page
/admin/billing(billing-admin-client.tsx, actionsadmin-billing.ts) — quotas par feature IA et config Stripe métier en base, effet ~60 s ; guidememento-note/docs/admin-billing-quotas-guide.md. - Hosts : machine agent/dev (192.168.1.83, Vibe/annotations locales) ≠ prod (192.168.1.190, dépôt
/opt/memento) — ne jamais diagnostiquer l'un pour l'autre. Production : conteneurmemento-noteport 3000, URL publique https://memento-note.com (nginx + Cloudflare ; ancien domaine note.parsanet.org) ;NEXTAUTH_URLaligné sur ce domaine ; auth prod requiertAUTH_GOOGLE_ID/AUTH_GOOGLE_SECRETdans.env.docker(sinon OAuthinvalid_client) etALLOW_REGISTRATION=truepour l'inscription email ; email sortant via Resend (SMTP_FROMex.noreply@memento-note.com, domaine vérifié sur resend.com) ; monitoring Grafana viaGRAFANA_BIND/GRAFANA_URLdans.env.docker(pas d'IP en dur dans le compose) ; deploy (deploy.yaml/deploy-prod.sh) sans toucher Postgres (pas depostgresql-client, pas de migrations auto en prod). - CI/CD Gitea :
.gitea/workflows/ci.yaml— CI surubuntu-24.04(lint + tests + build validation), deploy sur runnerdocker-host(build local/tmp/web-artifact.tgz, sans artifacts inter-runners) ; deploy manuel via.gitea/workflows/deploy.yamloubash scripts/deploy-prod.sh. - Migrations prebuilt + vérif deploy :
docker compose exec memento-note node ./node_modules/prisma/build/index.js migrate deploy(pasnpx prisma) ; helperscripts/migrate-docker.sh;GET /api/build-info(SHA Git) ; comparer127.0.0.1:3000et domaine Cloudflare — purger cache si versions divergent ; 403/api/manifestcôté domaine = souvent Cloudflare. - Éditeur riche :
rich-text-editor.tsx—immediatelyRender: false; activershouldRerenderOnTransaction: false(quick win perf TipTap 2.5) ; drag handle / menu bloc via@tiptap/extension-drag-handle-react(spec officielle — pas de double pluginDragHandleExtension+ composant React, pas de repositionnement maison) ; poignée dans colonne gutter fixe du wrapper (padding +getReferencedVirtualElement), pas sur le bord des listes/numéros ; CSS : pasopacity:0sur.drag-handle(visibilité gérée par le plugin) ; config/callbacks stables hors composant ; fondation blocs :tiptap-unique-id-extension.ts/data-idpersisté à la sauvegarde (références « Copier la référence ») ; Smart Paste :lib/editor/smart-paste-extension.ts; peek split note source :lib/note-peek-sync.ts+note-editor-split-peek.tsx; conversion markdown → texte enrichi : un seul convertisseurlib/markdown-to-html.ts(markdownToHtml, gfm+breaks) + une action atomiqueconvertToRichText(html)dansnote-editor-context.tsx(applique le HTML immédiatement viasetContentImmediate— pas lesetContentdébouncé 800ms — et basculeisMarkdown=false) ; toolbar (handleConvertToRichtext) et chat IA contextuel (contextual-ai-chat.tsx, actiontoRichText→/api/ai/convert-markdown) passent par cette action unique (ne pas dupliquer la conversion ni oublier de basculerisMarkdown) ; US-4structuredViewBlock(tiptap-structured-view-block-extension.tsx,structured-view-block-embed.tsx) : dual-mode — base locale autonome par défaut (/database,/vue,isLocal: true) + option « Lier à un carnet » (Structured Views) ; i18nstructuredViewBlock.*; rejeté : anciendatabaseBlock« Auteurs & Œuvres » et spec embed-onlydocs/story-nextgen-editor-us4-redesign.md; epic activedocs/story-nextgen-editor.md— priorité PERF > NEXTGEN > UX > MOBILE > MARKDOWN. - Sync mutations notes entre composants :
memento-note/lib/note-change-sync.ts(emitNoteChange, événementNOTE_CHANGE_EVENT) ; tracking quotas IA : événementai-usage-changed(window) — doit être dispatché depuis tous les points d'appel IA (recherche sémantique, auto-tag, auto-title, chat, reformulation, analyse carnet, etc.) ; UI quotas :usage-meter.tsx(polling 5s + écoute événement). - Roadmap / écart prototype vs prod : Web Clipper —
ClipperSimulator.tsx= référence design uniquement (pas de simulateur en prod) ; extensionmemento-note/extension/v0.3 Side Panel (clip page/sélection/lien ; popup Chrome se ferme au clic page — Side Panel pour la sélection) ; i18n extension 15 langues (_locales/, détection locale navigateur ; scriptextension/i18n/generate-translations.cjs) ;host_permissionsincl. LAN ; URL serveur configurable en dev, adresse prod figée en release ; cookies/session alignés avec l'instance cible ; Flashcards IA SM-2 livrées :/revision,/api/flashcards/*, génération depuis l'éditeur (GraduationCap) — réf. prototypeRevisionView.tsx; Structured Views partiellement livrées : schéma par carnet, Table/Kanban, champs partagés et valeurs par note (/home+ toolbar carnet) — suivi de tâches par carnet via Kanban structuré (pas de vue agrégée Notes/Tâches sur la home ; cases à cocher inline dans les notes) ; Éditeur Next-Gen livré (docdocs/story-nextgen-editor.mdpérimé — vérifier le code) : US-1 poignée gutter unique (editor-block-drag-handle.tsx+lib/editor/global-drag-handle-extension.ts, extension Noveltiptap-extension-global-drag-handle), US-2 menu action bloc (block-action-menu.tsx), US-3 Smart Paste transclusion (smart-paste-extension.ts+smart-paste-menu.tsx), US-4 database inline (structuredViewBlock), plusdata-id/liveBlock/ peek split ;/insightslivré :app/(main)/insights/page.tsx+network-graph.tsx(clusters sémantiques, bridge notes ; ≠/graph) ; US-TEMPORAL reporté ; encore en gap : transclusion bidirectionnelle complète, graphe knowledge enrichi (GraphKnowledgeMap.tsx) ; publication Chrome Web Store : icônes 16/48/128, privacy policy,host_permissionsprod restreints vs build dev ; Wizards :NotebookOrganizerDialog(tags/doublons) branché via bouton "Tags IA" danshome-client.tsx—StructuredViewsWizardencore orphelin (pas de point d'entrée UI) ; Publication web (note-editor-toolbar.tsx) : deux modes — simple (copie directe) + IA (2-3 templates visuellement distincts, reformulation/mise en page adaptée au contenu — exercices, toggles, callouts — images incluses, KaTeX pour équations) — quota IA consommé uniquement sur publication IA ; l'utilisateur rejette les rendus « copie du texte » / mise en page nulle ; champs DB publication sur modèleNote:publicSlug(paspublishedSlug),publishedContent(paspublishedHtml) —publishModeest paramètre API uniquement (mode: 'simple' | 'ai'), pas un champ en base ; Second Brain dashboard (/home,dashboard-view.tsx) livré : layout v5 configurable (~15 widgets,/api/dashboard/layout), briefing agrégé (/api/briefing), pistes fast+enrich (/api/briefing/paths,paths-fast.ts), suggestions agents, scan Gmail (GmailScanHistory), navigation sidebar/home; bento interactif —MindMapCard(clusters), suggestions agents (AgentSuggestion, cron), Memory Echo, sentiment, inbox/révisions ; Gmail OAuth (/api/integrations/gmail/*, pattern Calendar) — scan vols/colis/abonnements → notes + rappels ; crons entrypoint : agents, agent-suggestions, clusters, reminders, gmail-scan, sync-usage.