This commit is contained in:
gsinghpal
2026-03-16 08:14:56 -04:00
parent fdca9518ab
commit e56974d46f
196 changed files with 19739 additions and 3471 deletions

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Tree View -->
<record id="view_api_access_tree" model="ir.ui.view">
<field name="name">fusion.api.access.tree</field>
<field name="model">fusion.api.access</field>
<field name="arch" type="xml">
<list editable="bottom">
<field name="consumer_id"/>
<field name="provider_id"/>
<field name="is_enabled" widget="boolean_toggle"/>
<field name="monthly_budget_usd"/>
<field name="daily_budget_usd" optional="hide"/>
<field name="max_rpm"/>
<field name="max_rpd" optional="hide"/>
<field name="current_month_cost" string="Month Spend ($)"/>
<field name="current_day_requests" string="Today Reqs"/>
<field name="budget_usage_pct" widget="progressbar" string="Budget Used"/>
<field name="is_budget_exceeded" column_invisible="True"/>
</list>
</field>
</record>
<!-- Form View -->
<record id="view_api_access_form" model="ir.ui.view">
<field name="name">fusion.api.access.form</field>
<field name="model">fusion.api.access</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group string="Link">
<field name="consumer_id"/>
<field name="provider_id"/>
<field name="is_enabled"/>
</group>
<group string="Current Usage">
<field name="current_month_cost"/>
<field name="current_day_cost"/>
<field name="current_day_requests"/>
<field name="budget_usage_pct" widget="progressbar"/>
<field name="is_budget_exceeded"/>
</group>
</group>
<group>
<group string="Budget Limits">
<field name="monthly_budget_usd"/>
<field name="daily_budget_usd"/>
</group>
<group string="Rate Limits">
<field name="max_rpm"/>
<field name="max_rpd"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<!-- Action -->
<record id="action_api_access" model="ir.actions.act_window">
<field name="name">Access Rules</field>
<field name="res_model">fusion.api.access</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No access rules configured
</p>
<p>Access rules control which Fusion modules can use which API providers, with budget and rate limits.</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Tree View -->
<record id="view_api_consumer_tree" model="ir.ui.view">
<field name="name">fusion.api.consumer.tree</field>
<field name="model">fusion.api.consumer</field>
<field name="arch" type="xml">
<list>
<field name="name"/>
<field name="technical_name"/>
<field name="module_state" widget="badge"
decoration-success="module_state == 'installed'"
decoration-muted="module_state != 'installed'"
optional="show"/>
<field name="is_active" widget="boolean_toggle"/>
<field name="auto_detected"/>
<field name="first_seen_at" optional="hide"/>
<field name="total_month_cost" string="Month Cost ($)"/>
<field name="total_month_requests" string="Month Requests"/>
</list>
</field>
</record>
<!-- Form View -->
<record id="view_api_consumer_form" model="ir.ui.view">
<field name="name">fusion.api.consumer.form</field>
<field name="model">fusion.api.consumer</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_toggle_access" type="object"
class="oe_stat_button"
icon="fa-power-off">
<field name="is_active" widget="boolean_button"
options='{"terminology": {"string_true": "Active", "string_false": "Disabled"}}'/>
</button>
</div>
<div class="oe_title">
<h1><field name="name"/></h1>
</div>
<group>
<group>
<field name="technical_name"/>
<field name="module_id"/>
<field name="module_state"/>
</group>
<group>
<field name="auto_detected"/>
<field name="first_seen_at"/>
<field name="total_month_cost"/>
<field name="total_month_requests"/>
</group>
</group>
<notebook>
<page string="Access Rules" name="access">
<field name="access_ids">
<list editable="bottom">
<field name="provider_id"/>
<field name="is_enabled"/>
<field name="monthly_budget_usd"/>
<field name="daily_budget_usd"/>
<field name="max_rpm"/>
<field name="max_rpd"/>
<field name="current_month_cost" string="Month Spend"/>
<field name="current_day_requests" string="Today"/>
<field name="budget_usage_pct" widget="progressbar" string="Budget %"/>
</list>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- Action -->
<record id="action_api_consumer" model="ir.actions.act_window">
<field name="name">Consumers</field>
<field name="res_model">fusion.api.consumer</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No consumers detected yet
</p>
<p>Fusion modules will appear here automatically when they make their first API call.</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="action_dashboard" model="ir.actions.client">
<field name="name">Fusion API Dashboard</field>
<field name="tag">fusion_api_dashboard</field>
</record>
</odoo>

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Form View (used as dialog from provider form) -->
<record id="view_api_key_form" model="ir.ui.view">
<field name="name">fusion.api.key.form</field>
<field name="model">fusion.api.key</field>
<field name="arch" type="xml">
<form>
<header>
<button name="action_validate" type="object"
string="Validate Key" class="btn-primary"
icon="fa-check-circle"/>
</header>
<sheet>
<group>
<group>
<field name="name" placeholder="e.g. Production Key"/>
<field name="api_key" password="True" placeholder="Enter your API key"/>
<field name="environment"/>
<field name="is_default"/>
<field name="is_active"/>
</group>
<group>
<field name="provider_id" invisible="context.get('default_provider_id')"/>
<field name="provider_type" invisible="1"/>
<field name="validation_status" widget="badge"
decoration-success="validation_status == 'valid'"
decoration-danger="validation_status == 'invalid'"
decoration-muted="validation_status == 'unknown'"/>
<field name="last_validated_at"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
</group>
<group string="OAuth Credentials"
invisible="provider_type not in ('google_oauth', 'microsoft_oauth')">
<group>
<field name="client_id" password="True"/>
<field name="client_secret" password="True"/>
<field name="redirect_uri"/>
</group>
<group>
<field name="access_token" password="True"/>
<field name="refresh_token" password="True"/>
<field name="token_expiry"/>
</group>
</group>
<field name="notes" placeholder="Optional notes about this key..."/>
</sheet>
</form>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,207 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Kanban View -->
<record id="view_api_provider_kanban" model="ir.ui.view">
<field name="name">fusion.api.provider.kanban</field>
<field name="model">fusion.api.provider</field>
<field name="arch" type="xml">
<kanban class="o_kanban_dashboard" create="false">
<field name="name"/>
<field name="provider_type"/>
<field name="status"/>
<field name="active_key_count"/>
<field name="total_month_cost"/>
<field name="total_month_requests"/>
<field name="color"/>
<field name="icon_class"/>
<field name="website_url"/>
<templates>
<t t-name="card">
<div class="d-flex align-items-start mb-2">
<div class="me-3">
<i t-att-class="'fa fa-2x text-primary ' + (record.icon_class.value or 'fa-plug')"/>
</div>
<div class="flex-grow-1">
<strong><field name="name"/></strong>
<div class="text-muted small">
<field name="provider_type"/>
</div>
</div>
<div>
<field name="status" widget="badge"
decoration-success="status == 'active'"
decoration-muted="status == 'inactive'"
decoration-danger="status == 'error'"/>
</div>
</div>
<div class="row g-2 mt-2">
<div class="col-4 text-center">
<div class="fw-bold"><field name="active_key_count"/></div>
<div class="text-muted small">Keys</div>
</div>
<div class="col-4 text-center">
<div class="fw-bold">$<field name="total_month_cost" widget="float" digits="[10,2]"/></div>
<div class="text-muted small">Month</div>
</div>
<div class="col-4 text-center">
<div class="fw-bold"><field name="total_month_requests"/></div>
<div class="text-muted small">Requests</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<!-- Tree View -->
<record id="view_api_provider_tree" model="ir.ui.view">
<field name="name">fusion.api.provider.tree</field>
<field name="model">fusion.api.provider</field>
<field name="arch" type="xml">
<list>
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="provider_type"/>
<field name="status" widget="badge"
decoration-success="status == 'active'"
decoration-muted="status == 'inactive'"
decoration-danger="status == 'error'"/>
<field name="active_key_count"/>
<field name="total_month_cost" string="Month Cost ($)"/>
<field name="total_month_requests" string="Month Requests"/>
<field name="website_url" widget="url" string="Dashboard"/>
</list>
</field>
</record>
<!-- Form View -->
<record id="view_api_provider_form" model="ir.ui.view">
<field name="name">fusion.api.provider.form</field>
<field name="model">fusion.api.provider</field>
<field name="arch" type="xml">
<form>
<header>
<button name="action_activate" type="object" string="Activate"
class="btn-primary"
invisible="status == 'active'"/>
<button name="action_deactivate" type="object" string="Deactivate"
class="btn-secondary"
invisible="status != 'active'"/>
<field name="status" widget="statusbar"
statusbar_visible="inactive,active"/>
</header>
<sheet>
<div class="oe_title">
<h1><field name="name" placeholder="Provider Name"/></h1>
</div>
<group>
<group>
<field name="provider_type"/>
<field name="website_url" widget="url"/>
<field name="icon_class"/>
</group>
<group>
<field name="active_key_count"/>
<field name="total_month_cost"/>
<field name="total_month_requests"/>
<field name="sequence"/>
</group>
</group>
<field name="description" placeholder="Description of this API provider..."/>
<notebook>
<page string="API Keys" name="keys">
<field name="key_ids" context="{'default_provider_id': id}">
<list>
<field name="name"/>
<field name="masked_key" string="API Key"/>
<field name="environment"/>
<field name="is_default"/>
<field name="is_active"/>
<field name="validation_status" widget="badge"
decoration-success="validation_status == 'valid'"
decoration-danger="validation_status == 'invalid'"
decoration-muted="validation_status == 'unknown'"/>
<field name="last_validated_at"/>
</list>
<form>
<header>
<button name="action_validate" type="object"
string="Validate Key" class="btn-primary"
icon="fa-check-circle"/>
</header>
<sheet>
<group>
<group>
<field name="name" placeholder="e.g. Production Key"/>
<field name="api_key" password="True"
placeholder="Enter your API key"/>
<field name="environment"/>
<field name="is_default"/>
<field name="is_active"/>
</group>
<group>
<field name="provider_id" invisible="1"/>
<field name="provider_type" invisible="1"/>
<field name="validation_status" widget="badge"
decoration-success="validation_status == 'valid'"
decoration-danger="validation_status == 'invalid'"
decoration-muted="validation_status == 'unknown'"/>
<field name="last_validated_at"/>
<field name="company_id"
groups="base.group_multi_company"/>
</group>
</group>
<group string="OAuth Credentials"
invisible="provider_type not in ('google_oauth', 'microsoft_oauth')">
<group>
<field name="client_id" password="True"/>
<field name="client_secret" password="True"/>
<field name="redirect_uri"/>
</group>
<group>
<field name="access_token" password="True"/>
<field name="refresh_token" password="True"/>
<field name="token_expiry"/>
</group>
</group>
<field name="notes"
placeholder="Optional notes about this key..."/>
</sheet>
</form>
</field>
</page>
<page string="Access Rules" name="access">
<field name="access_ids">
<list>
<field name="consumer_id"/>
<field name="is_enabled"/>
<field name="monthly_budget_usd"/>
<field name="max_rpm"/>
<field name="max_rpd"/>
<field name="current_month_cost"/>
<field name="budget_usage_pct" widget="progressbar"/>
</list>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- Action -->
<record id="action_api_provider" model="ir.actions.act_window">
<field name="name">API Providers</field>
<field name="res_model">fusion.api.provider</field>
<field name="view_mode">kanban,list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Configure your first API provider
</p>
<p>Add API keys for OpenAI, Anthropic, Google Maps, and other services used by Fusion modules.</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,223 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Usage Log: Tree View -->
<record id="view_api_usage_tree" model="ir.ui.view">
<field name="name">fusion.api.usage.tree</field>
<field name="model">fusion.api.usage</field>
<field name="arch" type="xml">
<list create="false" edit="false" default_order="create_date desc">
<field name="create_date" string="Timestamp"/>
<field name="consumer_id"/>
<field name="provider_id"/>
<field name="user_id"/>
<field name="feature"/>
<field name="model_name"/>
<field name="tokens_in" optional="show"/>
<field name="tokens_out" optional="show"/>
<field name="total_tokens"/>
<field name="estimated_cost_usd" string="Cost ($)" widget="float" digits="[10,6]"/>
<field name="response_time_ms" string="Time (ms)" optional="hide"/>
<field name="status" widget="badge"
decoration-success="status == 'success'"
decoration-danger="status == 'error'"
decoration-warning="status in ('rate_limited', 'budget_exceeded')"/>
</list>
</field>
</record>
<!-- Usage Log: Form View -->
<record id="view_api_usage_form" model="ir.ui.view">
<field name="name">fusion.api.usage.form</field>
<field name="model">fusion.api.usage</field>
<field name="arch" type="xml">
<form create="false" edit="false">
<sheet>
<group>
<group>
<field name="create_date"/>
<field name="consumer_id"/>
<field name="provider_id"/>
<field name="user_id"/>
</group>
<group>
<field name="feature"/>
<field name="model_name"/>
<field name="status"/>
<field name="response_time_ms"/>
</group>
</group>
<group>
<group string="Token Usage">
<field name="tokens_in"/>
<field name="tokens_out"/>
<field name="total_tokens"/>
</group>
<group string="Cost">
<field name="estimated_cost_usd"/>
</group>
</group>
<group string="Error Details" invisible="not error_message">
<field name="error_message" nolabel="1"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- Usage Log: Pivot View -->
<record id="view_api_usage_pivot" model="ir.ui.view">
<field name="name">fusion.api.usage.pivot</field>
<field name="model">fusion.api.usage</field>
<field name="arch" type="xml">
<pivot string="API Usage Analysis">
<field name="consumer_id" type="row"/>
<field name="provider_id" type="col"/>
<field name="estimated_cost_usd" type="measure"/>
<field name="total_tokens" type="measure"/>
</pivot>
</field>
</record>
<!-- Usage Log: Graph View -->
<record id="view_api_usage_graph" model="ir.ui.view">
<field name="name">fusion.api.usage.graph</field>
<field name="model">fusion.api.usage</field>
<field name="arch" type="xml">
<graph string="API Usage" type="bar">
<field name="create_date" interval="day" type="row"/>
<field name="estimated_cost_usd" type="measure"/>
</graph>
</field>
</record>
<!-- Usage Log: Search View -->
<record id="view_api_usage_search" model="ir.ui.view">
<field name="name">fusion.api.usage.search</field>
<field name="model">fusion.api.usage</field>
<field name="arch" type="xml">
<search string="Search Usage">
<field name="consumer_id"/>
<field name="provider_id"/>
<field name="user_id"/>
<field name="feature"/>
<field name="model_name"/>
<separator/>
<filter name="filter_success" string="Success"
domain="[('status', '=', 'success')]"/>
<filter name="filter_errors" string="Errors"
domain="[('status', '=', 'error')]"/>
<filter name="filter_rate_limited" string="Rate Limited"
domain="[('status', '=', 'rate_limited')]"/>
<filter name="filter_budget_exceeded" string="Budget Exceeded"
domain="[('status', '=', 'budget_exceeded')]"/>
<separator/>
<filter name="group_consumer" string="Consumer" context="{'group_by': 'consumer_id'}"/>
<filter name="group_provider" string="Provider" context="{'group_by': 'provider_id'}"/>
<filter name="group_user" string="User" context="{'group_by': 'user_id'}"/>
<filter name="group_feature" string="Feature" context="{'group_by': 'feature'}"/>
<filter name="group_model" string="AI Model" context="{'group_by': 'model_name'}"/>
<filter name="group_status" string="Status" context="{'group_by': 'status'}"/>
<filter name="group_day" string="Day" context="{'group_by': 'create_date:day'}"/>
<filter name="group_month" string="Month" context="{'group_by': 'create_date:month'}"/>
</search>
</field>
</record>
<!-- Usage Log: Action -->
<record id="action_api_usage" model="ir.actions.act_window">
<field name="name">Usage Log</field>
<field name="res_model">fusion.api.usage</field>
<field name="view_mode">list,pivot,graph,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No API calls recorded yet
</p>
<p>Usage data appears here as Fusion modules make API calls through the Fusion API service.</p>
</field>
</record>
<!-- Daily Summary: Tree View -->
<record id="view_api_usage_daily_tree" model="ir.ui.view">
<field name="name">fusion.api.usage.daily.tree</field>
<field name="model">fusion.api.usage.daily</field>
<field name="arch" type="xml">
<list create="false" edit="false" default_order="date desc">
<field name="date"/>
<field name="consumer_id"/>
<field name="provider_id"/>
<field name="user_id" optional="hide"/>
<field name="feature" optional="hide"/>
<field name="model_name" optional="show"/>
<field name="request_count"/>
<field name="error_count" optional="show"/>
<field name="total_tokens"/>
<field name="total_cost_usd" string="Cost ($)" widget="float" digits="[10,4]"/>
<field name="avg_response_time_ms" string="Avg Time (ms)" optional="hide"/>
</list>
</field>
</record>
<!-- Daily Summary: Pivot View -->
<record id="view_api_usage_daily_pivot" model="ir.ui.view">
<field name="name">fusion.api.usage.daily.pivot</field>
<field name="model">fusion.api.usage.daily</field>
<field name="arch" type="xml">
<pivot string="Daily Usage Summary">
<field name="date" interval="month" type="row"/>
<field name="consumer_id" type="row"/>
<field name="provider_id" type="col"/>
<field name="total_cost_usd" type="measure"/>
<field name="request_count" type="measure"/>
<field name="total_tokens" type="measure"/>
</pivot>
</field>
</record>
<!-- Daily Summary: Graph View -->
<record id="view_api_usage_daily_graph" model="ir.ui.view">
<field name="name">fusion.api.usage.daily.graph</field>
<field name="model">fusion.api.usage.daily</field>
<field name="arch" type="xml">
<graph string="Daily Usage Trends" type="line">
<field name="date" type="row"/>
<field name="total_cost_usd" type="measure"/>
</graph>
</field>
</record>
<!-- Daily Summary: Search View -->
<record id="view_api_usage_daily_search" model="ir.ui.view">
<field name="name">fusion.api.usage.daily.search</field>
<field name="model">fusion.api.usage.daily</field>
<field name="arch" type="xml">
<search string="Search Daily Summary">
<field name="consumer_id"/>
<field name="provider_id"/>
<field name="user_id"/>
<field name="feature"/>
<field name="model_name"/>
<separator/>
<filter name="group_consumer" string="Consumer" context="{'group_by': 'consumer_id'}"/>
<filter name="group_provider" string="Provider" context="{'group_by': 'provider_id'}"/>
<filter name="group_user" string="User" context="{'group_by': 'user_id'}"/>
<filter name="group_model" string="AI Model" context="{'group_by': 'model_name'}"/>
<filter name="group_month" string="Month" context="{'group_by': 'date:month'}"/>
</search>
</field>
</record>
<!-- Daily Summary: Action -->
<record id="action_api_usage_daily" model="ir.actions.act_window">
<field name="name">Daily Summary</field>
<field name="res_model">fusion.api.usage.daily</field>
<field name="view_mode">list,pivot,graph,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No daily summaries yet
</p>
<p>Daily usage summaries are aggregated automatically each night by a scheduled action.</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Tree View -->
<record id="view_api_user_limit_tree" model="ir.ui.view">
<field name="name">fusion.api.user.limit.tree</field>
<field name="model">fusion.api.user.limit</field>
<field name="arch" type="xml">
<list editable="bottom">
<field name="user_id"/>
<field name="provider_id"/>
<field name="monthly_budget_usd"/>
<field name="max_rpd"/>
<field name="is_blocked" widget="boolean_toggle"/>
<field name="current_month_cost" string="Month Spend ($)"/>
<field name="current_day_requests" string="Today Reqs"/>
</list>
</field>
</record>
<!-- Form View -->
<record id="view_api_user_limit_form" model="ir.ui.view">
<field name="name">fusion.api.user.limit.form</field>
<field name="model">fusion.api.user.limit</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="user_id"/>
<field name="provider_id"/>
<field name="is_blocked"/>
</group>
<group>
<field name="monthly_budget_usd"/>
<field name="max_rpd"/>
</group>
</group>
<group>
<group string="Current Usage">
<field name="current_month_cost"/>
<field name="current_day_requests"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<!-- Action -->
<record id="action_api_user_limit" model="ir.actions.act_window">
<field name="name">User Limits</field>
<field name="res_model">fusion.api.user.limit</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No user limits configured
</p>
<p>Set per-user budget caps and request limits, or block individual users from API access.</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Root Menu -->
<menuitem id="menu_fusion_api_root"
name="Fusion API"
web_icon="fusion_api,static/description/icon.png"
sequence="90"/>
<!-- Dashboard -->
<menuitem id="menu_dashboard"
name="Dashboard"
parent="menu_fusion_api_root"
action="action_dashboard"
sequence="1"/>
<!-- Providers -->
<menuitem id="menu_providers"
name="Providers"
parent="menu_fusion_api_root"
action="action_api_provider"
sequence="10"/>
<!-- Consumers -->
<menuitem id="menu_consumers"
name="Consumers"
parent="menu_fusion_api_root"
action="action_api_consumer"
sequence="20"/>
<!-- Access Rules -->
<menuitem id="menu_access_rules"
name="Access Rules"
parent="menu_fusion_api_root"
action="action_api_access"
sequence="30"
groups="fusion_api.group_manager"/>
<!-- Usage Menu -->
<menuitem id="menu_usage"
name="Usage"
parent="menu_fusion_api_root"
sequence="40"/>
<menuitem id="menu_usage_log"
name="Usage Log"
parent="menu_usage"
action="action_api_usage"
sequence="1"/>
<menuitem id="menu_usage_daily"
name="Daily Summary"
parent="menu_usage"
action="action_api_usage_daily"
sequence="2"/>
<!-- Configuration Menu -->
<menuitem id="menu_configuration"
name="Configuration"
parent="menu_fusion_api_root"
sequence="90"
groups="fusion_api.group_manager"/>
<menuitem id="menu_user_limits"
name="User Limits"
parent="menu_configuration"
action="action_api_user_limit"
sequence="1"/>
</odoo>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.fusion.api</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//form" position="inside">
<app data-string="Fusion API" string="Fusion API"
name="fusion_api"
groups="fusion_api.group_manager">
<block title="General Settings">
<setting string="Default Environment"
help="Choose whether API calls default to production or sandbox keys.">
<field name="fusion_api_default_environment"/>
</setting>
<setting string="Auto-Detect Consumers"
help="Automatically register new Fusion modules when they first call the API.">
<field name="fusion_api_auto_detect"/>
</setting>
</block>
<block title="Budget &amp; Retention">
<setting string="Global Monthly Budget"
help="Set a global monthly cost cap across all providers. 0 = unlimited.">
<div class="content-group">
<div class="row mt8">
<label class="col-lg-3" for="fusion_api_global_budget"/>
<field name="fusion_api_global_budget" class="col-lg-3"/>
<span class="col-lg-2">USD</span>
</div>
</div>
</setting>
<setting string="Log Retention"
help="Keep detailed usage logs for this many days. Daily summaries are kept indefinitely.">
<div class="content-group">
<div class="row mt8">
<label class="col-lg-3" for="fusion_api_log_retention_days"/>
<field name="fusion_api_log_retention_days" class="col-lg-3"/>
<span class="col-lg-2">days</span>
</div>
</div>
</setting>
</block>
</app>
</xpath>
</field>
</record>
</odoo>