---
title: "Globus Resource Library"
slug: resource-library
section: Applicant Journey
status: draft
description: "The Globus Resource Library is the source of truth behind the Program Resources surface of the Applicant Portal — the program-managed catalog of handbooks, orientation videos, insurance information, and placement packs that programs publ…"
last-updated: 2026-06-19
---

# Globus Resource Library

# Globus Resource Library — Engineering Spec

The Globus Resource Library is the source of truth behind the Program Resources surface of the Applicant Portal — the program-managed catalog of handbooks, orientation videos, insurance information, and placement packs that programs publish to applicants. The surface page establishes what the surface shows and that the library is its source of truth; this page is the deeper engineering contract: the data model, the admin authoring surface programs use to publish, versioning, and how every resource is keyed to Program, Season, and Lifecycle Stage.

> **Architecture Principle — programs publish, the portal renders**
>
> The Resource Library is a Globus-owned catalog. Program admins author and publish resources and bind them to a program, season, and (optionally) a lifecycle stage. Globus resolves the applicable set per applicant at request time; the portal renders that set faithfully. The portal never hosts, versions, or curates resource content, and never holds a hard-coded list of which resources belong to which program or stage. Any such list baked into portal code is a bug, not a contract.

## Architecture Principle

The library exists so that content changes without portal deploys. A program admin can publish a new handbook, swap an orientation video, or unlock a placement pack by editing the catalog — not by shipping portal code. Three properties follow:

- Globus-owned catalog. Resources, their versions, and their bindings all live server-side. The portal queries for the resolved set per applicant.

- Bindings, not hard-coded lists. Which resources an applicant sees is the result of matching bindings against the applicant’s program, season, and stage — never a list in portal code.

- Immutable artifacts, mutable pointers. Published versions never change; publishing a new version moves the live pointer, preserving a complete, auditable history.

## Data Model

Three tables carry the library. A resource is the stable catalog entry (identity + type); a resource_version is an immutable published artifact under that entry; a resource_binding keys the entry to a program, season, and lifecycle stage. Resolution always reads a resource’s current published version, so bindings never need to be re-pointed when content changes.

### resource — the catalog entry

### resource_version — the published artifact

### resource_binding — the keying

> **Bindings point at the resource, not a version**
>
> A binding references the resourceId, never a specific versionId. That is deliberate: publishing a new version updates what every existing binding serves, without anyone having to touch the bindings. The version pointer is resolved at read time.

### How the tables relate

- One resource has many resource_version rows; at most one is in the published state.

- One resource has many resource_binding rows — the same handbook can be bound to several seasons or stages.

- Resolution joins bindings &rarr; resource &rarr; current published version, so a single publish fans out to every place that resource is surfaced.

## Program / Season / Lifecycle-Stage Keying

Every binding answers three questions: which program, which season, and at which stage a resource appears. Program is required; season and stage are optional, and leaving them null widens the binding’s reach.

### The Three Binding Axes

### Resolution Order & Specificity

At request time Globus collects every binding that matches the applicant’s context — a resource surfaces if its binding is satisfied. Matching is permissive on the null axes:

- Program must match exactly. A binding only resolves for its own program.

- Null season matches any season; a set season matches only that season.

- Null stage matches any stage; a set stage resolves only once the applicant has reached (or passed) it. Stage-gated resources are hidden until then.

- The resolved set is the union of all matching bindings, de-duplicated by resource so the same handbook bound at both program- and season-level appears once.

> **Stage gating is evaluated by Globus, never by the portal**
>
> Whether a placement pack is unlocked is a Globus decision keyed off the applicant’s current lifecycle stage. The portal must not hold its own “show after placement” logic — it renders only what resolution returns. See the Applicant Lifecycle for the canonical stage set.

## Admin Authoring Surface

Programs publish resources through an admin authoring surface in the sponsor tooling — a catalog manager where staff create a resource, upload (or embed) its artifact, set its bindings, and publish. This is the only place resource content enters the system; the portal is strictly downstream. Before publishing, staff can verify their bindings with the Resolution Preview — a live view of exactly which resources a given program/season/stage applicant would see.

### Who Authors

