feat(agent): add read-only PocketBase loaders
The only module in the agent layer that touches the network. Kept separate from formatting so tool output is unit-testable offline. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
15ecf1af05
commit
7d02ef1e3a
1 changed files with 92 additions and 0 deletions
92
src/lib/agent/load.ts
Normal file
92
src/lib/agent/load.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* PocketBase reads for the agent tool layer.
|
||||
*
|
||||
* The ONLY module here that touches the network. Every function is a
|
||||
* read — no create/update/delete, enforced by read-only.test.ts.
|
||||
*
|
||||
* Deliberately returns raw-ish records; shaping lives in ./format so it
|
||||
* can be unit-tested without a PocketBase instance.
|
||||
*/
|
||||
import { pbAdmin } from "@/lib/pb";
|
||||
import type { SiteRef } from "./resolve";
|
||||
|
||||
export async function loadSiteRefs(): Promise<SiteRef[]> {
|
||||
const pb = await pbAdmin();
|
||||
const sites = await pb.collection("sites").getFullList({
|
||||
fields: "id,name,project_code",
|
||||
sort: "name",
|
||||
});
|
||||
return sites.map((s) => ({
|
||||
id: s.id,
|
||||
name: s.name ?? "",
|
||||
projectCode: s.project_code ?? "",
|
||||
}));
|
||||
}
|
||||
|
||||
/** Everything the site financial roll-up needs, for one site. */
|
||||
export async function loadSiteBundle(siteId: string) {
|
||||
const pb = await pbAdmin();
|
||||
const [site, fixedCosts, timesheets, employees, purchaseOrders, fuelLogs, income] =
|
||||
await Promise.all([
|
||||
pb.collection("sites").getOne(siteId),
|
||||
pb.collection("fixed_costs").getFullList({ filter: `site='${siteId}'` }),
|
||||
pb.collection("timesheets").getFullList(),
|
||||
pb.collection("employees").getFullList({
|
||||
fields: "id,rate_per_hour,site,name",
|
||||
}),
|
||||
pb.collection("purchase_orders").getFullList({ filter: `site='${siteId}'` }),
|
||||
pb.collection("fuel_logs").getFullList({ filter: `site='${siteId}'` }),
|
||||
pb.collection("income_claims").getFullList({ filter: `site='${siteId}'` }),
|
||||
]);
|
||||
return { site, fixedCosts, timesheets, employees, purchaseOrders, fuelLogs, income };
|
||||
}
|
||||
|
||||
/** Every site plus the collections needed to roll all of them up at once. */
|
||||
export async function loadAllSitesBundle() {
|
||||
const pb = await pbAdmin();
|
||||
const [sites, fixedCosts, timesheets, employees, purchaseOrders, fuelLogs, income] =
|
||||
await Promise.all([
|
||||
pb.collection("sites").getFullList({ sort: "name" }),
|
||||
pb.collection("fixed_costs").getFullList(),
|
||||
pb.collection("timesheets").getFullList(),
|
||||
pb.collection("employees").getFullList({
|
||||
fields: "id,rate_per_hour,site,name",
|
||||
}),
|
||||
pb.collection("purchase_orders").getFullList({
|
||||
fields: "id,site,total_value,is_verified",
|
||||
}),
|
||||
pb.collection("fuel_logs").getFullList({
|
||||
fields: "id,site,litres,date_logged",
|
||||
}),
|
||||
pb.collection("income_claims").getFullList({
|
||||
fields: "id,site,paid_on,period_end",
|
||||
}),
|
||||
]);
|
||||
return { sites, fixedCosts, timesheets, employees, purchaseOrders, fuelLogs, income };
|
||||
}
|
||||
|
||||
/** Vehicles + fuel logs with vehicle expanded, for the attention roll-up. */
|
||||
export async function loadFleetBundle() {
|
||||
const pb = await pbAdmin();
|
||||
const [vehicles, fuelLogs] = await Promise.all([
|
||||
pb.collection("vehicles").getFullList({ sort: "description" }),
|
||||
pb.collection("fuel_logs").getFullList({ expand: "vehicle" }),
|
||||
]);
|
||||
return { vehicles, fuelLogs };
|
||||
}
|
||||
|
||||
/** Counts of records awaiting human verification. */
|
||||
export async function loadPendingVerification() {
|
||||
const pb = await pbAdmin();
|
||||
const [pos, dns] = await Promise.all([
|
||||
pb.collection("purchase_orders").getFullList({
|
||||
filter: "is_verified=false",
|
||||
fields: "id,purchase_order_number,supplier,total_value,site",
|
||||
}),
|
||||
pb.collection("delivery_notes").getFullList({
|
||||
filter: "is_verified=false",
|
||||
fields: "id,delivery_note_number,processing_status,date_received,site",
|
||||
}),
|
||||
]);
|
||||
return { pos, dns };
|
||||
}
|
||||
Loading…
Reference in a new issue