Skip to content
Deepanshu Kr Chaurasia

CI-Assistant

Windows connector and plugin platform

Connector-based desktop and backend software for running plugins and automating workflows in dental practice software: a pull-only Windows connector with JWT sign-in and signed, hash-verified package delivery over Azure queues and storage.

Period
Status
Designed and prototyped
Role
Software engineer and architect: connector, backend, package delivery
Team
Same four-person team; the RPA and plugin solutions engineer built the data extraction plugins
Stack
  • Python
  • C#
  • .NET
  • JWT
  • Azure Queue Storage
  • Azure Blob Storage
  • Django
  • PostgreSQL
  • Signed URLs
  • WebSockets

The problem

Dental practice software runs on Windows computers inside each practice, out of reach of a cloud API. The client needed its cloud platform to read practice data and automate workflows in that software, without the cloud ever connecting into the practice. CI-Assistant is the connector platform I designed and prototyped for that, alongside ClearInsight AI, in the same four-person team.

The engineering challenge

  • Systems out of reach. Practice systems sit on machines behind clinic networks, read by database query or by desktop automation.
  • Code that runs on a practice machine. Every integration package had to come from the platform, unchanged, and run with limited reach.
  • Unreliable paths. A failed query, an error from the practice system or a dropped connection could not lose a request.

Architecture

Azure CI server

  • Django backend, REST API, JWT and SAS issuing

Azure data

  • PostgreSQL, Practice data
  • Azure Blob Storage, Integration packages

Azure Queue Storage

  • Azure Queue Storage, Encrypted requests, retries

Practice machine

  • CI-Assistant connector, C# and .NET, JWT store
  • Package installer, Hash check, sandbox
  • Integrations, One per practice system

Practice software

  • Practice management system, Database or desktop app
Connect and authenticate
  1. Sign in. CI-Assistant connector to Django backend (Sign in). The connector runs on a computer inside the practice. The user signs in once, and the credentials go to the Django backend over a secure REST API.
  2. Token issued. Permitted. Django backend to CI-Assistant connector (JWT). Valid credentials get a JWT carrying the user ID, client ID and expiry, which the connector stores securely.
  3. Wrong credentials. Refused. CI-Assistant connector to Django backend (Sign in). Invalid credentials are refused with an error, and the user is asked to sign in again.
  4. Expired token. CI-Assistant connector to Django backend (Sign in); Django backend to CI-Assistant connector (JWT). The connector checks the token before each call. An expired one goes back for validation and is refreshed.
Install an integration
  1. Request a package. Package installer to Django backend (Request, JWT). To support a practice system, the connector asks the backend for its integration package, attaching its JWT.
  2. Invalid token. Refused. Package installer to Django backend (Request, JWT). Without a valid JWT the backend returns an error, and no download link.
  3. Signed link. Permitted. Django backend to Package installer (SAS URL, hash). With a valid JWT the backend returns a SAS-signed download URL and the package’s expected hash.
  4. Download. Package installer to Azure Blob Storage (Download (SAS)). Azure Blob Storage validates the SAS token before it serves the package, and refuses an invalid one.
  5. Verify and install. Package installer to Integrations (Sandboxed install). The connector checks the package against its hash, then runs it in a sandbox to add the integration.
Sync appointments
  1. Queued request. Django backend to Azure Queue Storage (Encrypted request). The backend never connects into the practice. It places an encrypted request for appointments on Azure Queue Storage.
  2. Pull. CI-Assistant connector to Azure Queue Storage (Pull request); CI-Assistant connector to Integrations (Pick integration). The connector pulls the request from the queue and picks the integration for the practice’s system.
  3. Read the practice system. Integrations to Practice management system (Query or RPA). The integration reads the appointments from the practice management system, by database query or by desktop automation (RPA).
  4. Return the data. CI-Assistant connector to Django backend (Data over REST); Django backend to PostgreSQL (Store). The connector sends the data back over the secure REST API, and the backend stores it in PostgreSQL.
When something fails
  1. Processing error. Integrations to Practice management system (Query or RPA). If the query, the practice system or the processing fails, the request is not dropped.
  2. Back to the queue. CI-Assistant connector to Azure Queue Storage (Return for retry). The message returns to Azure Queue Storage, where a retry policy decides when it runs again.
  3. Retry. CI-Assistant connector to Azure Queue Storage (Pull request). On the next attempt the connector pulls the request again and processing continues.
