Salta al contingut principal
Odoo · Mètode d'auditoria

Auditar un connector d'Odoo heretat: què mirar en una tarda abans de tocar una línia

Has heretat un connector de marketplace, transportista, signatura o EDI que va fer algú altre. Falla, o ningú se'n refia. Deu punts, el símptoma que delata cadascun i la consulta que el confirma en minuts.

Fitxa d'una instància del connector Mirakl a Odoo: connexió de prova OK, 206 ofertes i el comptador de registres de crides a 0

Una auditoria útil d'un connector d'Odoo no comença pels tests. Comença pel log i per una operació real de punta a punta: una comanda que entra, un enviament que surt, un reemborsament que torna. El connector Mirakl passava la seva suite en verd a Odoo 19, 18 i 17 i amagava 18 errors confirmats; un altre connector de marketplace donava 236 de 236 en builds reals d'Odoo.sh i amagava 20 errors de contracte i 12 de versió. Aquell article explica l'errada; aquest, el mètode: deu punts en ordre, el símptoma que delata cadascun i la prova que cap en una tarda.

Idea clau: el connector que hereves ja et diu què li passa, a la taula de log i als crons apagats.

Què recollir abans d'asseure't

Quatre dades que no depenen de qui va fer el connector. La versió real d'Odoo: SELECT latest_version FROM ir_module_module WHERE name = 'base';. La versió de l'API del tercer que assumeix el codi, gairebé sempre visible a la URL base. La data de l'últim canvi dels mocks: git log -1 --format=%cd -- tests/. I qui rep els errors: un correu, una activitat, un fitxer o ningú.

Els deu punts, en ordre

1. Escriu el log de debò?

Símptoma: la taula de log té zero files després de mesos de crons. Prova: SELECT last_value FROM pg_sequences WHERE sequencename = '<tabla_log>_id_seq';. Un NULL aquí vol dir que aquesta seqüència no s'ha llegit mai: ningú va esborrar les files, és que no se'n va escriure cap. Això va sortir a la producció del connector Mirakl. L'ajudant que retorna el model de log retornava un recordset buit en cas d'èxit, i a Odoo un recordset buit és fals, així que if not log_model: return False encertava sempre i cada «això ho registrem» era un no-op. L'arranjament és if log_model is False.

2. La data de tall de la sincronització

Símptoma: una comanda creada al matí i enviada a la tarda es queda a Odoo amb l'estat del matí. Prova: tres comandes que van canviar d'estat ahir al marketplace, comparades amb write_date i l'estat a Odoo. A Mirakl el connector demanava start_date, que filtra per data de creació, en lloc de start_update_date, que filtra per data de canvi.

3. Idempotència: doble comanda, doble reemborsament

Símptoma: dos sale.order amb la mateixa referència externa, o un reemborsament que apareix dues vegades al marketplace. Prova: SELECT client_order_ref, count(*) FROM sale_order GROUP BY 1 HAVING count(*) > 1;, i crear un duplicat des de odoo shell per veure si la base el rebutja de debò: que la restricció estigui escrita al model no vol dir que existeixi a Postgres. A Odoo 19 un _sql_constraints heretat ja no crea res i l'ORM només deixa un avís al log, així que perds la garantia sense adonar-te'n; al revés és sorollós, perquè models.Constraint no existeix a 17 ni a 18 i allà el mòdul ni tan sols s'importa. I el client HTTP: a Mirakl es reintentava davant de 5xx i timeout per a qualsevol mètode, també per al PUT del reemborsament.

4. Errors HTTP i reintents

Símptoma: el compte s'aixeca «no autoritzat» i tota la sincronització aturada. Prova: provoca un 401, un 429 i, si es pot, un 403 de quota. En el segon cas, el 403 de quota no venia en el format d'error documentat i es llegia com a fallada de permisos: un límit de velocitat ho aturava tot. El que s'ha de veure: Retry-After respectat i amb un topall, els 5xx i els timeouts reintentats només en lectures, el 429 també en escriptures perquè el servidor el va rebutjar sense processar-lo, i el compte bloquejat només per una fallada d'autenticació real.

5. Mocks davant del contracte real

Símptoma: un camp que sempre arriba buit, un filtre que «no filtra». Prova: posa l'OpenAPI actual del proveïdor al repositori i compara els paràmetres de cada wrapper, les claus de cada cos d'escriptura i els camps que llegeix cada parser. En el segon cas van sortir 16 discrepàncies així en 88 operacions, i quatre més només cridant: una capçalera de paginació relativa impedia importar ni una sola comanda a partir de la pàgina u.

6. Permisos i SSRF via redirecció

Símptoma: cap, i per això és a la llista. Prova: grep -rn "allow_redirects\|\.sudo()\|has_group" models/. Cada crida sortint ha de portar allow_redirects=False i rebutjar un 3xx, perquè requests segueix redireccions per defecte i un host compromès et pot enviar a una IP interna. I cada action_* que treballa amb sudo() ha de comprovar el grup al servidor: el groups= del botó és només interfície. Al juliol de 2026 ho vam aplicar a uns setze connectors propis.

7. Crons: numbercall i intervals

Símptoma: «el cron va deixar de córrer dimarts», sense error ni traça. Prova a Odoo 17: SELECT cron_name, active, numbercall, nextcall FROM ir_cron WHERE cron_name ILIKE '%conector%';. A 17 numbercall val 1 per defecte, així que un cron declarat sense ell corre una vegada i es desactiva sol, tal com és al ir_cron.py de la sèrie 17.0. Odoo 18 va eliminar el camp i 19 no el té, així que qui va provar a 18 o 19 no el va veure mai. I mira l'interval: una sincronització completa cada deu minuts acaba en un 429.

