← Back to AAI for MerusCase

Timeline

The chronological story of a case — every activity, every event, every upload — merged into one view, sorted newest-first, grouped by recency. The reference an attorney pulls up before a deposition, before trial, and when the client asks “what’s been happening on my case?”

The case names, dates, doctor names, and document references in this page are fictitious demonstration data. Your install runs against your actual case history.

On this page

What it is

At the prompt:

aaicase> timeline on Doe

Or by case ID:

aaicase> timeline on case [CASE-ID]

About thirty seconds later you have a single chronological view of the case’s entire history: phone calls logged, letters sent and received, hearings held, QMEs received, subpoenas served, every upload attached to an activity. Sorted newest-first — what’s current is at the top.

The timeline is the read-only counterpart to audit. Audit reads documents and finds money; timeline reads the chronology and tells the story. You run timeline before a deposition when you need to walk through what happened; you run audit when you need to know what’s broken.

How it runs (under the hood)

If you give it a name, the skill resolves to a case ID first via merus-search. Then two fetches:

/activities/index/[CASE-ID]  → ALL activities on the case (path param, not the global slice)
/events/index/[CASE-ID]      → ALL events on the case

The path-param form is critical — /activities/index alone returns only the most recent ~2,700 activities across the whole firm, which on a long-running case will miss anything older than a few months. Passing the case ID as a path segment unlocks the full per-case history.

Both responses are parsed in-memory, merged into a single stream, sorted by timestamp descending, then formatted for output. No temp directory, no second LLM pass, no string-matching.

Documented schema — no runtime discovery

The activity object uses numbered field names (“0”, “1”, “2”, …) instead of the descriptive names you’d expect. The skill reads from reference/api-reference.md, not by guessing.

The relevant field map, documented and stable:

FieldMeaning
"0"activity_type_id (number)
"1"activity_type_label (e.g. “Phone Call”, “Letter Received”)
"2"description (HTML — tags stripped before display)
"3"user_id (staff member who created the activity)
"4"activity_date (UNIX seconds — the date to sort by)
"5"created (UNIX seconds — row insertion time)
"6"upload_id (number, or 0 if no attachment)
"7"filename (when an upload is attached)

Field "4" is the sort key, with created as a fallback in case a row has a missing "4" (older Merus rows). The skill never tries to “discover” the schema at runtime — that would mean asking Claude to inspect a sample row, which on a case with 800 activities is wasted budget and a slower response. The schema is fixed; the skill knows it.

The merge: activities + events

Activities and events live in separate Merus tables but tell parts of the same story. A scheduled hearing is an Event (it appears on the calendar). The notes about the hearing are an Activity (they document what happened). Pulling only activities misses the “hearing is scheduled for next Tuesday” entry; pulling only events misses the notes about what was discussed.

The timeline pulls both, tags each row with its source type, and interleaves them in the single sorted view. Events get the EVENT prefix and the event type label (Hearing, QME, MSC); activities use the activity type label. The attorney sees one chronology with both sources clearly distinguishable.

Grouping by recency

Output is grouped by how recent each row is, with the boundaries adapting to case size:

Case sizeGrouping
Under 10 rowsOne flat section (no headers needed)
10–50 rowsLast 30 days / Last 90 days / Older
Over 50 rowsBy year/month (2026-05 / 2026-04 / 2026-03 / …)

The thresholds are deliberate. A long-running case with 600 activities is overwhelming as a flat list; grouping by month restores readability. A new case with 8 entries doesn’t benefit from grouping — the section headers would be most of the output.

Timezone handling

All Merus timestamps are UNIX seconds (UTC). The timeline converts each timestamp through new Date(ts * 1000) and renders to YYYY-MM-DD using .toLocaleDateString('en-CA'). The en-CA locale gives the YYYY-MM-DD format; the locale flag also anchors to the user’s local timezone. The user sees activities on the date they happened in the user’s office, not on the UTC date Merus stored them under.

