Skip to content

Serviced Account Mini Model

Purpose

This document is a developer-starting note for a bare-minimum Odoo Serviced Account model.

It does not attempt to finalize the full governance design. It exists to:

  • capture why the problem is structurally non-trivial
  • define a minimal object shape that can be prototyped in Odoo
  • keep transactional Odoo behavior separate from governance behavior
  • frame SSO and identity considerations without overloading the first model

1. Why This Is Not Straightforward

The Serviced Account object looks simple at first: "an organization that requires services."

But it quickly becomes more complex because:

  • the same identity may act in multiple governance contexts
  • internal and external organizations may both need governed access
  • Odoo transaction structure, commercial boundaries, and delegated access do not perfectly align
  • access may be mediated by a proxy API rather than native Odoo user seats

So the first model should be:

  • flexible enough to represent real cases
  • closed-boundary enough to avoid turning into a second CRM or HR system
  • small enough to prototype and revise

2. Two Edge Cases That Motivate the Design

EC-001: Dual-Context Human Actor

The same person may appear as a single res.partner record, but participate in more than one governed context.

Example:

  • the person is an employee/member inside an OVAC serviced account
  • the same person is also designated as account manager or sales-facing actor for an EXTC serviced account

Why this matters:

  • role meaning cannot safely live on res.partner alone
  • authority must be carried by the relationship between person and serviced account
  • permissions must stay isolated by account context

Design implication:

  • res.partner is the identity anchor
  • membership carries role, scope, and state
  • authorization is evaluated in account context, never globally by person

EC-002: Cross-Company Conflict-of-Interest

Odoo is company-structured. Commercial boundaries matter.

Example:

  • a person is modeled as member/employee under OVAC / OV1
  • the same person is proposed as designated account manager for EXTC under OV2
  • OV1 and OV2 are commercially distinct

This may be technically representable, but commercially sensitive.

Why this matters:

  • the base model should not be so rigid that it forbids all mixed-role cases
  • the base model should not be so loose that conflicts become invisible

Design implication:

  • the structure should allow multi-context memberships
  • conflict-of-interest checks should be handled by governance policy, not by over-hardcoding the schema
  • sensitive cross-company combinations should be flaggable, reviewable, and auditable

3. Design Intent

The v0 model should answer only these questions:

  1. What organization is being governed?
  2. Which people may act in relation to it?
  3. Under which serviced-account context are they acting?

The v0 model should not try to solve:

  • full enterprise RBAC
  • complete internal org modeling
  • advanced approval workflows
  • full SSO implementation
  • all conflict-of-interest policy combinations

4. Architectural Principles

4.1 Governance Is Not Transactions

All ERP business processes remain native Odoo:

  • customers remain res.partner
  • sales orders remain sale.order
  • invoices remain account.move
  • payments remain native accounting behavior

The ov.* domain is governance only.

This model does not:

  • reimplement sales workflow
  • reimplement pricing logic
  • reimplement inventory
  • duplicate customer master data

4.2 Separation of Concerns

Domain Responsibility
res.partner Identity anchor for organizations and people
Odoo core models Transaction and accounting truth
ov.serviced_account Governed service-account tree
ov.membership Authorization relationship in account context
Portal / UXI / BFF layer Authentication and permission resolution
Proxy internal user Technical execution of privileged actions

4.3 Design Goals

  • minimal schema surface
  • deterministic, context-bound authorization
  • hierarchy support without relying on res.partner.parent_id
  • clean audit trail
  • scope small enough to prototype and revise

5. Minimum Odoo Model Proposal

5.1 Core Objects

Object Purpose Notes
res.partner Identity anchor for organizations and people Reuse Odoo native partner model; do not place contextual authority here
ov.serviced_account Governed organization/account context External client or eligible affiliated entity that receives governed service/access
ov.membership Person-to-account authorization relationship Carries role, state, and scope in account context

5.2 ov.serviced_account Key Attributes

Attribute Type Purpose v0 Guidance
name Char Human-readable account name Required
partner_id Many2one(res.partner) Link to the canonical organization partner record Required, unique in practice for v0
account_class Selection Distinguish OVAC vs EXTC at minimum Required
parent_id Many2one(ov.serviced_account) Optional hierarchy / branch structure Optional
child_ids One2many(ov.serviced_account) Convenience inverse for hierarchy Derived
state Selection Governance lifecycle state Start with active, inactive
notes Text Short admin/governance note Optional, non-authoritative

5.3 ov.membership Key Attributes

Attribute Type Purpose v0 Guidance
serviced_account_id Many2one(ov.serviced_account) The governed account context Required
person_partner_id Many2one(res.partner) Person acting in that context Required; person only
role_code Char or Selection Role in this account context Keep simple in v0
membership_state Selection Membership status Start with active, suspended, revoked
scope_policy Selection Scope of authority Start with this_node_only, this_node_and_descendants
effective_from Datetime Optional activation time Optional
effective_to Datetime Optional expiry time Optional