Program administrators and authorized sponsor staff author resources, gated by the standard RBAC model — see Roles & Permissions . The acting user is resolved via resolveActor and stamped onto every create/publish for the audit trail. Applicants have no write access to the library; their view is read-only consumption.

### The Publish Flow

- Create the resource. Pick a type and title — this mints the stable catalog entry that bindings and versions hang off.

- Add a version. Upload the artifact (handbook PDF, video file) through the Globus-signed upload flow, or supply an embed URL for externally-hosted video. This creates a draft version.

- Bind it. Add one or more bindings — choose program (required), season (optional), and lifecycle stage (optional) for each.

- Publish. Transition the draft to published. Any previously-published version becomes superseded, and the resource immediately resolves to applicants whose context matches a binding.

### Resource Version States

| State | Meaning |
| --- | --- |
| | meaning |

_(row above is a template, repeated for each data row)_

## Resolution Preview

The authoring surface answers “what did I publish?”; the resolution preview answers “what will an applicant actually see?”. It is a staff-only tool in the catalog manager where a program admin enters a hypothetical applicant context — program, season, and lifecycle stage — and Globus runs the exact same resolution the portal consumes, returning the resolved resource set together with the bindings and versions that produced it. It closes the loop between authoring and consumption and lets staff catch mis-bound, unpublished, or stage-gated resources before publish, rather than discovering them through an applicant report.

> **Same resolver, preview mode**
>
> The preview does not re-implement matching. It calls the one resolution path described in the Resolution & Access Contract with a supplied context instead of a live applicant’s, so what the preview shows is what the portal would render. If the two ever diverge, the preview is the bug.

### Inputs

The admin supplies a synthetic applicant context. The axes mirror the three binding axes exactly, and the null-vs-set semantics match resolution: leaving an optional axis empty previews the wider, less-specific set.

| Input | Required | Notes |
| --- | --- | --- |
| | required | notes |

_(row above is a template, repeated for each data row)_

### Output

The preview returns the resolved set plus the provenance behind it, so an admin can see not just what resolves but why — which binding matched and which version is live.

| Returned | Notes |
| --- | --- |
| field | notes |

_(row above is a template, repeated for each data row)_

### Preview Behavior & Guarantees

- Read-only, no side effects. The preview resolves and reports; it never publishes, binds, or mutates. It is safe to run repeatedly while tuning bindings.

- Drafts are excluded. The preview shows what applicants would see today — only published versions resolve. A resource whose only version is still a draft surfaces as “bound, nothing to resolve,” flagging an incomplete publish.

- Stage gating is simulated, not bypassed. Setting a later stage reveals more resources exactly as advancing a real applicant would; the preview never shows stage-gated content the chosen stage has not yet reached, except in the explicit “stage-gated-but-hidden” diagnostic line.

- Archived resources and retracted versions are omitted, matching live resolution, so the preview never overstates what an applicant gets.

- It is a diagnostic, not a new contract. The preview adds no resolution rules of its own — it is a window onto the existing resolver, so it stays correct for free as resolution evolves.

## Versioning

### Immutable Versions, Mutable Pointer

A published version is never edited in place. To change a handbook, an admin publishes a new version; the old one is marked superseded and retained. The “live” artifact is simply whichever version is currently in the published state. This gives a complete, auditable lineage and a clean rollback story: re-publishing an older version is a forward transition, not a destructive edit.

### Versioning Rules

- One published version per resource. Publishing supersedes the prior live version atomically; there is never a window with two live versions.

- Version numbers are monotonic and never reused per resource, even across retraction and re-publish.

- Bindings are version-agnostic. Because they point at the resource, a new publish propagates to every binding automatically.

- Retraction leaves a gap. A retracted resource with no published version stops resolving entirely until a new version is published — the surface shows nothing rather than stale content.

## Resolution & Access Contract

This is the division of responsibility between Globus and the portal for the Program Resources surface. Globus resolves the set and mints access; the portal renders. File access always flows through Globus-signed, short-lived proxy URLs — the portal never receives a raw storage key, exactly as with My Documents. The wire-level shape of this contract — the exact endpoints, payloads, auth, and error responses — is enumerated in the HTTP Endpoint Contract below.

| Globus supplies | Portal renders / is responsible for |
| --- | --- |
| globus | portal |

