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
ProjectPeoplerow 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
ProjectPeoplerows yet. Add her contact to the projects she should access. - "Member can see project but can't manage membership" → that
requires
project_adminflag 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_leaderflag onProjectPeoplebroadens visibility within a discipline. - The
project_adminflag onProjectPeoplebypasses 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_visibilityflag (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.
- Do they have the Django permission to view this model class at all? Admin → Users → (user) → Permissions, or check group membership.
- No → not a visibility issue. PERMISSIONS layer. Add to appropriate group (e.g. "READ PERMISSIONS"). Done.
-
Yes → continue.
-
Does tenancy overlap? Admin → User Profile → Tenancy. Compare to the record's
tenants. - No overlap → TENANCY layer. Usually a missing config tenant on the user. See TENANCY.
-
Overlap → continue.
-
Is the record project-scoped, and is the user a project member? Check
ProjectPeoplerows for the user vs the record's project. - 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.
-
Yes (or not project-scoped) → continue.
-
(Documents only.) Is the document's data source visible to the user? Check the document's
data_source.tenantsvs user's tenants. - No → data sources layer. Either grant the user the missing data tenant or move the document to a data source the user can see.
-
Yes (or not a document) → continue.
-
(Workflow events only.) Does any of the user's roles match a transition rule? Check
ProjectPeople.disciplinesfor the user vs the transitions in / out of the event's current status. - No match, and not owner / assignee / project_admin → roles layer. Assign the relevant discipline, or change the transition requirements. See ROLES.
-
Match → continue.
-
(Workflow events only.) Is the event in a hidden state?
- Workflow has
limit_completed_visibility=Trueand event is complete → state rules layer (completion gate). - Associated document is checked out → state rules layer (check-out lock). The event is visible but transitions / edits are blocked.
- 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:
- Permission to view workflow events? ✓ (they have the standard read group)
- 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:
- Permission to view projects? ✓
- Tenancy overlap with each project? ✓ (you added her tenancy correctly)
- Project membership? ✗ — she has no
ProjectPeoplerows 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_visibilityto 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
diraction 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 inWorkflowWorkflow.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.