Repository navigation
Analysts Leaving
New in 3.7.0 Β· from #178 Β· System β Analysts
When somebody leaves, press the bin icon on their row in System β Analysts. It opens When someone leaves, which shows what they hold, offers to hand their open work to someone else, and then gives you three choices.
| Choice | What happens | Undo? |
|---|---|---|
| Deactivate | They can no longer sign in, and their API keys stop working. Their name stays on every ticket, note, change and audit entry they touched. The right choice for almost every leaver. | Yes - tick Active again |
| Anonymise | Everything Deactivate does, then their name and contact details are removed. Their records all stay, credited to "Former analyst #42"; their personal settings and sign-in links are deleted. For a request to be forgotten. | No |
| Delete | Removes the account and their personal settings. Only possible when their name is on no history at all - an account made by mistake, or a test login. | No |
A service desk's records are a history of who did what. If Max closed a ticket in February and left in March, the ticket should still say Closed by Max - next week, next year, and when somebody asks who approved a change. Deleting Max would either leave holes in that history or be refused by the database, so FreeITSM keeps the record whole and simply stops Max signing in.
Deactivating changes nothing about where their name appears. Nothing is renamed when they leave, and there is no grace period to set.
Open tickets, problems, changes and tasks assigned to them - and the knowledge articles, projects, contracts and domains they own - are listed with a count each. Tick Move it to, choose an analyst (or Nobody, to leave it unassigned), and it is moved as part of the same step.
- Each item moves exactly as if you had reassigned it by hand, so its own history records the change, and the new owner is told the way they normally would be.
- Closed items keep their name. Who handled a closed ticket is history, not work.
- If an item cannot be moved - a members-only project you are not a member of, for example - the window says which, so you can open it and reassign it yourself. The rest still move.
Some things are routed to a person rather than assigned to them: a form that sends its approvals to them, an SLA alert that notifies them, a seat on the CAB of an open change, rota shifts from today on, equipment still assigned to them, folders and report packs they own. These are listed, never changed for you - clearing a form's approver could let requests through unchecked, so it needs a person to decide who approves instead.
They also stop Delete: an account that is still set up somewhere is not one to remove.
Analysts are people, so their name, email address and phone number are personal data. An organisation can usually keep what it needs to show who did what, but not more than it needs, and not for longer. Anonymise is the tool for when the answer becomes "not the name either":
- the account becomes Former analyst #42, with a username and email nobody can use, and a password nobody knows;
- their job title, department, phone numbers, MFA and sign-in links are removed;
- their personal settings go: dashboards, preferences, saved views, signatures, memberships and grants;
- names FreeITSM stored beside their account are replaced too - on checklists, in the Files audit, and in ticket, task, problem and change history where an assignment recorded the name. Only a value that is their name is changed, never one that merely contains it.
What it cannot do: change a name somebody typed into the text of a note, a reply or an email. The window says so before you confirm.
FreeITSM gives you the tools; whether and when to use them is your organisation's call.
Before 3.7.0, Delete removed the account row and nothing else. On a fresh install, where the database protects its links between tables, that was refused the moment the analyst had a single dashboard widget saved, and the raw database error was shown:
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row:
a foreign key constraint fails (`analyst_ticket_dashboard_widgets`, CONSTRAINT `fk_atdw_analyst` ...)
The widgets were only the first of many: 212 columns across FreeITSM refer to an analyst. Removing the database's protection (the reporter's first suggestion) would have let a deleted analyst leave tickets pointing at nobody. So instead every one of those columns has been sorted into what leaving should do to it - removed with them, moved to someone else, listed for a person to decide, or kept as history - and Delete now removes their personal settings with them, and explains in words when it cannot go ahead.
The rules live in includes/analyst_lifecycle.php. The screen (system/analysts/index.php) and the endpoints (api/tickets/analyst_leaving.php, and the older delete_analyst.php) only adapt them.
| Kind | Meaning | Delete / Anonymise |
|---|---|---|
personal |
their settings, memberships and grants (dashboards, preferences, team and module membership, folder grants - including polymorphic principal_type = 'analyst' rows) |
removed |
secret |
sign-in material (SSO links, trusted devices, reset tokens, API keys) | removed |
live |
open work - moved by analystReassignLive() through each module's service |
moved first; closed rows of the same columns are history
|
setup |
routed to them; a person decides | listed; blocks Delete |
history |
who did what | kept; blocks Delete |
-
analystReferenceRegistry()is the map: every column that refers to an analyst, with its kind (and, for a polymorphic or partly-live column, the condition). -
TRAP:every column that refers to an analyst must be in the map.tests/analyst-lifecycle.phpdiscovers them three ways - foreign keys toanalystsinfreeitsm.sql, person-shaped integer column names, and type + id pairs - and fails on any it does not find there. A missing one is a raw error on a fresh install's delete, or a dangling reference on an install without foreign keys. - Reassignment goes through
TicketsService::updateTicket(),ProblemsService::updateProblem(),ChangesService::updateChange(),TasksService::saveTask(),KnowledgeService::saveArticle(),ProjectsService::updateProject()andDomainsService::updateDomain()- never a bulkUPDATE- so history, notifications and workflow triggers are a manual reassign's. Contracts has no partial update or history table, so its owner is updated directly. - Each action is written to
system_logs(analyst_deactivated,analyst_anonymised,analyst_deleted) by id only: a log of an anonymisation that kept the name would undo it.
Tested by tests/analyst-lifecycle.php - see Developer Tests - System.
Related: Leavers could still sign in Β· REST API - Analysts Β· Bugs resolved
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
- π§ͺ Developer tests
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- π Date & Time Formats
- 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
- β³ π« 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
- β³ π·οΈ 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
- β³ π 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
- β³ π·οΈ 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
- β³ πͺ #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