Skip to main content

TypeScript Advanced Data Operations

These patterns use the Node SQL runtime and the generated School Management fixture. The browser TFP client deliberately exposes a narrower transport profile.

Search page with rows and two facets​

One Request can return matching entities plus independently named navigation sidecars:

const rows = await Q.schools()
.withNameContaining("Primary")
.selectSchoolTypeWith(
Q.schoolTypesWithMinimalFields().selectCode().selectName())
.selectPlatformWith(Q.platformsWithMinimalFields().selectName())
.facetBySchoolTypeAs(
"schoolTypes",
Q.schoolTypesWithMinimalFields()
.withCodeIn("PRIMARY", "SECONDARY")
.selectCode().selectName().countSchoolsAs("schoolCount"),
true,
)
.facetByPlatformAs(
"platforms",
Q.platformsWithMinimalFields().selectName().countSchoolsAs("schoolCount"),
false,
)
.orderByIdDescending()
.limit(50)
.comment("Search schools with dashboard facets")
.purpose("Render the authorized operations dashboard")
.executeForList(context);

const typeBuckets = rows.facet("schoolTypes");
const platformBuckets = rows.facet("platforms");

The first Facet keeps allowed zero-count SchoolTypes. The second returns only Platform values represented by the current match set. Both remain separate from the primary rows collection.

Deep graph and per-parent Top-N​

Every relation level receives a typed child Request. The child limit is applied per Platform, not to the combined School result:

const platforms = await Q.platforms()
.selectName()
.selectSchoolListWith(
Q.schools()
.selectName()
.selectSchoolTypeWith(
Q.schoolTypesWithMinimalFields().selectCode().selectName())
.orderByStudentCapacityDescending()
.limit(3),
)
.comment("Load each platform and its three largest schools")
.purpose("Render the authorized platform capacity review")
.executeForList(context);

Keep this on the Node SQL profile and verify the provider trace contains the partition/window Top-N plan when qualifying a database.

Grouped and relation analytics​

Grouped analytics return record-shaped rows. Relation analytics retain typed parents and add named, read-only metrics:

const distribution = await Q.schools()
.groupBySchoolType()
.countAs("schoolCount")
.sumStudentCapacityAs("capacityTotal")
.avgStudentCapacityAs("capacityAverage")
.comment("Aggregate school capacity by type")
.purpose("Build the authorized capacity report")
.executeForRows(context);

const cards = await Q.schoolTypesWithMinimalFields()
.selectCode().selectName()
.countSchoolsAs("schoolCount")
.sumStudentCapacityOfSchoolsAs("capacityTotal", Q.schools())
.comment("Calculate type-level school metrics")
.purpose("Render the authorized type cards")
.executeForList(context);

Do not update an entity through an aggregate alias. distribution records and the named metrics on cards are projections of database calculations.

Audited read-modify-save​

let school = await Q.schools()
.withIdIs(schoolId)
.selectPlatformWith(Q.platformsWithMinimalFields().selectName())
.selectSchoolTypeWith(Q.schoolTypesWithMinimalFields().selectCode())
.comment("Load the complete school for capacity approval")
.purpose("Apply an authorized capacity revision")
.executeForOne(context);

if (!school) throw new Error("school not found");
school.updateStudentCapacity(newCapacity);
school = await school.auditAs("Approve revised student capacity").save(context);

Load every Checker/Fix input and retain the returned entity so subsequent mutations use the authoritative optimistic version.