Repository navigation
Task Work View Design
Status: all five phases built (20 Oct 2026), in the next release - forms belong to a task occurrence (Forms on tasks), and the Work view brings instructions, Knowledge procedures, checklists and forms together. Developer guide: Forms on tasks and the Work view. Note: the inline form is the Forms page in a frame rather than an extracted
FormFiller- see the developer guide for why.Decided 19 Oct 2026. This page sets out what I am building for issue #190, and why. It was written before any code so the approach could be checked first.
Updated 19 Oct 2026: @Dr4inder read the design and answered the seven questions - see section 8. Five went as suggested. Two changed the design: reading a task's form answers is now its own permission rather than following from reading the task (section 3), and the procedure links to Knowledge articles, with the text each occurrence was done against frozen into its record (section 3a). They also asked that two people saving the same occurrence's form conflict visibly rather than overwrite each other (Saving progress).
It builds directly on #181 - repeating task evidence, which is built and ships in 3.12.0. #181 is the record and #190 is the workbench: nothing here adds a second place to keep results, a second history or a second completion check. Section 2 says exactly what is reused.
The request, from issue #190 (raised by @Dr4inder):
"When carrying out a task, its instructions, checklist, form answers and supporting documents are the working material. An analyst should be able to open the task and complete that work in one place."
Take a task "Daily backup verification" that repeats every day, weekends included. Each day the analyst reads the backup reports, marks every job OK, Warning or Failure, explains anything that is not OK, attaches the report and raises a follow-up where something needs fixing.
Today that means leaving the task to fill in a form in the Forms module, finding the saved submission, coming back, typing its number into a checklist step, and then completing the task separately. FreeITSM never knows that the submission and the task belong together. The analyst is the only link.
The proposal is:
- A task (or its repeat) can say which forms it needs. Each occurrence gets its own fresh copy of that requirement.
- The form is filled in inside the task. The submission is linked to that occurrence automatically, so no numbers are copied by hand.
- A Work tab in the large task window brings together the instructions, checklists, forms, documents and follow-ups, with progress and one Complete button.
- Completing checks the required work through the gate that already exists, so it holds on every path: the task window, the board, the right-click menu, subtasks and the REST API.
- All of it feeds the #181 evidence report. Form answers, follow-ups and exceptions appear against the right occurrence and survive in its frozen record if the occurrence is removed.
Tasks with no checklist, form or procedure look exactly as they do now.
Mapped from the code (3.12.0 with #181), not from memory:
| The work view needs | Today | Verdict |
|---|---|---|
| One task per scheduled day, earlier ones still open | A repeat on a fixed schedule creates every occurrence on its date, whether or not the earlier ones are done | β Have it |
| The day an occurrence is for, kept apart from its due date and its completion |
scheduled_date (set once, never edited), due_date, completed_datetime and completed_by_id (#181) |
β Have it |
| The period being checked (for example "Saturday's backups") | Not recorded | β New (section 4) |
| Instructions | The task description (copied to each occurrence by the repeat) and the checklist template's description | |
| Checklist steps with mandatory markers, recorded values and Pass / Fail / Not applicable |
task_checklist_items (#181 added results, exception notes and step history) |
β Have it |
| Fresh results on each new occurrence | The repeat copies each checklist without its ticks, values or results | β Have it |
| A form linked to a task | No link at all. A submission can point at a ticket (form_submissions.ticket_id), never at a task |
β New (section 3) |
| A form filled in somewhere other than the Forms page | The field rendering and conditional logic are shared (FormRender, FormLogic), but the filling and saving code lives inside forms/fill.php
|
|
| Saved progress on a form |
form_drafts: one draft per person per form version, not tied to anything |
|
| Server-side validation of required and conditional answers |
FormsService::submitForm() re-works out which fields are visible, drops hidden answers and checks required fields, formats and options |
β Have it, reused unchanged |
| A retry that cannot submit twice | Nothing stops a double submit | β New |
| Documents on a task | The shared documents panel, scoped to the task's company (#181) | β Have it |
| Follow-up work | A task can link one ticket and one change. A subtask is part of the task, not a follow-up from it | |
| A completion check on every path |
ChecklistsService::assertTaskCompletionAllowed(), called before every open-to-closed change in updateTask, moveTask, the board's drag and subtask ticking, and so in the REST API too |
β Have it. Extended, not copied (section 6) |
| History of what happened to an occurrence |
task_events and the History tab (#181) |
β Have it. New event types |
| Evidence report, CSVs and the frozen copy of a removed occurrence |
TaskEvidence, TaskHistory::snapshot() (#181) |
β Have it. Extended |
Dr4inder's own line from the issue is the rule I am designing to:
"Reuse #181's occurrence history and evidence-reporting capabilities where applicable, rather than creating a separate compliance module or duplicating its data model."
| Owned by | #190 does | |
|---|---|---|
| The occurrence (one task row per scheduled date) | #181 and repeats | Reuses it. The occurrence is the unit of work. There is no new "run" or "execution" record beside the task |
scheduled_date, the due date in force at completion, who completed it |
#181 | Shows them on the Work tab and adds only the period (section 4) |
| Checklist steps, values, results, exception notes, step history | #181 / checklists | Shows them on the Work tab through the same endpoints. No second checklist editor |
History (task_events) |
#181 | New event types for forms and follow-ups, written through TaskHistory::record()
|
| The completion gate | Checklists on tasks | Widened into one task completion check covering checklists, required forms and follow-ups. It stays one function called from the same four places |
| Skip | #181 | Unchanged. Skipping is still not gated: not doing the work is the point |
| The evidence report and CSVs | #181 | Adds form answers, follow-ups and form exceptions to each occurrence's row |
| The frozen record of a removed occurrence | #181 |
snapshot() also freezes the linked submissions and their answers |
| Form definitions, versions, validation, drafts | Forms | Reused. A submission still points at the exact form version it was made on, which is the "template/version context" acceptance criterion 8 asks for |
A new section on the task, Forms, beside Checklists. It sits behind the same kind of switch as checklists on tasks (Tasks β Settings), so a team that does not want it never sees it. Adding a form to a task makes a row in a new table:
task_forms: task_id, form_id (the newest version when it was added), is_required, requirement_mode (warn or block, the same two levels checklists use), submission_id (empty until it is submitted), sort_order, who added it and when.
- On a repeat, the forms travel to the next occurrence the way checklists do: the requirement is copied, the answers are not. Each occurrence starts unanswered (acceptance criterion 8). The copy points at the form's newest version at that moment, so a form edited between Saturday and Sunday is used in its new shape from Sunday, and Saturday's submission keeps pointing at the version it was made on.
- One submission per form per occurrence. If a check genuinely needs two, it is a grid field or two forms on the task.
- An optional form (not required) is offered on the Work tab but never stops completion.
The Work tab renders the form inside the task, with the same field types, sections, conditional questions, lookups and grids as the Forms page. To do that without a second form engine, the filling code in forms/fill.php moves into a shared FormFiller (render, read the answers, save a draft, submit) that both the Forms page and the task use. The server half is untouched: the task submits through FormsService::submitForm(), so required, conditional and format validation are exactly the same.
The submission is saved with a new column, form_submissions.task_id, and task_forms.submission_id is set in the same transaction, so a submission can never exist half-linked. A task-linked submission does not get its own route into the Forms module's workflows other than the ones the form already has: its on submit actions run as they do today, with the task's number added to what they receive.
A draft made inside a task belongs to that occurrence, and is shared by everyone who may work on it (decision 3). Saturday's and Sunday's half-finished forms stay separate, reopening Saturday's task brings back Saturday's draft, and a check one analyst started can be handed to another. The draft shows who saved it last, and when. A draft made on the Forms page has no task and behaves exactly as it does today (one per person per form).
So a task's draft is not a form_drafts row (whose key is one per person) but lives on the requirement itself: task_forms.draft_json, draft_by_id, draft_datetime and a revision number.
Asked for by @Dr4inder: a stale save must produce a clear conflict and keep the analyst's work, never silently overwrite somebody else's changes. So every save is conditional on the revision it started from:
- Opening the form reads the draft and its
revision. - Saving sends that revision. The server updates the row only if the revision is still the same (
UPDATE β¦ WHERE revision = ?), and bumps it. - If somebody else saved in between, nothing is written. The answer is a conflict naming who saved and when, with their version. The Work tab keeps what this analyst typed on screen, says "Sam saved this form at 10:42 while you had it open", and offers Use theirs or Keep mine (which saves again on top of theirs, deliberately, with the new revision).
The same rule covers the submitted answers: submitting, and correcting an earlier submission, send the revision too, so two people cannot both submit the same occurrence's form, and a correction cannot replace a submission its author never saw.
Every submit from the Work tab carries a client reference generated when the form is opened. form_submissions gets a unique key on task + client reference, so a retry after a timeout returns the submission that already exists instead of making a second one. It is the same shape I proposed for change evidence uploads in #194, so the REST API ends up with one idempotency pattern, not two.
- A submission linked to a task can not be deleted from the Forms module while it is linked: it is that occurrence's evidence. If the occurrence is removed, the submission goes into its frozen record (section 7).
- Correcting a submitted answer is a new submission that replaces it on the task, with the replaced one kept and shown in the History, and it is subject to the same revision check as a draft. That follows the #181 setting Changing a completed task's checklist: on an install that refuses changes after completion, the form is locked once the task is done, too.
Embedding must not grant access (criterion 7), so:
-
Filling a form inside a task needs what filling it on the Forms page needs: access to Forms that is not Read only. Someone without it sees the form's name and "You need access to Forms to fill this in", and if the form is required, the Complete button says that is what is stopping it.
-
Reading a task's form answers is decided by one rule, written once (
TaskForms::mayReadAnswers()) and used everywhere the answers appear - the Work tab, the History tab's form events, the evidence report on screen and in print, and the form-answers CSV:You may read an occurrence's form answers if you can see the task, and either you have access to Forms (as you would need to read the same submission there), or your role grants the new everyday permission Read form answers on tasks.
Reading the task is never enough on its own (decision 4): task access does not quietly override Forms access. The new permission is how a Read only auditor (#181) is given exactly the answers on the occurrences they can already see, and nothing else in Forms - they still cannot open the Forms module, its other submissions or its designer. It is off unless a role grants it, so an upgrade gives nobody anything new.
Where the rule says no, the place the answers would be shows that a form was submitted, by whom and when, and "You do not have access to these answers" - so the record is visibly complete without its contents. The CSV writes the same words in the answer column rather than leaving rows out, so its row count does not depend on who ran it.
-
Forms are install-wide today, and so are their submissions. A submission linked to a task takes the task's company, so in a multi-company install the Forms module's submissions list only shows it to people who can see that task. This is the same rule #181 applied to a task's documents.
Decision 7: the instructions belong in the Work view, from records FreeITSM already has.
- Task instructions - the task's own description, which the repeat already copies to each occurrence.
- Step descriptions - a checklist template step's description is now copied to the task's step, so each step is readable in place (until now a task's step showed only its title).
-
Procedure references - a task, or its repeat, can reference Knowledge articles (
task_procedures: task, article, sort order). The Work tab shows each one in place, through Knowledge's own visibility rules: an article the viewer may not read is named, not shown. The repeat copies the references to each new occurrence, like checklists. - Supporting documents - the task's existing documents, as they are.
@Dr4inder asked that later edits must not rewrite the instructions behind historical evidence. Knowledge articles have version numbers, but an ordinary save edits an article in place - only save as a new version keeps the old text. So the version number alone cannot promise the words.
When an occurrence is completed (or skipped), each referenced article's title and body as they stand at that moment are frozen into its record: task_procedure_snapshots holds each distinct text once (keyed by its hash, so 365 daily occurrences done against the same SOP store it once), and the occurrence's reference keeps the snapshot, the article's version number and the time. The evidence report shows "done against: Backup verification SOP, version 4", and the frozen text is one click away even after the article has been edited, archived or deleted. A removed occurrence keeps it in its #181 frozen record.
While an occurrence is open it shows the article as it is now, because that is what the analyst is working from.
Writing procedures in FreeITSM - the longer-term direction @Dr4inder describes, where instructions, forms, checklists, findings and evidence all live here - is what this builds towards: Knowledge is where the procedure is written, and the occurrence is where it is carried out.
The issue asks for the scheduled date, the period being checked and the actual completion to stay distinct. Two of the three already exist from #181. The third is new:
| Column | Set by | Changes? | |
|---|---|---|---|
| This occurrence is for |
scheduled_date (#181) |
The repeat, once | Never |
| Period checked | new period_start, period_end
|
The repeat, from the rule, once | Never |
| Due | due_date |
The repeat, then people | Yes, and #181 records every move |
| Done |
completed_datetime, completed_by_id (#181) |
Completing | Cleared and recorded if reopened |
The repeat gains one setting, This occurrence checks: nothing in particular (the default, so existing repeats are unchanged), the scheduled day, the day before, or the time since the previous occurrence. The period is worked out when the occurrence is created and never edited afterwards, like scheduled_date.
Dr4inder's weekend case works today: the repeat creates Saturday's and Sunday's tasks on their days, and they can be completed on Monday as separate occurrences, each keeping its own date and records.
The one thing to be clear about is how #181's report judges them. If Saturday's task is due on Saturday and completed on Monday, the report calls it Late. That is accurate, but it may not be what a team means when its policy is "weekend checks are reviewed on Monday". So the repeat could optionally set when each occurrence is due, relative to its scheduled day (the same day, N days later or the next working day). Saturday's check is then for Saturday, checks Saturday's period, is due on Monday, and is On time when done on Monday, while a check done on Tuesday is still Late. Decision 2.
A finding often needs a ticket or a task to fix it. Today a task links to at most one ticket (tasks.ticket_id), which is already taken by "the ticket this task belongs to", and a subtask is part of the task, not a follow-up from it.
So a new table, task_follow_ups: task_id, kind (ticket or task), the record's id, where it came from (a checklist step, or a form submission and field), who and when, and the client reference that stops a retry creating it twice.
From the Work tab:
- Create a ticket or task. It opens prefilled with the occurrence's title, its scheduled date and the finding (the step's exception note, or the form answer), and is linked when saved.
- Link an existing ticket or task, with the same pickers the task window uses for links.
- Each follow-up shows its live status. Opening one follows the normal access rules, so a ticket the viewer cannot see is named by number only, as in the #181 report.
Whether an open follow-up stops the occurrence completing is a setting (decision 5). The default is that it does not: the check was performed and the finding recorded, which is exactly what completing means, and the follow-up stays open and linked.
The issue is right that a Complete button which checks things the board's drag does not would be worse than no check. #181 and the checklists work already solved where completion happens. There are four status writers, and each calls one gate before an open-to-closed change.
So I would widen that gate rather than add a second one. ChecklistsService::assertTaskCompletionAllowed() becomes a task completion check that gathers:
- mandatory checklist steps outstanding (unchanged)
- required forms with no submission (new)
- open follow-ups, if the setting says they block (new)
Each item is warn or block, with the same company block all floor that already reaches tasks. It stays one function, called from the same four places, so the board, the right-click Mark complete, a subtask tick, the task window and the REST API all get it at once. The Work tab's progress bar and the Complete button ask the same function (?check=complete) before posting, so what the analyst is told is computed by the code that enforces it.
A completion that goes through with warn items outstanding is recorded, as checklists record today, and appears in the #181 report as an exception.
Completing says the review was performed and its findings recorded. It never turns a finding into a success:
- A checklist step marked Fail stays a failure in the report (#181).
- A form answer can be marked as an exception too. In the form designer, a choice field can mark some answers (for example Warning and Failure) as counts as an exception. The marking belongs to the form version, so it cannot change after the fact. Those answers then appear in the #181 report's exceptions, beside failed steps, with the explanation fields that the form's conditional logic made the analyst fill in.
A failed save leaves the task open, keeps what was saved (submitted forms, ticked steps and drafts are separate saves, each already durable), and the Work tab lists what still needs attention. Complete is the last step and changes only the status, so a retry after a failure cannot create anything twice. Submissions and follow-ups are protected by their client references.
So the work done in the Work tab is still there when an auditor asks:
- Report row. Each occurrence gains its forms (submitted by, when, which version) and its follow-ups (kind, number, status), and the period checked where the repeat records one. Form answers marked as exceptions count in the summary's exceptions.
- Print. Each occurrence's form answers are printed under its checklist results, as the form showed them (labels, sections and the visible fields only).
- CSV. A fourth file, form answers: one row per answer, with series id, task id, submission id, form version and field, so it joins to the other three. Follow-ups go in the existing evidence file.
-
History events.
form_added,form_removed,form_submitted,form_replaced,follow_up_createdandfollow_up_linked, recorded throughTaskHistory::record()and shown in the History tab. -
A removed occurrence freezes its linked submissions, their answers and the form version's field labels into the same
task_removed_recordssnapshot as its checklists. The submission rows are kept as well, with their task link, so the Forms module's record and the report agree. Like the rest of #181's record, none of the new tables has a foreign key that would delete evidence with its task.
Answered by @Dr4inder on 19 Oct 2026.
| # | Question | Decision |
|---|---|---|
| 1 | Where the Work view lives | A Work tab in the large window, which a task with working material (a checklist, a form or a procedure) opens on by default. A personal preference turns that off; the panel and both layouts stay as they are |
| 2 | Weekend checks reviewed on Monday | An optional when each occurrence is due on the repeat (for example the next working day). Same day stays the default. One occurrence per scheduled day, with scheduled date, period checked, due date and completion all distinct |
| 3 | A draft inside a task | Shared by everyone who may work on the occurrence, showing who saved it last - and a stale save is a visible conflict that keeps the analyst's work (Saving progress) |
| 4 | Reading a task's form answers | Not from reading the task alone. Forms access, or a new, narrow permission Read form answers on tasks, applied the same way in the Work tab, History, report and CSV (Who can see and fill it) |
| 5 | An open follow-up at completion | Allowed by default, with the link and its live status kept. The review can be complete while the remediation is open |
| 6 | OK / Warning / Failure | A form with conditional explanation and action fields. Checklist results stay Pass / Fail / Not applicable; the form's counts as an exception answers feed the #181 report |
| 7 | The procedure / SOP | Task instructions, copied step descriptions, documents and references to Knowledge articles, with the text each occurrence was done against frozen into its record (section 3a) |
The questions as they were put
| # | Question | Options | My suggestion |
|---|---|---|---|
| 1 | Where the Work view lives | (a) A Work tab in the large window's tabs layout, which is also the tab the task opens on when it has work (a checklist, a form or a procedure) Β· (b) a third layout alongside Two columns and Tabs | (a). It is what the issue sketches, it keeps the panel and both layouts as they are, and a task with no work shows no Work tab. Opening on the Work tab would be a personal preference, on by default |
| 2 | Weekend checks reviewed on Monday | (a) Keep due = scheduled day, so Monday's review shows as Late in the #181 report Β· (b) Add when each occurrence is due to the repeat (section 4), so it can be On time | (b), as an option. The default stays "the same day", so nothing changes on upgrade |
| 3 | A draft inside a task | (a) Shared: anyone who works the occurrence sees and continues it Β· (b) Personal, as drafts are today | (a). The occurrence is the unit of work, and a check started by one person and finished by another is normal. Who saved it last is shown |
| 4 | Reading a task's form answers | (a) Anyone who can read the task, as with its checklist values Β· (b) Only people who also have access to Forms | (a). The answers are that occurrence's evidence, and a Read only auditor on Tasks (#181) needs to see them. Filling still needs Forms |
| 5 | An open follow-up at completion | Allowed (recorded) Β· Warn Β· Block. One setting in Tasks β Settings β Evidence | Allowed, the default |
| 6 | Warning as a checklist result | (a) Leave checklist results as Pass / Fail / Not applicable and use a form for OK / Warning / Failure Β· (b) Add Warning to checklist results too | (a). A form already does conditional "explain this" fields, which a checklist step cannot. Adding Warning to steps is easy later if it is wanted |
| 7 | The procedure / SOP | (a) The task description, plus each step's description, which is newly copied from the template Β· (b) Also a link to a knowledge article or document, carried by the repeat | (a) now, (b) later. (a) needs no new concept. (b) is worth doing once (a) is in use |
Each phase is useful on its own and ships in its own release:
-
Forms belong to a task.
task_forms,form_submissions.task_id, shared drafts with the revision check, the client reference, the repeat copying the requirement, the widened completion check, the Read form answers on tasks permission and its one rule, history events, the report, the CSV and the frozen record. Filling still happens in a window that opens the sharedFormFillerfrom the task, so the data model and the gate are proven first. - The Work tab - the key milestone for a single entry point. Instructions, step descriptions, procedure references with their frozen text, checklists, forms inline, documents, progress and Complete, plus the keyboard, narrow-screen and phone work.
-
Follow-ups.
task_follow_ups, create and link from a step or an answer, the setting. - Period and due offset on repeats, and counts as an exception in the form designer.
-
REST API.
GET /tasks/{id}/forms, andtask_idwithclient_referenceonPOST /forms/{id}/submissions, so an integration can submit a check against an occurrence. Completion over the API already goes through the gate.
| # | Criterion | Where |
|---|---|---|
| 1 | Reached through the normal task-opening flow; panel and layouts remain | Decision 1 |
| 2 | Instructions, steps and values, forms and evidence in the main area | Sections 3 and 9 (phase 2) |
| 3 | Submissions and follow-ups linked to the right occurrence automatically | Sections 3 and 5 |
| 4 | Each daily occurrence keeps its own progress, forms and evidence; weekend ones completed later keep their day | Sections 3 (drafts per occurrence) and 4 |
| 5 | Required work checked on every write path; failures and retries cannot make false completions or duplicates | Section 6, client references |
| 6 | The same records and save paths are reused; no parallel evidence store or editor | Section 2 |
| 7 | Permissions, conditional validation, closure rules, history and recurrence preserved; no extra access | Section 3 (Who can see and fill it), section 6 |
| 8 | Fresh results for each occurrence; history keeps the right task, period and version | Sections 1, 3 and 4 |
| 9 | Simple tasks stay simple; long content, keyboard, narrow screens and themes | Decision 1, phase 2 |
As the issue says: no enforced order of steps, no new workflow or approval engine, and no separate compliance module. The Work tab is a layout over records that already exist. The report shows what was recorded, and a warning or failure stays a warning or failure.
- Recurring task evidence - design (#181) Β· Repeating task evidence Β· Repeating task evidence - Developer Guide
- Checklists on tasks - Developer Guide Β· Forms Β· Form designer - Developer Guide
- Tasks Β· Recurring tasks
- Proposal: custom fields, inventory import and change evidence (#194) - the same client-reference idempotency pattern
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
-
Architecture
- β³ π§Ή Root folder tidy (URL routing)
- β³ π Database Integrity (FKs & constraints)
- β³ π οΈ Database Verification β Developer Guide
- β³ π§© Service Layer (UI + API share code)
- β³ πͺ€ Code traps (the TRAP: comments)
- β³ π Commenting for the Engineering wiki
- β³ π οΈ Engineering wiki scanner - Developer Guide
- β³ π Service-Layer progress
- π€ Contributing (read before a pull request)
- π§ͺ Developer tests
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- π Date & Time Formats
- π± Currencies
- π§ The sidebar (optional module rail)
- π§© Preference templates
- π Display order (modules, Watchtower cards) β Developer Guide
- Theming & Dark Mode
- ποΈ Recent β getting back to what you were doing
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
-
MobileβFriendly
- β³ π« Mobile: Tickets
- β³ π» Mobile: Assets
- β³ π Mobile: Calendar
- β³ π Mobile: Knowledge
- β³ π¦ Mobile: Service Status
- β³ πΌ Mobile: Watchtower
- β³ π§© Mobile: Problem Management
- β³ π Mobile: Change Management
- β³ πΏ Mobile: Software
- β³ β Mobile: Tasks
- β³ π Mobile: Forms
- β³ π Mobile: Contracts
- β³ π Mobile: Domains
- β³ π Mobile: People
- β³ π Mobile: Projects
- β³ ποΈ Mobile: Files
- β³ π Mobile: LMS
- β³ πΊοΈ Mobile: CMDB
- β³ πΊοΈ Mobile: Network Mapper
- β³ π§ Mobile: Process Mapper
- β³ βοΈ Mobile: Workflow
- β³ π₯οΈ Mobile: System
- β³ π Mobile: Reporting
- β³ π Mobile: System Wiki
- β³ π Mobile: Self-Service Portal
- β³ π§° Mobile: Techniques & Tricks
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- β³ π‘οΈ CSRF protection (S4) β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- π CardDAV contact sync
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π Proposal: custom fields, inventory import and change evidence (#194)
- β³ π οΈ Custom fields, evidence + inventory - review (#195-#197)
- β³ π οΈ Long forms in a task's Work view - review (#198)
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π REST API: Domains
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ π·οΈ REST API: Cost centres
- β³ π§βπΌ REST API: Analysts
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ π Rota copy and paste β Developer Deep Dive
- β³ β Checklists & SOPs
- β³ βοΈ Mandatory fields
- β³ π§Ύ Custom ticket fields
- β³ π·οΈ Ticket categories
- β³ π₯ Assigning tickets to a team, and escalation
- β³ π’ One board across every company
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ π Attachment size limits and large emails
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
-
β³
βοΈ Telegram channel - β³ β CSAT company scope and filters β Developer Guide
- β³ π₯ Microsoft Teams channel
- β³ π¨οΈ Mattermost channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ β Record previews
- β³ π Ticket notes: internal or shared
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ π¨ Telling the analyst a ticket is theirs
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π’ Ticket numbering
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ π Confidential tickets
- β³ π₯ Portal managers
- β³ π Who has seen a ticket
- β³ π Reading long tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ ποΈ The folder pane
- β³ π½ Just my tickets, or no closed ones
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- β³ π Case reports - a ticket and its work as one PDF
- β³ π Scheduled work in your own calendar
- Problem Management
- Tasks
- π Projects
-
Assets
- β³ π’ Moving an asset between companies
- β³ π Shared asset locations
- β³ π§βπΌ Assigning assets to analysts
- β³ π Warranty and lease alerts
- β³ π Leases
- β³ π Saved table views
- β³ π¨οΈ Recording anything, and importing it
- β³ π§© Asset type layouts
- β³ π Inventory freshness
- β³ π Connected assets
- β³ π Asset review
- β³ π·οΈ QR asset labels
- β³ π Who holds what, and handover documents
- β³ π₯οΈ The inventory agent (PowerShell)
- β³ ποΈ Proxmox VE servers
- β³ βοΈ VMware Cloud Director servers
- β³ π Linking equipment to tickets
- β³ βοΈ Follow-up tasks on a ticket
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
-
Forms
- β³ π¨ The form designer β Developer Guide
- β³ π Layout & the grid β Developer Guide
- β³ ποΈ Collections β grouping submissions
- β³ π Submissions as PDFs
- β³ β‘ What happens next β a form's own actions
- β³ π οΈ Sections & conditional logic β Developer Guide
- β³ π οΈ Lookup fields β Developer Guide
- β³ π‘οΈ Catalogue request approvals
- People
- Domains
- ποΈ Files
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ π’ One board across every company
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)
- What this is
-
π Bugs resolved
- β³ π Escaped text could leave its attribute
- β³ π Task descriptions were not cleaned
- β³ π Task documents ignored company scope
- β³ π Repeating tasks ignored company scope
- β³ π¬ #183 Mailbox checks overlapped
- β³ π #188 Transfer lock shown off when unknown
- β³ β #184 Subtask names and Overdue
- β³ π§© #186 Teams: the buttons did nothing
- β³ π Text in a change could run script
- β³ π AI settings changed without the AI permission
- β³ πͺ #178 Deleting an analyst failed
- β³ π« A team with no departments showed 0 tickets
- β³ π Projects: adding a phase did nothing on Save
- β³ π Leavers could still sign in
- β³ πΌοΈ Logo and courses broke on Apache with PHP-FPM
- β³ π’ Chat tickets ignored your ticket numbering
- β³ π Dates shown as a dash, or in server time
- β³ π Assets β Users showed people from other companies
- β³ π Restricted analysts could read other modules' data
- β³ πΌοΈ Replies with a picture in the thread failed to send
- β³ π Reply attachments never reached the customer
- β³ π οΈ Outbound email attachments β Developer Guide
- β³ π A global SSO provider was missing from the portal
- β³ π Behind a proxy, the SSO redirect said http
- β³ βοΈ The portal tagline moved when you saved it
- β³ π¨ The portal settings screen forgot what you saved
- β³ π‘οΈ The approvals inbox said "Error" and nothing else
- β³ π A table's answers were missing from the PDF
- β³ β A single-select column let you tick every option
- β³ π The portal ignored a form's field widths
- β³ π The tasks board stopped taking clicks
- β³ ποΈ #121 The index list is out of date after upgrading
- β³ π #133 The calendar subscription was empty
- β³ π #131 Tasks always reopened on the board
- β³ π₯ #129 Every page returned HTTP 500 after upgrading
- β³ π³ #127 A PHP warning above the System page
- β³ π #126 Notes stamped with the server's clock
- β³ π Storing every date in UTC
- β³ πͺ The portal was down for everyone signed in
- β³ βοΈ #120 Workflow notes could never be written
- β³ βοΈ #123 Three errors when running Database Verification
- β³ π #122 The description box was a stub in the corner
- β³ π£ Demo data deleted real accounts
- β³ π #117 Sign-in redirected to the wrong address
- β³ π¨ #108 The priority dot was invisible
- β³ β±οΈ #116 Time logged from the right-click menu
- β³ π #114 API keys refused by our own guard
- β³ ποΈ #110 Assigning a task told nobody
- β³ πͺ #107 Signed out while still working
- β³ π #103 "Share with Requester" reached nobody
- β³ π #102 Search found nothing for hyphens
- β³ πͺ #101 Source code editor opened behind
- β³ βοΈ #88 Subtasks could not be ticked off
- β³ π» #84 Asset deep link selected nothing
- β³ π« #79 A new ticket arrived with no status
- β³ π§ #79 A ticket from email did not say so
- β³ π #78 Bell opened to nothing
- β³ π¬ #77 Mail only collected from Inbox
- β³ π #74 The default password could not be changed
- β³ π¦ #70 Renaming an impact level
- β³ π€ #67 App-only mailboxes could not send
- β³ π #45 Verify only ever worked for Microsoft
- β³ π #45 IMAP reported as not authenticated
- β³ βοΈ An email template stopped escaping itself
- β³ π The portal dashboard showed the wrong time
- β³ π’ The folder said 99 and the list showed 96