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 SAsis 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 Appsare app surfaces operating inside the selected SA context.
Examples:
My CustomersMy ProductsMy DealsMy Messages
2.4 CRUD in Context¶
When the user enters an app, PA has full operating context:
actor: the human usersa: 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:
actorsa
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¶
sais the tenancy and organizational boundary.actoris the within-SA assignment boundary.
Interpretation:
{actor = null, sa = X}means shared or unassigned within SAX{actor = A, sa = X}means assigned to actorAwithin SAX
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¶
sais the inclusive selector.actoris 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_actororactor 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.messageor 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.partnerorganization/contact treesres.companystock.locationhierarchiesproduct.templateandproduct.productstock.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.partnermay 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.lotmay be: - structurally affiliated to product and location
- SA-shared while in a shared pool
- actor-assigned while reserved
- a
stock.locationis 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
Ais not a member of SAX
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:
saremains the primary governance boundaryactormay 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.partnerstructure - 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 normalizeactortonull - direct reassignment path
- a record may be explicitly reassigned from actor
Xto actorY
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_manageris the root of the SA membership tree - the current
sa_managermay additionally get SA-level roll-up through descendant child-SAs
Rationale:
- semantic labels such as
admin,staff, andagentare 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_manageris 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_managermay 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_managerof 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.locationstock.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