People Customers and Suppliers Roadmap - edmozley/freeitsm GitHub Wiki

People, customers and suppliers β€” roadmap

Raised in #153 (Contracts) and #154 (Domains) by @mbsouth Β· Status: steps 1 and 2 built (3.0.0) Β· step 3 built (3.1.0, with #162)

This page sets out how FreeITSM will let you be the customer and the supplier β€” and why it will get there by growing what already exists rather than adding a new Contacts module.


The request, in one paragraph

FreeITSM was designed for an IT manager who buys: 100 laptops from Dell, hosting from a web host, a support contract from a reseller. Contracts point at a supplier, domains have an analyst as their owner, and everything assumes we are the customer.

Many of the people running FreeITSM are small IT companies who do both. They buy for their own small estate, and they sell β€” hardware, managed services, web, email and domain hosting, web design β€” under contracts with their customers. For them a contract's other party may be a customer, a domain may belong to a customer, and the same person or company turns up in tickets, assets, contracts and domains. They want to see all of it in one place.

That is a fair description of a large part of FreeITSM's audience, and the design should serve it β€” without changing anything for the IT manager who only buys.


We are closer than it looks

The request reads as if every module keeps its own list of people. It doesn't. Here is what FreeITSM actually stores:

Kind of record Where it lives Shared by
People you serve β€” requesters, customers' staff, portal users users, shown as Tickets β†’ Users and Assets β†’ Users β€” one list, shown in two places Tickets, Assets, the self-service portal, LMS, Forms, Knowledge, web chat, WhatsApp/Telegram/Slack, the REST API, directory sync (LDAP/Entra), CardDAV
Companies you serve Companies β€” the multi-company feature (tenants) Everything; a company is also a security boundary
Organisations you buy from suppliers Contracts, Assets
A supplier's people contacts, shown as Contracts β†’ Contacts, always tied to a supplier Contracts only
Your own staff analysts Everything β€” they are the accounts that sign in and hold permissions

So the "Tickets β†’ Contacts, Assets β†’ Contacts, Software β†’ Contacts…" picture does not exist: the people you serve are already in one central list, and a person's company, job title, department, phone, mobile and manager live on it (most of them filled in automatically by directory sync).

Exactly one list of people stands apart β€” a supplier's contacts β€” and exactly two things are genuinely missing:

  1. A contract can only point at a supplier. There is no way to record a contract where you are the supplier and somebody else is the customer. (Domains have the same gap: nothing records who a domain is for.)
  2. There is no single page for a person or a company showing their tickets, assets, contracts and domains together.

Neither needs a new place to keep people. Both need the existing places joined up.


The plan

Step 1 β€” Contracts: Customer or Supplier Β· βœ… built β€” see Contracts with customers

A contract gets a choice above its party field:

  • Supplier β€” as today: one of your suppliers. Every existing contract is a supplier contract, unchanged.
  • Customer β€” a company you serve, or a person from your users.

Everything else about a contract β€” dates, value, notice periods, terms, documents, the expiry trigger β€” works the same either way. The contract list can show both, or filter to one.

Domains get the same idea as one new, optional field: Customer β€” who is this domain for? The owner (an analyst) stays as it is and keeps getting the renewal reminders. An IT manager who only manages their own domains leaves it empty and sees no difference.

Who can see a customer contract turned out to be the real design question: a customer belongs to a company, so by default only analysts who can see that company see the contract β€” with a setting to show them to everyone in Contracts instead. How that is applied everywhere a contract is read is in the developer guide.

πŸ“Œ Add, never swap. Nothing that exists changes meaning. A field that meant the supplier still means the supplier; a customer is a new, separate field. Swapping what an existing field points at β€” or offering a setting that does β€” would silently break saved records, reminders, reports and the API for whoever chose the other setting.

Step 2 β€” One page per person and per company Β· βœ… built β€” see People

A People area, reachable from the main menu as a place of its own, where one page shows everything about somebody:

  • A person β€” their details, their tickets, the assets they hold, contracts where they are the customer, domains they are the customer for, their courses and form submissions.
  • A company β€” the same, for everybody in it.

This is the "see all related data for a customer in one place" part of the request β€” and it is built on the list every module already uses, so nothing moves and nothing is copied.

Step 3 β€” Suppliers and their contacts in People Β· βœ… built β€” see People

