Custom fields on every entity
Your org defines the schema, no code and no migration. They render on the web forms and the phone forms, filter in list views, and come back through the API. Retiring a definition is a soft delete, so the values already recorded stay readable.
A documented JSON API
JWT-authenticated, every entity, with a generated OpenAPI schema and both Swagger and Redoc served by the backend itself. The mobile app is a client of it, which is the only guarantee that matters: the API is not a side door, it is the door.
Tenant isolation in the database
Postgres row-level security, keyed on the organisation in your token and applied by the database rather than by application code. A query that forgets its filter returns nothing instead of returning someone else.
Attachments where the work happens
Files on leads, contacts, tasks and tickets from either client, and on deals from the phone. An account takes an attachment through the API with no screen calling it yet, and an invoice does not take one at all.
Two roles, and no role matrix
Admin and User. That is the whole list, and saying so is more useful than a permissions grid you would have to test. Access is decided by role plus ownership plus organisation, and the checks live in the API rather than in the interface.
The numbers you can act on
Ticket analytics by agent and by queue, a weighted pipeline forecast, and a real accounts-receivable aging report with buckets rather than a single overdue flag. Not a dashboard builder.