Fig. 02 · Professional · Tacbot.ai

Enterprise Integrations & Quality

Bi-directional ServiceNow sync without update loops, NetBox inventory, email-to-case intake and a daily end-to-end safety net.

Project
Enterprise Integrations & Quality
Role
Software Engineer
Period
07/2025 - present
Context
Professional · Tacbot.ai
Stack
Go · Gin · PostgreSQL · ServiceNow · NetBox · Microsoft Graph · Playwright · GitHub Actions
Outcomes
  1. Bi-directional ServiceNow incident and CMDB sync with update-loop prevention
  2. NetBox inventory pull and push with live schema discovery and approval staging
  3. Daily scheduled end-to-end validation of business-critical vendor workflows

Problem

Enterprise customers run their IT operations in their own systems - incidents and CMDB in ServiceNow, network inventory in NetBox - while vendors report issues by email. The case platform has to sit between all of them: every vendor email must become a case, every case must stay consistent with the customer’s ITSM record in both directions, and the inventory the cases refer to must stay current - for many customers at once, each with a differently configured instance.

Constraints

  • Two systems of record. Cases change in the platform and in the customer’s ITSM system; both must converge without echoing each other.
  • Every instance is different. Customers customise fields, statuses and object types, so nothing can be hardcoded to one schema.
  • Tenant isolation. Each customer’s data lives in its own database, so every integration path must be tenant-aware.
  • Private networks. Inventory systems often sit behind a customer’s firewall.
  • Releases must not break vendor workflows. The flows that matter most are asynchronous and span several services.

Architecture

The figure follows a case from vendor email to the customer’s ITSM system and back, and inventory from NetBox into the platform.

  1. 01

    Email becomes a case

    Vendor email arrives in Gmail, Microsoft 365 or generic IMAP mailboxes. The intake collects it - over Microsoft Graph with OAuth2 where needed - stores attachments per tenant, and the platform creates the case automatically.

  2. 02

    Every tenant stays isolated

    Each write is routed to that tenant's own database, so one customer's cases, attachments and history never share storage with another's.

  3. 03

    One orchestrator, any ITSM provider

    Case creation, replies, status, priority, impact, assignee and closure each raise an event; the integration orchestrator decides by origin whether to sync, and the ServiceNow connector maps it to the customer's model and calls its API with journal entries and attachments.

  4. 04

    Updates come back - without echoing

    Webhooks from ServiceNow update the case. The connector records the journal entries and attachment names it sent, recognises them when they return and does not apply them twice, so two systems that both sync never chase each other in an update loop.

  5. 05

    Nothing fails silently

    An inbound sync that fails is captured with its payload and cached attachments in a failure queue, where it can be reviewed with AI assistance, retried or dismissed. Missed journal entries are backfilled.

  6. 06

    Network inventory flows in from NetBox

    The inventory connector discovers NetBox's schema live, applies the tenant's field mappings and pulls devices and circuits on a schedule into a staging area for approval. For real-time changes it creates NetBox Event Rules that run a generated push script.

  7. 07

    Every day, the whole path is exercised

    A Playwright suite scaffolds test tenants, drives email-to-case and vendor workflows end to end against each environment, then tears the tenants down - scheduled daily in GitHub Actions.

Fig. 02 - Enterprise integrations & qualityScale model
VendormailboxesEmailintakeAttachmentstorageCaseplatformTenantdatabasesITSMconnectorITSMsystemTestautomationNetworkinventory(NetBox)InventoryconnectorSyncfailurequeue
Fig. 02 · Plan - components, connections and data flows
Read the diagram as text

Components

