Skip to content

PA SA Context and Attribution Model

Status

Incremental capture of agreed design points.

Purpose

This document captures the agreed PA user-flow and {actor, sa} attribution model for SA-governed operations.

It exists to prevent discussion loss while the broader SA design is still being developed.

Terminology in this document follows the repo definitions in Terminology, especially Portal App (PA), Serviced Account (SA), actor, sa, and the {actor, sa} pair.

In this repo, PA is not a separate application from OVApp.

PA means the SA-governed portal mode of OVApp, where login, SA selection, and governed app access are mediated through the SA context.

1. PA Entry Model

  • SA is accessed through PA.
  • PA is the SA-governed portal form of OVApp, not a separate app.
  • PA is SA-agnostic at login time.
  • A PA user is any previously registered person with at least one membership to at least one SA.
  • PA behaves like a super app.

2. PA User Flow

2.1 Login

  • The user logs into PA without selecting an SA first.
  • Login is not tied to one SA.

2.2 My SAs

  • After login, PA presents My SAs.
  • My SAs is derived from the user's memberships.
  • If the user has only one SA, that SA is the default selection.

2.3 My Apps

  • After SA selection, PA presents My Apps.
  • My Apps are app surfaces operating inside the selected SA context.

Examples:

  • My Customers
  • My Products
  • My Deals
  • My Messages

2.4 CRUD in Context

When the user enters an app, PA has full operating context:

  • actor: the human user
  • sa: the selected Serviced Account on whose behalf actions are taken

This context must be preserved for both creation and later filtering of SA-governed records.

3. Record Attribution Model

3.1 Required PA Attributes

PA-created SA-governed records carry nullable attribution fields:

  • actor
  • sa

Represented together as:

  • {actor, sa}

3.2 Nullability

  • These fields are nullable so non-PA-native Odoo records do not need them populated.
  • PA-governed records should use them consistently.

3.3 Semantics

  • sa is the tenancy and organizational boundary.
  • actor is the within-SA assignment boundary.

Interpretation:

  • {actor = null, sa = X} means shared or unassigned within SA X
  • {actor = A, sa = X} means assigned to actor A within SA X

4. Visibility Model

4.1 Base Rule

A record is visible in current PA context only when:

  • record.sa == current_sa

Then app policy determines whether actor must also match.

4.2 Actor Logic

  • sa is the inclusive selector.
  • actor is the exclusive selector.

This means:

  • the current SA must always match first
  • actor then determines whether the record is personal or shared inside that SA

4.3 Per-App Visibility Policy

Visibility policy is defined per app, not once globally for the whole SA.

Current agreed policy shapes:

  • assigned_only
  • actor sees only records where actor == current_actor
  • assigned_plus_unassigned
  • actor sees records where actor == current_actor or actor is null

4.4 Three Visibility Regimes

Do not classify visibility by model name alone.

Classify visibility by usage regime.

Current working regimes are:

  • actor_assigned
  • record visibility or workload is tied to one actor inside the current SA
  • natural fit is {actor, sa}
  • sa_shared
  • record belongs to the current SA scope but is not inherently owned by one actor
  • natural fit is {sa} with optional per-app visibility policy
  • structurally_affiliated
  • record is long-lived and linked by structure, containment, or reference relationships rather than by actor assignment
  • visibility is derived from structural affiliation, not from touch history

4.5 Typical Examples By Regime

Typical actor_assigned records:

  • mail.message or chatter-like posts in PA work context
  • tasks, activities, cases, and tickets
  • deals or opportunities
  • sales orders in PA workflow
  • reservations

Typical sa_shared records:

  • products exposed inside one SA
  • fleets or shared locations under one SA
  • shared asset pools
  • pricing, catalog, or reference objects made available to one SA
  • customer records when the whole SA may view them

Typical structurally_affiliated records:

  • res.partner organization/contact trees
  • res.company
  • stock.location hierarchies
  • product.template and product.product
  • stock.production.lot
  • warehouse or logistics structures
  • SA membership and the SA tree itself

4.6 Overlap Is Normal

Some models may participate in more than one regime depending on usage.

Examples:

  • a customer on res.partner may be:
  • structurally affiliated as a durable master record
  • actor-assigned for account ownership
  • SA-shared when visible to the whole SA
  • a serial/item on stock.production.lot may be:
  • structurally affiliated to product and location
  • SA-shared while in a shared pool
  • actor-assigned while reserved
  • a stock.location is inherently structural, but may also be SA-shared when exposed as a governed fleet or operating location

5. App-Specific Patterns

5.1 Products / Fleet

  • Products in a fleet for an SA will often start with actor = null.
  • A reservation assigns that product to a specific actor.

5.2 Deals

  • Deals are associated with the creating actor by default.
  • They remain with that actor unless explicitly removed from that actor's care.

6. Integrity Rule for {actor, sa}

6.1 Membership Integrity

If actor is not null, then actor must be a valid member of sa.

Invalid case:

  • a record carries {actor = A, sa = X}
  • but actor A is not a member of SA X

This is an integrity failure, not a normal business state.

