AccountedPro - Concepts
The whole engine is four nouns: Access Rule → Door → Access Profile → Scope.
Access Rule
One Access Rule governs one DocType (say Sales Invoice). It is a container for the doors, plus a few switches:
| Setting | Effect |
|---|---|
| Enabled | The master switch for this DocType. Off restores native behaviour immediately. |
| Default Deny | Off — the app only adds access; where no door opens, native perms decide. On — if no door opens, the record is hidden. |
| Door resolution | How several matching doors combine — see below. |
A DocType with no enabled rule is un-governed: the engine returns “no opinion” and Frappe's own permissions apply unchanged. Installing the app is inert until you add a rule.
Doors
A door is a single grant. Read it as three columns:
WHO WHICH ROWS WHAT THEY CAN DO
roles + "Current user is" scope (AND/OR/NOT of chips) Access Profile (+ per-door overrides)
- Who — the roles the door applies to (blank = any role), optionally narrowed to specific accounts by a Current user is chip in the scope.
- Which rows — the scope: a nested boolean tree of chips (see Row scopes). It compiles to SQL for lists and is evaluated per-row for single documents. An empty scope opens every row.
- What they can do — the Access Profile, plus per-door overrides: field rules, child-row visibility, block files / print / email, hide the timeline, hide on list, a custom banner, and the profile granted when a request is approved.
Doors are positive grants: a person sees the union of the rows opened by the doors that apply to them. A door whose scope matches no rows simply contributes nothing.
A door scoped by Current user is IN (a, b, c) does not restrict people outside that list — it just doesn't apply to them. So a door for a handful of scanner accounts never hides anything from everyone else.
Access Profile
A reusable bundle, referenced by doors, with two halves.
Actions — booleans mapping to permission types: discover, read, write, create, delete, submit, cancel, amend, print, email, export, share, report. Discover means “may know it exists / see it in a count” without full read; read implies discover.
Default field access + field rules — the baseline visibility for every field, and per-field overrides. See Fields and child tables. Common profiles are conventions you create and name yourself:
| Profile | Meaning |
|---|---|
| Full | Read + write + all actions; fields Editable |
| Read-Only | Read + print/export, no write; fields Read-only |
| Blurred | Discover/read, but default field access = Blur — a hard cap that hides all values until a request is approved |
| Discover-only | The record exists (shows in lists/counts) but its contents are hidden |
Default Deny
The single most important switch on a rule.
- Off — layer targeted rules onto an existing setup. Where no door opens for a person, native Frappe permissions decide.
- On — the app is authoritative. If no door opens on a record, it is hidden. “Deny by default, grant explicitly.”
It is evaluated as “did any door open?” — not “did the person match a role”. A door that applies by role but whose scope matches no rows counts as not opened.
Door resolution
When several doors match one record, door_resolution decides what the person can do there. Row visibility always unions across doors regardless of this setting.
- Best access wins (default) — combine every matching door; the person gets the most permissive actions and the most-visible field access (field masking still respects the Blurred hard cap).
- First match wins — only the top-most matching door decides. Drag doors with the
⋮⋮handle to set precedence. Use it when a restrictive door must shadow a broader one — e.g. a Blurred “archive” door listed above a Full door.
Next: Row scopes.