@quietflow/runtime-client
v0.1.4
Published
Read approved company data from inside a Quiet Flow app — one call that works under `qf dev` and deployed, without the app ever holding a credential.
Maintainers
Readme
@quietflow/runtime-client
How an app published to Quiet Flow reads company data. One function, one shape
of answer, and the same code whether the app is running under qf dev on the
builder's machine or deployed for the whole company.
npm install @quietflow/runtime-clientimport { readCompanyData } from "@quietflow/runtime-client";
app.get("/accounts", async (request, response) => {
const answer = await readCompanyData(request, {
capability: "crm.read",
operation: "list_accounts",
});
response.json(answer);
});Pass the incoming request through — it is how Quiet Flow knows which employee
is asking — and name a capability and an operation. Both of those names
are printed together on Company data in Quiet Flow, under the account you are
reading from, and list_company_systems says the same pair to an assistant (#622).
Write them exactly as they are given: an operation name taken off an IT screen is
the provider's own name for the action, which is a different string and is refused.
Where the app's
manifest declared more than one place it reads that kind of data from, add
as: "acquired-customers" to say which. An operation may declare safe scalar
inputs, such as parameters: { withinDays: 14 }. These are named and bounded by
the connector; they are not filters. There is no field list, row predicate, or
query, because Quiet Flow builds the real request from what the Data Owner
approved.
The answer is { status, records, page, scope }. status is ok, denied,
provider_unavailable, or unavailable; on anything but ok there is a
message already written for the person using the app — show it as it is.
While nobody has approved real access yet, qf dev serves invented rows in the
real shape and marks the answer sample: true, so the app can say so on screen.
When answer.page.hasMore is true, call again with
page: { cursor: answer.page.cursor }; the cursor is opaque and must be reused,
not constructed.
What it does
- Chooses its own authentication. Under
qf devit uses the run's dev session; deployed it uses the identity file the platform mounts. App code never branches on the difference. - Re-reads the app's identity on every call. The platform rotates it; nothing here caches it, so nothing here expires an hour in.
- Forwards who is asking. Deployed, the gateway's signed context is required — a request without one is refused with a sentence, never sent unauthenticated.
- Rejects redirects and incomplete answers. The app's identity is sent only to the configured broker endpoint, and a rolling upgrade cannot turn a partial response into a value the app was promised was complete.
What it does not do
- Run in a browser. It refuses with a sentence. Ask from server-side code and send the result to the page.
- Write anything. This is a read client.
- Accept a query. Safe operation parameters and broker-issued page cursors are supported; fields, filters, expansions, and queries are not, and an extra property on the call never reaches the wire.
- Hold a credential. There is no token to configure, copy, or leak.