View diagram
Azure CI serverAzure dataAzure Queue StoragePractice machinePractice softwareDjango backendREST API, JWT and SAS issuingPostgreSQLPractice dataAzure Blob StorageIntegration packagesAzure Queue StorageEncrypted requests, retriesCI-Assistant connectorC# and .NET, JWT storePackage installerHash check, sandboxIntegrationsOne per practice systemPractice management systemDatabase or desktop app

CI-Assistant was the second system I built for the same US dental healthcare client, through Shidul. The RPA and plugin solutions engineer built the data extraction plugins that read each practice system; I designed and built the platform they run on: the connector, the backend, and the signed, sandboxed package delivery, in Python, C# and .NET.

The design has five parts. A Django backend on Azure signs the connector in, issues download links and stores practice data in PostgreSQL. Integration packages live in Azure Blob Storage, and requests travel through Azure Queue Storage. On the practice machine, the connector signs in, installs integrations and runs them against the practice management system. The Django backend is the connector API hosted by the ClearInsight AI admin application.

This is the architecture I designed and prototyped. The diagram above is a simplified version of my design flowchart.

Pull-only by design

The cloud never opens a connection into the practice. When the backend needs data, such as the practice’s appointments, it places an encrypted request on Azure Queue Storage. The connector pulls the request, reads the practice system through the right integration, by database query or by desktop automation (RPA), and sends the result back over a secure REST API. The backend stores it in PostgreSQL.

Key decisions

The connector pulls; the cloud never connects in

Options considered: the cloud connects into the practice when it needs data, or the connector pulls requests from a queue.

Why: requests wait on Azure Queue Storage and the connector collects them, so the practice network never has to accept a connection from outside.

Trade-off accepted: a request runs when the connector next pulls it, not the moment it is made.

Azure Queue Storage, not Service Bus or Celery

Options considered: Azure Service Bus, Celery with Redis, or Azure Queue Storage.

Why: Queue Storage sits in the same storage account as the packages, with no extra service, cost or credential. The services on each side are not all Python, so a queue any runtime can read over HTTP is the right boundary, where Celery belongs inside a Django application.

Trade-off accepted: no sessions, ordering, dead-letter queues or duplicate detection. Service Bus is the upgrade when the platform needs them.

Separate services for the backend, packaging and delivery

Options considered: one backend for everything, or services that deploy independently and talk through queues and storage.

Why: a failure in one path does not block the others, and a package transfer resumes after a dropped connection.

Trade-off accepted: more parts to deploy and watch, joined only by queues and storage.

Security and identity

The user signs in once on the connector. The credentials go to the backend over a secure REST API, and valid ones come back as a JWT carrying the user ID, client ID and an expiry. Invalid credentials are refused with an error. The connector stores the token securely and checks it before each call; an expired token goes back for validation and is refreshed. API and WebSocket communication is secured with JWT.

Secure package delivery

Support for each practice system ships as an integration package. The connector requests a package with its JWT, and the backend validates the token before returning a download URL signed with a SAS token, together with the package’s hash. Azure Blob Storage validates the SAS token before it serves the file, so an invalid link is refused.

The connector then verifies the package against its hash and runs it in a sandbox to add the integration.

Delivery and operations

Queue Storage and Blob Storage carry requests and packages asynchronously. A failed query, an error from the practice system or a failure while processing does not lose the request. The message goes back to Azure Queue Storage, a retry policy decides when it runs again, and the connector pulls it on the next attempt.

Result

I explored integration with several dental practice management systems through API research, desktop automation experiments, secure messaging and isolated plugin execution, and prototyped the plugin-based connector architecture shown here. This work was exploration and prototyping, not shipped integrations, and there are no usage numbers to report. The client ceased operations before commercial launch; both systems I built for the client, ClearInsight AI and CI-Assistant, run today as live demonstrations.

Demo

Desktop software has no public demo. The package delivery flow on the home page steps through each stage, from a published package to a sandboxed run, and the diagram above walks through each scenario.