Compare commits
84 changed files with 988 additions and 0 deletions
1
.agents/JOB_BUS.md
Symbolic link
1
.agents/JOB_BUS.md
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
/Users/marchon/job-bus/docs/JOB_BUS_LLM_INSTRUCTIONS.md
|
||||
6
.jobbus.json
Normal file
6
.jobbus.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"enabled": true,
|
||||
"manifest": "jobs/pieces.yaml",
|
||||
"farm": "scripts/jobbus-farm.sh",
|
||||
"instructions": ".agents/JOB_BUS.md"
|
||||
}
|
||||
6
AGENTS.md
Normal file
6
AGENTS.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Agent notes
|
||||
|
||||
## Job-bus multi-build
|
||||
This repo farms multi-build pieces via NATS job-bus. See [.agents/JOB_BUS.md](.agents/JOB_BUS.md).
|
||||
Edit `jobs/pieces.yaml`, then run `./scripts/jobbus-farm.sh` (or `make farm`).
|
||||
CPU pieces → Xeons (137/138); GPU pieces → Mac. Always set `requires` per piece.
|
||||
81
CATALOG-HOST.md
Normal file
81
CATALOG-HOST.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# Move the documentation catalog to another hostname
|
||||
|
||||
The catalog is a **static tree** (`site/` in the monorepo). HTML cards and PDF clicks are **path-relative**, so the same files can be served from `https://zapier.georgelambert.org/` today and `https://docs.verae-time.net/` later without rewriting links.
|
||||
|
||||
Live service doors (portal, IAM, fleet, …) stay on their own hostnames. Forgejo stays on `git.georgelambert.org`.
|
||||
|
||||
**Script:** `scripts/rewrite-docs-host.py` in [master-zapier-plan-draft](https://git.georgelambert.org/marchon/master-zapier-plan-draft)
|
||||
**Build:** `scripts/build-docs-site.py` · **Deploy:** `scripts/deploy-docs-site.sh`
|
||||
|
||||
## Default (relative) — no hostname pass
|
||||
|
||||
1. Build: `python3 scripts/build-docs-site.py`
|
||||
2. Rsync the `site/` directory to the new host document root (must be the site root, `/`).
|
||||
3. Point DNS + TLS (Caddy `file_server` with `index index.html index.pdf README.html README.pdf`) at that tree.
|
||||
|
||||
PDF annotations look like `README.pdf` and `../../index.html` (relative to the PDF). Browsers resolve them against the PDF’s own URL, so they follow the new host.
|
||||
|
||||
Optional label in the HTML banner (not a link target):
|
||||
|
||||
```bash
|
||||
DOCS_PUBLIC_HOST=docs.verae-time.net python3 scripts/build-docs-site.py
|
||||
```
|
||||
|
||||
## Absolute URLs (only if a viewer needs them)
|
||||
|
||||
Bake a public origin at build time:
|
||||
|
||||
```bash
|
||||
DOCS_PUBLIC_URL=https://docs.verae-time.net \
|
||||
DOCS_PUBLIC_HOST=docs.verae-time.net \
|
||||
python3 scripts/build-docs-site.py
|
||||
```
|
||||
|
||||
Or retarget an **already built** `site/` without rebuilding PDFs from markdown:
|
||||
|
||||
```bash
|
||||
# Lab origin → future docs host
|
||||
python3 scripts/rewrite-docs-host.py \
|
||||
--site ./site \
|
||||
--from https://zapier.georgelambert.org \
|
||||
--to https://docs.verae-time.net
|
||||
|
||||
# Strip the origin (same as the default build)
|
||||
python3 scripts/rewrite-docs-host.py --site ./site --relative
|
||||
|
||||
python3 scripts/rewrite-docs-host.py --site ./site --from … --to … --dry-run
|
||||
```
|
||||
|
||||
The rewrite walks HTML/SVG/CSS/JS/MD text and PDF `/URI` annotations. It does **not** change `portal.zapier.georgelambert.org`, `iam.…`, or `git.georgelambert.org`.
|
||||
|
||||
## Caddy (any host)
|
||||
|
||||
```caddy
|
||||
docs.verae-time.net {
|
||||
root * /SSD2/sites/docs.verae-time.net
|
||||
encode gzip zstd
|
||||
file_server {
|
||||
index index.html index.pdf README.html README.pdf
|
||||
}
|
||||
try_files {path} {path}/index.html {path}/index.pdf {path}/README.html {path}/README.pdf
|
||||
}
|
||||
```
|
||||
|
||||
Lab copy: `packages/verae-ops/caddy/zapier.georgelambert.org.caddy`.
|
||||
|
||||
## Check
|
||||
|
||||
```bash
|
||||
python3 scripts/check-doc-links.py
|
||||
```
|
||||
|
||||
Local files must exist for homepage hrefs and PDF URI targets. Off-site HTTPS (Forgejo, live doors) is left alone.
|
||||
|
||||
## Publish lab catalog (today)
|
||||
|
||||
```bash
|
||||
git -C /Users/marchon/apps/zapier push ns1 main
|
||||
git -C /Users/marchon/apps/zapier push ns1 main:master
|
||||
bash scripts/deploy-docs-site.sh
|
||||
# → marchon@70.88.205.138:/SSD2/sites/zapier.georgelambert.org
|
||||
```
|
||||
22
HOST-DEPS.md
Normal file
22
HOST-DEPS.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Host dependencies for every Forgejo module
|
||||
|
||||
The installer lives in **verae-bootstrap** (not this summaries repo):
|
||||
|
||||
- Script: `scripts/host-deps.sh`
|
||||
- Manifest: `host-deps.tsv` (one row per Forgejo repo)
|
||||
- Narrative: [HOST-DEPS.md](https://git.georgelambert.org/marchon/verae-bootstrap/src/branch/main/HOST-DEPS.md)
|
||||
|
||||
It detects Debian/Ubuntu vs Alpine (and best-effort macOS), checks that git, curl, Node, native build tools, and `nats-server` are present, and **downloads/installs** whatever is missing on **this** machine.
|
||||
|
||||
```bash
|
||||
git clone ssh://git@git.georgelambert.org:2223/marchon/verae-bootstrap.git
|
||||
cd verae-bootstrap
|
||||
bash scripts/host-deps.sh --check --type ns1-all-in-one
|
||||
bash scripts/host-deps.sh --type ns1-all-in-one
|
||||
export VERAE_SRC=$HOME/verae-src
|
||||
bash scripts/fetch.sh ns1-all-in-one
|
||||
```
|
||||
|
||||
Alpine if `bash` is not installed yet: `apk add --no-cache bash git curl`.
|
||||
|
||||
Catalog hostname move (relative PDFs): [CATALOG-HOST.md](CATALOG-HOST.md).
|
||||
44
MESSAGE-FLOWS.md
Normal file
44
MESSAGE-FLOWS.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Message flows
|
||||
|
||||
## 1. Create timestamp (async)
|
||||
|
||||
1. Zapier → `POST https://zappier-edge/v1/timestamp` (`x-api-key`)
|
||||
2. zappier-edge meters → `POST middleware/zapier/v1/timestamp`
|
||||
3. splitter: chain sha256; optional `verae.archive.put`
|
||||
4. middleware → chain create or existing lookup
|
||||
5. middleware publishes `verae.zapier.jobs.watch` `{ jobId, tenantId, … }`
|
||||
6. HTTP 202 `{ jobId }` back to Zapier
|
||||
7. job-poller consumes watch, GET chain status
|
||||
8. On terminal: `verae.zapier.jobs.events`
|
||||
9. webhook-deliver POSTs Zapier REST Hook if subscribed
|
||||
|
||||
## 2. Wait
|
||||
|
||||
Same as (1) but HTTP holds until `jobs.events` or `WAIT_TIMEOUT_MS` → `{ status: pending, jobId }`.
|
||||
|
||||
## 3. Hash already registered
|
||||
|
||||
Step 4 returns original jobId + original seal. No second chain write. `receipts[0].kind = seal`. Later archive attaches become `receipts[1…]` if `includeAttached`.
|
||||
|
||||
## 4. includeAttached
|
||||
|
||||
After seal is known, aggregator publishes `verae.archive.query`. Each WORM: bloom miss = no packet; hit = `verae.archive.reply.<correlationId>`. Aggregator merges into wait JSON.
|
||||
|
||||
## 5. Multipart attachments
|
||||
|
||||
Splitter emits one `archive.put` per file (`kind: file`, `contentSha256`). Chain never stores bytes.
|
||||
|
||||
## 6. Batch Merkle (bulk summary)
|
||||
|
||||
1. Zapier → `POST /v1/timestamp/batch` (one item per line)
|
||||
2. Middleware hashes each item (leaves), builds Merkle tree
|
||||
3. Chain seals **only the root**
|
||||
4. Each leaf proof → `verae.archive.put` `kind: tree` on a sharded tree node
|
||||
5. Central `GET /hashes/{leaf}` → miss (`itemizedOnMainChain: false`)
|
||||
6. `GET /hashes/{leaf}?includeTree=true` → aggregator broadcasts `verae.archive.query` `kinds=["tree"]`
|
||||
7. Tree node bloom hit → `archive.reply.<id>` with proof; others silent
|
||||
8. Response: root seal + `tree-leaf` receipt
|
||||
|
||||
## 7. Simulator
|
||||
|
||||
`packages/verae-zapier-simulator` replays flows 1–6 in-process with a trace console, fault injection, and modification suggestions. It does not connect to live NATS.
|
||||
101
README.md
Normal file
101
README.md
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# zapier-docs-master
|
||||
|
||||
[](https://github.com/RichardLitt/standard-readme)
|
||||
|
||||
Summaries, NATS contracts, and message flows for every Verae Time × Zapier module.
|
||||
|
||||
**Live catalog:** https://zapier.georgelambert.org/
|
||||
**Move the catalog to another host:** [CATALOG-HOST.md](CATALOG-HOST.md) (relative PDF links; `scripts/rewrite-docs-host.py`)
|
||||
**Host OS / Node / NATS install:** [verae-bootstrap HOST-DEPS](https://git.georgelambert.org/marchon/verae-bootstrap)
|
||||
**Overview (start here):** https://git.georgelambert.org/marchon/overview
|
||||
**Operator console:** http://127.0.0.1:3850/ (Fleet · Trace · Docs)
|
||||
**Monorepo:** https://git.georgelambert.org/marchon/master-zapier-plan-draft (`main` and `master`)
|
||||
|
||||
## Git repos (Forgejo on NS1)
|
||||
|
||||
| Repo | URL |
|
||||
|------|-----|
|
||||
| master-zapier-plan-draft | https://git.georgelambert.org/marchon/master-zapier-plan-draft |
|
||||
| zappier-edge | https://git.georgelambert.org/marchon/zappier-edge |
|
||||
| verae-middleware | https://git.georgelambert.org/marchon/verae-middleware |
|
||||
| verae-zapier-app | https://git.georgelambert.org/marchon/verae-zapier-app |
|
||||
| verae-activate | https://git.georgelambert.org/marchon/verae-activate |
|
||||
| verae-request-splitter | https://git.georgelambert.org/marchon/verae-request-splitter |
|
||||
| verae-archive-worm | https://git.georgelambert.org/marchon/verae-archive-worm |
|
||||
| verae-archive-aggregator | https://git.georgelambert.org/marchon/verae-archive-aggregator |
|
||||
| verae-tree-node | https://git.georgelambert.org/marchon/verae-tree-node |
|
||||
| verae-zapier-simulator | https://git.georgelambert.org/marchon/verae-zapier-simulator |
|
||||
| zapier-user-docs | https://git.georgelambert.org/marchon/zapier-user-docs |
|
||||
| verae-fleet | https://git.georgelambert.org/marchon/verae-fleet |
|
||||
| **overview** | https://git.georgelambert.org/marchon/overview |
|
||||
| verae-nats-process | https://git.georgelambert.org/marchon/verae-nats-process |
|
||||
| **zapier-docs-master** (this repo) | https://git.georgelambert.org/marchon/zapier-docs-master |
|
||||
| **verae-ops** | https://git.georgelambert.org/marchon/verae-ops |
|
||||
| verae-staff-iam | https://git.georgelambert.org/marchon/verae-staff-iam |
|
||||
| verae-keep | https://git.georgelambert.org/marchon/verae-keep |
|
||||
| verae-bootstrap | https://git.georgelambert.org/marchon/verae-bootstrap |
|
||||
| verae-uptime | https://git.georgelambert.org/marchon/verae-uptime |
|
||||
| verae-backup | https://git.georgelambert.org/marchon/verae-backup |
|
||||
| verae-deploy | https://git.georgelambert.org/marchon/verae-deploy |
|
||||
| verae-proxmox | https://git.georgelambert.org/marchon/verae-proxmox |
|
||||
| verae-nats-cluster | https://git.georgelambert.org/marchon/verae-nats-cluster |
|
||||
|
||||
Clone (SSH port 2223):
|
||||
|
||||
`git clone ssh://git@git.georgelambert.org:2223/marchon/<name>.git`
|
||||
|
||||
## Modules
|
||||
|
||||
| Module | Summary | NATS in | NATS out |
|
||||
|--------|---------|---------|----------|
|
||||
| zappier-edge | Metered HTTPS for Zapier | — | — (HTTPS to middleware) |
|
||||
| verae-middleware | Job id + wait HTTP | jobs.events | jobs.watch |
|
||||
| verae-activate | Pushable Zapier app | — | — |
|
||||
| verae-zapier-app | Full Zapier nouns | — | — |
|
||||
| request-splitter | Hash vs files | — | archive.put |
|
||||
| archive-worm | Bloom WORM node | archive.query, archive.put | archive.reply.* (hit only) |
|
||||
| archive-aggregator | Merge archive replies | archive.reply.* | archive.query |
|
||||
| tree-node | Merkle leaf proofs | archive.query, archive.put | archive.reply.* (hit only) |
|
||||
| zapier-simulator | Trace console (in-process) | — | — |
|
||||
| zapier-user-docs | Signup → lookup guide | — | — |
|
||||
| verae-fleet | Replica floors + monitor | — | — |
|
||||
| overview | System map | — | — |
|
||||
| nats-process | Template worker | example.process.in | example.process.out / reply.* |
|
||||
| ops | Install / Docker / Proxmox / metal | — | — |
|
||||
|
||||
## Documents in this repo
|
||||
|
||||
- [MESSAGE-FLOWS.md](MESSAGE-FLOWS.md) — numbered request paths
|
||||
- [modules-and-nats.md](modules-and-nats.md) — address table
|
||||
- [archive-nats.md](archive-nats.md) — bloom / multi-receipt design
|
||||
- [composition.md](composition.md) — HTTPS hops
|
||||
- `modules/<name>/SUMMARY.md` and `NATS.md`
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Install](#install)
|
||||
- [Usage](#usage)
|
||||
- [Contributing](#contributing)
|
||||
- [License](#license)
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
git clone ssh://git@git.georgelambert.org:2223/marchon/zapier-docs-master.git
|
||||
cd zapier-docs-master
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
# No single entrypoint is declared in this tree.
|
||||
ls
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Questions: open an issue at https://git.georgelambert.org/marchon/zapier-docs-master/issues. Pull requests are accepted.
|
||||
|
||||
## License
|
||||
|
||||
UNLICENSED © George Lambert
|
||||
91
archive-nats.md
Normal file
91
archive-nats.md
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# Archive NATS: jobs, multipart split, hash receipts, WORM bloom fan-out
|
||||
|
||||
Zapier never speaks NATS. HTTPS stops at zappier → middleware. Middleware owns jobs, splitting, chain lookup, and archive aggregation.
|
||||
|
||||
## End-to-end
|
||||
|
||||
```text
|
||||
Zapier --HTTPS--> zappier (meter, x-api-key)
|
||||
--HTTPS--> middleware /zapier/v1/timestamp[/wait]
|
||||
1. split multipart
|
||||
chain: SHA256 only (+ optional public-meta digest)
|
||||
archives: public JSON, encrypted private JSON, files
|
||||
2. publish jobs.watch → return jobId (202)
|
||||
3. waiters subscribe jobs.events
|
||||
4. lookup SHA256 on chain (mock or Verae)
|
||||
already sealed → original receipt, no new seal
|
||||
later attach records → extra receipts
|
||||
5. if includeAttached:
|
||||
publish verae.archive.query
|
||||
WORM nodes: bloom miss = silence
|
||||
bloom hit = reply
|
||||
aggregate until WAIT_ARCHIVE_MS
|
||||
6. jobs.events completed JSON → waiter / REST Hook
|
||||
```
|
||||
|
||||
Blockchain stores **hash + time + block + certificate**. Public metadata, encrypted metadata, and file bytes live on **WORM archives**.
|
||||
|
||||
## Splitter
|
||||
|
||||
`splitRequest(body | multipart)`:
|
||||
|
||||
| Field | Destination |
|
||||
|-------|-------------|
|
||||
| `data` / `sha256` | Chain register or lookup |
|
||||
| `publicMetadata` | Archive put (clear) |
|
||||
| `privateMetadata` | Archive put (ciphertext) |
|
||||
| `files[]` | Archive put; chain gets content hashes + ids |
|
||||
| `includeAttached` | Whether wait path queries archives |
|
||||
|
||||
## Hash already registered
|
||||
|
||||
Return original `jobId` and original seal. Do not write a second chain timestamp.
|
||||
|
||||
If later attach jobs exist for that hash, `receipts` is an array: seal first, then attachment receipts in time order.
|
||||
|
||||
## Subjects
|
||||
|
||||
| Subject | Publisher | Subscriber |
|
||||
|---------|-----------|------------|
|
||||
| `verae.zapier.jobs.watch` | HTTP edge | job poller |
|
||||
| `verae.zapier.jobs.events` | poller | waiter, webhook router |
|
||||
| `verae.archive.put` | splitter | archive that owns the shard |
|
||||
| `verae.archive.query` | aggregator | **every** archive (not a shared queue group) |
|
||||
| `verae.archive.reply.<correlationId>` | archive on bloom hit | aggregator |
|
||||
|
||||
Query payload: `{ correlationId, sha256, tenantId, kinds[] }`.
|
||||
`kinds` may include `tree` for Merkle leaf proofs (hashes sealed only as a bulk summary root).
|
||||
Reply payload: `{ archiveId, sha256, records[] }`.
|
||||
|
||||
Bloom miss → no reply. Aggregator timeout → complete with whatever arrived.
|
||||
|
||||
## WORM archives
|
||||
|
||||
Each process holds append-only records + a bloom of SHA256 keys it stores. False positives OK; false negatives must be rare. Bloom is not an ACL — on hit, still check tenant/share.
|
||||
|
||||
Harness: three mock archives with overlapping hashes.
|
||||
|
||||
## Completed job JSON (wait / hook)
|
||||
|
||||
```json
|
||||
{
|
||||
"jobId": "…",
|
||||
"status": "completed",
|
||||
"sha256": "…",
|
||||
"receipts": [
|
||||
{ "kind": "seal", "timestamp": "…", "certificate": "…", "blockIndex": 42 },
|
||||
{ "kind": "metadata-attach", "attachedAt": "…", "publicMetadata": {} }
|
||||
],
|
||||
"files": [{ "id": "…", "sha256": "…", "archiveId": "archive-b" }],
|
||||
"archivesQueried": true,
|
||||
"archiveReplies": 2
|
||||
}
|
||||
```
|
||||
|
||||
Flag off or all blooms miss → `files` empty, extra receipts omitted.
|
||||
|
||||
## Security
|
||||
|
||||
- Zapier never connects to NATS or archives.
|
||||
- Private metadata only on authenticated archive replies.
|
||||
- NS1 NATS stays loopback; use `scripts/nats-tunnel.sh`.
|
||||
33
composition.md
Normal file
33
composition.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Composition: zappier commercial edge + Verae adapter
|
||||
|
||||
```text
|
||||
Users → Zapier UI
|
||||
Zapier cloud runs packages/verae-zapier
|
||||
--HTTPS, x-api-key--> packages/zappier /v1/*
|
||||
(meter, quote, 401/403, usage)
|
||||
--internal HTTPS--> packages/verae-zapier-middleware /zapier/v1/*
|
||||
--sync--> api.veraetime.net or MOCK_VERAE
|
||||
--NATS--> workers --> Verae + Zapier REST Hooks
|
||||
|
||||
Humans → zappier /portal signup, API key, usage, reloads, invoices
|
||||
Ops → zappier /admin rate card, tiers, customers, PO invoices
|
||||
```
|
||||
|
||||
## Ownership
|
||||
|
||||
| Concern | Package |
|
||||
|---------|---------|
|
||||
| API keys, custom pricing, Stripe, invoices, portal | `packages/zappier` |
|
||||
| Timestamp/verify/status, NATS, REST Hooks, mock Verae | `packages/verae-zapier-middleware` |
|
||||
| Zapier Platform nouns (creates/searches/triggers) | `packages/verae-zapier` |
|
||||
| Official SDK reference | `vendor/zapier-platform` |
|
||||
|
||||
Zapier never talks to NATS or `api.veraetime.net`.
|
||||
|
||||
Do not reimplement Stripe, invoices, or the rate-card UI inside the Verae middleware.
|
||||
|
||||
Public keys are zappier `x-api-key` (issued at portal signup). Middleware `zmw_` / `PLAN_LIMITS` stay internal until composition PR 4 removes them from the public path.
|
||||
|
||||
Demo zappier routes `/v1/transform` and `/v1/storage` are a metering sandbox, not Verae timestamping or encrypted LTS.
|
||||
|
||||
Payment invoices (zappier) are not certified timestamp receipts (Verae feature i).
|
||||
23
jobs/pieces.yaml
Normal file
23
jobs/pieces.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Multi-build piece manifest for job-bus.
|
||||
# Copy to jobs/pieces.yaml in your repo and edit.
|
||||
# Each piece becomes one tracked job; kind routes cpu→Xeons, gpu→Mac.
|
||||
batch: "zapier-docs-master-EDITME"
|
||||
defaults:
|
||||
kind: cpu
|
||||
requires: []
|
||||
timeout_sec: 3600
|
||||
cleanup: none # or on_success; full wipe via: job-cleanup --batch <batch>
|
||||
pieces:
|
||||
- id: piece-01
|
||||
kind: cpu
|
||||
requires: [bin:bash]
|
||||
cmd: ["make", "piece-01"]
|
||||
# cwd: defaults to repo root on submitter; set worker-visible path if needed
|
||||
- id: piece-02
|
||||
kind: cpu
|
||||
requires: [ffmpeg, pip:numpy]
|
||||
cmd: ["python3", "scripts/build_piece.py", "--piece", "2"]
|
||||
- id: piece-gpu-hero
|
||||
kind: gpu
|
||||
requires: [pip:Pillow]
|
||||
cmd: ["python3", "scripts/gpu_hero.py"]
|
||||
85
modules-and-nats.md
Normal file
85
modules-and-nats.md
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# Modules and NATS message contracts
|
||||
|
||||
Master map of every service in the Zapier ↔ middleware ↔ chain ↔ WORM-archive path.
|
||||
|
||||
Zapier cloud **never** connects to NATS. Internal services do: middleware workers, archives, account-balance, zappier-edge billing, CS, sales, and accounting.
|
||||
|
||||
## Who talks to whom (HTTPS vs NATS)
|
||||
|
||||
```text
|
||||
[Zapier Platform app] HTTPS [zappier-edge] HTTPS [middleware-http]
|
||||
| | NATS verae.billing.* |
|
||||
| v |
|
||||
[customer portal] [account-balance] NATS JetStream
|
||||
[CS :3011] queue account-balance (NS1 loopback :4222)
|
||||
[sales :3012] ^ |
|
||||
[accounting :3013] | request-reply |
|
||||
+-------------------------------+
|
||||
+------------------+------------------+-------------+
|
||||
| | |
|
||||
[job-poller] [webhook-deliver] [archive-aggregator]
|
||||
| |
|
||||
| HTTPS | NATS query/reply
|
||||
[verae-chain-client] |
|
||||
[archive-worm × N]
|
||||
bloom miss = silence
|
||||
```
|
||||
|
||||
## Module catalog
|
||||
|
||||
| Module | Repo (Forgejo) | Runtime | Listens | Sends |
|
||||
|--------|----------------|---------|---------|-------|
|
||||
| zapier-platform-app | `verae-zapier-app` | Zapier cloud | User Zap steps | HTTPS to zappier-edge |
|
||||
| zappier-edge | `zappier-edge` | Public HTTPS :3000 | Zapier, portal, admin | HTTPS to middleware; NATS billing after authz |
|
||||
| access-authz | `verae-access-authz` | :3020 + NATS | `verae.access.authz.check` | allow/deny |
|
||||
| access-web | `verae-access-web` | :3021 | customer browser | billing statement/reload |
|
||||
| access-api | `verae-access-api` | :3022 | x-api-key | statement; HTTPS to middleware |
|
||||
| access-leaf | `verae-access-leaf` | :3023 | S2S leaf | archive/jobs only |
|
||||
| access-zapier | `verae-access-zapier` | :3024 | Zapier HTTPS | jobs.watch after authz |
|
||||
| account-balance | `zappier-account-balance` | :3010 + NATS | `verae.billing.*` | statement/adjust replies |
|
||||
| customer-service | `zappier-customer-service` | :3011 | CS staff HTTP | NATS balance.adjust / statement.get |
|
||||
| sales-pricing | `zappier-sales-pricing` | :3012 | Sales HTTP | NATS statement.get; HTTPS to edge for multipliers |
|
||||
| accounting-export | `zappier-accounting-export` | :3013 | Accounting HTTP | reads invoices; NATS statement |
|
||||
| middleware-http | `verae-middleware` | Public HTTPS :3100 | zappier-edge | NATS jobs.watch; HTTP to chain; wait on jobs.events |
|
||||
| job-poller | `verae-job-poller` | Worker | `verae.zapier.jobs.watch` | `verae.zapier.jobs.events`; HTTP GET chain status |
|
||||
| webhook-deliver | `verae-webhook-deliver` | Worker | `verae.zapier.webhooks.deliver` + events | HTTPS POST Zapier REST Hook |
|
||||
| request-splitter | `verae-request-splitter` | In middleware | HTTP body / multipart | chain hash; `verae.archive.put` |
|
||||
| archive-aggregator | `verae-archive-aggregator` | Worker / in wait | `includeAttached` on wait | `verae.archive.query`; reads `verae.archive.reply.<id>` |
|
||||
| archive-worm | `verae-archive-worm` | N copies | `verae.archive.query`, `verae.archive.put` | `verae.archive.reply.<id>` if bloom hits |
|
||||
| tree-node | `verae-tree-node` | N copies (WORM role) | `verae.archive.query`, `verae.archive.put` kind `tree` | `verae.archive.reply.<id>` if bloom hits |
|
||||
| zapier-simulator | `verae-zapier-simulator` | Local HTTP :3847 | operator browser | in-process replay of all addresses |
|
||||
| zapier-user-docs | `zapier-user-docs` | Static | — | catalog `/user-docs/` |
|
||||
| verae-chain-client | `verae-chain-client` | Library | — | HTTPS `api.veraetime.net` or MOCK |
|
||||
| fleet | `verae-fleet` | Local HTTP :3850 | operator | keepFloor + SSH hosts |
|
||||
| staff-iam | `verae-staff-iam` | :3028 | staff login | none (HTTP) |
|
||||
| keep | `verae-keep` | :3860 / :3861 | host supervisor | none |
|
||||
| bootstrap | `verae-bootstrap` | clone/install | — | — |
|
||||
| overview | `overview` | Static | — | high-level map |
|
||||
| nats-process | `verae-nats-process` | Template worker | `verae.example.process.in` | `.out` / `.reply.*` |
|
||||
| docs-master | `zapier-docs-master` | Static | — | published on zapier.georgelambert.org |
|
||||
|
||||
## Addresses (subjects)
|
||||
|
||||
| Address | Kind | Payload (required fields) |
|
||||
|---------|------|---------------------------|
|
||||
| `verae.zapier.jobs.watch` | JetStream work queue | `tenantId`, `veraeUserId`, `jobId`, `tokenRef`, `enqueuedAt`, `attempt`, `maxAttempts`, `intervalMs`, `traceId` |
|
||||
| `verae.zapier.jobs.events` | JetStream events | `event` (`timestamp.completed\|failed\|timeout`), `tenantId`, `jobId`, `status`, `traceId`, `emittedAt` |
|
||||
| `verae.zapier.webhooks.deliver` | JetStream work queue | `hookId`, `tenantId`, `targetUrl`, `event`, `payload`, `attempt`, `traceId` |
|
||||
| `verae.zapier.usage` | optional | `tenantId`, `action`, `amount`, `at` |
|
||||
| `verae.billing.statement.get` | request-reply | `customerId` → prepaid, credits, usage, payments |
|
||||
| `verae.billing.balance.adjust` | request-reply | `customerId`, `cents`, `reason`, `agent` |
|
||||
| `verae.billing.usage.recorded` | pub | meter events from zappier-edge |
|
||||
| `verae.billing.payment.recorded` | pub | portal reload / invoice paid |
|
||||
| `verae.billing.credit.applied` | pub | CS goodwill |
|
||||
| `verae.access.authz.check` | request-reply | `{ plane, subject, principal }` → `{ allow, reason }` |
|
||||
| `verae.access.web.billing.statement.get` | ingress | web plane only; mapped after authz |
|
||||
| `verae.access.api.*` | ingress | customer API plane |
|
||||
| `verae.access.zapier.*` | ingress | Zapier plane |
|
||||
| `verae.access.leaf.in` | ingress | S2S leaf; never billing |
|
||||
| `verae.archive.put` | JetStream | `sha256`, `tenantId`, `kind` (`publicMeta\|privateMeta\|file\|tree`), `record`, `traceId` |
|
||||
| `verae.archive.query` | pub to **all** archives | `correlationId`, `sha256`, `tenantId`, `kinds[]`, `traceId` |
|
||||
| `verae.archive.reply.<correlationId>` | replies | `archiveId`, `sha256`, `records[]`, `traceId` |
|
||||
|
||||
## Completed job JSON (back to Zapier)
|
||||
|
||||
See `docs/02-architecture/archive-nats.md`. Seal receipts from chain; extra receipts and `files[]` from archive aggregation when `includeAttached` is true.
|
||||
3
modules/overview/NATS.md
Normal file
3
modules/overview/NATS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# NATS — overview
|
||||
|
||||
Documentation only. Describes the central 3-server cluster. Zapier never connects.
|
||||
3
modules/overview/SUMMARY.md
Normal file
3
modules/overview/SUMMARY.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# overview
|
||||
|
||||
High-level system map, 3-node NATS cluster, uptime, network failure, address routing. Repo: `overview`.
|
||||
3
modules/verae-access-api/NATS.md
Normal file
3
modules/verae-access-api/NATS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# NATS — verae-access-api
|
||||
|
||||
Plane `api`. Statement and jobs.watch after authz. No credits, no archive.
|
||||
3
modules/verae-access-api/SUMMARY.md
Normal file
3
modules/verae-access-api/SUMMARY.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# verae-access-api
|
||||
|
||||
Direct customer API (`x-api-key`). Separate from Zapier Platform.
|
||||
3
modules/verae-access-authz/NATS.md
Normal file
3
modules/verae-access-authz/NATS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# NATS — verae-access-authz
|
||||
|
||||
`verae.access.authz.check` request-reply. Queue `access-authz`. Fail closed.
|
||||
3
modules/verae-access-authz/SUMMARY.md
Normal file
3
modules/verae-access-authz/SUMMARY.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# verae-access-authz
|
||||
|
||||
Default-deny authorization step on the NATS address path. Planes: zapier, web, api, leaf, staff.
|
||||
3
modules/verae-access-leaf/NATS.md
Normal file
3
modules/verae-access-leaf/NATS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# NATS — verae-access-leaf
|
||||
|
||||
`verae.access.leaf.in` → authz.check → `verae.archive.*` / jobs.*. Denied: billing.
|
||||
3
modules/verae-access-leaf/SUMMARY.md
Normal file
3
modules/verae-access-leaf/SUMMARY.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# verae-access-leaf
|
||||
|
||||
Server-to-server NATS leaf ingress. Archive and jobs only. Never billing.
|
||||
3
modules/verae-access-staff/NATS.md
Normal file
3
modules/verae-access-staff/NATS.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# NATS — verae-access-staff
|
||||
|
||||
Plane `staff`. Authz then billing statement/adjust.
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue