← Retour aux travaux
2024 · Plateforme Odoo 19 · en production

Rebound Technologies

Une plateforme Odoo 19 qui fait tourner l'entreprise de bout en bout — ventes, CRM, RH, projets, treatment, cashflow, audit GAAP. Une quarantaine de modules personnalisés, une régression Playwright nocturne sur AWS, et le premier projet où nous tenons les trois sièges en parallèle : Dan à l'architecture et au DevOps, Dina aux modules Odoo, Hasina à l'automatisation des tests.

Rôle
Architecture · modules Odoo · automatisation des tests · DevOps
Durée
Depuis 2024, en cours
Équipe
3 ingénieurs — Dan, Dina, Hasina
VISUEL DE PROJET · PLACEHOLDER
FIG. 01
Contexte

Rebound Technologies est une entreprise américaine d'opérations et de treatment. Leur plateforme Odoo 19 est la colonne vertébrale de la société au jour le jour — ventes, CRM et contacts, RH et feuilles de temps, projets, domaine treatment, cashflow et audit GAAP, stockage de documents, intégrations Slack et Microsoft Calendar et Mapbox — le tout dans un seul arbre, autour d'une quarantaine de modules personnalisés et d'une douzaine de dépendances OCA choisies avec soin.

C'est le premier projet où nous tenons les trois sièges simultanément, chacun le sien. Dan tient le poste de CTO : architecture, revue de code, et l'infrastructure AWS / Terraform. Dina livre les modules Odoo — fonctionnalités, champs, vues, règles d'accès, la forme quotidienne du produit. Hasina mène l'automatisation des tests : une batterie de régression Playwright nocturne et le pipeline CodeBuild qui la fait tourner. Chaque PR passe par au moins deux d'entre nous.

La forme choisie était délibérée. Un `flag.mixin` pour que n'importe quel modèle puisse être flaggé avec une raison — et `FlaggedRenderer` met les lignes correspondantes en évidence partout où elles apparaissent. Un mixin `audit.model` pour les champs que les RH ne voient pas. Un `knock.model` pour que chaque transition d'état déclenche un workflow Knock / Slack sans que chaque modèle réécrive le câblage. Des scripts de migration versionnés par module dans `migrations/19.0.X.Y.Z/`. Un tag de test par module.

Nous sommes dessus depuis 2024. Vivant sur Odoo 19 depuis la migration — une cadence régulière de business-as-usual : bugs, fonctionnalités, améliorations, chaque ticket Jira sur sa propre base, chaque PR adossée à une pipeline verte. La régression Playwright bâtie par Hasina se déclenche chaque nuit à 2h UTC contre staging et reporte vers S3 + CloudFront.

Périmètre

Ce que nous avons bâti.

rebound_flag · rebound_audits · rebound_knock01

Trois mixins d'architecture dont héritent les 45 modules métier. Flagger n'importe quel modèle avec une raison ; ajouter des champs d'audit que les RH ne voient pas ; déclencher des workflows Knock / Slack sur changement d'état — gratuit, une fois hérité.

rebound_base · rebound_theme · rebound_widgets02

Scaffolding UI et design tokens partagés sur toute la plateforme.

rebound_account · rebound_cashflow · rebound_gaap_audit03

Couche comptable avec projection de cashflow et audit aligné GAAP.

rebound_crm · rebound_contacts · rebound_partner_duplicates04

CRM avec déduplication de partenaires.

rebound_hr · rebound_timesheets · rebound_time_off · rebound_holidays · rebound_purchase_hr05

Domaine RH : employés, feuilles de temps, congés, jours fériés, flux d'achat côté RH.

rebound_purchase · rebound_expense · rebound_divvy · rebound_ramp06

Achats et dépenses sur carte d'entreprise avec intégrations Divvy et Ramp.

rebound_treatment · rebound_rec_center · rebound_friction07

Le domaine opérationnel et treatment propre à Rebound — la partie que personne d'autre n'a.

rebound_project · rebound_activity · rebound_my_stuff08

Surfaces projet et workflow personnel.

rebound_documents · rebound_directory · rebound_portal · rebound_email_marketing · rebound_social09

Contenu, portail, messagerie sortante.

rebound_jira_integration · rebound_microsoft_calendar · rebound_mapbox · rebound_slack_unfurl · mapsly_connector10

Intégrations externes.

test_automation11

Batterie Playwright + Pytest contre le staging Odoo. Menée par Hasina ; ~690 commits dans son propre repo.

rebound_infra12

AWS géré par Terraform : EventBridge → Lambda → CodeBuild (timeout 240 min) → S3 + CloudFront pour la régression nocturne à 2h UTC. Plus SES pour deux domaines.

Approche

À quoi ressemble le travail, en 4 pièces.

01

Trois sièges, un atelier