_(row above is a template, repeated for each data row)_

## HTTP Endpoint Contract

The wire-level API behind the data model and resolution contract above. Two distinct surfaces: the admin authoring endpoints programs use to create, version, bind, publish, and retract resources, and the applicant resolution endpoints the portal calls to read the resolved set and mint access. Admin endpoints are gated by the standard RBAC resource.manage permission and stamp the resolved actor onto every write; applicant endpoints are identity-scoped and read-only. Artifact upload and access mirror the Document Storage signed-URL handshake — clients never stream bytes through Globus and never see a storage key.

> **Contract, not implementation**
>
> These endpoints define the contract engineers code against. The binary-handling routes (signed upload/access URLs over object storage) live in the GLOBUS Hub repo, exactly as the document binary routes do; this docs site owns the wire shape.

### Admin Authoring Endpoints

The authoring surface walks the publish flow with these endpoints: create the resource, add a version (uploaded artifact or embed), bind it, then publish. Bindings and archival are managed independently of versions because bindings point at the resource, not a version.

### Applicant Resolution Endpoints

The portal never asks for specific resources — it sends only the applicant identity and renders whatever resolves. The list endpoint returns metadata only; a separate per-render call mints the short-lived access URL so the authorization check and audit record happen on every read.

### Request & Response Shapes

The resolution response carries everything the portal needs to render a card and pick a viewer, and nothing more — no fileKey, no durable URL. Access URLs are requested per render against the resource id.

GET /api/applicant/resources
X-Applicant-User-Id:

200 OK
resources

POST /api/applicant/resources/:id/access
X-Applicant-User-Id:

200 OK (uploaded artifact)
render / download / inline / accessUrl / https://storage.googleapis.com/...signed... / fileName / camp-handbook-2026.pdf / expiresAt / 2026-06-24T18:05:00Z

200 OK (externally-hosted video)
render / embed / embedUrl / https://player.example.com/v/abc123

POST /api/admin/resources/:id/versions/:versionId/publish
(RBAC: resource.manage)

200 OK
resourceId / uuid / versionId / versionNumber / state / published / publishedAt / 2026-06-24T17:40:00Z / supersededVersionId

### Proxied Access-URL Handshake

Reading a resource artifact is a two-step handshake mirroring the Document Storage proxied download — the portal never holds a durable link to a file.

- The portal renders the resolved set from GET /api/applicant/resources — titles, types, descriptions only. No URL is present in that list response, so nothing durable can be cached or leaked.

- When the applicant opens or downloads a resource, the portal calls POST /api/applicant/resources/:id/access. Globus re-resolves the caller against that resource’s bindings (a stage-gated or archived resource is refused even if its id is known), then mints a fresh signed GET URL for the resource’s current published version — or returns the embedUrl for externally-hosted video.

- The client uses the returned accessUrl (download or inline render) or loads the embedUrl in a player. The URL expires in minutes and cannot be reused once expired; the next render re-requests it. Each call is logged as a read.

> **Access is re-authorized per request, not at list time**
>
> Resolving into the list is not a durable grant. Because the access URL is minted per request after re-checking bindings, a resource that is retracted, archived, or stage-locked between the list call and the access call is refused at access time. A request for a resource the caller does not resolve to returns 404, never 403 — existence is not leaked, exactly as with proxied document downloads.

### Error Responses

All endpoints use the platform’s standard error envelope. The notable cases:

| Status | When |
| --- | --- |
| | when |

_(row above is a template, repeated for each data row)_

## Audit & Governance

Every mutating action on the library — create resource, add version, bind, publish, supersede, retract, archive — is recorded through the standard audit layer with a dotted, scoped vocabulary (e.g. resource.published, resource.binding_added, resource.retracted), keyed to the actor resolved at write time. Combined with immutable versions, this gives a full answer to “who published what to which applicants, and when.” Audit writes are best-effort and never fail the underlying mutation. The real-time stream is visible on the Audit Console .

## Related Pages

);
}

function EndpointTable(: )

function FieldTable(: ) {
return (

| Field | Type | Notes |
| --- | --- | --- |
| field | type | notes |

_(row above is a template, repeated for each data row)_
