Skip to content
Agile Defense

Curriculum / Frontend & OSDK Developer

CAPSTONEUnit 9unit-09

Capstone: end-to-end mission app

not started~360 min
A complete, deployed, Marketplace-packaged mission command app on the Ontology, with a handoff doc covering scopes, deployment, and read-confirmation limits.

Introduction

Scenario: You are shipping the mission command app one final time end-to-end: a deployed, Marketplace-packaged OSDK React application on the supply-chain Ontology that surfaces disruption risk and lets operators act on it. Everything from the prior units now converges into one auditable delivery.

This capstone integrates every capability you have built across the course into a single, reproducibly deployed mission command app on the supply-chain Ontology. The app is a frontend-only OSDK React application: it authenticates against Foundry through an OAuth2 client registered in Developer Console, reads object sets and aggregations from the Ontology REST API v2, fires an Ontology Action behind a UI control, calls a published query, is hosted on a Foundry enrollment subdomain, and is packaged as a Marketplace product so it installs reproducibly on another enrollment. This cohort is assumed to be coding-capable (TypeScript/React plus OAuth2); the capstone is a working application, not a configuration exercise.

The discipline of this unit is honesty about what can be verified. The application itself is client-side code, and almost none of that surface is exposed by any documented Foundry READ API: the code repository contents, the generated OSDK package, the React components, the OAuth2 client configuration and its scopes, the VS Code workspace, the static build artifacts, and the Marketplace packaging are all authoring artifacts that you attest to, not values a reader can fetch. What a read client can confirm is the Ontology the app consumes - that the object types exist (Search Objects / Aggregate Objects over the Ontology REST API v2) - plus the lasting effects and outputs the app produces: the object state left behind by an applied Action, the structured value returned by Execute Query on the published query, and the existence of the hosted-application resource. Apply Action is a WRITE that requires both api:ontologies-read and api:ontologies-write scopes, so you never confirm it by reading the action; you confirm the resulting object state. The hosted-application resourceType enum used by the existence check is still unconfirmed and must be verified against the live Filesystem v2 API at build time.

By the end you will have delivered the packaged, deployed app together with a handoff document. The handoff must spell out the OAuth2 grant choice and the least-privilege scopes the app requests, how it is hosted and installed (the enrollment subdomain plus the install-time parameter mapping Marketplace performs), and - critically - the read-confirmation limits: which guarantees rest on a verifiable Ontology read versus which rest only on your attestation that the client code, configuration, and packaging are correct. This honesty about the verification boundary is itself a graded outcome of the capstone.

Capability focus: End-to-end mission app: scoped OSDK app + React SPA + REST search/aggregate + Apply Action + Execute Query + hosting + Marketplace packaging. · Artifact: A deployed, packaged mission command app with a deployment + handoff package.

Key concepts

  • Ontology SDK (OSDK): A type-safe client that gives a development environment direct access to the Foundry Ontology (TypeScript via NPM, plus Python, Java, and other languages). OSDK applications are created and managed in Developer Console, and the SDK uses a token scoped only to the ontological entities the application may access, layered on top of the signed-in user's own permissions - a least-privilege, governance-aware model.
  • Developer Console: The surface for building and managing Custom Applications and their associated authorization (OAuth) clients and generated SDKs. It is where the app's OAuth client, SDK generation and docs, resource-access restrictions, optional Foundry web hosting, and optional code-repository integration are configured. These configuration internals are authoring state and are not exposed by a documented READ API.
  • Ontology REST API v2 (Search Objects / Aggregate Objects): Read-only Ontology operations the app uses to surface data. Search Objects (POST /api/v2/ontologies/{ontology}/objects/{objectType}/search) filters objects by a query body; Aggregate Objects (POST .../aggregate) computes count/sum/avg/min/max with optional where filters and grouping. Both require only the api:ontologies-read OAuth2 scope.
  • Apply Action vs. Execute Query: Apply Action is a WRITE that modifies object/link state and requires BOTH api:ontologies-read and api:ontologies-write scopes - an applied Action is therefore confirmed read-side via the resulting object state, never by reading the action itself. Execute Query (POST /api/v2/ontologies/{ontology}/queries/{queryApiName}/execute) runs the latest published version of a query and returns a value; it requires only api:ontologies-read.
  • OAuth2 grant types and least-privilege scoping: Foundry third-party apps use the Authorization Code Grant (acts on behalf of a signed-in Foundry user via redirect; offline_access yields a refresh token) or the Client Credentials Grant (a non-interactive service user). Scopes are space-separated; a read-only mission view needs only api:ontologies-read, while the Apply Action path additionally needs api:ontologies-write. Requesting only what each flow needs is the security posture the handoff must document.
  • Foundry web hosting and Marketplace packaging: Foundry web hosting serves frontend-only OSDK apps as static assets on an enrollment subdomain (no server, similar to GitHub Pages); you zip the dist/ build and deploy via Developer Console or the @osdk/cli. The Developer Console-to-Marketplace integration packages the app with its metadata, OAuth client spec, website assets, and content security policies, and on install auto-maps environment-specific values (Foundry URL, OAuth client ID, OAuth redirect URL, Ontology RID, Ontology API name). Production/Singleton products are the recommended approach for shipping deployed websites.
  • Read-confirmation boundary: The capstone's verifiable surface is the Ontology the app consumes plus the durable effects it produces - object types existing, aggregations reproducing a headline metric, the object state an applied Action leaves behind, the Execute Query value, and the existence of the hosted-application resource. The client code, generated package, React UI, OAuth client config, VS Code workspace, build artifacts, and Marketplace packaging are attested, not READ-API-confirmable.

