AIDA Labs · Library

AIDA Project Plan: data model for the Project Board

AIDA Labs · Library · Design · Draft v0.1 for review · 3 October 2026

This document maps out the relational database behind the AIDA Project Board, the editable, web-managed version of a project plan. The read-only Project Blueprint is generated from it. It uses the Sample Bank AML Intelligence Hub plan as the worked example and becomes the definition of the AIDA Project Plan product.


1. Decisions so far (Mike, 3 October 2026)

TopicDecision
DatabaseTwo versions: one on PostgreSQL, one on PocketBase. Each must be able to run on AIDA Labs Toronto or AIDA Labs Quebec
Sign-inOur own accounts first (email and password, held in the board's own database). Microsoft single sign-on can be added later
Progress trackingAll four: status with red/yellow/green health, percent complete, actual dates against the baseline, and hours with earned value (SPI and CPI)
SalesforceImport and export files. Tables map cleanly to Salesforce custom objects; data moves by CSV with Data Loader. No live link
Azure and DatabricksPortable by design. The PostgreSQL version moves to Azure Database for PostgreSQL unchanged, and every table has a flat export for Databricks (Delta tables)
BlueprintAlways read-only. It's generated from a published snapshot of the board, never edited directly

2. What PMI guidance this follows

PMI guidanceHow the model applies it
The WBS covers 100% of the scope; children roll up to their parent; the lowest level is the work package, with a single owner (PMI, What is a WBS)wbs_element is a tree. Every task has exactly one accountable owner, and hours and progress roll up to the parent
A WBS dictionary defines each element's scope, milestones, responsible party, resources and acceptance criteriaEach element carries a description, deliverable, acceptance criteria, owner and assignments, so the dictionary is a report on this table, not a separate document
Hard logic only, no open ends, no logic on summary rows, few hard constraints, "as soon as possible" by default (PMI, Scheduling 101)Dependencies are allowed only between tasks and milestones, never summary rows. A built-in check lists open-ended tasks and every constraint
Identify the critical path and watch near-critical workThe scheduling engine calculates float. The Sample Bank plan's stated critical path is kept as a record and compared with the calculated one
Baseline, then manage by exception; SPI = EV ÷ PV, CPI = EV ÷ AC (PMI, Monitoring performance against baseline)Approved baselines are frozen snapshots. Earned value is calculated from baseline hours, percent complete and actual hours
Change controlAny change to an approved baseline goes through a change_request and creates a new baseline version

The current PMBOK Guide is the Eighth Edition (November 2025). It's organised around principles, seven performance domains (governance, scope, schedule, finance, stakeholders, resources, risk) and non-prescriptive process guidance. The model's table groups follow those domains (section 4).

One gap in the Sample Bank plan as it stands. Its WBS is organised by phase and work area ("1. Initiation and governance setup", "2. Discovery and design"…), and most rows are activities. PMI recommends organising the WBS around deliverables. The model supports both: a wbs_element can be a deliverable, a work package, a task or a milestone. Whether to restructure the Sample Bank WBS around deliverables is a decision for you (see section 9).

3. How it fits together

 People edit here                Published, read-only
 ┌────────────────────┐ publish  ┌────────────────────┐ build  ┌──────────────────────┐
 │ Project Board      │ ───────► │ plan_snapshot      │ ─────► │ Project Blueprint    │
 │ (web app, editable)│ (button, │ (frozen JSON of    │        │ (static pages, never │
 │ PostgreSQL or      │  logged) │  the whole plan)   │        │  edited directly)    │
 │ PocketBase         │          └────────────────────┘        └──────────────────────┘
 └────────────────────┘                    │
        │ exports                          └──► portal Project Plan pop-up (same JSON)
        ▼
 CSV / MS Project XML / Jira CSV / Salesforce Data Loader CSV / Databricks (Delta)
  • The board is the system of record. The Blueprint and the portal's Project Plan pop-up read only from a published snapshot. They can't change the board, and the board can't change them without a new publish.
  • The snapshot has exactly the shape the Blueprint uses today (the WBS, MILESTONES, LANES, RES and release lists), so the current Blueprint and the portal pop-up work unchanged.

4. Tables

Naming is portable: lower-case snake_case, a id text primary key (UUID), created_at / updated_at / created_by / updated_by on every table. Weeks are kept alongside dates, because the Sample Bank plan is written in weeks 1–52.

4.1 Governance: projects, people, access

TablePurposeKey columns
app_userA sign-in account (our own accounts)email (unique), display_name, password_hash (PostgreSQL version; PocketBase uses its built-in auth collection), is_active, last_login_at
organizationClient or AIDA Labsname, short_name
projectOne projectorganization_id, code, name, description, status, start_date (nullable until set), calendar_id, current_baseline_id, published_snapshot_id
calendarWorking calendarname, week_starts_on, hours_per_week
calendar_exceptionHolidays and shutdownscalendar_id, date, reason
project_roleRoles on a project (Sponsor, Project Lead, Developer, AML Ops SME…)project_id, name, description, expected_commitment
project_memberA person on a project, in a roleproject_id, user_id (nullable for people without an account), person_name, organization, project_role_id, is_active
user_groupEditable groups (for example "Release 1 testers")project_id, name, description
group_memberWho is in each groupgroup_id, project_member_id
permissionWhat each role may doproject_role_id, object_type, can_view, can_edit, can_approve

Security and visibility. A user sees a project only if they're a project_member. What they can view, edit or approve comes from their role's permission rows, plus any groups they belong to. Items assigned to a person, a role or a group (section 4.4) are editable by that assignee.

4.2 Scope and schedule

TablePurposeKey columns
work_areaThe plan's lanes (Governance, Data sourcing…)project_id, code, name, short_name, sort
wbs_elementThe WBS tree: deliverables, work packages, tasks and milestonesproject_id, parent_id, code ("3.20"), name, element_type (deliverable / work_package / task / milestone / summary), work_area_id, description, deliverable, acceptance_criteria, start_week, duration_weeks, planned_start, planned_finish, constraint_type (default "as soon as possible"), constraint_date, is_critical_stated, sort
dependencyLogic between tasksproject_id, predecessor_id, successor_id, type (FS / SS / FF / SF, default FS), lag_days. Rule: tasks and milestones only, never summary rows
releaseReleasesproject_id, code (R1), name, theme, goal, from_week, to_week, live_week
release_itemWhat a release delivers, plus its targets, feeds and phasesrelease_id, kind (deliver / target / feed / phase / dashboard), text, sort
quality_gateGates with exit criteria and approversproject_id, release_id, name, when_text, due_week, exit_criteria, approver_role_id, status, approved_by, approved_at
milestone_detailExtra detail for a milestonewbs_element_id, number (M5), accountable_role_id, what_done_looks_like

4.3 Baselines and change control

TablePurposeKey columns
baselineAn approved version of the planproject_id, version ("v0.1"), name, status (draft / approved / superseded), approved_by, approved_at, notes
baseline_elementFrozen copy of each element in that baselinebaseline_id, wbs_element_id, start_week, duration_weeks, planned_start, planned_finish, planned_hours
change_requestProposed changes to an approved baselineproject_id, number, title, reason, impact_schedule, impact_hours, status (raised / assessed / approved / rejected), decided_by, decided_at, resulting_baseline_id
decisionDecision log (never rewritten)project_id, date, decision, made_by, related_element_id

4.4 Assignments and resources

TablePurposeKey columns
assignmentWho does a task. An assignment targets exactly one of a person, a role or a groupwbs_element_id, assignee_type (member / role / group), member_id, project_role_id, group_id, raci (R / A / C / I), planned_hours. Check: exactly one target is filled
role_allocationPlanned hours per week by role and period (the plan's RES table)project_id, project_role_id, from_week, to_week, hours_per_week
raci_activityThe charter's RACI matrixproject_id, activity, sort
raci_entryOne RACI cellraci_activity_id, project_role_id, value (R / A / C / I / A/R)

4.5 Progress and earned value

TablePurposeKey columns
task_statusCurrent progress, one row per taskwbs_element_id, status (not started / in progress / done / blocked), health (red / yellow / green), percent_complete (0–100), actual_start, actual_finish, forecast_finish, note, updated_by, updated_at
status_historyEvery progress change, never rewrittenwbs_element_id, field, old_value, new_value, changed_by, changed_at
time_entryActual hourswbs_element_id, project_member_id, week_number, work_date, hours, note
status_periodReporting periods (for example each week)project_id, period_end, is_closed
ev_snapshotEarned value at each period end (calculated, stored for trends)project_id, status_period_id, wbs_element_id (null = whole project), pv_hours, ev_hours, ac_hours, spi, cpi

How earned value is calculated (in hours, until cost rates are agreed):

  • PV (planned value): baseline hours scheduled to be done by the period end.
  • EV (earned value): baseline hours × percent complete.
  • AC (actual cost): actual hours from time_entry.
  • SPI = EV ÷ PV and CPI = EV ÷ AC. 1.0 is on plan; below 1.0 needs attention.

4.6 Risks, stakeholders and the rest of the Blueprint

TablePurpose
riskRisk register: code, title, description, work area, timing, owner, monitor, probability, impact, mitigation, contingency, early warning, status
stakeholderStakeholder register: name or role, interest, influence, engagement, communication rhythm, RACI value
epic, user_story, story_taskEpics and user stories, linked to WBS tasks (the Blueprint's Epics & User Stories)
next_stepThe charter's next steps
attachmentFiles linked to any record (charter PDF, workbook)
audit_logEvery insert, update and delete: table, record, user, time, before and after

4.7 Publishing

TablePurpose
plan_snapshotA frozen JSON copy of the whole plan, in the Blueprint's exact data shape: project_id, baseline_id, published_by, published_at, json, checksum

The Blueprint build reads the latest snapshot. Nothing reads the live tables directly.

5. The two database versions

PostgreSQL versionPocketBase version
Runs onAIDA Labs Toronto or AIDA Labs Quebec (or Azure Database for PostgreSQL later, unchanged)AIDA Labs Toronto or AIDA Labs Quebec (a single program with its own SQLite file; already used on Quebec for the job-search portal)
TablesSection 4, as SQL tables with foreign keys, check constraints and viewsSection 4, as PocketBase collections with relation fields. The app_user table is PocketBase's built-in auth collection
SecurityRow-level security policies from project_member and permissionPocketBase API rules on each collection, based on the signed-in user's membership
Calculations (float, earned value, roll-ups)SQL functions and views, the same pattern as the AML hub's KPI functionsComputed by the web app, or by PocketBase hooks
Best forLarger projects, reporting, the path to Azure and DatabricksSmall teams and quick set-up; one file to back up

Both versions use the same table and column names, so the same exports and the same web front end work against either. The front end talks to an API layer, not to the database directly.

6. Exports and compatibility

TargetHow
DatabricksOne flat file (CSV or Parquet) per table, loaded into Delta tables with the same names. Primary and foreign keys are recorded as informational constraints in Unity Catalog
AzurePostgreSQL version: dump and restore into Azure Database for PostgreSQL
Salesforce (files, no live link)Each table maps to a custom object (WBS_Element__c, Dependency__c, Assignment__c…). Our id is stored in an External ID field, so Data Loader can upsert and keep links between objects. Parent links become lookup fields
Microsoft ProjectExport and import as Microsoft Project XML: tasks with outline level, start and finish, duration, milestones and predecessor links
JiraCSV export of tasks as issues, with epics and parent links, for Jira's CSV importer
Portal and Blueprintplan_snapshot JSON

7. The web front end (Project Board)

Each screen reuses the read-only views already built for the portal pop-up, made editable:

  • Plan: a Gantt chart and table. Edit names, weeks, owners and dependencies, with drag-to-reschedule, and a check that flags open ends and summary-row logic.
  • My work: tasks assigned to me, my roles or my groups. Update status, health, percent complete, actual dates and hours here.
  • Milestones and gates: approve gates and record evidence.
  • Baselines and change requests: compare the current plan with any baseline and approve changes.
  • Risks, stakeholders, RACI: registers people can edit.
  • Reports: SPI and CPI trends, variance against baseline, and the critical path.
  • Publish: a button that creates a plan_snapshot and rebuilds the Blueprint and portal through the usual reviewed deploy script.
  • Admin: members, roles, groups and permissions.

8. Loading the Sample Bank plan as the first project

Everything in the Sample Bank Blueprint maps directly:

Blueprint dataTable
plan.WBS (85 tasks and milestones in 6 groups) and newtasks (13 Sample Bank fit-gap tasks)wbs_element, dependency
charter.LANESwork_area
charter.MILESTONESmilestone_detail
The release list, with gatesrelease, release_item, quality_gate
plan.RES, plan.PWrole_allocation
charter.TEAM, RACI_ROLES, RACIproject_role, raci_activity, raci_entry
charter.RISKS, STAKEHOLDERS, NEXT_STEPSrisk, stakeholder, next_step
Epics and storiesepic, user_story, story_task

Baseline v0.1 would be created from it as-is.

9. Open questions. Not guessed; need your answer

  1. Project start date and calendar. The Sample Bank plan runs in weeks 1–52 with no calendar dates. What date is week 1, and which holidays should the calendar skip?
  2. Restructure the WBS around deliverables? PMI recommends it. The Sample Bank plan is organised by phase and work area. Keep it as is for the first load, or restructure?
  3. Who approves a baseline and change requests on Sample Bank: the Sponsor alone, or the Sponsor and the Project Lead?
  4. Cost in earned value. Earned value is in hours for now. Should it also use cost rates per role, and in what currency?
  5. Planned hours per task. The plan has hours per role per period (RES), not per task. For earned value, hours have to be spread onto tasks. Spread them by duration within each role, or enter them task by task?
  6. Who gets accounts. Only AIDA Labs, or Sample Bank people too? This decides the first set of roles and permissions.
  7. Which version first: PostgreSQL or PocketBase?

Sources

‹ Back to the library