Visibility

Part of the user manual. Related: PERMISSIONS · TENANCY · NOTIFICATIONS · ROLES · PROJECTS · WORKFLOWS.

If a user tells you "I can't see X", this is the page to open first.

REBIM has five independent visibility layers. Each can hide a record on its own. The most common support questions ("contractor gets emails but no rows", "colleague sees the event and I don't", "I can't see any projects") all map to one of these layers — and once you know which, the fix is usually immediate.


Permissions vs. visibility — the distinction that matters

These two are often lumped together as "permissions" and the conflation is exactly what makes troubleshooting hard. They're different concepts:

  • Permissions = what you're allowed to do at all. CRUD on a model class. "Can I edit documents? Can I delete a workflow?" Set by Django user perms + group membership. See PERMISSIONS.
  • Visibility = which specific records appear in your view. Applied as filters per record instance. "Of all the documents, which ones do I see in MY table?"

A user can have full CRUD permissions on workflow events AND see zero events, because every visibility layer below filtered them all out. Conversely, a user can have no edit permission but still SEE plenty of records — they just can't change them.

When diagnosing "I can't see X," check permissions once (it's an all-or-nothing model-class right). The interesting question — which records, and why these and not those — is about visibility.


TL;DR — the five visibility layers

# Layer Question it answers Detail
1 Tenancy Is this record in my tenant world? TENANCY
2 Project membership Am I in this project at all? PROJECTS
3 Data sources Within this project, is this document in my data scope? PROJECTS — links back to TENANCY
4 Roles (workflow events) Does any of my role assignments grant me access to this event? ROLES
5 State-specific rules (workflow events, documents) Is the record in a state that hides it from me? WORKFLOWS

Layers are applied in order. The cheapest checks (tenancy, project membership) are first; the more situational ones (role, state) layer on top. First "no" wins — once a record is filtered out at any layer, the ones beneath don't matter.

Different record types use different subsets of the layers:

Record type Layers that apply
Project 1 (+ project membership IS layer 2 for projects themselves)
Workflow event 1, 2, 4, 5
Workflow transmittal 1, 2
EDMS document 1, 2, 3, 5 (check-out)
Contact 1
Schedule event 1, 2
Configuration objects (workflows, statuses, etc.) 1

The five layers in detail

Layer 1 — Tenancy

Every record carries zero, one, or many tenant labels. Every user carries zero, one, or many tenant labels. A user sees a record only if their tenants intersect.

Most common failure mode: a user with data tenants but no config tenant. Notifications fire (server can match them), but the frontend table can't render rows because workflow / status / discipline lookups all fail. See TENANCY § The "I get emails but no table rows" failure mode.

Layer 2 — Project membership

Most records in REBIM are project-scoped. To see records inside a project, you generally need to be either:

  • the project's owner (creator), OR
  • a member of the project (a ProjectPeople row links your contact to the project).

Tenancy alone does not grant project access. A user can match the project's tenancy and still see nothing — they need an actual membership row.

Failure modes:

  • "User in tenancy but can't see any projects" → no ProjectPeople rows yet. Add her contact to the projects she should access.
  • "Member can see project but can't manage membership" → that requires project_admin flag on her ProjectPeople row (or ownership), not just membership.

Layer 3 — Data sources

Within a project, documents are bucketed by data source. Each data source carries its own tenancy. A project lists which data sources belong to it (Project.data_sources is a many-to-many).

A user sees a document only if its data source's tenancy intersects their tenancy. This is the layer that lets a single project host documents for multiple parties (each with their own data tenant) without those parties seeing each other's documents.

Symptom: a user can see the project, sees an empty document table or fewer rows than expected. Check the document's data source's tenancy against the user's.

Full detail: PROJECTS — also see TENANCY § Data sources.

Layer 4 — Roles (workflow events only)

This is the trickiest layer and the one most "I can see it / they can't" comparisons resolve to.

The mechanism in short:

  • Project members are assigned disciplines via their ProjectPeople.disciplines (many-to-many). Disciplines act as roles.
  • Workflow transitions can require one or more disciplines (transition_roles / readonly_roles / commentonly_roles).
  • A workflow event becomes visible to a user when the user's disciplines satisfy the role rules of any transition in or out of the event's current state.
  • The role_leader flag on ProjectPeople broadens visibility within a discipline.
  • The project_admin flag on ProjectPeople bypasses role checks inside the project.

The non-obvious part: transition roles light up the FROM state, not the TO state. If transition T fires at status A → B and requires role R, then role-R users see the event the moment it enters A — so they can act on it — not when it lands in B.

Full detail: ROLES.

Layer 5 — State-specific rules

A small set of additional rules that can hide records or block actions based on state, applied after roles:

  • Document check-out. A checked-out document locks edits to one user. Locks transitions on associated workflows too. Other users can still see the doc but most write actions are blocked.
  • Workflow completion visibility. A workflow's limit_completed_visibility flag (per workflow definition) hides completed events from non-admins / non-creators. Active events stay visible per the role rules above.
  • FRA report state. FRA reports have their own visibility rules tied to project + role flags. See WORKFLOWS.

Full detail: WORKFLOWS, EDMS-tab specifics in PROJECTS.


Troubleshooting decision tree

When a user reports "I can't see X", walk these in order. First "no" identifies the layer.

  1. Do they have the Django permission to view this model class at all? Admin → Users → (user) → Permissions, or check group membership.
  2. No → not a visibility issue. PERMISSIONS layer. Add to appropriate group (e.g. "READ PERMISSIONS"). Done.
  3. Yes → continue.

  4. Does tenancy overlap? Admin → User Profile → Tenancy. Compare to the record's tenants.

  5. No overlap → TENANCY layer. Usually a missing config tenant on the user. See TENANCY.
  6. Overlap → continue.

  7. Is the record project-scoped, and is the user a project member? Check ProjectPeople rows for the user vs the record's project.

  8. No → project membership layer. Add the user's contact to the project (or grant ownership). The user must be a member to see project-scoped records, regardless of tenancy.
  9. Yes (or not project-scoped) → continue.

  10. (Documents only.) Is the document's data source visible to the user? Check the document's data_source.tenants vs user's tenants.

  11. No → data sources layer. Either grant the user the missing data tenant or move the document to a data source the user can see.
  12. Yes (or not a document) → continue.

  13. (Workflow events only.) Does any of the user's roles match a transition rule? Check ProjectPeople.disciplines for the user vs the transitions in / out of the event's current status.

  14. No match, and not owner / assignee / project_admin → roles layer. Assign the relevant discipline, or change the transition requirements. See ROLES.
  15. Match → continue.

  16. (Workflow events only.) Is the event in a hidden state?

  17. Workflow has limit_completed_visibility=True and event is complete → state rules layer (completion gate).
  18. Associated document is checked out → state rules layer (check-out lock). The event is visible but transitions / edits are blocked.
  19. None of the above → user should see this; if they don't, it's a bug. Capture details and report.

Symptom catalogue

Symptom Likely layer First check
Get email but no row in the workflow table 1 (tenancy — missing config) UserProfile.tenancy includes the shared config tenant
Workflow row visible but workflow name / status blank 1 (partial config tenancy) Same
Can see project but no documents inside it 3 (data sources) Each data_source.tenants for the project's sources
Can't see ANY projects 2 (project membership) ProjectPeople rows for this user; also owned projects
Colleague sees workflow event, I don't, same project 4 (roles) OR 5 (state) Compare each user's disciplines; check the event's current transitions
Event used to be visible, now isn't 4 (transition advanced past the role I hold) Event's status + the transitions in/out of it, vs my roles
Can see event but no "Transition" button appears 4 + 5 (readonly role match only, or check-out lock) Role check + document check-out state
Just created a record and can't see it 1 (created untenanted; only untenanted users see it) Record's tenants — likely empty
Just added user to a new tenant, suddenly they can't see existing data 1 (legacy records have no tenant; "no-tenant" is its own tenant) See TENANCY § No-tenancy is itself a tenancy
Document edits blocked despite the user being project_admin 5 (check-out lock — overrides project_admin for edits) EdmsDocument.checked_out_by
Can see active workflow events but completed ones disappear 5 (limit_completed_visibility on this workflow definition) The workflow's limit_completed_visibility flag

Worked examples

Example 1 — Andy's question

"Contractor gets emails about workflow events but can't see them in their workflow table."

Walk the layers:

  1. Permission to view workflow events? ✓ (they have the standard read group)
  2. Tenancy overlap? ✗ — contractor has data tenants but no config tenant.

Stops at layer 1. The email path matches the user via ProjectPeople → site_login (independent of tenancy filtering on configuration). The frontend can't render rows because workflow definition / status names aren't visible to the user.

Fix: add the shared config tenant to the contractor's UserProfile.tenancy. See TENANCY for the full explanation.

Example 2 — Role mismatch

"Alice sees this workflow event, Bob doesn't, both are in the project."

Walk the layers — both pass 1–3. At layer 4:

  • The event's current status has an outgoing transition that requires the Architect discipline.
  • Alice has Architect in ProjectPeople.disciplines. ✓
  • Bob has Mechanical, not Architect. ✗

Bob won't see the event until it advances to a status whose in/outgoing transitions have a role Bob holds.

Fix options:

  • If Bob should see it: add Architect to his disciplines, OR add Mechanical to the transition's roles.
  • If he shouldn't: behaviour is working as designed.

See ROLES for the full mechanism.

Example 3 — New tenant member sees no projects

"Added this user to our tenancy yesterday, she says she can't see any projects."

Walk the layers:

  1. Permission to view projects? ✓
  2. Tenancy overlap with each project? ✓ (you added her tenancy correctly)
  3. Project membership? ✗ — she has no ProjectPeople rows and owns no projects.

Tenancy alone doesn't grant project access. She needs membership.

Fix: create a contact for her if one doesn't exist (her contact should have site_login = her user), then add a ProjectPeople row per project she should see. Project admin or system admin does this via the project's People tab.

Example 4 — Completed events disappear

"Closed events stopped appearing in my table."

Walk the layers — passes 1–4 normally. At layer 5:

  • The workflow definition has limit_completed_visibility=True.
  • Once an event completes, it hides from non-admins / non-creators.

Fix options:

  • If unintentional: flip the workflow definition's limit_completed_visibility to False.
  • If by design: the user is in the wrong table. Admins can see complete events; in a "show only mine" view, only creator + assignee retain visibility post-completion.

For developers

This page is for users and admins. Implementation pointers:

  • Tenancy filter (layer 1): core.views.BimViewSet.get_queryset.
  • Project membership filter (layer 2): apps.projects.models.ProjectManager.for_user.
  • Data source filter (layer 3): applied per-document in the EDMS-related viewsets and the dir action on Project.
  • Role-based event filter (layer 4): mostly client-side — apps_workflow.js: can_user_perform_transition, is_owner_or_assignee. The backend returns rows the frontend may still hide.
  • State-specific rules (layer 5): scattered — check-out logic in EdmsDocument, completion visibility in WorkflowWorkflow.limit_completed_visibility, transition-role-from-state semantics in the workflow signal handlers.

A practical consequence: when diagnosing "I can't see X" from logs alone, the backend may have served the row. The frontend then applied layer 4/5 filters client-side. To reproduce a true "can't see" end-to-end, hit the frontend, not the API.

See devdocs/ for codebase-level material.