Skip to content

Commit 5343b42

Browse files
[UPD] Copilot instructions
1 parent 16d69d2 commit 5343b42

File tree

1 file changed

+161
-35
lines changed

1 file changed

+161
-35
lines changed

.github/copilot-instructions.md

Lines changed: 161 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
* Si ya existe un docstring, puede sugerirse un estilo básico acorde a PEP8, pero **no será un error** si faltan `return`, tipos o parámetros documentados.
3333
5. No proponer cambios puramente estéticos (espacios, comillas simples vs dobles, orden de imports, etc.).
34+
6. Mantener el feedback **muy conciso** en los PRs: priorizar pocos puntos claros, evitar párrafos largos y no repetir el contexto que ya está explicado en la descripción del PR.
3435

3536
---
3637

@@ -104,48 +105,175 @@
104105
* En operaciones masivas, promover writes vectorizados y recomputes en lotes; en v19 se pueden combinar con `env.cr.commit()` controlado o helpers de progreso (`_commit_progress`) cuando el diff ya manipula crons.
105106
* Ejemplo sugerido: `partners.write({'comment': 'Actualizado masivamente'})` y `_commit_progress(processed=len(partners))` en jobs largos.
106107
* Recordar que estas prácticas no solo mejoran performance: al mantenerse dentro del ORM se heredan los controles de acceso, auditoría y reglas multi-compañía.
108+
* Tener en cuenta la **navegación de campos relacionales** en Odoo: acceder a campos encadenados como `m.fiscal_position_id.l10n_ar_tax_ids` es seguro incluso cuando `fiscal_position_id` está vacío (devuelve un recordset vacío). Por eso, expresiones como `not m.fiscal_position_id.l10n_ar_tax_ids` ya cubren el caso en que no haya posición fiscal y **no hace falta** añadir un chequeo previo separado sobre `fiscal_position_id`.
109+
* Revisar accesos directos por índice en listas o recordsets, por ejemplo `lines[0].id`: si el conjunto está vacío puede lanzar `IndexError`. Copilot debe sugerir patrones más seguros (por ejemplo `if lines: first = lines[0]`) o, cuando sea posible, reescribir la lógica para trabajar sobre el recordset completo en lugar de un único elemento.
107110

108111
---
109112

110-
## Cambios estructurales y scripts de migración – **cuestiones generales (v18+v19)**
113+
## Cambios estructurales y scripts de migración – **cuestiones generales**
111114

112-
Las mismas reglas generales descritas en la sección de Odoo 18 se aplican también aquí. Copilot debe reutilizar la misma lógica para decidir si pide migración o no:
115+
Cuando el diff sugiera **cambios de estructura de datos**, **siempre evaluar** si corresponde proponer un **script de migración** en `migrations/` (pre/post/end) **y recordar el bump de versión**.
113116

114-
1. Renombres de campos **almacenados** y de modelos.
115-
2. Cambios de tipo con impacto real en la representación en DB (no para `Char → Text` u otros cambios triviales).
116-
3. Eliminación de campos con reestructuración de datos.
117-
4. Nuevos campos `compute` con `store=True` que requieren backfill, con advertencias en modelos muy grandes.
118-
5. Cambios de dominios o **eliminación/renombre** de valores de `selection` (añadir keys nuevas no requiere script en general).
119-
6. Cambios o adición de `_sql_constraints` / índices con riesgo de conflicto con datos existentes (al menos emitir **advertencia**).
120-
7. Cambios en `ir.model.data` / XML IDs, especialmente con `no_update="1"` cuando el contenido lógico cambia (sugerir forzar el cambio).
121-
8. Cambios de reglas de acceso / propiedad que requieran recalcular ownership o multi-company.
117+
### Reglas generales de estructura de `migrations/`
122118

123-
En caso de duda, Copilot debe:
119+
* La carpeta dentro de `migrations/` debe corresponder con la versión declarada en el manifest (p. ej. `migrations/19.0.1.0/`).
120+
* Los scripts deben ser idempotentes, trabajar en lotes y registrar logs claros.
124121

