How to use this guide
Log in as the admin user. Complete the three Required setup cards once (top to bottom), then run the numbered test steps in order. Every "Open …" button deep-links into this scratch org. Every Apex block is copy-to-clipboard: paste it into Setup → Developer Console → Debug → Open Execute Anonymous Window, or run the referenced .apex file with sf apex run --file "<file>" --target-org SystemTrackerTest. The .apex files referenced here sit in this same folder.
Required = mandatory setup or a state that must already be true before the step will work. Step = a normal test action you perform and observe. Each test step lists its Where (exact card, tab, and position) and, when relevant, a REQUIRED BEFORE THIS STEP line.
Seed the walkthrough dataRequiredAdmin
Creates the foundation every link below points to: an Aviation Program and Project, published System Templates (Door → Camera), seeded Systems & Equipment (Door 1000 with child Camera A), a Transition Event (which auto-provisions the Readiness Certification, Executive Authorization, and Asset Acceptance gates) + a Stakeholder, and an Inspection Request. Idempotent — safe to re-run.
sf apex run --file "System Tracker Build/System Testing Walkthrough/seed_walkthrough.apex" --target-org SystemTrackerTest
Expect the debug log to end with RCT_SEED_DONE and print the Project / Door / Gate / IR record Ids.
Seed the Commissioning Matrix with door and camera checklistsRequiredAdmin
The matrix renders one grid per template, and each grid only looks like a matrix once several systems share that template. Run both scripts so the matrix shows two grids with multiple rows each — the full functionality of the feature.
- Doors: ensures Door 1000–1004 exist and instantiates the Door Commissioning - Aviation template into a live checklist for each (one grid, 5 rows).
- Cameras: ensures the Camera Commissioning - Aviation template exists, ensures Camera A–C exist, and instantiates a camera checklist for each (a second grid, 3 rows).
Both scripts seed varied item statuses (Passed / Failed / Deferred / Not Started) so every cross-section cell is populated and colour-coded. Idempotent and lookup-based — re-running re-applies the status pattern rather than duplicating.
sf apex run --file "System Tracker Build/System Testing Walkthrough/seed_matrix_doors.apex" --target-org SystemTrackerTest
sf apex run --file "System Tracker Build/System Testing Walkthrough/seed_matrix_cameras.apex" --target-org SystemTrackerTest
Expect MATRIX_SEEDED doors=5 checklists_created=4 items_updated=125 and CAMERA_MATRIX_SEEDED template_created=true cameras=3 checklists_created=3 items_updated=36 on first run (fewer created on re-runs). To link a single door checklist only, run instantiate_door_checklist.apex instead.
Confirm & grant commissioning accessRequiredAdmin
The admin user carries the Citiri_Admin permission set group (which includes COS_Commissioning_Manage and COS_Commissioning_Governance). Setting item status from the matrix cells additionally requires COS_Commissioning_Execute (which grants the COS_Execute_Commissioning_Checks custom permission). Run the snippet to guarantee the running user holds all three; without Execute the matrix in Step 4 is visible but read-only.
COS_Commissioning_* sets are assigned to your user.Set<String> want = new Set<String>{
'COS_Commissioning_Manage', 'COS_Commissioning_Governance', 'COS_Commissioning_Execute',
'CitiriOS__COS_Commissioning_Manage', 'CitiriOS__COS_Commissioning_Governance', 'CitiriOS__COS_Commissioning_Execute'
};
Set<Id> have = new Set<Id>();
for (PermissionSetAssignment a : [SELECT PermissionSetId FROM PermissionSetAssignment WHERE AssigneeId = :UserInfo.getUserId()]) {
have.add(a.PermissionSetId);
}
List<PermissionSetAssignment> toAdd = new List<PermissionSetAssignment>();
for (PermissionSet ps : [SELECT Id FROM PermissionSet WHERE Name IN :want]) {
if (!have.contains(ps.Id)) toAdd.add(new PermissionSetAssignment(AssigneeId = UserInfo.getUserId(), PermissionSetId = ps.Id));
}
if (!toAdd.isEmpty()) insert toAdd;
System.debug('Assigned ' + toAdd.size() + ' commissioning permission set(s).');
Reload any open Salesforce tab after assigning permission sets so the new access takes effect.
Browse the published System TemplatesAdmin
System Templates are the reusable, industry-scoped blueprints the toolkit seeds from. Confirm the Door → Camera pair is published for Aviation.
System_Template__c).- Open the System Templates list view.
- Confirm Door (Record Type Target = Parent) and Camera (Record Type Target = Equipment, parent = Door) are both Active for Industry Aviation.
Seed the system hierarchy with the System ToolkitAdmin
The System Toolkit picks published templates (Opti pre-selects the checklist-backed ones) and seeds them onto the project as a parent/child Systems & Equipment hierarchy — a junction-action-manager for systems.
COS_Commissioning_Manage (P3).- Open the project and select the Commissioning tab.
- In the System Toolkit card, select Door and Camera (Opti highlights the checklist-backed ones).
- Choose Seed Selected Systems and watch the Commissioning Matrix above gain rows.
P1 already seeds Door 1000 + Camera A so the later steps work immediately; use the Toolkit here to add more systems and watch the matrix react.
Monitor the Commissioning MatrixExecutive / Governance
The Commissioning Matrix renders one grid per checklist template. After P2 you see two grids: a Commissioning & Witnessing grid for the doors and an IST grid for the cameras. Within a grid, every system built from that template is a row, the template's sections and items are the columns (section headers group the item columns), and each cell shows that item's status — colour-coded Passed / Failed / Deferred / Not Started. Each row ends with a progress count and an overall status badge; summary tiles show tracked / commissioned / in-progress counts across all systems.
- Confirm you see two grids: the door grid (5 rows) and the camera grid (3 rows), each with its own sections and items.
- Read down a column to compare how every system is doing on the same check; read across a row for one system's status on every item. Each grid scrolls sideways for wide templates.
- Note the varied rows P2 seeded: Door 1000 fully Passed, Door 1001 Failed (a red cell), Door 1002 In Progress, Door 1003 Not Started, Door 1004 near-complete with a Deferred cell; Camera A fully Passed, Camera B with a Failed cell, Camera C with a Deferred cell.
- Use the three summary tiles to gauge overall progress, and select a system name (e.g. Door 1000) to open its record.
Set item status from any matrix cellNewCustomer User / Contractor
Every populated cell carries a status menu, so an authorized user sets the status of any system-and-item intersection in place — the row's progress and overall status roll up instantly, without leaving the project page. This works in both grids and is the live version of the Door Tracker grid.
COS_Commissioning_Execute (P3) for the cell menus. Without Execute the grid is read-only; a dash (—) cell means that item is not part of that system's checklist.- In the door grid, on the Door 1002 row (In Progress), find a Not Started cell under Construction / Delivery Checks (for example Door Card).
- Select the cell's ▾ arrow and choose Passed. The cell turns green, the row's progress count increases, and the overall status badge refreshes.
- Do the same in the camera grid — on Camera B, set a Configuration cell to Failed or Deferred and watch the colour and row rollup change.
- Compare across each grid — every row's colour pattern reflects the statuses you and P2 have set.
Optional — reset the Door 1000 checklist items to "Not Started" (or just re-run P2's seed_matrix_doors.apex to restore the varied pattern across all doors)
Id doorId = [SELECT Id FROM CitiriOS__System_Equipment__c
WHERE CitiriOS__Display_Name__c = 'Door 1000' AND CitiriOS__Project__r.Name = 'RCT Walkthrough Project' LIMIT 1].Id;
Set<Id> nodeIds = new Set<Id>();
for (CitiriOS__Activity_List_Node__c n : [SELECT Id FROM CitiriOS__Activity_List_Node__c
WHERE CitiriOS__Activity_List__r.CitiriOS__System_Equipment__c = :doorId]) nodeIds.add(n.Id);
Set<Id> frontier = new Set<Id>(nodeIds);
Integer guard = 0;
while (!frontier.isEmpty() && guard++ < 10) {
Set<Id> next = new Set<Id>();
for (CitiriOS__Activity_List_Node__c c : [SELECT Id FROM CitiriOS__Activity_List_Node__c WHERE CitiriOS__Parent_Node__c IN :frontier]) {
if (nodeIds.add(c.Id)) next.add(c.Id);
}
frontier = next;
}
List<CitiriOS__Activity_List_Item__c> items = [SELECT Id FROM CitiriOS__Activity_List_Item__c WHERE CitiriOS__Activity_List_Node__c IN :nodeIds];
for (CitiriOS__Activity_List_Item__c it : items) it.CitiriOS__Status__c = 'Not Started';
update items;
System.debug('Reset ' + items.size() + ' checklist items to Not Started.');
Ingest contractor progress in bulkCustomer User / Contractor
Where item-level toggling (Step 4) is granular, contractors also report progress in bulk: the customer user pastes a CSV into the Import Contractor Sheet card, or an integration updates the systems' rollup contract fields directly. The Apex below simulates a contractor completing checklists across every seeded system on the project.
COS_Commissioning_Manage (P3) to commit an import, and at least one seeded system.Id projId = [SELECT Id FROM CitiriOS__Project__c WHERE Name = 'RCT Walkthrough Project' LIMIT 1].Id;
List<CitiriOS__System_Equipment__c> eq = [
SELECT Id, CitiriOS__Display_Name__c
FROM CitiriOS__System_Equipment__c
WHERE CitiriOS__Project__c = :projId
];
for (CitiriOS__System_Equipment__c e : eq) {
e.CitiriOS__Components_Total_Count__c = 4;
e.CitiriOS__Components_Verified_Count__c = 4;
e.CitiriOS__Checklist_Complete__c = true;
e.CitiriOS__Checklist_Status__c = 'Complete';
e.CitiriOS__Status__c = 'Tested';
e.CitiriOS__Stage__c = 'Handover_Prep';
}
update eq;
System.debug('Checklist rollups completed for ' + eq.size() + ' systems.');
Open the Door 1000 record afterward: its contract rollup fields should read 4/4 components verified, Checklist Status = Complete, Status = Tested. These rollup fields live on the System record, distinct from the per-item statuses shown in the matrix grid.
Review the System & Equipment listCustomer User / Contractor
The flat System & Equipment list shows every tracked record on the project (parents and children) with status, stage, checklist status, and scheduled date — a quick working list beside the rolled-up matrix.
- Scan the list for status, stage, and checklist status across all systems.
- Open any row (e.g. Door 1000) to continue to the next step.
Drill into a System recordCustomer User / Contractor
The System & Equipment record page has its own Commissioning tab showing the child components and attached files — where a customer user inspects an individual system and its sub-components.
- Open Door 1000 and select the Commissioning tab.
- Confirm Camera A appears under Sub Systems & Equipment.
- Review the Files related list for attached documents.
Advance the readiness gateExecutive / Governance
Once systems are tested, governance advances the control gates. The project has three in sequence — Readiness Certification (1), Executive Authorization (2), and Asset Acceptance (3), all starting Pending. Use the gate action in the UI, or the Apex below to simulate an executive passing the first gate.
COS_Advance_Commissioning_Gate to use the gate action and COS_Make_Gate_Decision to persist the change — both are in the admin PSG (P3). A user without them is blocked (intended defense-in-depth).- In the Gates section, find Readiness Certification (sequence 1) and use its advance / decision action, or run the Apex below.
- Confirm the gate status changes to Passed.
CitiriOS__Control_Gate__c g = [
SELECT Id, CitiriOS__Status__c FROM CitiriOS__Control_Gate__c
WHERE CitiriOS__Project__r.Name = 'RCT Walkthrough Project'
AND CitiriOS__Gate_Type__c = 'Readiness Certification' LIMIT 1
];
g.CitiriOS__Status__c = 'Passed';
g.CitiriOS__Evaluated_By__c = UserInfo.getUserId();
g.CitiriOS__Evaluation_Date__c = Datetime.now();
update g;
System.debug('Readiness Certification gate advanced to Passed.');
Decide the Inspection Request (IR#)Executive / Governance
The final governance action accepts or rejects an externally-issued Inspection Request. The seed created one (status Submitted). Use the IR action in the Commissioning Governance card, or the Apex below to simulate acceptance.
COS_Decide_Inspection_Request to use the IR action (in the admin PSG, P3).- In the Inspection Requests section, open the submitted request and choose Accept (or run the Apex below).
- Confirm the request status changes to Accepted.
CitiriOS__Readiness_Attestation__c a = [
SELECT Id, CitiriOS__Status__c FROM CitiriOS__Readiness_Attestation__c
WHERE CitiriOS__Project__r.Name = 'RCT Walkthrough Project'
AND CitiriOS__Attestation_Type__c = 'Inspection Request' LIMIT 1
];
a.CitiriOS__Status__c = 'Accepted';
a.CitiriOS__Reviewed_By__c = UserInfo.getUserId();
a.CitiriOS__Review_Date__c = Datetime.now();
update a;
System.debug('Inspection request accepted.');
Known scratch-org caveat — Inspection Request Number field
In this scratch org the Inspection_Request_Number__c field will not materialize at runtime (a confirmed source-tracking artifact — a deploy reports success but describe/SOQL still cannot see the field). The Commissioning Governance card's Inspection Requests list selects that field, so that section may show an error. The Gates section (Step 8) and the Apex above are unaffected — the Apex sets only the status. To fully restore the IR list, add a Text field Inspection Request Number (API Inspection_Request_Number__c, length 80, External ID, Unique) on Readiness Attestation in Setup, or recreate the scratch org from source.
Reset the walkthroughAdmin
Return the project to a clean pre-demo state — removes seeded systems (and their Activity List checklists), gates, and the inspection request, while keeping the Program/Project so links stay valid. Re-run P1 then P2 to reseed.
Show reset Apex
Set<Id> projIds = new Map<Id, CitiriOS__Project__c>([
SELECT Id FROM CitiriOS__Project__c WHERE Name = 'RCT Walkthrough Project'
]).keySet();
delete [SELECT Id FROM CitiriOS__Activity_List__c WHERE CitiriOS__Project__c IN :projIds];
delete [SELECT Id FROM CitiriOS__Readiness_Attestation__c WHERE CitiriOS__Project__c IN :projIds];
delete [SELECT Id FROM CitiriOS__Control_Gate__c WHERE CitiriOS__Project__c IN :projIds];
delete [SELECT Id FROM CitiriOS__System_Equipment__c WHERE CitiriOS__Project__c IN :projIds AND CitiriOS__Group__c != null];
delete [SELECT Id FROM CitiriOS__System_Equipment__c WHERE CitiriOS__Project__c IN :projIds];
System.debug('Walkthrough data reset. Re-run P1 then P2 to reseed.');