feat(integrations): GitHub ticket sync, ticket email notifications & platform updates#278
Open
melihsunbul wants to merge 53 commits into
Open
Conversation
# Conflicts: # apps/web/src/components/admin/settings/integrations/github/github-config.tsx # apps/web/src/components/admin/settings/settings-nav.tsx # apps/web/src/components/admin/settings/team/member-actions.tsx # apps/web/src/components/auth/auth-dialog.tsx # apps/web/src/components/auth/portal-auth-form-inline.tsx # apps/web/src/lib/client/queries/admin.ts # apps/web/src/lib/server/domains/api/__tests__/auth.test.ts # apps/web/src/lib/server/events/process.ts # packages/db/drizzle/meta/_journal.json # packages/db/src/schema/api-keys.ts # packages/db/src/schema/index.ts # packages/email/src/index.ts # packages/widget/CHANGELOG.md # packages/widget/package.json
…cketing_and_authz Merges all branch-specific ticketing/RBAC/CRM migrations (0048-0059) into a single migration that runs after upstream/main's 0048-0065.
Main's 0050_api_keys_scopes adds 'scopes' as text (JSON-encoded). The ticketing RBAC needs it as text[] (native PostgreSQL array) for GIN indexing and direct array containment queries. Migration now DROPs the text column and re-adds as text[]. Service hasScope() accepts both formats for safety.
The hand-written section used malformed -->statement-breakpoint markers (missing space) which caused Drizzle to concatenate statements, and it duplicated the Drizzle-generated CREATE TABLE without IF NOT EXISTS.
# Conflicts: # apps/web/src/lib/server/domains/notifications/notification.service.ts # apps/web/src/lib/server/functions/auth-helpers.ts # apps/web/src/lib/server/functions/notifications.ts # apps/web/src/lib/server/mcp/tools.ts # apps/web/src/routes/admin/feedback.index.tsx # apps/web/src/routes/api/widget/identify.ts # apps/web/src/routes/widget/index.tsx # packages/db/drizzle/meta/_journal.json
Merge upstream main branch containing live-chat features (migrations 0085-0110), analytics improvements, and auth upgrades into the fork's authz-and-ticketing branch. Migration consolidation: - Fork's ticketing migration (formerly 0085) renumbered to 0111 to follow the upstream's latest migration (0110_oauth_refresh_token_family_idx) - Access-control migrations (0066-0084) already present in upstream; restored from upstream's versions Conflict resolution strategy: - Both sides' functionality preserved (RBAC/ticketing + live-chat/analytics) - Additive imports, types, and locale keys merged from both branches - Navigation sidebar includes both Tickets and Conversations entries - Feature flags gate both supportInbox and permission-gated nav items
Use upstream's refactored widget (widget-nav, WidgetOverview, live-chat) as the base and re-integrate the fork's support-ticket features on top: - WidgetSupportCard/List/New/Detail components - ticketingEnabled + imageUploadsInWidget loader data - quackback:open 'support' message handler - Back navigation for support views
- portal-header-nav.ts: merge both buildNavItems into single function with isSignedIn + supportEnabled params - portal-header.tsx: single navItems call with all params - settings-nav.tsx: remove duplicate UserGroupIcon import - settings.types.ts: remove duplicate Pick type line in PublicWidgetConfig - dispatch.ts: merge duplicate type imports, fix missing closing braces in dispatchTicketSlaBreach - targets.ts: remove duplicate matchingWebhooks declaration (keep fork's detailed inline filter) - portal-header-nav.test.ts: rewrite tests to cover merged buildNavItems API
- widget-auth.ts: merge two getWidgetSession overloads into single function
accepting Request | { request?, roll? } to support all calling patterns
- mcp/tools.ts: add missing closing blocks (})catch/}) for 3 tools whose
bodies were truncated during merge (list_tickets, unlink_contact,
manage_organization)
- events/types.ts: add conversation events to EventData union, remove
orphaned union members at end of file
- webhook/constants.ts: merge conversation event config entries into the
WEBHOOK_EVENT_CONFIG array with category field, add 'conversations'
to WEBHOOK_EVENT_CATEGORIES
- dispatch.ts: add all missing event dispatch functions (ticket, conversation, inbox, team, contact, organization, ticket-status, post.mentioned) - ticket.service.ts: add restoreTicket, descriptionJson/Text to UpdateTicketInput, syncSourceIntegrationId to Create/Update/Assign/Transition inputs - inbox.service.ts: fix EventInboxRef cast and import path - contact/organization services: fix @quackback/db restricted imports - team.service.ts: remove unused imports, fix dispatch casts - webhook.types.ts: add missing secret and deletedAt fields - webhook.service.ts: include secret/deletedAt in mapWebhook - notifications.ts: merge duplicate notifications mapper - use-notifications-queries.ts: remove duplicate type property - upload.ts: restore correct auth pattern from main - consent.tsx: separate scope groups properly - admin.tsx: restore getPlanNotice loader call - config[.]json.ts: fix ServerConfig and duplicate hmacRequired - handler.test.ts: fix unclosed mock - sample-payloads.ts: use Partial type for incomplete map - webhooks.ts/functions: fix return type and arg counts - ticket.threads.ts: fix Date→string for firstResponseAt - ticket.attachments.ts: pass ticket ref to dispatch functions - db.ts: re-export TicketPriority and TicketVisibilityScope types - functions/inboxes.ts: fix restricted import, pass actor context
…fixes Phase 0 completion: - db.ts: re-export TicketStatusCategory type - functions/tickets.ts: fix restricted import, prefix unused var, add manualSyncTicketFn stub (Phase 8 placeholder) - github/hook.ts: fix restricted import, remove unused EventTicketRef and prefix unused accessToken - github/ticket-inbound.ts: fix restricted import - github-config.tsx: remove unused Input import, prefix unused label/setLabel - github.tsx: remove unused useQueryClient import - mcp/tools.ts: add actor arg to createComment, addReaction, removeReaction - webhook-event-picker.tsx: type Set<string> for clearCategory - ticket-queue-sidebar.tsx: use object literal for search prop - ticket-linked-issues.tsx: type onSuccess result - queries/tickets.ts: add externalLinks stub query (Phase 8) - test mocks: add ipAddress/userAgent/source to AuthContext mocks - updated-payload-shape.test.ts: fix as-cast via unknown - markdown-tiptap.ts: use any[] for tiptap extensions (version mismatch) Phase 1 (TypeID prefix documentation): - packages/ids/src/prefixes.ts: document intentional sharing of 'audit' prefix between audit_event and audit_log, and 'linked_entity' between post_external_links and ticket_external_links
Security fix: internal agent notes and shared-team threads dispatched via ticket.thread_added were leaking to Slack/Discord/Linear integrations. - targets.ts getIntegrationTargets(): add guard blocking ticket.thread_added with audience 'internal' or 'shared_team' from integration delivery - targets.ts getWebhookTargets(): extend existing guard to also block 'shared_team' audience (previously only blocked 'internal') - Add targets-ticket-visibility.test.ts covering all audience permutations
- Add registerPath for POST /tickets/{ticketId}/assign
- Add registerPath for POST /tickets/{ticketId}/transition
- Add registerPath for DELETE /tickets/{ticketId}/shares/{shareId}
- Add registerPath for DELETE /tickets/{ticketId}/participants/{participantId}
- Add GET method to /tickets/{ticketId}/threads/{threadId}
- Add GET method to /tickets/{ticketId}/threads/{threadId}/attachments/{attachmentId}
- Regenerate openapi.json (20 ticket paths, up from 16)
7 serial tests covering: - Navigate to tickets section via sidebar - Create a new ticket (subject, description, submit) - View ticket detail from queue list - Add a public reply via thread composer - Change ticket status (Open → Solved) - Change ticket priority (Normal → High) - Edit ticket subject inline
- resolve: add concurrent race test (ConflictError → 409 TICKET_STALE) - replies: add bodyJson rich-text round-trip test - tickets: add CORS header assertion on GET list - tickets: add contact-linked session visibility test
- ticket-inbound.test.ts: 14 tests covering all inbound event types (opened, closed, reopened, edited, assigned, unassigned), config gates, external link creation, and loop-prevention via syncSourceIntegrationId - ticket-message.test.ts: 8 tests for buildTicketIssueBody and buildTicketUpdateBody (title, labels, description, edge cases)
Add ticket thread external link storage and migration support for mapping Quackback ticket threads to external GitHub issue comments, including integration sync-log metadata. Sync public ticket thread create, update, and delete events to GitHub comments, ingest GitHub issue/comment webhooks back into ticket threads, and skip source integrations to prevent sync loops. Add a GitHub ticket-comment backfill script and focused coverage for inbound webhook handling, outbound hooks, target filtering, and sync-log schema behavior. Harden OAuth and webhook callback origin resolution for configured public URLs, forwarded hosts, and tunnel/private origins. Improve admin audit views with unified workspace/security audit pagination, CSV export helpers, richer filters, and route coverage. Expose widget ticketing controls and support flows, restore widget ticket API handlers, and add focused widget ticketing UI/API tests.
Add Customers routes and tables that unify contacts, portal users, segments, and permission-gated ticket counts. Improve ticket activity and thread detail UI with editable descriptions and richer audit summaries. Extend segment filters to linked contact and organization attributes, guard client query data, serialize server-function dates consistently, and route widget email identify through the API.
# Conflicts: # apps/web/src/lib/server/functions/admin.ts # packages/db/drizzle/meta/_journal.json
Add widget applications and environment profiles with origin validation, signed context tokens, per-profile config overrides, content filters, and support categories. Enforce scoped widget and portal support access across chat, tickets, public feedback, help center, and changelog flows, including audit events and client redaction. Route widget tickets through profile support categories and inbox defaults, expose application/profile management in settings, and pass app/environment context through the widget SDK. Improve GitHub reconnect and repository fetch error handling while preserving existing integration config on targeted reconnects.
Expose the widget enabled flag through config responses and tear down the SDK/page when a widget is disabled. Resolve SDK origins from the public request or loaded script, preserve application and environment defaults through the bootstrap snippet, and support Home-only widget navigation. Tighten widget settings layout constraints to avoid horizontal overflow.
…tures This commit includes several key updates from recent development sessions: - Implemented durable ticket email notifications with dedicated event targets and handlers. - Fixed widget ticket description editing by resolving authorization and request handling issues. - Fixed widget configuration settings in the admin portal. - Added support for changelog taxonomy and metadata. - Enhanced GitHub integration with improved webhook handling and ticket synchronization. - Updated database schemas and Drizzle migrations for changelog taxonomy and ticket email preferences.
Ensure active GitHub ticket sync integrations have the outbound event mappings needed for ticket updates, comments, and legacy post creation, including a migration to repair existing rows. Tighten webhook registration and inbound ticket/comment sync handling, update ticket/widget authz transport paths, and expand tests around GitHub sync, widget ticket APIs, and sensitive server-function GET inputs.
- add public base URL resolution + auth redirect/email link rewriting for tunneled/proxied deployments - default widget ticket list scope to requester-owned and add migration 0120 to backfill old scope values - enrich ticket event dispatch/email config/template with structured sections, details, and full thread snapshots - broaden stale ticket field merge handling and add tests for event payloads, URL rewriting, and ticket email rendering
Add per-org and per-segment control over which portal tabs are visible. - New DB migration: adds portal_tab_config column to settings and a portal_tab_segment_overrides table for segment-level overrides - New portal domain module (domains/portal/) with service layer and types - New server functions: getPortalTabConfigFn, updatePortalTabConfigFn, updateSegmentTabOverridesFn (admin-only, audit-logged) - Internal API route /api/v1/internal/portal-tabs for control-plane writes - Admin settings route admin/settings.portal-tabs.tsx - Updated buildNavItems() to accept enabledTabs config; each tab is opt-out (defaults to visible when config is absent) - Portal layout loader resolves the effective tab config for the current user (signed-in users get segment-level overrides applied) - Added portalTabCustomization feature flag to TierFeatureFlags (OSS: always on) - New segment fields and IDs for portal tab override entities
…nd changelog - Add segment-based visibility to help-center categories (public / targeted) with allowedSegmentIds and allowedPrincipalIds columns - Add changelog segment visibility table (changelogSegmentVisibility) for per-segment category/product restrictions - Add changelogVisibilityConfig JSON column to settings for org-level defaults - New visibility services: help-center.visibility.ts, changelog-visibility.service.ts - Filter help-center articles and categories by viewer segment on portal routes - Filter public changelog entries by segment visibility config - Add admin settings page for changelog visibility (settings.changelog-visibility) - Add changelog filters component for public portal (changelog-filters-public) - DB migrations: 0122 (hc category audience), 0123 (changelog visibility), 0124 (visibility metadata normalisation) - Extend category form dialog with audience targeting fields - Tests: help-center-visibility, categories API, oauth integration updates
- add attachment UX and rich-text image support across admin, portal, and widget ticket flows - add thread attachment loaders/components and ticket attachment query helpers - expand attachment APIs/auth checks and enforce safer file upload constraints - extend GitHub integration mappings and hook logic for attachment add/remove events - add Quackback issue/system markers to prevent inbound echo/duplicate ticket creation - improve storage/public URL handling for tunneled dev origins and private-host proxying - add fallback email delivery path when event processing fails
- add external-surface permissions and related DB/id updates - add segments, user-attributes, and changelog visibility API routes - expand MCP handler/tools and event dispatch sample payload support - update widget ticket flows and remove legacy ticket-attachments function - refresh locales, tests, and CI diff-coverage workflow/script
- Add roles/role-assignments/permissions CRUD endpoints and role.service - Add teams CRUD with member management and archive/unarchive - Add conversation action routes: assign, reply, note, priority, read, end, status, tags, and comment reactions - Add widget-profiles domain service and API routes - Add moderation domain service and API routes - Add portal-tabs routes and shared schema - Add chat-tags API routes and settings routes - Expand event types, dispatch, webhook constants, and sample payloads - Massively expand MCP tools coverage across all new domains - Add API schema files for roles, teams, segments, settings, suggestions, help-center, widget-profiles, user-attributes, portal-tabs, apps - Add permission guards across existing domain services (boards, changelog, help-center, inboxes, roadmaps, segments, sla, statuses, tags, etc.)
…s, moderation, comment reactions, and MCP routing rule + attachment tools
- Add chat-tags.ts: CRUD and attach/detach OpenAPI schemas for conversation tags
- Add conversation-actions.ts: schemas for conversation status, priority, assignment, and message mutations
- Add moderation.ts: schemas for pending posts/comments review and moderation actions
- Update comments.ts: add POST/DELETE /comments/{commentId}/reactions endpoints
- Update openapi.ts + index.ts: register new schema modules
- Update mcp/tools.ts: add manage_routing_rule tool (create/update/delete/reorder); import getThread, attachToThread, listAttachmentsForThread, removeAttachment, canEditFields, RoutingRuleId
- Update mcp handler tests to cover new tools
Add a large set of unit/integration tests across the authz-and-ticketing branch — covering ticketing, authz, SLA, changelog, help centre, inboxes, audit, segments, organizations, notifications, queue workers, integration OAuth connect flows, and admin/portal/widget route loaders and components. This closes the large majority of the changed-line gap; the residual is the hard tail (giant stateful components, the SSE stream, dead defensive branches, DST edges). Test infrastructure: - vitest.config.ts: default maxWorkers to 50% (overridable via VITEST_MAX_WORKERS) to stabilise the import-heavy, mock-based suite - packages/widget: add vitest setup + v8 coverage config; reorder the package export conditions - e2e: add getOtpCode helper for email-OTP sign-in flows - ci: drop the differential-coverage gate step Fixes: - rich-text-editor: allow data attributes and skip the second DOMPurify pass under Happy DOM, which strips allowed heading tags in that test DOM; production browsers and server-sanitised TipTap JSON are unaffected
Authz and ticketing
# Conflicts: # apps/web/src/components/admin/__tests__/admin-sidebar.test.tsx # apps/web/src/components/admin/changelog/changelog-metadata-sidebar-content.tsx # apps/web/src/components/admin/changelog/create-changelog-dialog.tsx # apps/web/src/components/public/__tests__/portal-header.test.tsx # apps/web/src/lib/client/queries/admin.ts # apps/web/src/lib/server/auth/index.ts # apps/web/src/lib/server/db.ts # apps/web/src/lib/server/domains/api/schemas/changelog.ts # apps/web/src/lib/server/domains/boards/board.service.ts # apps/web/src/lib/server/domains/changelog/changelog.public.ts # apps/web/src/lib/server/domains/changelog/changelog.service.ts # apps/web/src/lib/server/domains/help-center/help-center.category.service.ts # apps/web/src/lib/server/domains/settings/__tests__/parse-json-config.test.ts # apps/web/src/lib/server/domains/settings/settings.types.ts # apps/web/src/lib/server/events/dispatch.ts # apps/web/src/lib/server/events/process.ts # apps/web/src/lib/server/functions/recovery-codes-consume.ts # apps/web/src/lib/server/functions/sso.ts # apps/web/src/lib/server/mcp/tools.ts # apps/web/src/routes/_portal.tsx # apps/web/src/routes/api/auth/$.ts # apps/web/src/routes/api/v1/changelog/$entryId.ts # apps/web/src/routes/api/v1/changelog/index.ts # apps/web/src/routes/widget.tsx # bun.lock
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.
What
Bi-directional GitHub ticket sync, durable ticket email notifications, ticket attachments, and the supporting updates across the integration platform.
Concepts
syncSourceIntegrationId); events that came from an integration are not sent back to it, and Quackback system markers stop inbound echoes creating duplicate tickets.How it works
integrations/github/) —hook.tsmaps ticket create/update/comment/attachment events to GitHub issues/comments;ticket-inbound.tsingests GitHubopened/closed/reopened/edited/assigned/unassignedand comment webhooks back into threads. Mappings live inticket-external-links/ticket-thread-external-linkswithintegration-sync-logmetadata; migration0119repairs existing rows' event mappings. A backfill script seeds links for existing ticket comments.packages/email/) —templates/tickets/ticket-event.tsxrenders structured sections, details and full thread snapshots;send-ticket-event-emailadds the fallback delivery path.inbound-webhook-handler,webhook-registration,oauth/oauth-handlers,save, and per-providerfunctions.ts(asana, jira, linear, gitlab, hubspot, intercom, notion, salesforce, trello, zendesk, clickup, discord, monday, make, n8n, zapier); ntfy integration files.How to use
Safety
Verification
bun run typecheck,bun run lint;ticket-inbound.test.ts, githubhook.test.ts, ticket-message builders, inbound-webhook-handler (github) andsend-ticket-event-email.test.ts(included).📚 This is a stacked series — please review & merge in order
These 10 PRs are split by concern and ordered by dependency. Each is opened against
main, so until the PRs before it have merged, a PR's diff is cumulative (it also contains the earlier batches). As the earlier PRs merge and we rebase the next branch ontomain, each diff reduces to just its own batch. Merging all 10 in order reproduces our integrated branch exactly (verified: the cumulative tip of the series is byte-identical to it).Order (by branch):
01-data-model-foundation— data model, TypeIDs, migrations02-rbac-authz-teams— RBAC, teams, organisation & auth surfaces03-events-audit-webhooks— event dispatch, audit log, webhooks, notifications04-ticketing-crm-core— ticketing / CRM core05-sla-inboxes-routing— SLA policies, inboxes, business hours, routing06-github-sync-and-ticket-email— GitHub ticket sync, ticket email, integration platform07-widget-profiles— scoped widget profiles + ticket submission08-api-openapi-mcp— OpenAPI surface, MCP tools, conversation actions, API keys09-content-visibility— changelog/help-centre visibility, segments, portal tabs10-test-coverage— broad unit/integration test suite + supporting infraPart of the roadmap: #283