Glossary
Plain-language definitions of the terms used across CRM docs and code. New contributors should skim this once; veterans cross-link from PR descriptions.
A
Activity log — a generic audit-trail table (activity_logs) for
compliance-relevant events. Rows: user_id, action, subject_type,
subject_id, properties (JSON), created_at. See
security.md § audit trail for current
coverage.
Audit actor — BaseController::auditActor($authUser) returns
['actor_user_id' => ..., 'impersonator_id' => ...?]. Used to
enrich ActivityLog.properties so admin impersonation traces
through (cross-repo #36).
Auth user — the array merged into the request by
VerifyOAuthToken middleware. Shape: {id, email, name, locale, timezone, tenants, scopes, is_admin, is_system_admin}. Source: the
identity backend's /api/user response.
C
CheckPermission — the middleware that enforces tenant membership + scope-gate + policy evaluation. Comes second in the middleware chain (after VerifyOAuthToken). See security.md § permission gate.
Composable — a reusable Vue 3 use<Name>() factory function.
CRM ships useApiError, useDeleteDialog, usePaginationDeepLink,
useTypeAhead. See composables/README.md.
CRM — the per-tenant operational backend in this repo
(tenant/tenant-backend-crm). Owns contacts, companies, projects,
tasks, chat, documents, knowledge base, sms templates, blog/page
content, calendars, time tracking.
D
Deployment-per-tenant — the multi-tenancy model. Each tenant
runs its own pod set / database / Redis namespace / RabbitMQ queue.
No tenant_id discriminator column on CRM tables (dropped
2026-05-12). See multi-tenant.md.
Drift detection — CI mechanism that compares declared
permissions against expected state. npm run api:check for SDK
drift, crm:list-permissions --json for permission-registry drift.
E
Empty state — UI shown when a list is empty. CRM list pages split this into "first-run empty" (CTA: add) vs "search returned nothing" (CTA: clear filters). Pattern reference: contacts/index, companies/index, projects/index.
EnsuresFolderAccess — App\Http\Concerns trait. Shared
ensureFolderAccess($folder, $userId, $mode) guard for the Document
- DocumentVersion controllers. Explicit-deny semantics (KRITIKUS #4, #8).
EnsuresProjectMembership — App\Http\Concerns trait. Shared
ensureProjectMember($projectId, $tenantId, $userId) guard for the
Task* + parent controllers. Admin bypass for is_system_admin.
Extract (controller extract) — moving methods from a heavy parent controller to a focused sibling. See controller-split.md.
F
F0–F10 — the phase plan used for the CRM refactor sweep. F0 is the security KRITIKUS slice (immediate); F1–F10 are progressive quality / structure / documentation goals. See changelog.md for what landed in each.
FQN permission — fully qualified permission name:
tenant.{tenant_name}.crm.{namespace}.{action}. Built by
CheckPermission from the route's can:{namespace}.{action} and
the env-bound TENANT_NAME (see environment-reference.md).
I
Identity event — message published by the identity backend on
the vecton.events RabbitMQ exchange. CRM consumes 5 event types
(user.scheduled_for_deletion, user.updated, tenant.member_added,
tenant.member_removed, policy.updated). See events.md.
Impersonator — when an admin uses identity's impersonation flow,
the token carries impersonator_id. auditActor() surfaces this in
ActivityLog so forensic review can answer "an admin did this on
behalf of …".
J
JWT (in this codebase) — Bearer token issued by identity's
OAuth/Passport setup. Validated by VerifyOAuthToken middleware via
a call to identity's /api/user.
K
KRITIKUS / MAGAS / KÖZEPES / ALACSONY — the severity buckets in the audit findings (231 total). KRITIKUS = immediate, MAGAS = batch-1 fixes, KÖZEPES + ALACSONY = polish / tech-debt.
L
Last admin guard — UI/API rule that prevents removing or downgrading the only admin on a resource (project, document folder, chat channel). The system would otherwise become unmanageable. See ProjectMemberController, DocumentFolderMemberController.
M
Markdown sanitize — sanitizeMarkdown() helper in
KbArticleController. Strips <script|iframe|...> tags, on*=
event handlers, javascript: URLs. Defense-in-depth alongside the
frontend DOMPurify pass (MAGAS #68).
N
Notification snackbar — Pinia store useNotificationStore()
that owns the global success/error toast. Stores never call it
directly; they go through useApiError for consistency.
P
Per-action permission — granular permission split (e.g.
time_entries.create vs time_entries.export). Replaces coarse
time_entries.write. Allows role-based scoping (an intern can
record their own time without grant to bulk-export).
Policy cache — Redis (or fallback) cache of identity-fetched
policies keyed by policies:{tenantId}:{userId}:{sha256(token)[:12]}.
TTL 1h. Tagged crm.policies + tenant:{tid}. Flushed by
identity.policy.updated event.
Provisioned by — SmsAccount::provisioned_by. The user id of
the admin who created the account. For system-token calls the
admin id flows via X-Admin-User-Id header (KRITIKUS #10).
R
Restore on re-add — when adding a member that was previously
soft-deleted (ProjectMember), the handler restores the tombstone
row instead of inserting a fresh one. Preserves the joined_at
history. See ProjectMemberController::store (MAGAS #58).
S
Scope-gate — the third gate in CheckPermission. For tokens
with a scopes[] claim (service accounts), the requested
permission must match one of the scopes via segment-by-segment
glob. See service-accounts.md.
SDK regeneration — npm run api:sync (export Scramble JSON,
run openapi-ts) + npm run api:check (CI gate). See api.md.
Soft delete — SoftDeletes Eloquent trait on most CRM
models. Default sets deleted_at and excludes from queries.
ProjectMember was retrofitted in 2026-05-12 (MAGAS #58) with a
partial unique index (project_id, user_id) WHERE deleted_at IS NULL.
State machine — model-side enum of legal status transitions.
Example: LeaveRequest::TRANSITIONS = ['pending' => ['approved', 'rejected', 'cancelled'], ...] + canTransitionTo(). Replaces
ad-hoc === 'pending' checks (MAGAS #64).
System token — shared secret between identity backend and CRM
for service-to-service calls (no user). Header
X-System-Token. Compared in constant time via hash_equals
(cross-repo #40).
T
TenantUser — local cache row mirroring the identity user's
profile for fast list/typeahead rendering. PK is the identity
user id (string). is_active=false means the user was
soft-removed from this tenant (set by IdentityEventHandler).
Token-hash cache key — the :{sha256(token)[:12]} suffix on
the policy cache key. Token rotation lands on a fresh slot; old
slots TTL-clear. Without it, refresh tokens inherited the prior
token's cached policy (cross-repo #39).
Transient failure — identity backend is sick (timeout, 5xx,
connect refused). Distinguished from "token rejected" so the SPA
doesn't log out on a temporary outage. CRM returns 503
identity_unavailable and recovers on its own.
Trait (in App\Http\Concerns) — small reusable guard /
helper used by multiple controllers. CRM has two
(EnsuresProjectMembership, EnsuresFolderAccess). Adding a
third should clear ~3 consumers worth of duplication first.
U
Unaccent — Postgres extension that strips diacritics in
LIKE comparisons. App\Support\Search::whereLike() uses it so
"arvai" matches "Árvai" (MAGAS #61).
useApiError — composable for store-side snackbar dispatch.
Stores call notifyError(err, fallbackKey) / notifySuccess(key)
on every CRUD path. Single source of truth — pages don't dispatch.
V
VerifyOAuthToken — first middleware in the chain. Calls
identity /api/user, caches the result (60s, by token hash),
merges the payload into the request as auth_user. Returns 503
on transient failure (not 401).
W
Webhook — outbound HTTP POST CRM sends on certain events
(chat.message.sent, blog_post.published, etc.). Per-tenant
configuration in the webhooks table. Delivery + retry via
WebhookEventPublisher service.