8. La versió d'Odoo que el codi assumeix

Símptoma: un formulari sense chatter, una pestanya «payload» en blanc, una comanda cancel·lada al marketplace que continua confirmada a Odoo. Prova: grep -rn "<chatter/>\|widget=\"json\"\|read_group\|<tree\|<list" views/ models/. A Mirakl van sortir els quatre alhora: <chatter/> existeix des de 18, widget="json" només a 19, read_group està deprecat a 19, i sale.order.action_cancel() retorna un assistent a 17 i 18 per a una comanda confirmada, així que la cancel·lació mai no passava. És la llista de un mòdul que compila a Odoo 19 i no s'instal·la.

9. Migració de les dades històriques

Símptoma: arregles el càlcul i les comandes antigues continuen malament, perquè el connector no torna a tocar una comanda existent. Prova: compta els registres anteriors a la correcció que incompleixen la regla nova i decideix entre un script de migració o una correcció única i documentada. A Mirakl van ser 18 comandes amb l'IVA duplicat al total; es van corregir les 15 actives, només si el total coincidia amb el del marketplace. I una trampa: les dades noupdate de base, els grups entre elles, no es reapliquen en actualitzar, així que un canvi de pertinença deixa el grup buit a producció i ple a la teva base neta.

10. Documentació del tercer davant del comportament real

Símptoma: el codi fa el que diu el PDF i el servidor fa una altra cosa. Prova: una crida real per família d'endpoint i una revisió de quins endpoints estan deprecats avui. A Mirakl el model d'importació per fitxer continuava vigent, però la missatgeria feia servir un endpoint deprecat. En el segon cas, un endpoint acceptava un únic valor on la documentació deia llista, i aquell referencial portava buit des del principi. Va l'últim perquè és el més car.

La tarda, resumida

PuntSímptomaProva
LogZero files després de mesos de cronscount(*) i pg_sequences.last_value
Data de tallEstats congelatsComandes d'ahir contra write_date
IdempotènciaDuplicats, doble reemborsamentGROUP BY HAVING; la base rebutja el duplicat?
Errors HTTP«No autoritzat» després d'un 429/403Provocar 401, 429, 403
MocksCamp sempre buitOpenAPI actual contra wrappers i parsers
SSRF i permisosCapgrep allow_redirects, sudo(), has_group
CronsS'apaga sense error (17)SELECT active, numbercall FROM ir_cron
Versió d'OdooChatter o payload en blancgrep chatter, widget json, read_group, tree/list
HistòricEl vell continua malament després de l'arranjamentComptar registres previs que incompleixen la regla
DocumentacióEl servidor no fa el que diu el PDFUna crida real per família d'endpoint

Què surt de l'auditoria: un informe amb severitat, no una llista de desitjos

L'informe ordena per dany: primer diners (doble reemborsament, comanda duplicada, IVA dues vegades), després dades (estat congelat, log que no escriu, cron apagat), després ergonomia. Cada troballa porta la seva reproducció i el que no es reprodueix es ratlla: a l'auditoria de Mirakl van entrar 121 candidats, 33 es van refutar en un passada escèptica i només 18 van sobreviure.

La segona sortida és el gate: la suite que hi havia, en verd abans i després, no prova la correcció. La prova és la correguda a les tres sèries sobre builds reals, 163 de 163 a 19, 18 i 17 per a Mirakl, més una verificació en viu. És el que separa un connector natiu ben fet d'una capa intermèdia que sobreviu a força de no comprometre's.

Quan es parxeja i quan es reescriu

Es parxeja quan el model de dades és correcte (una taula per objecte del tercer, un log, una referència externa única) i les errades viuen a la capa HTTP, les finestres i les versions: cap en una versió, com amb Mirakl. Es reescriu quan falla el fons: una API que el proveïdor ha retirat, sense log ni referència externa, escriptures no idempotents per disseny, o un connector lligat a una sèrie d'Odoo quan en necessites tres. És la decisió que preparem per a consultories i partners tecnològics que hereten integracions, i també quan el connector és el del seu propi programari.

Preguntes freqüents

Per què no començar per la suite de tests?

Perquè una suite en verd diu que el codi coincideix amb el seu mock, no amb el proveïdor ni amb producció. La suite va al final, com a gate de la correcció.

Cal accés a producció?

Per als punts 1, 2, 3, 7 i 9 sí, o a una còpia: la seqüència del log, els estats congelats, els duplicats i els crons apagats només es veuen en dades reals.

Què lliureu al final?

Un informe amb cada troballa provada i ordenada per diners, dades i ergonomia; la recomanació de parxejar o reescriure; i, si es corregeix, l'arranjament amb el seu gate a les sèries d'Odoo del client. El detall és a serveis.

Enllaços útils dins de FlexigoTech

Els tests estaven en verd i el connector no funcionava32 errors que la suite no veiaConnector Mirakl OdooQuè ha de resoldre en un marketplace realEnginyeria Odoo per a consultoriesAuditoria i suport d'integracions heretadesPartners tecnològicsCom treballem amb partners d'OdooConnector d'Odoo per al teu programariQuan el connector a auditar és el de la teva plataforma

El que fem sobre això

Integracions a midaQuè fa, captures, versions i preu.

Has heretat un connector que falla o del qual ningú se'n refia?

Explica'ns què integra, en quina versió d'Odoo corre i quin símptoma veus. Et diem quins punts de la llista miraríem primer i què cal per fer-ho. Escriu a comercial@flexigobe.com o truca al +34 616 809 504.

Parlar amb un enginyer