Skip to content

Causality map

This is the single biggest reference page in the academy. It lists every meaningful user action in dooer, alongside everything that ripples when you do it: which models are touched, which notifications fire, which audit log entries get written, which gamification effects trigger, and where it shows up in the UI.

Read this top-to-bottom and you have the full causal model of the app. Every lesson in the academy points back at one or more rows here.

How to use this page

  • As a learner — open this when you finish a journey. Find the row that matches the action you just took. Notice the whole cascade, not just the change you saw on screen. That awareness is what separates "I clicked a button" from "I understand the system."
  • As a builder / debugger — when something behaves unexpectedly, find the row for the action that triggered it. The downstream columns tell you which signal handlers and side-effects to inspect.

Conventions

  • Notifications fired — these are Notification rows created in the database; each one fires post_save_BoundedExecutor → SMTP (after transaction.on_commit()).
  • AuditLog action — the action field on the row written to AuditLog. The row also stores changes_json (before/after) and the actor_id.
  • Gamification effect — only WorkItem completion mutates dooer_points. See How it works.

Tasks (WorkItem)

Action Models touched Notifications fired AuditLog action Gamification UI ripples
Create quick task WorkItem TASK_ASSIGNED (if assignee ≠ self) create Task appears in board column matching status; dashboard tile counts update; assignee's bell badge increments
Create full-brief task WorkItem + BriefSequence BRIEF_ISSUED + TASK_ASSIGNED create +10 if status=Complete on create Brief ID printed on task (BR-{ORG}-{PROJECT}-{YEAR}-NNN); brief downloadable as .docx
Edit task field inline WorkItem update Field re-renders; if status changed, task may move between Kanban columns
Mark task Complete WorkItem (completed_at stamped), UserProfile (points) STATUS_CHANGED_TERMINALoriginal_assigner update +5 (quick) or +10 (brief); may trigger level-up email Task moves to Done column; level-up modal pops if threshold crossed; profile shows new points total
Reassign task WorkItem.assignee_id TASK_ASSIGNED (new), TASK_REASSIGNED (original assigner), TASK_REASSIGNED_AWAY (old; suppressed if actor==old) reassign All three recipients see entries in their bells
Add subtask WorkItem (parent_id set) TASK_ASSIGNED (if assignee ≠ self) create Subtask nested under parent; parent's effort_hours auto-rolls-up
Add predecessor (blocker) Dependency "Blocked" badge appears on the dependent task; cleared when blocker completes
Drag task in Eisenhower WorkItem.priority and/or status update Quadrant grid + 5-day strip both recalculate
Drag task to day column (5-day) WorkItem.target_date update Daily workload gauge recomputes; overbook warning fires if cap exceeded
Propose effort WorkItem.effort_hours_pending EFFORT_REVISION_REQUESTEDoriginal_assigner effort_propose Approver sees row in /approvals
Approve effort WorkItem.effort_hours locked; parent rolls up EFFORT_REVISION_APPROVED → assignee effort_approve Effort badge moves from "Proposed" → locked value
Reject effort WorkItem.effort_hours_pending cleared EFFORT_REVISION_REJECTED → assignee effort_reject Assignee re-proposes
Accept pending task WorkItem.acceptanceStatus=Accepted (none) update Task leaves approvals queue; appears in assignee's task list
Reject pending task WorkItem.acceptanceStatus=Rejected (none) update Task returns to pending queue if reassigned
Stop recurrence WorkItem.recurrence cleared update Future occurrences removed; existing task remains
Delete task WorkItem deleted (cascade cleanup via pre_delete signal) delete Task removed from board; confirmation modal shown first
Upload attachment Attachment RESOURCE_UPLOADED → stakeholders attachment_add Attachment list on TaskDetail; file size + uploader stamped

Feedback

Action Models touched Notifications fired AuditLog action UI ripples
Add feedback to task Feedback (unique pending-per-author constraint) (effort-type feedback triggers approval chain) feedback_create Appears on TaskDetail Feedback tab; rolls up to project's Feedback Register tab
Edit feedback Feedback feedback_update Updated row in registers
Convert feedback to task New WorkItem (origin=feedback); Feedback.status=Approved TASK_ASSIGNED if assigned create + feedback_approved Feedback marked closed; new task appears in board
Approve feedback Feedback.status=Approved (depends on type) feedback_approved Status badge changes
Reject feedback Feedback.status=Rejected feedback_rejected Status badge changes