The one remaining island was Contracts β†’ Contacts. This page first imagined moving contacts into People's list of users, with a person optionally belonging to a supplier. When it came to building it, the same result came without moving anything:

  • People β†’ Suppliers lists every supplier, searchable by its contacts' names too.
  • A supplier's page shows its contacts, the contracts with it, the equipment bought from it, and every domain where it is the registrar, the customer, or the technical contact through one of its people.
  • A contact's page shows how to reach them, their supplier, and the domains they are named on.
  • Both are in ⌘K and the recent trail, and a domain's page links to them.

Contacts stay in Contracts β†’ Contacts and are edited there. So a supplier's contact still cannot sign in to the portal, is not offered as a ticket's requester, and is never touched by directory sync β€” the three risks this page named are not managed, they simply do not arise. Moving the data would also have needed a migration on every install, for every install, including the many that never asked for it. Because Contracts owns these records, their pages need Contracts as well as People.

What it does not do (and would still need the move): let a supplier's contact raise a ticket as themselves. If that turns out to matter, it is the one part of the original idea left.

Domains, at the same time (#162). A domain's customer can now be a supplier, optionally with one of its contacts, as well as a person from Users; and its technical contact can be one of your analysts as well as a supplier contact. Both are new fields beside the old ones β€” the owner still means the analyst responsible, and still gets the reminders. See Domains.

And then

With a contract able to name its customer, contracts in the self-service portal β€” a customer seeing the contracts they hold and their documents β€” becomes straightforward. It is not part of steps 1–2, but they are what make it possible.


Why not a separate Contacts module?

The suggestion was a central FreeITSM β†’ Contacts module where every contact lives, belongs to groups (supplier, customer, company, individual), and is used everywhere. The goal behind it β€” one place to look β€” is right, and step 2 delivers it. A new module is the wrong way to get there:

  1. It would be a third place people live, not the only one. Users and analysts cannot simply move into it (below), so a Contacts module would sit beside them β€” the opposite of central.
  2. users is the most load-bearing table in the product. It is the portal's sign-in, the requester on every ticket, the subject of directory sync and CardDAV, the person in the REST API, and it carries the company that decides who may see what. Moving it into a new module means touching sign-in, sync, permissions and the API at once β€” for everyone, including the many installs that never asked for any of this.
  3. Analysts are not contacts. An analyst is an account with permissions β€” modules, roles, companies. Mixing accounts with address-book entries is how a contact ends up with access it should never have.
  4. Companies are a security boundary. In FreeITSM a company decides what each analyst can see. A contacts module with its own idea of "a customer company" is a second definition of company β€” and two definitions that mostly agree is how data starts leaking between customers. (The CRM page makes the same point.)
  5. Groups that change what a record is are fragile. A contact that is "a customer" in one place and "a supplier" in another needs every module to agree which it is today; a person who belongs to a company and optionally to a supplier does not.
  6. Step 2 gets the benefit without the move. The value of a contacts module is the page that shows everything about someone. That page can be built on the records that already exist.

What would make us revisit it

Being parked is not a rejection. A Contacts module is worth reconsidering if somebody makes a compelling case for one list showing users, supplier contacts, analysts and customers who are not users β€” together, as one kind of record. A case that would change the answer would need to show:

  • a real job that steps 1–3 cannot do β€” something people genuinely need to do that one page per person and per company does not cover;
  • how sign-in, portal access and directory sync stay safe when a contact becomes (or stops being) somebody who can log in;
  • how it keeps a single meaning of company, so the multi-company security boundary is not weakened;
  • what happens to every existing user, supplier contact and analyst on upgrade β€” with nothing anybody relies on changing meaning.

How this fits with other pages

  • CRM and a real service catalogue (parked) weighed exactly step 1's choice β€” a direction on contracts versus a separate customer-agreement record β€” and named the risk of the first: "supplier" baked into names a flag might not reach. Step 1 takes the direction approach, and treats that risk as its checklist: every place that reads a contract's supplier is found and taught that a contract may have a customer instead. The CRM page's larger ideas (cost-to-serve, account health, entitlement) are untouched by this, and still parked.
  • CalDAV and CardDAV (parked) is about keeping the people list in step with an outside address book. Steps 1–2 make that list more central, which makes the case for syncing it stronger, not weaker.
  • Groups of people β€” teams, learning groups and people groups are about who may do what, not who a contract is with; none of this changes them.

Steps 1 and 2 are built (3.0.0): Contracts with customers (developer guide) and People (developer guide). Step 3 is built (3.1.0): suppliers and their contacts in People, and a domain's customer and technical contact widened in Domains.