Skip to main content

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 actorBaseController::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.

EnsuresFolderAccessApp\Http\Concerns trait. Shared ensureFolderAccess($folder, $userId, $mode) guard for the Document

  • DocumentVersion controllers. Explicit-deny semantics (KRITIKUS #4, #8).

EnsuresProjectMembershipApp\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 sanitizesanitizeMarkdown() 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 bySmsAccount::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 regenerationnpm run api:sync (export Scramble JSON, run openapi-ts) + npm run api:check (CI gate). See api.md.

Soft deleteSoftDeletes 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.