Projects

Action Models touched Notifications fired AuditLog action UI ripples
Create project Project (slug unique per org) (none) create Appears in "Planning" column of /projects
Change project status Project.status (none) update Repositioned in project Kanban; status visible on linked tasks list
Edit project name/description Project update Header updates everywhere project is referenced
Upload project asset Resource (project-level) PROJECT_ATTACHMENT_ADDED → project watchers attachment_add Project → Assets tab
Delete project Project (cascade) delete Project removed from /projects; linked tasks lose project_id

Meetings

Action Models touched Notifications fired AuditLog action UI ripples
Create meeting Meeting + MeetingAttendee × N MEETING_SYNCED_FROM_OUTLOOK (if Outlook-synced) create Meetings list; on each attendee's calendar view
Add meeting decision (decision sub-record) Decisions log on MeetingDetail
Add meeting action item WorkItem (linked via meeting) TASK_ASSIGNED create New task in board, linked back to meeting
Add meeting note MeetingNote + WorkItemBriefNote (if linked to a task) Notes panel on MeetingDetail; back-link on linked task
Set RACI role on attendee MeetingAttendee.raci_role Role tag visible on attendee chip
Delete meeting Meeting (cascade) delete Confirmation; removed from list

Comments

Action Models touched Notifications fired AuditLog action UI ripples
Add comment on task Comment + N × Notification (one per watcher) COMMENT_ADDED to each watcher (excluding self) implicit Comment appears on task; watcher bells + emails

Comment cost

A comment on a 10-watcher task = 10 emails. Make comments worth that price. (See T-1.6.)


Notifications

Action Models touched Notifications fired AuditLog action UI ripples
Mark single notification read Notification.is_read=true Bell badge decrements
Mark all read Notification × N Bell badge resets to 0
Delete notification Notification (soft-delete) Disappears from bell

Notes

Action Models touched Notifications fired AuditLog action UI ripples
Create note MeetingNote (free-standing) create Appears in Notes list
Edit note MeetingNote update Live preview updates; linked task panels refresh
Link note to task WorkItemBriefNote (M2M junction) Note appears in task's Related Notes panel; back-link on note
Delete note MeetingNote (cascade junctions) delete Note removed from list; links cleared

Sticky Notes

Action Models touched UI ripples
Create sticky StickyNote (per-user, max 10) Note appears on dashboard sticky board
Edit sticky StickyNote (debounced save on blur) Persisted after ~2s of no typing
Delete sticky StickyNote Note removed

Account / Settings

Action Models touched Notifications fired AuditLog action UI ripples
Edit profile UserProfile Avatar/bio updated everywhere
Change password User.password + JWT blacklist All outstanding refresh tokens for that user invalidated
Edit notification preferences UserProfile.email_notifications_enabled Future notifications respect new prefs
Invite team member Invitation (welcome email after acceptance) invite Pending invite in Settings → Team
Remove team member Organization.members member_remove Member loses access
Change member role RBAC group role_change Member's view changes accordingly

Read-only actions (no side effects)

These show data but don't mutate anything. Useful to know which ones are "safe to explore":

  • View dashboard, board, calendar, reports.
  • Filter views (filters are client-side or query-string).
  • Search globally (Cmd+K).
  • Export to XLSX (read + format; doesn't change data).
  • Drill into Manager Reports.
  • Open Audit Log.

The big picture

Three patterns repeat across the table:

  1. Every meaningful change creates an audit log row. That's the configuration baseline (see Configuration baseline).
  2. Most actions fire one or more notifications. Notifications are dooer's "information radiator" — they push state to people who need it (see Capture, organize, reflect).
  3. The accountability lineage is preserved. original_assigner_id never changes. It outlives every reassignment.

If you understand those three patterns, you understand 80% of the system.


← Academy