The reason this matters: an activity timestamped at 5:00 PM Pacific (2026-05-04 17:00 PT) is 2026-05-05 00:00 UTC. Naive UTC slicing (toISOString().slice(0,10)) would show this activity dated 2026-05-05 in the user’s timeline — one day AHEAD of when the attorney actually worked on it. That’s confusing when the attorney remembers “we did that yesterday afternoon.” The skill anchors to local time so a 5:00 PM Pacific activity shows as 2026-05-04, matching the attorney’s lived experience.

The same locale-anchored YYYY-MM-DD rendering is used across activity-display skills (timeline, health-check recent-activity, prep-hearing event windows). Consistent format, consistent timezone.

Attachment icons

If field "6" (upload_id) is non-zero, the timeline shows a paperclip icon and the filename:

2026-03-15  QME Report         Dr. Sample ortho — 12% WPI lumbar [📎 qme.pdf]

The filename comes from field "7". If field "7" is empty but the upload exists, the icon still renders with a generic upload label so the attorney knows there’s a document attached even if the description doesn’t name it.

The timeline does not read the attached PDFs — that’s audit’s job. Timeline is the index; audit is the content read.

Example output

TIMELINE — Doe, Jane v. Sample Container Inc (Case #[FILE-#])
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Last 30 days
  2026-05-04  Phone Call         CLIENT CALL — confirming hearing prep
  2026-04-30  EVENT [Hearing]    Status conference, Anaheim WCAB Dept 4
  2026-04-28  Letter Received    Defense response to TD demand [📎 def-resp.pdf]
  2026-04-21  Hearing            ✓ Status conference — continued to 6/15

Last 90 days
  2026-03-15  QME Report         Dr. Sample ortho — 12% WPI lumbar [📎 qme.pdf]
  2026-03-02  Letter Sent        TD demand to Sample Insurance [📎 td-dmd.pdf]
  2026-02-28  Subpoena Served    SDT to medical provider for records
  2026-02-14  EVENT [QME]        QME with Dr. Sample, Anaheim
  2026-02-05  Application Filed  Original ADJ filing — [ADJ-#]

Older
  2025-11-12  Intake             New case opened — DOI 2025-10-15
  2025-10-15  EVENT [DOI]        Date of injury

158 total entries on this case

Timeline vs. audit

TimelineAudit
Time~4 minutes~4 minutes
ReadsActivity + event metadataPages 1–5 of every PDF on the case
FindsWhat happened, in orderWhat’s wrong, what’s owed, what’s misfiled
Writes backNothingCase summary, action tasks
Use casePre-depo prep, client call, narrative reviewPre-trial workup, case takeover, large settlement push

The relationship: timeline tells you what to ask audit to look at more carefully. “The QME report came in on 3/15. Was there an objection?” The timeline shows you the report; the audit reads the document and tells you whether the response was timely.

When to run it

Troubleshooting

The timeline only shows recent activity

The skill used /activities/index without the case-ID path param — that returns the global slice (~2,700 recent across the firm), which on an older case misses everything pre-window. Use the case ID directly (timeline on case [CASE-ID]) to force the per-case endpoint.

Dates look off by one day

If you’re looking at the same activity in the Merus UI and seeing a different date, the difference is timezone — Merus UI and the timeline both show local time, but the user’s local time and the Merus server’s local time can disagree if they’re in different timezones (rare but possible at multi-office firms). For a single document where the date is dispositive (deposition exhibit prep), confirm against the underlying record.

An activity I expected to see isn’t there

Most common cause: it was never logged. The Merus UI sometimes accepts data entered into the wrong place (an “event” note left blank in the notes field, a phone call recorded as a contact edit rather than an activity). The timeline only shows what’s in /activities and /events — if a piece of work happened but wasn’t recorded, it doesn’t exist for the system.

HTML markup in a description

Activity descriptions are HTML in the raw data. The skill strips tags before display. If you see raw <p> in the output, the stripping regex missed a malformed tag — report it and the regex will be tightened.

Attachment icon shows but I can’t find the file

The upload exists in Merus but might be on a different case if it was reassigned. Use read upload [id] with the upload ID to fetch it directly, or run audit case to verify all uploads on this case are correctly attached.

Part of AAI for MerusCase — code-guarded AI case intelligence for California Workers’ Comp attorneys.