125-
* describir el riesgo,
126-
* sugerir un posible enfoque de migración,
127-
* pero **no exagerar**: si el cambio es claramente no rompedor (ej. añadir un valor extra de `selection` sin tocar los anteriores), no pedir migración.
122+
### Ejemplos de cambios estructurales (actualizado con tus criterios)
123+
124+
En estos casos **normalmente corresponde** proponer migración (salvo notas en contra):
125+
126+
1. **Renombrar campos o modelos**
127+
128+
* **Campos:** proponer migración **solo si el campo es almacenado** en base de datos:
129+
* campos normales (`Char`, `Many2one`, `Boolean`, etc.),
130+
* campos `compute` con `store=True`.
131+
* Campos `compute` **sin** `store=True` no requieren script por el renombre en sí (son virtuales).
132+
* **Modelos:** renombrar modelos **siempre** implica revisar migración (`ir.model`, `ir.model.data`, tablas relacionales, vistas, acciones…).
133+
134+
2. **Cambiar tipos de campo**
135+
136+
* Se considera cambio estructural cuando **cambia la representación en la base de datos** (p.ej. `Char → Many2one`, `Selection → Many2one`, `Integer → Monetary`, `Many2one → Many2many`, etc.).
137+
* Cambios “compatibles” a nivel de PostgreSQL **no suelen requerir script**, por ejemplo:
138+
* `Char → Text` o ajustes de tamaño de `Char`;
139+
* cambios de precisión en `Float` sin cambio de semántica.
140+
* Aun así, si el cambio implica lógica nueva (p.ej. pasar de `Boolean` a `Selection` con múltiples estados) puede requerir mapeo de datos.
141+
142+
3. **Quitar campos para reestructurar información**
143+
144+
* Por ejemplo, dividir un campo en varios (split) o fusionar varios en uno (merge).
145+
* Siempre revisar si hay datos que deban preservarse antes de eliminar el campo original.
146+
147+
4. **Agregar campos `compute` almacenados (`store=True`) con backfill**
148+
149+
* Si el campo nuevo es `compute` y `store=True`, y se espera que tenga valor para **registros históricos**, conviene:
150+
* Proponer **script `post`** que haga el backfill **en lotes**.
151+
* Añadir una **advertencia explícita** cuando el modelo tiene muchos registros (p.ej. millones) para que el cálculo no se haga en una sola transacción que bloquee la tabla.
152+
153+
5. **Cambiar dominios o valores de campos `selection`**
154+
155+
* **Añadir nuevos valores de `selection`**:
156+
En general **no requiere migración** si solo se agregan opciones nuevas y no se tocan las existentes.
157+
* **Eliminar o renombrar keys existentes de `selection`**:
158+
* Puede dejar valores históricos huérfanos o inválidos → proponer script que mapee `old_value → new_value` o que normalice registros antiguos.
159+
* Mencionar que hay que tener en cuenta el comportamiento de campos relacionados (p.ej. un `Many2one` con `ondelete` específico) si el `selection` influye en lógica que crea o elimina registros.
160+
* **Cambios de dominio** en campos relacionales (`Many2one`, `Many2many`):
161+
* Si el nuevo dominio excluye valores usados históricamente, puede ser necesario limpiar o remapear datos para que no queden registros en estados imposibles.
162+
* Recordar que el `ondelete` del campo define qué ocurre al eliminar registros apuntados; hay que respetarlo al limpiar datos.
163+
164+
6. **Cambiar o añadir `_sql_constraints` (unique / index)**
165+
166+
* Cambios en constraints `UNIQUE` o adición de nuevas constraints/índices pueden **fallar con datos existentes** (duplicados, valores nulos, etc.).
167+
* Al menos, Copilot debe:
168+
* emitir una **advertencia** sobre el riesgo de fallo en el upgrade,
169+
* sugerir revisar datos previos (y, cuando se vea necesario, un **pre-script** que limpie duplicados o normalice datos antes de aplicar la constraint).
170+
171+
7. **Cambios en `ir.model.data` / XML IDs**
172+
173+
* Renombres de XML IDs (`module.name → module2.name2`) o cambios en `module` / `name` suelen requerir:
174+
* script para actualizar referencias dependientes (acciones, vistas, menús, records en otros módulos),
175+
* o uso de utilidades de upgrade.
176+
* Caso especial: registros con `no_update="1"`:
177+
* Si cambia solo texto/etiquetas menores, puede no hacer falta migración.
178+
* **Si cambia el contenido lógico** (ej. campo `domain`, configuración, secuencias) y el registro tiene `no_update="1"`, debes **sugerir forzar el cambio**:
179+
* vía script que actualice explícitamente los registros por su `xml_id`,
180+
* o mediante un proceso de “force update” apropiado.
181+
182+
8. **Cambios de reglas de acceso / propiedad**
183+
184+
* Cambios profundos en `record rules` o en campos que determinan propiedad (company, website, owner…) pueden necesitar scripts para:
185+
* recomputar propiedad,
186+
* asignar company/website por defecto,
187+
* o migrar datos entre reglas.
188+
189+
> **Nota:** No se incluye en esta lista el caso “Añadir `required=True` a campos existentes sin default” como condición automática de migración; Copilot no debe sugerir script de migración **solo** por ese motivo, salvo que en el diff se vea claro que hay datos históricos incompatibles.
128190

