Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# SPDX-FileCopyrightText: 2026 AOT Technologies
#
# SPDX-License-Identifier: Apache-2.0

name: docs

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: write

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install docs dependencies
run: pip install mkdocs mkdocs-material

- name: Build (PRs — validates site builds cleanly)
if: github.event_name == 'pull_request'
run: mkdocs build

- name: Deploy to GitHub Pages
if: github.event_name == 'push'
run: mkdocs gh-deploy --force
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ coverage.xml
bandit-report.json
.venv*/

# MkDocs generated site
/site/

# debug
launch.json

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ SPDX-License-Identifier: Apache-2.0
<p align="center">
<img src="./docs/images/nw-primary-logo-tag.png" alt="Node Wire — Layered Connector Framework" />
</p>
node wire is a three-layer Python platform that runs connector adapters (Google Drive, SMTP, Stripe, FHIR, etc.) and exposes them over REST, gRPC, or MCP. It provides a consistent execution contract with built-in validation, resilience, and telemetry.
node wire is a three-layer Python platform that runs connector adapters (Google Drive, SMTP, Stripe, FHIR, Salesforce, Slack, and more) and exposes them over REST, gRPC, or MCP. It provides a consistent execution contract with built-in validation, resilience, and telemetry.

## Prerequisites

Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Report suspected vulnerabilities privately through either of the following:
- **GitHub Security Advisories** — use the
[private vulnerability reporting](https://github.com/AOT-Technologies/node-wire/security/advisories/new)
form for this repository (preferred).
- **Email** — send details to **security@aot-technologies.com**.
- **Email** — send details to **opensource@aot-technologies.com**.

When reporting, please include as much of the following as you can:

Expand Down
2 changes: 1 addition & 1 deletion SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Thanks for using Node Wire! Here's how to get help.
## Security issues

- **Do not** open a public issue. Follow the [Security Policy](SECURITY.md)
(GitHub private advisory or security@aot-technologies.com).
(GitHub private advisory or opensource@aot-technologies.com).

## Commercial support

Expand Down
144 changes: 141 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# SPDX-FileCopyrightText: 2026 AOT Technologies
#
# SPDX-License-Identifier: Apache-2.0
<!--
SPDX-FileCopyrightText: 2026 AOT Technologies

SPDX-License-Identifier: Apache-2.0
-->

# Node Wire Architecture

Expand All @@ -14,6 +16,142 @@ The platform is split into three layers:
- **Layer B – Connectors** (`src/node_wire_<connector>/`): Adapters that implement that contract and call external systems (HTTP Generic, SMTP, Stripe, Google Drive, FHIR Epic, FHIR Cerner, Salesforce, Slack). Each connector has its own input/output schema and business logic.
- **Layer C – Bindings** (`src/bindings/`): How the platform is exposed to the outside world—REST API, gRPC server, MCP server—and how connectors are loaded from configuration (ConnectorFactory + `config/connectors.yaml`).

<div class="nw-diagram-stack" markdown="1">

<div class="nw-diagram nw-diagram--row" markdown="1">

```mermaid
%%{init: {"theme": "base", "themeVariables": {"fontSize": "16px", "fontFamily": "Inter, system-ui, sans-serif", "primaryTextColor": "#E8EDF5", "lineColor": "#62d2f5"}, "flowchart": {"nodeSpacing": 36, "rankSpacing": 40, "padding": 16}}}%%
flowchart LR
subgraph clients ["External Clients"]
direction LR
REST["REST clients"]
GRPC["gRPC clients"]
MCP["MCP / AI agents"]
end

classDef client fill:#1a3a4a,stroke:#37c4f0,stroke-width:2px,color:#E8EDF5
class REST,GRPC,MCP client
style clients fill:#151920,stroke:#37c4f0,stroke-width:2px,color:#37c4f0
```

</div>

<div class="nw-flow-connector nw-flow-down"><span>requests ↓</span></div>

<div class="nw-diagram nw-diagram--row" markdown="1">

```mermaid
%%{init: {"theme": "base", "themeVariables": {"fontSize": "16px", "fontFamily": "Inter, system-ui, sans-serif", "primaryTextColor": "#E8EDF5", "lineColor": "#62d2f5"}, "flowchart": {"nodeSpacing": 36, "rankSpacing": 40, "padding": 16}}}%%
flowchart LR
subgraph layerC ["Layer C · Bindings · src/bindings/"]
direction LR
RestAPI["REST API<br/>FastAPI :8000"]
GrpcSrv["gRPC Server<br/>:50051"]
McpSrv["MCP Server"]
Factory["ConnectorFactory"]
Config["connectors.yaml"]
end

RestAPI --> Factory
GrpcSrv --> Factory
McpSrv --> Factory
Config -. "loads" .-> Factory

classDef bindings fill:#243044,stroke:#37c4f0,stroke-width:2px,color:#E8EDF5
classDef config fill:#242930,stroke:#8A9BAC,stroke-width:2px,color:#E8EDF5
class RestAPI,GrpcSrv,McpSrv,Factory bindings
class Config config
style layerC fill:#151920,stroke:#37c4f0,stroke-width:2px,color:#37c4f0
```

</div>

<div class="nw-flow-connector nw-flow-down"><span>ConnectorFactory ↓</span></div>

<div class="nw-diagram nw-diagram--row nw-diagram--runtime" markdown="1">

```mermaid
%%{init: {"theme": "base", "themeVariables": {"fontSize": "40px", "fontFamily": "Inter, system-ui, sans-serif", "primaryTextColor": "#E8EDF5", "lineColor": "#62d2f5"}, "flowchart": {"nodeSpacing": 156, "rankSpacing": 40, "padding": 16}}}%%
flowchart LR
subgraph layerA ["Layer A · Runtime · src/node_wire_runtime/"]
direction LR
Validate["Pydantic validation"]
Policy["PolicyHook"]
Resilience["Retries & circuit breaker"]
Errors["ErrorMapper"]
Otel["OpenTelemetry"]
end

Validate --> Policy
Policy --> Resilience
Resilience --> Errors
Otel -. "traces" .-> Resilience

classDef runtime fill:#3a3420,stroke:#ecb32e,stroke-width:2px,color:#E8EDF5
classDef telemetry fill:#242930,stroke:#8A9BAC,stroke-width:2px,color:#E8EDF5
class Validate,Policy,Resilience,Errors runtime
class Otel telemetry
style layerA fill:#151920,stroke:#ecb32e,stroke-width:2px,color:#ecb32e
```

</div>

<div class="nw-flow-connector nw-flow-down"><span>BaseConnector.run ↓</span></div>

<div class="nw-diagram nw-diagram--row" markdown="1">

```mermaid
%%{init: {"theme": "base", "themeVariables": {"fontSize": "16px", "fontFamily": "Inter, system-ui, sans-serif", "primaryTextColor": "#E8EDF5", "lineColor": "#62d2f5"}, "flowchart": {"nodeSpacing": 32, "rankSpacing": 36, "padding": 16}}}%%
flowchart TB
subgraph layerB ["Layer B · Connectors · src/node_wire_*/"]
direction TB
subgraph bRow1 [" "]
direction LR
GDrive["Google Drive"]
SMTP["SMTP"]
Stripe["Stripe"]
FHIR["FHIR Epic/Cerner"]
end
subgraph bRow2 [" "]
direction LR
SFDC["Salesforce"]
Slack["Slack"]
HTTP["HTTP Generic"]
end
end

classDef connector fill:#3a2430,stroke:#e01d5a,stroke-width:2px,color:#E8EDF5
class GDrive,SMTP,Stripe,FHIR,SFDC,Slack,HTTP connector
style layerB fill:#151920,stroke:#e01d5a,stroke-width:2px,color:#e01d5a
style bRow1 fill:transparent,stroke:transparent,color:transparent
style bRow2 fill:transparent,stroke:transparent,color:transparent
```

</div>

<div class="nw-flow-connector nw-flow-down"><span>outbound calls ↓</span></div>

<div class="nw-diagram nw-diagram--row" markdown="1">

```mermaid
%%{init: {"theme": "base", "themeVariables": {"fontSize": "16px", "fontFamily": "Inter, system-ui, sans-serif", "primaryTextColor": "#E8EDF5", "lineColor": "#62d2f5"}, "flowchart": {"nodeSpacing": 36, "rankSpacing": 40, "padding": 16}}}%%
flowchart LR
subgraph external ["External Systems"]
ThirdParty["Third-party APIs & services"]
end

classDef ext fill:#1a3338,stroke:#62d2f5,stroke-width:2px,color:#E8EDF5
class ThirdParty ext
style external fill:#151920,stroke:#62d2f5,stroke-width:2px,color:#62d2f5
```

</div>

<div class="nw-flow-connector nw-flow-up"><span>↑ ConnectorResponse returns through Layer C to clients</span></div>

</div>

### Data Flow (Simplified)

1. A request arrives via REST, gRPC, or MCP.
Expand Down
8 changes: 5 additions & 3 deletions docs/compliance/hipaa-considerations.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# SPDX-FileCopyrightText: 2026 AOT Technologies
#
# SPDX-License-Identifier: Apache-2.0
<!--
SPDX-FileCopyrightText: 2026 AOT Technologies

SPDX-License-Identifier: Apache-2.0
-->

# HIPAA Compliance Considerations

Expand Down
8 changes: 5 additions & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# SPDX-FileCopyrightText: 2026 AOT Technologies
#
# SPDX-License-Identifier: Apache-2.0
<!--
SPDX-FileCopyrightText: 2026 AOT Technologies

SPDX-License-Identifier: Apache-2.0
-->

# Configuration Guide

Expand Down
Loading
Loading