Project Management

Why a config-driven PM layer beats a hard-coded one

Project teams routinely track tasks in spreadsheets, status in email threads, and time in separate approval tools. When you hard-code each screen, you get three disconnected surfaces that share no permission model, no event bus, and no common data layer. AuraBoot's project management solution is a single plugin where portfolios, projects, tasks, time entries, and the approval workflow are all declared in JSON and wired together through the same command pipeline, permission engine, and activity feed that every other AuraBoot module uses.

Data model summary

Thirteen cooperating models cover the full PM surface:

  • pm_portfolio — Programme-level container; states planning → active → on_hold → closed.
  • pm_project — The main work unit; code auto-generated as PRJ-{yyyyMMdd}-{seq}; states planning → in_progress → completed → archived. Creator is auto-added as an active pm_project_member.
  • pm_task — Five types: Epic, Story, Task, Bug, Milestone. Self-referencing pm_task_parent_id for sub-tasks. Rich-text description and file attachments included.
  • pm_task_assignment — RACI assignments (Responsible / Accountable / Consulted / Informed) per task.
  • pm_task_dependency — Four dependency types: finish-to-start, start-to-start, finish-to-finish, start-to-finish.
  • pm_time_entry — Hours logged against a project and task; categories: Development, Design, Testing, Meeting, Management, Other; billable flag; states draft → submitted → approved/rejected.
  • pm_label, pm_task_label, pm_task_comment, pm_task_watcher, pm_task_activity — Color-coded labels, threaded comments, notification subscriptions, and a full audit trail of every status change, assignment, and attachment event.
  • pm_project_role — Master-data roles (Project Manager, Project Member, Project Viewer) that drive the permission matrix.

Task state machine

Task states
-----------

  [create] ──> todo ──> in_progress ──> done
                |             |           |
                v             v           v (reopen)
            cancelled     cancelled     todo
                |
                v (reopen)
               todo

  on complete: pm_task_done_at auto-set
  on reopen: confirmation required

Key commands

The full solution defines 42 commands. A representative sample:

CommandTypeModelPermission
pm:create_projectcreatepm_projectpm.project.manage
pm:activate_projectstate_transitionpm_projectpm.project.manage
pm:create_taskcreatepm_taskpm.task.manage
pm:start_taskstate_transitionpm_taskpm.task.manage
pm:complete_taskstate_transitionpm_taskpm.task.manage
pm:reopen_taskstate_transitionpm_taskpm.project.manage
pm:create_time_entrycreatepm_time_entrypm.timesheet.manage
pm:submit_time_entrystate_transitionpm_time_entrypm.timesheet.manage
pm:approve_time_entrystate_transitionpm_time_entrypm.timesheet.approve

pm:create_project carries two auto-set side effects: the project code is generated (PRJ-20260411-001 style) and a pm_project_member record is inserted for the creator — no extra API calls required.

Process orchestration

Portfolio (active)
  └─ Project: planning ──> in_progress
                                 │
                    ┌────────────▼────────────┐
                    │  Task: todo             │  ← pm:create_task
                    └────────────┬────────────┘
                                 │ pm:start_task
                    ┌────────────▼────────────┐
                    │  Task: in_progress      │
                    └───────┬────────┬────────┘
                            │        │ pm:cancel_task
                   pm:complete_task  │
                    ┌───────▼──┐  ┌──▼──────────┐
                    │  done    │  │  cancelled  │
                    └───────┬──┘  └──────┬──────┘
                            │            │ pm:reopen_task
                            └─────┬──────┘
                                  │
                           ┌──────▼──────┐
                           │  Time Entry │  ← pm:create_time_entry
                           │  (draft)    │
                           └──────┬──────┘
                                  │ pm:submit_time_entry
                           ┌──────▼──────┐
                           │  submitted  │
                           └──────┬──────┘
                    ┌─────────────┴────────────┐
              pm:approve             pm:reject
                    │                         │
               approved                  rejected

Permission example

A realistic multi-role deployment:

  • Project Manager — Layer 3 ownership: full read/write/manage access to all data in their project (pm.project.manage, pm.task.manage, pm.member.manage, pm.timesheet.approve). Sees budget and planned-progress fields.
  • Contributor (Layer 2 ReBAC) — Holds pm.task.manage but only sees tasks where pm_task_assignee_id = current_user or they are in pm_task_assignment. Cannot read tasks assigned to colleagues in the same project.
  • Budget field (Layer 5 field-level)pm_pf_budget on pm_portfolio is hidden for any principal that does not hold pm.portfolio.manage. Contributors and viewers see the portfolio name and status but the budget cell is masked.
  • Cross-project view (Layer 4 ABAC) — The pm_my_tasks named query scopes results to the caller's own assignments. Viewing another user's task list requires an explicit pm.task.read grant scoped to that project — absent that grant, the cross-project table returns zero rows regardless of org hierarchy.

All four layers are evaluated in sequence before the page renders. No frontend branching required.

Dashboard and named queries

The pm_dashboard page delivers an executive overview through seven visualization blocks:

BlockTypeWhat it shows
Key Metricsstat-cardTotal Projects, Active, Completed, Total Tasks, Overdue Tasks, Total Hours
Monthly Trendline chartCreated vs. completed tasks by month
Project Statuspie chartDistribution across planning / in_progress / completed / archived
Task Statuspie chartDistribution across todo / in_progress / done / cancelled
Resource Utilizationbar chartTotal vs. billable hours per user (last 3 months)
Project HealthtablePer-project: task count, progress %, overdue count, health status
Overdue TaskstableTask, project, priority, due date, days overdue

Twelve named queries back the dashboard and personal views (pm_my_tasks, pm_my_watching, pm_my_participating, pm_project_health_overview, and more).

Pages shipped

PageKindDescription
pm_dashboarddashboardExecutive KPIs and health tables
pm_project_listlistStatus-tab filtered project list
pm_project_detaildetailProject info with lifecycle action toolbar
pm_task_listlistTasks with type / status / priority columns
pm_task_formformMulti-section form: basic info, rich-text description, attachments
pm_portfolio_listlistPortfolio list with status tabs
pm_time_entry_listlistTime entries with search and approval actions

Extending the solution

Because every definition is in JSON, extension does not require code changes:

  • Add a new task type by appending a value to the pm_task_type dictionary.
  • Add a time category (client_meeting) by extending pm_time_category.
  • Create a per-project burndown named query and add its block to pm_dashboard.json.
  • Link projects to CRM accounts via a reference field — cross-plugin wiring that inherits the same permission model.

Enterprise note — Multi-tenant Portfolio Governance (cross-tenant rollup queries, tenant-scoped Project Manager delegation), License/Entitlement enforcement on pm.timesheet.approve, AI-assisted task breakdown via the Agent Control Plane, and Observability Pro per-command trace spans are commercial-only capabilities. The open-core runtime described above is the same in every edition.

Next steps

  • System overview — how plugins, commands, and the runtime fit together
  • Command pipeline — the execution contract used by every command above
  • Permissions — the five-layer model used in the role example
  • Plugin manifest — how to declare dependencies and ship the solution as a package
  • Agent readiness — designing agentHint and risk fields for safe AI execution