Skip to content

Analytics Event Schema

Generated: 2025-11-22 Version: 1.0 Scope: Activation, HR profiles, Leave, Recruitment (MVP slice)

1. Taxonomy Overview

Event naming follows VerbNoun or NounStateChanged semantics. All events MUST include eventVersion to allow additive evolution.

Categories: - activation. (signup, invite, activation) - user. (profile interactions) - leave. (type, accrual, request) - recruit. (job, applicant, feedback) - system.* (infrastructure, isolation tests)

2. Common Envelope

Field Type Required Description
eventName string Y Canonical event identifier (e.g., activation.SignupStarted)
eventVersion int Y Schema version for this event (start at 1)
occurredAt ISO-8601 Y UTC timestamp
traceId string Y Correlates multi-step flows
tenantId string Conditional Present after tenant provisioning
userId string Conditional Actor user if authenticated
actorRole string Conditional Role context (owner, admin, employee, hiringManager)
source string Y Origin (frontend, backend, job-accrual, batch)
requestId string Conditional Attach for API-origin events
metadata object N Arbitrary key-value (non-PII)
pii object N (Restricted) Encrypted or hashed sensitive fragments (e.g., emailHash)

PII handling: raw PII never emitted—only hashed values (SHA-256 + salt) or classification tags.

3. Event Definitions

3.1 Activation

activation.SignupStarted (v1)

Field Type Notes
emailHash string Hashed user email
signupFlowVersion string A/B test variant

activation.TenantProvisioned (v1)

Field Type Notes
tenantId string Newly created tenant
ownerUserId string User who initiated provisioning
provisioningLatencyMs int Time from request to ready

activation.InvitationCreated (v1)

| Field | Type | Notes | | invitationId | string | Internal ID | | invitedEmailHash | string | Hashed invitee email | | expiresAt | ISO-8601 | Expiration timestamp |

activation.InvitationAccepted (v1)

| Field | Type | Notes | | invitationId | string | Link back to created invite | | userId | string | New user id | | acceptanceLatencyMs | int | Time from creation to acceptance |

activation.ActivationCompleted (v1)

| Field | Type | Notes | | userId | string | Activated user | | profileFieldsCompletedPct | number | % required profile fields completed |

3.2 User Profile

user.ProfileViewed (v1)

| Field | Type | Notes | | profileUserId | string | Owner of profile viewed | | viewerUserId | string | Actor | | isSelf | boolean | Self vs other |

user.ProfileEdited (v1)

| Field | Type | Notes | | profileUserId | string | Edited profile | | editorUserId | string | Actor | | changedFields | string[] | List of field keys changed |

3.3 Custom Field

user.CustomFieldAdded (v1)

| Field | Type | Notes | | fieldId | string | New field identifier | | fieldType | string | text|number|date|dropdown | | required | boolean | Required flag |

3.4 Leave

leave.LeaveTypeCreated (v1)

| Field | Type | Notes | | leaveTypeId | string | Identifier | | accrualRateHoursPerMonth | number | Basic accrual |

leave.AccrualRun (v1)

| Field | Type | Notes | | jobId | string | Accrual job execution id | | employeesProcessed | int | Count | | durationMs | int | Total job duration | | success | boolean | Outcome |

leave.LeaveRequestCreated (v1)

| Field | Type | Notes | | leaveRequestId | string | Identifier | | employeeId | string | Requesting employee | | leaveTypeId | string | Type | | startDate | ISO-8601 | Start | | endDate | ISO-8601 | End | | hoursRequested | number | Requested hours |

leave.LeaveRequestStatusChanged (v1)

| Field | Type | Notes | | leaveRequestId | string | Identifier | | oldStatus | string | Previous | | newStatus | string | New | | changedByUserId | string | Actor |

3.5 Recruitment

recruit.JobPublished (v1)

| Field | Type | Notes | | jobId | string | Job opening | | isRemote | boolean | Remote flag | | location | string | Optional city/region |

recruit.ApplicantStageChanged (v1)

| Field | Type | Notes | | applicantId | string | Candidate | | jobId | string | Job reference | | oldStage | string | Previous stage | | newStage | string | New stage | | changedByUserId | string | Actor |

recruit.FeedbackAdded (v1)

| Field | Type | Notes | | applicantId | string | Candidate | | jobId | string | Job reference | | authorUserId | string | Feedback author | | feedbackLength | int | Character count (content stored elsewhere) |

3.6 System

system.IsolationTestExecuted (v1)

| Field | Type | Notes | | testId | string | Test reference | | passed | boolean | Outcome | | durationMs | int | Duration |

4. Versioning Strategy

  • Minor additive fields bump eventVersion only if consumer parsing requires branching.
  • Removed/renamed fields require new eventName suffix (e.g., ActivationCompletedV2).
  • Deprecation tracked in a CHANGELOG under /docs/analytics/CHANGELOG.md (to be created when needed).

5. Privacy & Compliance

  • Hash emails with salted SHA-256; salt rotated quarterly.
  • Avoid sending full PII in events; for diagnostics use metadata with classification tags (e.g., "containsPII": false).
  • Retention: raw event store 180 days, aggregated metrics indefinite.

6. Quality Rules

  • Event emission must not block request: fire-and-forget or async queue.
  • If emission fails, record fallback log with same envelope minus fields.
  • Validate event schema via JSON Schema in CI (future task).

7. Sample JSON (activation.InvitationCreated v1)

{
  "eventName": "activation.InvitationCreated",
  "eventVersion": 1,
  "occurredAt": "2025-11-22T10:15:30Z",
  "traceId": "trace-123",
  "tenantId": "ten-456",
  "userId": "usr-789",
  "actorRole": "admin",
  "source": "backend",
  "invitationId": "inv-001",
  "invitedEmailHash": "sha256:abcdef...",
  "expiresAt": "2025-11-25T10:15:30Z",
  "metadata": {"uiVersion": "1.0.3"}
}

8. Implementation Checklist

  • JSON Schemas created per event.
  • Emission library wrapper with envelope auto-population.
  • Error handling & retry strategy defined.
  • Dashboard queries validated (activation funnel, stage conversion).
  • Data retention job scheduled.

9. Open Questions

  1. Need separate event for magic link validation pre-activation? (activation.MagicLinkValidated)
  2. Include environment (dev/stage/prod) explicitly or infer from infrastructure metadata?
  3. Standardize correlation across message broker vs HTTP (same traceId propagation)?

Document Version: 1.0