C'est le premier projet où nous tenons les trois sièges en même temps. Dan porte l'architecture, la revue de code et le côté AWS / Terraform. Dina porte les modules Odoo — fonctionnalités, champs, vues, sécurité. Hasina porte le pipeline de tests — suites Playwright, CodeBuild qui les fait tourner la nuit. Chaque PR passe par au moins deux d'entre nous.

02

Mixins architecturaux, pas du copier-coller

Trois modèles Odoo abstraits — `flag.mixin`, `audit.model`, `knock.model` — dont les modules métier héritent. Le flag, c'est une ligne sur n'importe quel modèle ; les champs d'audit viennent gratuitement ; les transitions d'état déclenchent automatiquement les workflows Knock. Le coût est payé une fois ; chaque nouveau module en recueille les dividendes.

03

Un pipeline de test qui veille pendant que la plateforme dort

Une suite de régression Playwright + Pytest qui tourne contre staging chaque nuit à 2h UTC. Lambda déclenche CodeBuild, CodeBuild clone le repo de tests, Playwright pilote les écrans Odoo en direct, les résultats partent vers S3 et une URL de rapport mise en cache par CloudFront — et Slack est prévenu. Nous voyons les échecs avant qu'un utilisateur ne les rapporte.

04

Préparation à Odoo 19, écrite noir sur blanc

Nous avons migré la plateforme vers Odoo 19 — et avons noté ce que nous avons appris, dans le CLAUDE.md du module, pour que les mêmes pièges ne soient pas revécus. `read_group` → `_read_group`, templates OWL de boutons de liste, `is_manually_modified` sur `account.move`, `fieldDependencies` qui par défaut est `readonly: true`, page de réglages avec `t-foreach` clé `app.name` — une vingtaine de pièges de migration, tous documentés à côté du code qui les évite.

Choix techniques

Les solutions dont nous sommes le plus fiers.

01

Miroir de la vue SQL `hr.employee.public`

Odoo 19 redirige les non-RH vers `hr.employee.public`, une vue SQL. Tout nouveau champ sur `hr.employee` qui n'est pas mirroré comme champ `related store=False` sur le modèle public lève une `AccessError` pour les non-RH — y compris les many2many où l'on ne peut pas `store=True` puisqu'aucune table de relation n'existe pour la vue. Règle documentée une fois ; elle gouverne désormais chaque champ RH ajouté.

02

knockapi vs gestion des exceptions paiement

`rebound_knock` épingle `knockapi==0.5.8`, qui tire `simplejson` en dépendance transitive. `simplejson` monkey-patche `requests.models.complexjson`, ce qui casse la gestion d'exceptions des payment-providers d'Odoo. `rebound_knock/__init__.py` annule le patch à l'import — `requests.models.complexjson = json` — et le flux paiement reste correct.

03

`is_manually_modified` et factures OCR

Tout `write()` sur `account.move` sans `skip_is_manually_modified=True` dans le context active le flag de modification manuelle, ce qui tainte les factures OCR (elles ne sont plus traitées comme importables). Les assignations de champs en post-création sont enveloppées dans `with_context(skip_is_manually_modified=True)` pour que le signal OCR ne soit pas perdu par accident.

04

Le widget domain et les champs toujours invisibles

Le widget `domain` d'Odoo 19 appelle `record.fieldNames.includes(resModel)` pour trouver sa cible. Les champs toujours invisibles sont sautés à la construction de `fieldNames`, donc le champ de nom de modèle référencé dans `options.model` doit être visible — au minimum `readonly="1"`. La page de migration Odoo 19 dans CLAUDE.md catalogue la surprise pour qu'elle ne morde pas la personne suivante.

05

Régression Playwright nocturne, de bout en bout

Cron EventBridge à 2h UTC → Lambda (`rebound-regression/src/main.py`, Python/boto3) → CodeBuild (Node 18 + Python 3.12, timeout 240 minutes) → clone de `rebound-tech/test_automation` → Playwright pilote les écrans Odoo staging → résultats vers S3, servis derrière CloudFront. Slack et Knock prévenus à la fin. Les échecs n'attendent pas un utilisateur pour être signalés.

06

Migration-par-version, scriptée

Chaque module suit le versioning `19.0.X.Y.Z`. Quand une migration est nécessaire, on bumpe la version et on dépose `migrations/19.0.X.Y.Z/pre-migrate.py` ou `post-migrate.py` avec une fonction `migrate(cr, version)`. La pipeline les ramasse ; les données bougent avec le code ; rien de manuel en production.

Résultats

Quelques chiffres, en formes brutes.

44+
Modules Odoo personnalisés
Odoo 19
En production
Nocturne
Régression Playwright à 2h UTC
Tous les trois
Premier projet, sièges distincts

Stack
Odoo 19PythonPostgreSQLPlaywrightPytestTerraformAWSKnockSlack

Un projet qui mérite ce niveau de soin ?

Démarrer une conversation