On this page

This guide is for operators supporting CRM, company files and Zoho. It describes implementation contracts; check the deployed revision and effective configuration before changing a service. Never paste live credentials, signed URLs, customer SQL bindings or provider payloads into public documentation.

Watch the lesson

CRM operations and performance Watch on YouTube from 00:24

Watch on YouTube.

Release and authority

CRM_RELEASE_PROFILE=mvp restricts advanced surfaces. CRM_MVP_PROVIDERS_ENABLED can allow the provider slice without enabling all advanced CRM. Per-feature release flags and rollout controls can further restrict navigation, reads, writes, file import, OAuth and AI. None of these settings grants a subscription feature or staff access.

CRM middleware reuses the authenticated user, initialized tenancy and selected company in a request-scoped CrmRequestContext. Session company selection is a preference, not cached authorization. Decisions are invalidated at transaction/write and entitlement boundaries and expire at observed subscription deadlines. Workers establish fresh authority; they never inherit a browser's in-memory grant.

The supported shared lookup cache covers projections for Helpdesk categories/custom fields, knowledge categories, tags and company settings. It is namespace/schema scoped, rotates generation on committed writes, bypasses transactional reads and falls back to the database when unavailable. It does not cache Eloquent objects, record permissions or write grants. Default lookup lifetime is 300 seconds; confirm config/workspace-lookups.php and deployment settings.

Measure the right work

Separate total request duration, cumulative SQL execution, query count, queued work and browser rendering. PDO instrumentation includes native safety/source checks that ordinary Laravel query events can omit. Many SQL executions are not hundreds of browser HTTP requests. Do not add overlapping traces together.

Redis moves queued work out of the browser request when a real worker is configured. Setting the driver alone does not prove that a worker processed it. Compare separately profiled requests under the same fixture/host conditions and inspect slow rendering as well as repeated SQL. The historical accepted deal/draft timings are in Private drafts; they do not meet a universal 30–100 ms target.

Queue and event support

The recorded event deployment enables ZOHO_RECORD_EVENTS_ENABLED and the supported Contacts engine, while ZOHO_AUTOMATION_ENABLED=false keeps scheduled provider scans disabled. Its dedicated Redis worker is:

text
php artisan queue:work zoho_sync --queue=zoho-sync

php artisan zoho:recover-record-events redispatches pending local receipts and renews CRM notification leases. It does not fetch full provider record lists. Confirm scheduler execution, registration expiry, queue depth, failed jobs and per-connection receipts. Scope and mapping changes, selected-company changes or missing purchased capability can block a healthy worker. Do not solve a blocked receipt by relaxing its authorization checks.

Storage and cleanup

Configure the private/public disks through COMPANY_FILES_PRIVATE_DISK and COMPANY_FILES_PUBLIC_DISK. Oracle uses distinct private/public buckets and verified anonymous access behavior; unsupported object ACL assumptions must not replace the bucket-level policy checks. Live probes use only exclusive synthetic prefixes, never customer payloads.

Preview abandoned upload candidates without deleting:

text
php artisan company-files:prune TENANT_ID COMPANY_ID --hours=168 --limit=100

The default is a dry run. --execute removes only eligible unreferenced objects after authority/reference checks. Minimum age is 24 hours; batch size is 1–1000. Referenced, active, uncertain or failed-deletion objects stay charged. This is not a bucket-wide garbage collector.

Other maintenance commands are crm:prune-drafts, crm:prune-import-evidence and scoped crm:archives:purge. Review their --help, current retention/leases and output before use. Purging evidence does not delete imported operational records and can remove the ability to rollback automatically.

crm:reconcile-storage is a read-only preview by default. Its --apply rebuilds derived accounting under locks; it does not grant plan capacity. The recorded web production rollout explicitly uses snapshot accounting. Do not switch to the optimized ledger merely because tables exist: the complete native policy/schema manifest must first qualify, and source counters remain authoritative on mismatch.

Acceptance boundaries

Recorded web acceptance covers the core MVP and scoped later changes, not every advanced feature in the original PRD. Zoho transport deployment does not establish a production customer's OAuth consent or actual record delivery. Native Helpdesk action endpoints are a newer pending release. Always distinguish source tests, isolated native API tests, browser checks, live provider tests and deployment smoke evidence.

For changes, run the entire affected test files without fail-fast, collect all failures, fix them as a batch and repeat the related scope. Avoid a full-system run for an unrelated documentation or narrow feature edit. Isolate test databases/schema and preserve source data. This guide records procedures, not permission to deploy or mutate production.

Mobile live-message reload repair

The reviewed server repair at 467068898 corrects participant eager loading on polymorphic message relationships. The temporary Message query must not copy Message company predicates onto a tenant-only User target. The concrete target still builds its own scoped query, preserving its actual ownership boundaries. This is a relation-construction fix, not removal of tenant checks or a grant to load arbitrary participants.

Use this deployed repair's own receipt separately from the earlier web CRM release and the later pending native Helpdesk endpoints. When diagnosing a mobile reload failure, check both message retrieval and participant loading before assuming a websocket or client polling problem.