Describes Engine9 timeline file formats (Timeline ID vs Timeline Raw) and how to construct them using only the utilities exported by @engine9/input-tools. Use when creating or transforming timeline-shaped data in plugins or ingestion code.
Use this skill whenever you are:
timeline-style table (for example via server workers).Engine9 models person-level activity as timeline entries. A timeline entry is a single fact about a person at a point in time (email send, open, click, transaction, signup, etc.), identified by:
ts: timestamp of the event.entry_type_id: numeric type from TIMELINE_ENTRY_TYPES (input-tools/timelineTypes.js).person_id: internal person identifier.plugin_id: which plugin this event came from (used as UUID namespace).id: a deterministic UUID derived from the above (via getTimelineEntryUUID).There are two main on-disk timeline file shapes:
person_id and id. These are ready to load into the timeline table.person_id. They must go through person resolution and ID assignment before they can be loaded.Use when you want data that is ready to be:
timeline table.id (UUID).Timeline ID files are typically produced by:
person_id and plugin_id.getEntryTypeId and getTimelineEntryUUID from @engine9/input-tools.Minimum required fields for a Timeline ID file that downstream workers will accept:
id: UUID for the timeline entry.
getTimelineEntryUUID, or provided as a stable remote_entry_uuid.InputWorker.id, appendTimelineId writes this into the id column.ts: timestamp (string or number) that can be parsed into a Date.person_id: internal numeric person id.entry_type_id: integer from TIMELINE_ENTRY_TYPES.Common optional fields:
source_code_id: numeric source code identifier.email_domain: lower-cased domain, often derived from email.The downstream timeline table schema usually includes:
id column (UUID stored as text).ts (millis since epoch).entry_type_id and person_id.source_code_id and email_domain.When authoring a Timeline ID-producing job or plugin using @engine9/input-tools:
id, ts, person_id, and entry_type_id on each emitted row.entry_type_id, but you may also keep a string entry_type for debugging; resolution between the two happens via TIMELINE_ENTRY_TYPES, getEntryTypeId, and getEntryType.plugin_id; getTimelineEntryUUID uses it as the UUID namespace when generating id.Use when you have raw events from an external system and cannot yet assign person_id but still want to capture structured activity.
Examples:
Timeline Raw files:
person_id (by definition for this skill).id.
id, it is usually an external event ID or remote_entry_uuid, not necessarily the final Engine9 id.ts (or a field that is mapped to ts).entry_type (string) or entry_type_id (numeric).remote_person_id, email, or similar).Typical fields you will see:
ts or a source-specific timestamp (later mapped to ts).entry_type or entry_type_id (e.g. 'EMAIL_UNSUBSCRIBE', 'EMAIL_OPEN', etc.).email, remote_person_id, phone number, etc.account_id, plugin_id, url, user_agent, ip_address, etc.For example, a plugin may map an inbound event into a row with:
ts, account_id, entry_type_id, email, email_domain, url, user_agentand no person_id yet.
The usual pathway for Raw → ID is:
ts, entry_type/entry_type_id, and contact info).person rows.person_id to each row.getEntryTypeId (if needed) to ensure entry_type_id is set from TIMELINE_ENTRY_TYPES when only entry_type is present.getTimelineEntryUUID to:
ts, entry_type_id, plugin_id, and person_id.id.id, ts, person_id, entry_type_id, optional source_code_id, etc.).Choose Timeline ID files when:
person_id and plugin_id in the current process.timeline table.id.Choose Timeline Raw files when:
person_id and compute final id values.In practice:
person_id).id via getTimelineEntryUUID.timeline and detail tables.When working with any timeline format, prefer the utilities in @engine9/input-tools:
TIMELINE_ENTRY_TYPES (timelineTypes.js): bidirectional map between string entry types and numeric entry_type_id.getEntryTypeId: resolve entry_type → entry_type_id with validation.getEntryType: resolve entry_type_id → entry_type.getTimelineEntryUUID: generate or normalize id given ts, entry_type_id, plugin_id, and person_id, respecting remote_entry_uuid / remote_entry_id when present. Uses plugin_id as the UUID namespace.uuidIsValid: validate that a string is a proper UUID.Use these helpers instead of hard-coding IDs or types whenever you construct timeline rows, whether Raw or ID.