update
This commit is contained in:
74
fusion_api/views/api_access_views.xml
Normal file
74
fusion_api/views/api_access_views.xml
Normal 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>
|
||||
91
fusion_api/views/api_consumer_views.xml
Normal file
91
fusion_api/views/api_consumer_views.xml
Normal 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>
|
||||
9
fusion_api/views/api_dashboard_views.xml
Normal file
9
fusion_api/views/api_dashboard_views.xml
Normal 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>
|
||||
54
fusion_api/views/api_key_views.xml
Normal file
54
fusion_api/views/api_key_views.xml
Normal 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>
|
||||
207
fusion_api/views/api_provider_views.xml
Normal file
207
fusion_api/views/api_provider_views.xml
Normal 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>
|
||||
223
fusion_api/views/api_usage_views.xml
Normal file
223
fusion_api/views/api_usage_views.xml
Normal 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>
|
||||
63
fusion_api/views/api_user_limit_views.xml
Normal file
63
fusion_api/views/api_user_limit_views.xml
Normal 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>
|
||||
71
fusion_api/views/menus.xml
Normal file
71
fusion_api/views/menus.xml
Normal 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>
|
||||
50
fusion_api/views/res_config_settings_views.xml
Normal file
50
fusion_api/views/res_config_settings_views.xml
Normal 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 & 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>
|
||||
Reference in New Issue
Block a user