Aller au contenu

Guidelines

Source of truth for code, UI, and process conventions in Aletheia. Anything written here is authoritative — code that violates these guidelines should be flagged in review and fixed.

This folder is for code authors and Claude. End-user / operator documentation lives in docs/. Roadmap and planning live in roadmap/. Cross-repo API and infra contracts live in contracts/.

Why a separate top-level folder

  • Single audience per file (Claude + developers writing code), single tone.
  • Mechanical scoping for hooks, audits, and PR-time checks (guidelines/**).
  • Drift is visible: a missing file for a recurring UI or backend primitive is an obvious gap.
  • Symmetric with the existing top-level concept folders (roadmap/, contracts/, docs/).

Layout

guidelines/
  README.md                         # this file — index + status of every guideline
  ui/                               # per-component visual rules
    search-sort-filter.md
    lists.md
    forms.md
    detail-pages.md
    dropdowns.md
    badges.md
    design-tokens.md
  ux/                               # system-wide interaction patterns (cross-component)
    page-states.md
    feedback-and-confirmation.md
    navigation.md
    microcopy.md
  backend/                          # Django patterns
    views.md
    models.md
    migrations.md
    forms.md
    admin.md
  security/                         # auth, isolation, PII
    multi-tenant-isolation.md
    auth-and-permissions.md
    pii-and-logging.md
  celery/                           # background jobs and beat schedule
    task-conventions.md
  integrations/                     # external connectors (Doctolib, Pennylane, Logosw, INPI)
    overview.md
    doctolib.md
    pennylane.md
    logosw.md
    inpi.md
  imports/                          # AbstractImporter / ImportRow patterns
    abstract-importer.md
  testing/
    pytest-patterns.md
  i18n/
    translation-rules.md
  development-workflow/
    overview.md

ui/ vs ux/. ui/ is per-component visual rules (badges, lists, forms, dropdowns). ux/ is cross-component interaction patterns (empty/loading/error states, navigation, microcopy, feedback channels). When in doubt: if it's about one component's appearance, it's ui/; if it's a pattern that applies across many components, it's ux/.

Granularity rule. Every topic gets a folder, even if it currently holds a single file. Topics naturally grow (i18n splits into translation rules + model strings + JS strings; dev-workflow splits into git + environments + deploys), and folder-per-topic costs almost nothing today while making future splits painless. Audit globs stay uniform: guidelines/*/....

Naming. Folders and files are kebab-case. File names describe content, not topic (translation-rules.md, not i18n.md inside i18n/). No UPPER_CASE, no dates in filenames.

File format

Every guideline file should open with the same frontmatter so the status table stays accurate without manual bookkeeping:

# {Title}

> **Status:** Implemented | Draft | Placeholder
> **Last reviewed:** YYYY-MM-DD
> **Owner:** (optional)

## Scope
One paragraph: what this guideline covers and when it kicks in.

## Rules
The actual rules — copy-pasteable snippets preferred over prose.

## Known deviations
Where the codebase doesn't yet follow the rule, with a pointer to the roadmap item that closes the gap.

Status

Statuses: - Implemented — content is current and authoritative. - Draft — content exists but hasn't been reviewed against current code. - Placeholder — file exists to mark the gap; content to be written from an audit + skeleton/reference-page extraction.

Path Status Last reviewed Notes
i18n/translation-rules.md Draft 2025-12-04 Migrated from docs/I18N_GUIDELINES.md — verify against current LANGUAGE_CODE='nl-be' trick before promoting to Implemented
development-workflow/overview.md Draft 2026-04-14 Migrated from docs/DEVELOPMENT_WORKFLOW.md — verify deploy section still matches Makefile + deploy.sh
ui/search-sort-filter.md Implemented 2026-04-18 Authoritative for list/sort/filter stack; one known deviation (finance module) tracked in roadmap/backlog/finance-filter-unify.md
ui/lists.md Implemented 2026-04-18 Mined from skeleton + reference impls (practices, patients, holders); covers file layout, two empty states, action column, density rules; defers sort/filter to search-sort-filter.md
ui/forms.md Implemented 2026-04-18 Mined from skeleton + form-enhancements.{css,js} + holder_form (contextual reference); covers Alpine state, edit-mode safeguards, validation/auto-format hooks
ui/detail-pages.md Implemented 2026-04-18 Mined from skeleton + entity/practice references; covers heading + actions, two-column card grid, audit footer, layout-table-vs-data-table distinction; substitution cheatsheet for the 15 <h5>-in-card-header audit hits
ui/dropdowns.md Placeholder Document SearchSelect widget + sort/filter conventions for <select> options
ui/badges.md Implemented 2026-04-18 4-state status palette + badge-type family modifier pattern; entity & movement variants; flags 2 internal inconsistencies (naming scheme, hardcoded oklch in module CSS)
ui/design-tokens.md Implemented 2026-04-18 Full catalogue mined from static/css/base.css; includes audit cheatsheet for the 2026-04 hardcoded-value findings
ux/page-states.md Placeholder Empty / loading / error / no-permission states across all pages
ux/feedback-and-confirmation.md Placeholder Toast vs banner vs modal, confirmation dialog patterns
ux/navigation.md Placeholder Top nav, breadcrumbs, deep-linking, redirect-after-action rules
ux/microcopy.md Placeholder Tone, button verbs, error messages, FR/EN consistency
backend/views.md Placeholder Document SortableFilterableListMixin, HtmxResponseMixin, CBV conventions
backend/models.md Placeholder Document TimeStampedModel, AuditModel, SoftDeleteModel usage
backend/migrations.md Placeholder When to write a data migration, naming conventions
backend/forms.md Placeholder Django form / ModelForm conventions, complements ui/forms.md
backend/admin.md Placeholder When to register, list_display / list_filter / inline conventions
security/multi-tenant-isolation.md Placeholder High blast radius — practice scoping rules, queryset filtering
security/auth-and-permissions.md Placeholder Custom User, login, permission decorators / mixins
security/pii-and-logging.md Placeholder What never to log, Sentry scrubbing, PII categories
celery/task-conventions.md Placeholder Task naming, idempotency, retry, beat schedule, failure surfacing
integrations/overview.md Placeholder Shared connector patterns (auth, retry, pagination, persistence)
integrations/doctolib.md Placeholder Doctolib API, daily 3 AM sync, appointment reconciliation
integrations/pennylane.md Placeholder Pennylane Redshift + REST v2, dual-backend abstraction
integrations/logosw.md Placeholder File-based ingestion via apps/collection/ + apps/imports/
integrations/inpi.md Placeholder INPI RNE via apps/annuaire/, code→label mappings
imports/abstract-importer.md Placeholder Document AbstractImporter lifecycle, ImportRow tracking, bulk mode
testing/pytest-patterns.md Placeholder Fixture conventions, integration vs unit boundary

Roadmap for this folder

Linear bring-up (one-time)

  1. Beef up content — turn placeholders into Implemented files by mining: recent "consistency sweep" commits, reference implementations (patients/treatments/holders), and templates/skeletons/. Track as roadmap/in-progress/guidelines-flesh-out.md once started.
  2. Retroactive audit — run a subagent that grep-walks templates/ and apps/*/views.py against every Implemented guideline. Output a ranked punch list to roadmap/backlog/. Triggered after step 1 stabilises a primitive.
  3. Proactive enforcement — add a PostToolUse hook (or PR-time ui-conformance subagent) that re-runs the same checks on edited files. Should also flag new patterns that appear in code but aren't covered by any guideline — the drift-detection signal.
  4. CLAUDE.md tightening — once the guidelines folder is the single pointer surface, the CLAUDE.md "UI Design System" section becomes a thin index into guidelines/ui/ rather than a partial duplicate.

Ongoing — audit vs. challenge

Two recurring activities, different questions:

  • Audit (continuous, mechanical) — "does the code follow the rules?" — surfaces violations of existing rules. Output: backlog entries to fix code. Eventually hook-driven.
  • Challenge (periodic, judgmental) — "are the rules the right rules?" — surfaces missing rules, stale assumptions, primitives that should exist but don't. Output: ideas to evolve guidelines themselves.

Audit alone produces a locally-consistent codebase converging on possibly-suboptimal rules. Challenge alone produces evolving rules nobody adopts. Need both.

Challenge pass — template

Run a challenge against one primitive at a time. Cap at 1-2 challenges per quarter, only against primitives showing a real signal (see triggers below). Resist the urge to re-litigate everything.

Triggers — run a challenge when one is true: - Recurring deviations in audit output for the same primitive (3+ deferred items in a row → the rule is missing, not the code is wrong). - User pain surfaces in real flows (e.g. "I had to fix the dropdown sorting on every form" → ui/dropdowns.md needs a challenge). - External drift — a new reference design system landed (Material You, Geist, Primer) and our equivalent primitive feels old. - Time-based — primitive is Implemented but hasn't been reviewed in >12 months.

Process:

  1. Pick one primitive. Write the trigger in one sentence: "Challenge ui/forms.md because [reason]." If you can't fill that sentence, don't run the challenge.

  2. Spawn a challenge subagent. Skeleton prompt:

    Read guidelines/<primitive>.md. Then: - Survey 5 real implementations in the codebase that should follow it. Note where the rule fits, where it doesn't, where the implementation diverged anyway. - Compare to 1-2 external references (name them: e.g. GitHub Primer forms, Vercel Geist forms). - Identify 3 things the current rule does not address but should. - Identify 1-2 rules that look outdated or rarely useful and propose retiring or rewording them. - Output: a single Markdown report under 500 words, structured as "Keep / Change / Add / Drop." Don't write to any guideline file — just propose.

  3. Triage the report. For each Keep/Change/Add/Drop:

  4. Quick wins (clear consensus, low risk) → edit the guideline directly, bump Last reviewed, note the change in commit message.
  5. Bigger changes (need design discussion) → file as roadmap/ideas/guideline-<primitive>-challenge.md. Promote to backlog only after discussion.
  6. Rejected → note inline in the guideline as a "Considered and rejected" anchor (so the next challenge doesn't re-propose it).

  7. Bump status if material. A challenge that significantly rewrites a guideline resets its status to Draft until re-reviewed against current code. A challenge that confirms-with-tweaks keeps it Implemented but updates Last reviewed.

  8. Close the loop. Add a one-liner to the bottom of the challenged guideline: "Last challenged: YYYY-MM-DD — see roadmap/ideas/... (or commit <sha>) for outcome."

Output convention: - Challenge reports go to roadmap/ideas/guideline-<primitive>-challenge-YYYY-MM.md if bigger than a quick edit. - Audit reports go to roadmap/backlog/<primitive>-audit-YYYY-MM.md (the convention used 2026-04).

What NOT to challenge: - Placeholders. If the guideline isn't Implemented yet, you're writing it, not challenging it. - Rules that came from a recent incident or post-mortem. Those have their reason in the commit message; respect it. - Anything you'd reword purely for style. Challenges need to surface a real gap, not a rewrite for taste.

Update this README's status table whenever a file's status changes — it is the only manually-maintained index.