Repository navigation
feat(incidents): follow the Insights API follow-ups — server transition table, chat prompt, insight ↔ ticket/chat links - #438
Merged
Conversation
…on table, chat prompt, insight links Aligns with openframe-saas-tenant#3149 (Insight ai and assigned items): - Status transitions come from `insightStatusTransitions` (an @inline fragment on Query, spread in the list and detail operations) instead of a client mirror of the validator — the mirror had already drifted (ACKNOWLEDGED/SNOOZED now only → RESOLVED). - "Fix with Mingo" fetches the server's `insightChatPrompt` and turns its leading `@insight:` / `@device:` markers into labelled mentions; the client-side prompt builder is gone. The chat created from that draft carries `insightId` on `POST /dialogs` (launcher store link, consumed on create, dropped on any change of conversation or a close). - Every Mingo context reference to an incident (picker item, open view, chip) now carries the STORED insight id — what the real `InsightContextResolver` looks up — not the Relay global handle. - Create Ticket from an incident sends `CreateTicketInput.insightId`; the form shows the "Assigned Incident" it is filed from (new prefill keys). - Incident details lists the Mingo sessions started from it (`dialogs(filter: { insightId })`), each opening in the drawer. Requires the #3149 API: the list/detail queries select the new field, so this must not deploy ahead of it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nent openframe-oss-lib#2248 records a ticket filed from an incident as an assignment owned by the insight (item INSIGHT → target TICKET, from `CreateTicketInput.insightId`). So: - The incident page shows its tickets through `AssignedItemsView` pointed at the incident (`itemType: INSIGHT`) under an "Assigned Ticket" heading — the ticket page's component, not a new table. - The ticket form shows the incident it is filed from as a read-only `AssignmentsField` row (INSIGHT is a client-only target: not pickable, never written through `assignItem`; it goes out as `insightId`). The bespoke "Assigned Incident" block is gone. - `AssignmentItemType` gains INSIGHT; `ASSIGNMENT_TARGET_TYPES` stays the server list, `ALL_ASSIGNMENT_TARGET_TYPES` adds the client-only target. - The incident's Mingo-sessions query lives under the `mingo-dialogs` key, so the drawer's create invalidates it. Verified on tenant-3149-53: transitions from the server table (ACKNOWLEDGED offers only Resolve), Fix with Mingo from `insightChatPrompt` with both chips resolved by the real resolver, the created dialog linked to the insight and listed on the incident, Create Ticket → the ticket listed under Assigned Ticket. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…Open Mingo Session once a chat is linked The sessions list under the notes is gone; the header's Mingo action reopens the latest chat started from the incident when there is one, and starts one otherwise. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ssigned-ticket links; no lookup spinner - Table rows carry the "chat already started" answer (one aggregate lookup query keyed on the page's insight ids, fanning out through `fetchQuery` so it shares the per-incident cache the detail header reads) and settle into "Open Mingo Session" / "Fix with Mingo" in place — the row data, not the column closure, because `DataTableRow` is memoized on the row object. - The detail header suspends on the lookup instead of showing a spinner, so it renders once with the right label. - Assigned tickets: api-service-core hands the target a Relay global id; the ticket pages key on the raw one, so the link said "ticket not found". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…lookup, one Mingo-button decision - The dialog↔insight link no longer rides the launcher store (a side-channel any dialog create consumed and any conversation switch outside `selectDialog` kept): `sendInNewDialog` reads the incident off the first message — the `@insight:<id>` token, or an INSIGHT context item — and passes it to `createDialog(insightId)` explicitly. - `useLatestIncidentDialog(s)`: a GraphQL error envelope answers null like a transport failure (the header must not fall over on an ai-agent without the filter); only drawer-visible statuses count; the aggregate can no longer reject; one shared stale time; docs on the hook. - `mingoActionFor` is the one decision behind the header button and the table cell; the row carries the whole action so the memoized `DataTableRow` never reads a stale closure. A session row is inert while another prompt is in flight; the prompt fetch is guarded by a ref, not stale state. - `rawIdOf` in `src/lib/relay-id.ts` replaces the inline idiom and the assignments-local copy; assigned Ticket targets decode guarded on the typename so a raw ObjectId can never be mangled. - Comments that contradicted the stored-id rule (`context-types.ts`) or named a removed section fixed; `AssignmentItemType.INSIGHT` in the schema. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Query Details had no skeleton and popped in under the notes; it now has the same heading over the report table's own loading rows (four columns, one row — the common shape), as the Suspense fallback and in the page skeleton. - The notes skeleton reserved an 80px bar; the loaded section with no notes is the heading over the "Add Note" button, so the bar is that button's size. Measured on a cold load vs loaded: header 96/96, summary card 260/260, notes 56/56; Query Details differs only by the record's own row count. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… the ones after it Code-review finding: the parser stopped at the first marker of a kind this build does not know; now it keeps that token in the text and reads on. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Contributor
Author
Contributor
🦩 Flamingo Code Review4 finding(s) — 0 action required · 4 recommended · 0 informational Mode: advisory · 4 defect(s) outside any rule Inline comments: 4 new Need another pass? Commits pushed after this review are not reviewed automatically.
Prefer typing? Comment React 👍/👎 on inline comments to teach the reviewer. Started 2026-09-21 09:57 UTC · updated 2026-09-21 09:58 UTC · workflow run |
kirill-567
approved these changes
Sep 21, 2026
pavlo-flamingo
added a commit
that referenced
this pull request
Sep 21, 2026
Conflicts: - schema.graphql: kept the branch's re-introspected SDL and ported main's additions into it (remote access requests from #441; insightChatPrompt, insightStatusTransitions and AssignmentItemType.INSIGHT from #438). - incidents/utils/fix-with-mingo-prompt.ts: took main's deletion. The prompt is built server-side now, so the branch's EMPTY_VALUE edit has no target.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Frontend side of flamingo-stack/openframe-saas-tenant#3149 (+ flamingo-stack/openframe-oss-lib#2248, flamingo-stack/openframe-saas-lib#894).
insightStatusTransitionsis read through one@inlinefragment onQuery, spread into the list and detail operations (no extra round trip), and drives the row menu and the header button. The client mirror of the validator is deleted — it had already drifted (ACKNOWLEDGED / SNOOZED now only → RESOLVED).insightChatPrompt. Fetched on click; its leading@insight:/@device:markers become labelled mentions, the ask becomes the text (fix-with-mingo-draft.ts, unit-tested). The dialog created from that draft sendsinsightIdonPOST /dialogs(launcher-store link, consumed on create, dropped on any change of conversation / new chat / close).InsightContextResolverlooks up; the chip re-encodes it for its own query.AssignedItemsView(itemType: INSIGHT) under "Assigned Ticket"; the ticket form shows the incident it is filed from as a read-onlyAssignmentsFieldrow (INSIGHT is a client-only target: not pickable, never written throughassignItem, sent asCreateTicketInput.insightId).dialogs(filter: { insightId }), each row opens the drawer on that conversation.Depends on (must be deployed first)
saas-tenant #3149, oss-lib #2248, saas-lib #894 — the list/detail queries select
insightStatusTransitions, so this fails against an API without it.Verified on tenant-3149-53
tsc,lint:ci, Prettier,relay, vitestStill backend-bound
Ticket.insightId(or the link exposed on the ticket).AssignmentTargetType).🤖 Generated with Claude Code