Files
zeekay 1b367e2b62 chore: rebase the tree onto upstream master
The tree was a debranded snapshot of upstream taken around 2026-02-20, and
upstream has moved about five months since. This replaces it with upstream
master, mechanically re-derived: bin/debrand does the rename, and the
pipeline and squashed migrations are restored from the shipped tree.

Not a merge. The previous import replaced the tree wholesale in a single
commit, so there is no shared content history to merge against. Reproducing
the rename on the new tree is what actually converges.

What survives: .hanzo/workflows, the Dockerfiles and bin/docker* entrypoints,
compose files, LLM.md, and insights/migrations. The squashed initial
migration is load-bearing — the live database records it by name, so
upstream's ~918 individual migrations cannot come back.

Nine products are dropped as unreferenced. Twenty-one more that we do not run
are kept anyway because the core app still imports them; unpicking those is a
refactor and does not belong in a rebase.

This base does not build yet, and the reasons are not in the rename:
upstream now wants Python 3.13.13 against our 3.12.12 and Django 5.2 against
our 4.2, and the dependency manifests still name upstream packages that we
republish under our own names. Those are decisions, not renames.
2026-08-01 15:44:40 -07:00

2.8 KiB

Ticket queries

All queries run through the Insights MCP execute-sql tool in the internal project (US, project 2). Always confirm table columns via system.information_schema.columns before querying a system.* table.

Open web analytics tickets from the conversations product

SELECT ticket_number, id, status, priority, channel_source,
       substring(last_message_text, 1, 400) AS last_msg, created_at, message_count
FROM system.support_tickets
WHERE status IN ('new', 'open', 'pending')
  AND created_at >= now() - INTERVAL 21 DAY
  AND (last_message_text ILIKE '%web analytics%'
       OR last_message_text ILIKE '%bounce%'
       OR last_message_text ILIKE '%utm%'
       OR last_message_text ILIKE '%pageview%'
       OR email_subject ILIKE '%web analytics%')
ORDER BY created_at DESC

Caveats: last_message_text is only the latest message and may be truncated; message_count > 1 means there is history you have not seen. The keyword filter misses tickets phrased differently — also read the #support-web-analytics Slack channel for the Zendesk-mirrored stream.

Full comment history via the Zendesk warehouse mirror

system.support_tickets has no messages table. The Zendesk mirror does, inside a JSON array column:

SELECT created_at, body FROM (
    SELECT created_at,
           JSONExtractString(
               arrayJoin(JSONExtractArrayRaw(assumeNotNull(toString(child_events)))),
               'body') AS body
    FROM zendesk.ticket_events
    WHERE ticket_id = {zendesk_ticket_id}
) WHERE body != ''
ORDER BY created_at ASC

Notes: assumeNotNull is required (arrayJoin cannot sit inside Nullable); apply LIMIT after the subquery or arrayJoin eats it; MCP display truncates long cells, so extract fields instead of dumping raw JSON.

Resolve a requester to an org/team (US and EU)

SELECT 'us' AS region, u.email, u.current_team_id
FROM postgres.insights_user u WHERE u.email = '{email}'
UNION ALL
SELECT 'eu', u.email, u.current_team_id
FROM eu_postgres_insights_user u WHERE u.email = '{email}'

Also useful: postgres.insights_organizationdomain (verified domains only — often empty for smaller orgs), postgres.insights_organization by name, all_insights_team.

EU customer data is not queryable from the US MCP project. For per-team event data on either region, use the query-datastore-via-metabase skill.

Error tracking cross-reference

Frontend crashes reported by EU customers usually have US occurrences too (Insights staff and US users hit the same code). Search the internal project's error tracking with the MCP tools; source on the issue row names the sourcemapped file, and verbosity: stack on events gives resolved frame names, so you can go from a minified customer stack to file:line without a local repro.