Companion video

End-to-end mission app walkthrough (placeholder) · open on YouTube

Hands-on activity

each step validates · the unit completes when all steps pass
  1. 1

    Confirm the full Ontology backbone the app consumes

    Confirm the full Ontology backbone the capstone app consumes before trusting any of its views. Using a read client with the api:ontologies-read scope, list the Ontology's object types and verify that all five supply-chain types the app depends on - Supplier, PurchaseOrder, Shipment, InventoryItem, and DisruptionEvent - exist and each carries a primary key. This is the one part of the app's data contract a reader can directly verify: the object types are exposed by the Ontology REST API v2, whereas the OSDK package the app generates against them, and the React components that render them, are client-side artifacts you attest to rather than fetch. If any type is missing or unkeyed, the rest of the capstone's reads cannot be relied on.

    not startedinstance check

    Confirms all five supply-chain object types exist with primary keys (the composite backbone).

  2. 2

    Reproduce the app's headline metric

    Reproduce the app's headline metric from the Ontology itself, independent of the rendered dashboard. The mission dashboard shows a 'total exposure' KPI tile; confirm it with a read-only Aggregate Objects call (POST .../objects/InventoryItem/aggregate) computing the sum of InventoryItem.exposureUsd, which must equal the expected total. Because Aggregate Objects needs only api:ontologies-read, this verification mirrors exactly what the app's read path does. Note the boundary: the aggregate confirms the number the tile should display, not that the React tile actually renders it correctly - the rendered UI is client-side code you attest to, while the aggregation is the read-confirmable ground truth behind it.

    not startedinstance check

    Confirms the dashboard tile total exposure reproduces via a sum aggregation.

  3. 3

    Prove the app's action write landed

    Prove the app's Action write actually landed by inspecting durable object state. The app fires an Ontology Action (assigning an owner and triaging a disruption) from a UI control, but Apply Action is a WRITE that requires both api:ontologies-read and api:ontologies-write scopes, so there is no documented READ API that confirms the apply call itself. Instead, read DisruptionEvent objects and confirm at least one triaged event - a non-empty owner and a status in {assigned, resolved}. That surviving object state is the only read-confirmable evidence that the Apply Action path works end-to-end; the button wiring and the write request are client code and configuration you attest to, while the resulting state is what a reader can verify.

    not startedinstance check

    Confirms a triaged DisruptionEvent (owner + status) via object state — the app's action write landed.

  4. 4

    Run the app's published query

    Run the app's published query and confirm its result is schema-valid. Call Execute Query (POST /api/v2/ontologies/{ontology}/queries/recommendMitigation/execute) with the expected parameters (disruptionId: "DISR-1"); it runs the latest published version and returns a value object that must contain the expected keys (recommendation, rationale, confidence). Execute Query needs only api:ontologies-read and exposes the query's output, not its internals - you confirm the published function's contract by its returned value, with no introspection into the function's implementation. This verifies the query path the app calls; the panel that displays the result remains client-side code you attest to.

    not startedinstance check

    Executes the published recommendMitigation function and confirms a schema-valid result.

  5. 5

    Assemble the deployment + handoff package

    Assemble the deployment and handoff package - the part of the capstone that is honestly self-attested because it lives outside the READ-API surface. Deliver the Marketplace-packaged app (metadata, OAuth client spec, website assets, content security policies) and a handoff document that records: the OAuth2 grant choice and the least-privilege scopes the app requests (api:ontologies-read for the read and query paths, plus api:ontologies-write for the Apply Action path - nothing broader); how the app is hosted on its enrollment subdomain and how Marketplace auto-maps install-time parameters (Foundry URL, OAuth client ID, OAuth redirect URL, Ontology RID, Ontology API name) on a destination enrollment; and the read-confirmation limits themselves - which guarantees rest on a verifiable Ontology read (object types, the exposure aggregate, the triaged object state, the Execute Query value) versus which rest only on your attestation (repository contents, the generated OSDK package, React components, OAuth client configuration, the VS Code workspace, build artifacts, and Marketplace packaging). The packaging and the document are authoring artifacts that no documented Foundry READ API exposes, so a reviewer judges them directly rather than via a check.

    not startedself-attested

    Self-attested: the Marketplace-packaged app plus a handoff doc (OAuth scopes/grant, hosting, read-confirmation limits).