129191
---
130192

131-
## Scripts de migración en `migrations/`: pre / post / end (v19)
193+
## Cobertura de tests automatizados – reglas generales
132194

133-
* Mismas definiciones y mapeo que en la sección de Odoo 18.
134-
* En Odoo 19 se pueden mencionar utilidades de `odoo.upgrade.util` (p.ej. `change_field_selection_values`, helpers para índices y constraints) cuando el diff ya usa el módulo de upgrade.([Odoo][5])
195+
* Cuando el diff introduzca **funcionalidad nueva no trivial** (nuevos métodos con lógica compleja, nuevos flujos de negocio, refactors grandes, nuevas APIs, etc.), revisar si existe cobertura de tests razonable para esos cambios.
196+
* Si no se ve una cobertura clara, sugerir de forma **concreta y breve** qué tipo de test añadir (unitarios de modelo, tests de wizards, tours, pruebas sobre reportes, etc.), sin exigir una suite completa para cada cambio.
197+
* Para cambios pequeños o puramente cosméticos (ajustes en textos, vistas simples, pequeñas correcciones) **no hace falta** proponer la creación de tests nuevos.
135198

136199
---
137200

138-
## Convenciones de scripts en `migrations/` (v19)
201+
## Scripts de migración en `migrations/`: pre / post / end (reglas generales)
202+
203+
> **Objetivo:** preservar datos y mantener instalabilidad/actualizabilidad segura.
204+
205+
- **pre**: Se ejecutan antes de actualizar el módulo. Útiles para preparar datos o estructuras que eviten fallos durante el upgrade.
206+
- **post**: Se ejecutan justo después de actualizar el módulo. Ideales para recalcular datos, limpiar residuos o ajustar referencias tras el cambio.
207+
- **end**: Se ejecutan al final de la actualización de todos los módulos. Indicados para tareas globales que dependen de múltiples módulos o para ajustes finales.
208+
209+
### Mapeo de cambio → acción recomendada (actualizado)
210+
211+
* **Rename de campo almacenado (mismo modelo)**
212+
213+
* **Pre-script**: crear columna/alias temporal o copiar datos del campo viejo al nuevo antes de que Odoo toque el esquema, si el cambio puede romper constraints.
214+
* **Post-script**: limpieza de residuos, recomputes de campos derivados si aplica.
139215

140-
Iguales que en 18:
216+
* **Renombrar modelo**
141217

142-
* Scripts idempotentes, por lotes, con logs claros.
143-
* Carpeta `migrations/<module_version>/` alineada con la versión del manifest.
144-
* `pre_*.py`, `post_*.py` y/o scripts `end` según corresponda.
218+
* **Pre-script**: preparar mapeos en `ir.model` y `ir.model.data`, y ajustar referencias técnicas si es necesario.
219+
* **Post-script**: re-enlazar vistas, acciones, menús, reglas y volver a chequear accesos.
220+
221+
* **Eliminar campo y mover datos a otros campos (split/merge)**
222+
223+
* **Pre-script**: copiar datos a los nuevos campos (cuando sea posible) antes de que el schema elimine la columna original.
224+
* **Post-script**: normalizar referencias, recalcular computes, limpiar helpers.
225+
226+
* **Agregar campo `compute` con `store=True`**
227+
228+
* **Pre-script (opcional y solo en modelos muy grandes)**: crear columna en DB o preparar estructura para evitar locks largos.
229+
* **Post-script (recomendado)**: backfill **en lotes** para poblar el valor almacenado; es importante para modelos con muchos registros.
230+
231+
* **Cambiar tipo de campo con cambio real de representación**
232+
233+
* **Pre-script**: crear columna temporal con el nuevo tipo y migrar datos (con conversión).
234+
* **Post-script**: intercambiar/renombrar columnas, borrar la vieja, disparar recomputes si hace falta.
235+
236+
* **Cambios en `selection` (eliminar/renombrar keys existentes)**
237+
238+
* **Pre-script**: mapear valores antiguos → nuevos (tabla de mapeo) usando helpers como `change_field_selection_values()` cuando aplique.
239+
* **Post-script**: validar que no quedan valores huérfanos y que las reglas de negocio siguen cumpliéndose.
240+
* **Añadir keys nuevas**: **no proponer script** salvo que el diff muestre una migración masiva explícita de valores.
241+
242+
* **Nuevas constraints `_sql_constraints` (unique) / índices**
243+
244+
* **Pre-script (recomendado cuando haya riesgo)**: detectar y resolver duplicados o datos inconsistentes antes de crear la constraint.
245+
* **Post-script**: crear el índice/constraint y, si procede, validar que no haya fallos.
246+
247+
* **Cambios en registros XML con `no_update="1"`**
248+
249+
* **Post-script**: actualizar esos registros por API (respetando `xml_id`) cuando el contenido lógico haya cambiado y no vaya a ser reaplicado por el upgrade normal.
250+
251+
* **Cambios de reglas de acceso / multi-company / multi-website**
252+
253+
* **Pre- o post-script** según el caso, para rellenar campos obligatorios (company, website, owner) y evitar que registros queden inaccesibles.
254+
255+
> **Regla general:** si el cambio puede **romper durante el upgrade**, usa **pre-script**; si requiere **recalcular o reaplicar** después del código nuevo, usa **post-script**. Si se necesita una acción global al final, usa **end-script**.
145256

146257
---
147258

148-
## Checklist rápida para el review (v19)
259+
## Convenciones de scripts en `migrations/` (generales)
260+
261+
* Ubicación: `migrations/<module_version>/`.
262+
* Nombres sugeridos:
263+
264+
* `pre_<breve-descripcion>.py`
265+
* `post_<breve-descripcion>.py`
266+
* Requisitos:
267+
268+
* Idempotentes (seguros si se ejecutan más de una vez).
269+
* En lotes (`batch_size` razonable) para datasets grandes.
270+
* Logs claros (uso de `_logger.info`).
271+
* Manejo de transacciones cuando aplique (evitar locks largos).
272+
* Documentar al inicio **qué suponen** y **qué garantizan**.
273+
274+
---
275+
276+
## Checklist rápida para el review
149277

150278
| Categoría | Qué comprobar Copilot |
151279
| ------------------ | ------------------------------------------------------------------------------------------------------------ |
@@ -159,7 +287,7 @@ Iguales que en 18:
159287

160288
---
161289

162-
## Heurística práctica para el bump de versión (v19)
290+
## Heurística práctica para el bump de versión
163291

164292
* **SI** el diff toca cualquiera de: `models/`, `views/`, `data/`, `report/`, `security/`, `wizards/`
165293
**Y** `__manifest__.py` no cambia `version`**Sugerir bump**.
@@ -168,9 +296,10 @@ Iguales que en 18:
168296

169297
---
170298

171-
## Estilo del feedback (v19)
299+
## Estilo del feedback
172300

173301
* El feedback debe ser **breve, concreto y accionable**.
302+
* Priorizar comentarios en forma de **lista corta de puntos** (37 ítems) y frases breves en lugar de bloques de texto extensos.
174303
* Ejemplos rápidos:
175304

176305
* “La constraint nueva podría definirse como `models.Constraint` en lugar de `_sql_constraints`.”
@@ -179,17 +308,14 @@ Iguales que en 18:
179308

180309
---
181310

182-
## Resumen operativo para Copilot (v19)
183-
184-
1. **Aplicar las mismas reglas generales** que en v18 para revisión de código, manifest y migraciones.
185-
2. **Diferenciar claramente**:
311+
## Resumen operativo para Copilot
186312

187-
* cambios estructurales que requieren migración (según la lista ajustada),
188-
* de ajustes menores que no la necesitan (p.ej. `Char → Text`, añadir valores de `selection`).
189-
3. Tener en cuenta las **novedades de Odoo 19**:
313+
1. **Detecta cambios en modelos/vistas/seguridad/datos → exige bump de `version` en `__manifest__.py`.**
314+
2. **Si hay cambio estructural (según la lista actualizada) → propone y describe script(s) de migración en `migrations/` (pre/post/end)**, con enfoque idempotente y en lotes.
315+
3. Distingue entre:
190316

191-
* preferir la nueva API de constraints/índices cuando corresponda,
192-
* revisar cuidadosamente vistas y permisos ligados a IA, Equity, ESG, WhatsApp, VOIP, etc.
193-
4. Mantener un feedback **conciso y orientado a acción**, evitando micro-comentarios.
317+
* **cuestiones generales**,
318+
* y **matices específicos de Odoo 19**, por ej. preferir la nueva API de constraints/índices cuando corresponda.
319+
4. Mantén el feedback **concreto, breve y accionable**.
194320

195321
[^odoo19]: Resumen basado en las Odoo 19 Release Notes oficiales y artículos técnicos sobre cambios del ORM e índice/constraints en Odoo 19.

0 commit comments

Comments
 (0)