"""Cached AI-generated commentary for a report run. One row per (report, period_from, period_to, comparison_mode, company). Refreshed on demand or via cron when the underlying data has changed.""" from odoo import _, api, fields, models class FusionReportCommentary(models.Model): _name = "fusion.report.commentary" _description = "AI-Generated Report Commentary Cache" _order = "generated_at desc" report_id = fields.Many2one('fusion.report', required=True, ondelete='cascade') company_id = fields.Many2one('res.company', required=True, default=lambda self: self.env.company) period_from = fields.Date(required=True) period_to = fields.Date(required=True) comparison_mode = fields.Selection([ ('none', 'None'), ('previous_period', 'Previous Period'), ('previous_year', 'Previous Year'), ], default='none', required=True) summary = fields.Text() highlights = fields.Json() # list of strings concerns = fields.Json() # list of strings next_actions = fields.Json() # list of strings generated_at = fields.Datetime(default=fields.Datetime.now, required=True) generated_by = fields.Selection([ ('on_demand', 'On Demand'), ('cron', 'Cron'), ('templated', 'Templated Fallback'), ], default='on_demand', required=True) provider = fields.Char(help="LLM provider used (e.g. 'openai', 'claude', 'local'). " "Empty for templated fallback.") _unique_period = models.Constraint( 'UNIQUE(report_id, company_id, period_from, period_to, comparison_mode)', 'Only one commentary cache row per report+period+mode.', )