6.2 Membership Removal Rule

If membership between actor and sa is removed, integrity must be restored by setting:

  • actor = null

The {actor, sa} pair must not remain in a broken state.

7. Operational Meaning for Proxy Execution

  • PA establishes the active {actor, sa} context before app CRUD operations.
  • Newly created PA records must be stamped with {actor, sa}.
  • Those stored attributes are then used to filter the relevant record set when PA interacts with Odoo through proxy execution.

This means {actor, sa} is not only audit metadata.

It is also an operational selector for later reads and updates.

This does not mean actor is the universal visibility selector for every record class.

For durable shared or structural records:

  • sa remains the primary governance boundary
  • actor may be null, optional, or secondary
  • visibility may instead derive from SA affiliation or structural membership inside the SA-governed operating universe

Additional assignment rule:

  • do not inherit PA visibility broadly from res.partner structure
  • do not force one universal SA-visibility pattern onto all models
  • use explicit SA scoping only where governance actually matters
  • allow some records to remain global when SA scoping is unnecessary
  • prefer derived visibility where SA scope is already expressed by an assigned parent, container, or structural relationship

8. Current Open Questions

  • Reassignment rules between actors inside the same SA are not yet settled.
  • Exact hierarchy-based override behavior is not yet settled.
  • The exact Odoo field names and model mixin strategy are not yet settled.

9. Incremental Hierarchy and Reassignment Direction

9.1 Reassignment Paths

Two reassignment paths are currently accepted:

  • indirect normalization path
  • if membership or user association is removed in a way that breaks {actor, sa} integrity, execution must normalize actor to null
  • direct reassignment path
  • a record may be explicitly reassigned from actor X to actor Y

These are different operations and should not be conflated.

9.2 Hierarchy Layers

The old shorthand role stack is no longer the semantic model of record.

Current direction:

  • every PA actor operates through explicit SA membership
  • reporting and scope expansion come from hierarchy position, not a short role label
  • any member with subordinates may get team-level roll-up inside the current SA
  • the current sa_manager is the root of the SA membership tree
  • the current sa_manager may additionally get SA-level roll-up through descendant child-SAs

Rationale:

  • semantic labels such as admin, staff, and agent are too coarse for the management structure now required
  • hierarchy is more functional because it answers real questions such as my manager, my team, and recursive roll-up directly from current state
  • hierarchy is more flexible because it supports more than three layers without redefining role meaning
  • hierarchy is more reliable because reporting and scope can be derived from the tree structure instead of depending on loosely interpreted labels

9.3 Supervisor-Style Management Apps

There is a likely need for management-oriented PA apps that are not shown to all actors.

Current example direction:

  • My Team

Possible use:

  • manage actors/memberships within the current SA
  • review records across actors
  • support reassignment workflows
  • expose broader filtered views such as all customers within the current SA

9.4 SA as a Managed Odoo Object

SAs are also Odoo records.

Therefore, SA records themselves should be considered CRUD-capable through PA/proxy execution, subject to role policy. Therefore, SA records themselves should be considered CRUD-capable through PA/proxy execution, subject to hierarchy and governance policy.

9.5 Hierarchy and Authority Direction

The current hierarchy and authority direction is:

  • authority inside one SA follows the explicit membership tree
  • the current sa_manager is the unique membership-tree root
  • any member with subordinates may roll up reporting across direct and indirect subordinates in the current SA
  • only the current sa_manager may roll up from the current SA into descendant child-SAs

Interpretation:

  • inherited visibility and reporting are driven by hierarchy, not by semantic role labels
  • cross-SA roll-up is specific to the current sa_manager of the current SA
  • explicit membership remains required for participation in any SA

9.6 Asset Governance Direction

The current asset-governance direction is still under review.

Settled baseline:

  • physical asset structures remain native Odoo:
  • stock.location
  • stock.production.lot

Current interpretation:

  • a physical asset cannot belong to more than one SA at a time
  • SA affiliation reflects ownership/governed possession in the business sense
  • initial assignment of assets to an SA happens from the Odoo side, not by self-assignment from the SA side

Current design questions:

  • whether governed assets need an explicit wrapper such as ov.asset
  • whether asset visibility should derive primarily from explicitly SA-scoped fleets or locations
  • how much asset assignment should be explicit versus structurally derived
  • whether a location-scoped fleet is sufficient for most shared-asset visibility
  • when an item may need direct SA affiliation apart from its location/fleet

Working constraints for that decision:

  • do not introduce an additional SA-side parent/child asset tree unless it adds real semantic value
  • if the underlying Odoo location already expresses item membership, prefer deriving membership from that structure
  • avoid duplicate independent SA assignment on an item already governed by an SA-scoped fleet or location
  • if a location has no fleet binding, a separate item-level affiliation may still need to be considered

9.7 Still Not Settled

The following items remain open:

  • exact hierarchy-based authority boundaries for management apps and structural operations
  • who may create new SA records
  • exact CRUD policy by visibility regime for durable shared and structural records
  • final asset-affiliation model, including explicit assignment versus structural derivation