Architecture: control and file data are separate
A transfer has two jobs: decide who may send what to whom, and move the encrypted bytes. pipeit keeps them apart.
A transfer has two jobs: to clarify who may send what to whom, and to bring the encrypted bytes to the receiver. pipeit separates these jobs. The online API manages accounts, devices, releases, jobs and states. The data path can run directly between endpoints or through the relay (server route). Switching the data path does not automatically change the receiver or the meaning of the job.
- Sign-in, releases, transfer orderControl and permissions
- Acceptance, status, receiptsControl and permissions
- Encrypted file data, directlyFile data
- Alternative: encrypted framesAlternative path
- Forwarded without storing a fileAlternative path
- Durable stateControl and permissions
- Bounded budgets and leasesControl and permissions
- Events and jobsControl and permissions
The two data paths are alternatives, not a parallel double send. Even with direct online file transport, the API can be needed for authorization, setting up the connection and status. Nearby transfers between the pipeit apps and the local pairing of native clients work without the online API; the receipt is synced the next time the device is online.
| Building block | Its job | Not its job |
|---|---|---|
| Go/Chi API | Business rules, permissions, states and HTTP contracts | Decrypting file contents of a normal end-to-end transfer |
| PostgreSQL and sqlc | Durable business state, versions, atomic decisions | Storing the payload of all live transfers as blobs |
| Redis | Bounded shared budgets and occupancy or leases | An unbounded file queue |
| NATS/JetStream and workers | Event processing and background tasks | The file byte stream of a transfer |
| WebSocket and native transport adapters | Moving encrypted frames between authorized endpoints | Inventing account rights of their own |
| S3-compatible storage | Storage for separate profiles, including pipeit Cloud, and operational storage tasks | An automatic backup of every current live transfer |
| React/TypeScript web app and native clients | Selection, local keys, cryptography, file access, operation | A different meaning of “delivered” |
| OpenAPI and the shared Go SDK | Versioned interfaces and reusable native flows | A substitute for each client's own file and key handling |
Scroll sideways to see the whole table.
Why business logic stays central
Every client shows the same transfer state the same way. A server daemon must not read the same receiver block as a success that shows as an error in the browser. Conversely, the backend cannot check whether a local folder is writable under the service user. That check belongs in the shared native file library; the receive release and the allowed actions remain part of the shared contract.
Related guides
From sending to verified receipt
The factual order of an online transfer: order, acceptance, encrypted frames, verification and a signed receipt.
Encryption: file content, keys and signatures
Which standard algorithms protect a file sent from device to device, what each one does, and what the profile does not promise.
Relay: diskless does not mean workless
Why the relay (server route) keeps no file yet still uses memory and CPU, and how backpressure keeps it bounded.