5.4 Minimum Invariants

  • A Serviced Account is an organization context, not a person.
  • A person may have multiple memberships across multiple serviced accounts.
  • Role semantics belong to ov.membership, not directly to res.partner.
  • Transactional customer/order behavior remains native Odoo.
  • Governance objects do not replace CRM, accounting, or company setup.
  • Authorization is evaluated in account context, never by person alone.

5.5 Initial Role Pattern

Keep the initial role model simple.

Suggested v0 examples:

Role Example Capabilities
admin full account management
agent create draft sales orders or service actions
finance view financial information and request invoice-related actions
viewer read-only access

Role logic should be enforced in the application and proxy/API layer, not hardcoded into native Odoo user-seat behavior.

6. What Counts As A Serviced Account In v0

For v0, a Serviced Account is:

  • an organization that receives governed services, delegated access scope, or account-level operational governance

This may include:

  • EXTC - true external client/customer organization
  • OVAC - affiliated or subsidiary organization that still needs governed service/account treatment

This does not mean all Omnivoltaic internal org units should automatically be modeled as Serviced Accounts.

The working rule is:

  • if the organization is being treated as an account subject of service/governance, it may be a Serviced Account
  • if the organization is purely an internal operating structure, it should remain in normal Odoo company/org constructs unless a later need proves otherwise

7. SSO and Identity Considerations

The identity and access design must stay aligned with DIRAC architecture.

Relevant DIRAC prior disclosures:

  • UXI is the single point of access with centralized authentication and authorization support
  • FED is the enforcement layer for auth, entitlement, and role policies
  • TEAMS is a Microsoft-based communications/document domain already relevant to OVES workflows
  • DIRAC materials also reference SSO / Cloak-style authentication integration in the broader ecosystem

Implications for this mini-model:

  • do not assume every governed actor will be a native paid Odoo user
  • do not assume all identities originate inside Odoo CRM
  • do not embed IdP-specific behavior directly into the first Odoo schema

Instead, separate:

  • identity source: Teams / Microsoft-based identity, local portal identity, or other future IdP
  • person anchor in Odoo: res.partner
  • execution identity in Odoo: proxy/internal res.users
  • governance authority: ov.membership

7.1 Two Initial Identity Modes

Mode Likely Population Identity Source Odoo Pattern
teams_federated OVAC-side users and other Microsoft-managed actors Microsoft / Teams / Entra-style SSO path Resolve external identity to res.partner, then evaluate ov.membership
odoo_native_crm EXTC-side contacts/customers first known through CRM/commercial flows Odoo-native partner/contact lifecycle, with later portal/SSO possible Start from res.partner, then evaluate ov.membership

7.2 What The Model Should Not Hardcode Yet

Do not hardcode in v0:

  • Keycloak-specific tables or fields
  • Microsoft tenant-specific claims mapping
  • portal onboarding workflow
  • automatic synchronization rules between Teams identities and Odoo users

Those belong to the next layer of identity/access design, not to the minimum Serviced Account object.

8. Proxy API Assumption

This mini-model assumes privileged Odoo actions may be executed by a proxy/internal user on behalf of non-seat actors.

Therefore:

  • business actor attribution should not rely only on create_uid
  • the account context used for access resolution should be explicit
  • later implementation should add transaction-side attribution fields where needed

Examples of privileged actions that may go through the proxy path:

  • confirm sales order
  • create invoice
  • issue refund
  • edit account-affecting commercial controls

The important rule is:

  • proxy res.users performs technical execution
  • real human actor remains attributable separately
  • serviced-account context remains explicit for audit and authorization

9. What We Are Not Building In v0

This model is intentionally not:

  • a parallel customer model
  • a replacement for native Odoo access rules
  • a workflow engine
  • a pricing or inventory abstraction
  • a complete SSO implementation
  • a full conflict-of-interest policy engine

10. Developer Starting Point

If developers start coding now, the first prototype should only prove:

  1. an organization partner can be wrapped by ov.serviced_account
  2. a person partner can hold multiple ov.membership rows
  3. one person can appear in both OVAC and EXTC contexts without schema breakage
  4. role/scope live on membership, not on partner
  5. hierarchy is possible, but optional

11. Deferred By Design

Explicitly defer these items until after the first prototype:

  • advanced role catalog
  • supervisor model
  • conflict-of-interest rule engine
  • approval workflow engine
  • detailed SSO mapper implementation
  • transaction-side custom attribution fields beyond what is needed to prove the pattern

12. Guiding Principle

Keep the Serviced Account model:

  • structural, not transactional
  • contextual, not person-global
  • flexible in relationships
  • conservative in scope