Vendor mailboxes (external, not owned)
Gmail, Microsoft 365 and generic IMAP mailboxes where vendors send case-related email.
Email intake
Polls mailboxes over IMAP and Microsoft Graph with OAuth2, extracts attachments and hands each message to the case platform.
Attachment storage
Object storage that keeps each tenant's email attachments separately.
Case platform
Multi-tenant case-management service in Go (Gin, GORM). Its integration orchestrator turns every case and alert event into provider-agnostic sync actions.
Tenant databases
One PostgreSQL database per tenant; every request is routed to its tenant's database.
ITSM connector
ServiceNow connector - maps fields, statuses, priority, impact and assignee, parses webhook envelopes, and synchronises journal entries and attachments in both directions.
ITSM system (external, not owned)
The customer's own ServiceNow, holding incidents and the CMDB. A generated Update Set installs the outbound side of the integration there.
Test automation
Playwright suite that creates test tenants, runs business-critical vendor workflows end to end and removes the tenants afterwards.
Network inventory (NetBox) (external, not owned)
The customer's NetBox - devices, circuits and connectivity - often on a private network reached through a tenant-selected gateway tunnel.
Inventory connector
Discovers the inventory schema live, applies the tenant's field mappings, stages scheduled polls for approval and receives pushed changes.
Sync failure queue
Failed inbound syncs are captured with their payload and cached attachments, so they can be reviewed, retried or dismissed instead of lost.

Flows

  • Email becomes a case: Vendor mailboxes → Email intake → Case platform → Tenant databases.
  • Case change sent to ITSM: Case platform → ITSM connector → ITSM system.
  • ITSM update applied without echo: ITSM system → ITSM connector → Case platform → Tenant databases.
  • Daily end-to-end run: Test automation → Case platform.
  • Inventory changes reach the platform: Network inventory (NetBox) → Inventory connector → Case platform.
  • A failed sync is kept for retry: ITSM system → ITSM connector → Sync failure queue.

Key decisions & trade-offs

A provider-agnostic orchestrator in front of the connectors

Case and alert events - creation, email replies, status, priority, impact, assignee, closure, manual sync - go to one integration orchestrator, which decides by the event’s origin whether it should sync and calls the provider’s connector. Calling ServiceNow directly from each handler would have been faster to write, but it would have scattered sync rules across the codebase and made a second ITSM provider a rewrite instead of a new connector.

Recognise our own updates instead of suppressing webhooks

When the platform writes to ServiceNow, ServiceNow fires a webhook back. The connector records the journal entries and attachment names it sent and drops them when they return. Disabling webhooks for a window after each write was the simpler option, but it would also have dropped genuine changes made in that window; recognising our own changes keeps both sides fully synchronised.

Install the customer side as a generated Update Set

The outbound half of the integration - REST messages, OAuth configuration and incident rules - ships as a ServiceNow Update Set generated per tenant, which the customer imports. Step-by-step setup instructions would have avoided the generator, but every manual step was a chance for a misconfigured instance that only failed in production.

Capture failures, never drop them

An inbound sync that fails is stored in a failure queue with its payload and cached attachments, where it can be reviewed with AI assistance, retried or dismissed; missed journal entries are backfilled. When a new case looks like an existing ticket, the user chooses to link it, create a new one or link a ticket manually rather than the platform guessing.

Discover NetBox’s schema live instead of hardcoding it

The NetBox connector reads each instance’s object types, fields and status choices live, so a NetBox upgrade or plugin cannot drift out of sync with a table in our code. Scheduled polls of devices and circuits land in a staging area that a user approves before upload, because a bad field mapping on an automatic upload could overwrite good inventory. For real-time changes the platform creates NetBox Event Rules that run a generated push script, and every call can go through a tenant-selected gateway tunnel to reach instances on private networks.

Results

  • Cases stay synchronised with ServiceNow in both directions - creation, updates, priority, impact, assignee, closure, links, journal entries and attachments - and CMDB inventory can be imported with field mappings.
  • NetBox devices and connectivity reach the platform by scheduled, approved pulls and by event-driven pushes.
  • Vendor email from Gmail, Microsoft 365 and IMAP mailboxes becomes cases automatically.
  • Business-critical vendor workflows are validated end to end every day across environments.

The end-to-end suite covers 53 specs, scaffolds and tears down its own test tenants, and runs on a daily schedule in GitHub Actions with separate cleanup workflows.

What I’d do next

  • Replay recorded ServiceNow and NetBox webhook payloads as contract tests, so a customer’s customisation is caught before release rather than in the failure queue.
  • Retry failure-queue entries automatically with backoff for transient errors, leaving people only the failures that need a decision.
  • Extend the daily end-to-end run to the inventory pull-and-approve flow.