Aller au contenu principal

Règles & consignes d'architecture

AGENTS.md, à la racine du dépôt, est le contrat de toute contribution, humaine ou automatisée. Chaque règle est garantie par un test : en enfreindre une fait échouer make ci.

#RègleGarantie par
1Une seule couche HTTP. Un fournisseur ne crée jamais de client HTTP ; il utilise les fonctions utilitaires de financials/providers/base.py, où se trouvent les nouvelles tentatives, les pauses, la limite de concurrence et le proxytests/test_provider_http_policy.py
2Les réglages sont réels. Lisez les réglages avec les fonctions utilitaires de settings.py ; chaque variable de .env.example est lue par le code ; une valeur invalide revient à la valeur par défaut avec un avertissementtests/test_env_settings.py
3Les documents disent la vérité. Les chiffres de README.md correspondent au code ; les tableaux de ARCHITECTURE.md listent chaque route, migration et moduletests/test_docs_consistency.py
4Les fournisseurs se chargent, ou l'échec est visible (PROVIDER_SPECS, /health)tests/test_docs_consistency.py
5Les unités sont déclarées dans monitoring/units.pytests/test_provider_units.py
6Les seuils de couverture ne font que monter, un par fournisseurtests/test_coverage_gate.py
7Sécurisé par défaut. Chaque route exige une clé sauf si elle est déclarée publique ; une route qui modifie quelque chose n'est jamais un GETtests/test_auth_defaults.py
8L'image Docker est autonome ; .env n'y entre jamaistests/test_docker_image.py
9Le journal d'utilisation ne retarde jamais une réponse ; aucune IP n'est enregistrée sauf demandetests/test_usage_recorder.py
10Aucun accès réseau réel dans les tests (fake_network, pages enregistrées)tests/conftest.py
11Les versions sont verrouillées (requirements*.lock, vérifiées par hash)tests/test_dependency_lock.py
12Les prix appartiennent à une cotation : clé (asset_listing_id, resolution, time), date de séance à minuit UTC, tickers résolus par database/price_series.pytests/test_price_series.py
13Les symboles sources sont vérifiés, jamais devinés (historical/yahoo_symbols.py)tests/test_yahoo_symbols.py
14Les nombres affichés sont lus à un seul endroit (financials/numbers.py)tests/test_numbers.py
15Un chiffre restitué nomme sa source (Sources de /fundamental)tests/test_financials_formatter.py
16Rien de ce qui est lu dans Redis n'est exécuté, rien n'est supprimé sans limite (cache JSON, nettoyage borné avec dry_run)tests/test_cache_service.py, tests/test_database_cleanup.py
17La CI teste sur la base de données d'une installation (même image TimescaleDB)tests/test_ci_workflow.py
18Les états financiers sont lus par exercice (financials/fiscal_years.py)tests/test_fiscal_years.py
19Une clé de cache contient chaque paramètre qui change la réponsetests/test_cache_keys.py

Couches​

  • routers/ analysent la requête et traduisent les erreurs applicatives en statuts HTTP.
  • use_cases/ dépendent des ports de use_cases/ports.py, jamais de FastAPI, de SQLAlchemy ni d'un fournisseur.
  • Le code bloquant est appelé via concurrency.run_sync().

Voir Couches & ports.

Identité​

  • Ne prenez jamais un ticker pour un identifiant global : SPFF est un ETF obligataire en EUR dans un catalogue et un fonds américain chez Yahoo. Résolvez une cotation (ticker, place, devise) et utilisez le symbole vérifié pour elle.
  • Ne masquez jamais un échec par une valeur de repli ou un except silencieux : indiquez pourquoi quelque chose manque (reason, note, warnings).