---
title: "References Flow (Stateless)"
slug: references-flow
section: Portals
status: stable
description: "The Applicant Portal references flow under the target stateless architecture: the Globus Hub is the sole source of truth for all reference data, and the Applicant Portal is a pure presentation layer and proxy — it resolves templates, for…"
last-updated: 2026-06-19
---

# References Flow (Stateless)

# References Flow (Stateless)

The Applicant Portal references flow under the target stateless architecture: the Globus Hub is the sole source of truth for all reference data, and the Applicant Portal is a pure presentation layer and proxy — it resolves templates, forwards referee details, and reads step status at render time, never persisting reference templates, mappings, or submissions of its own.

See also: Portal Overview & Boundaries and Integration Contract .

## Stateless Model

The legacy implementation mirrored Globus-owned reference data into the Portal's own PostgreSQL tables (templates, template-to-step mappings, and submissions). Under the stateless model the Portal holds no reference state: every read is resolved from Globus at render time, and every write is proxied straight through to Globus.

> **Grounding correction — verify against Hub source, not the audit note**
>
> The originating audit ticket cited POST /api/references/receive for submission initiation. That route does not exist in the Hub (Alliance-Strategies/BackOfficePrototype). The real create-and-invite route is POST /api/reference-submissions. Likewise there is no inbound SendGrid webhook on the Hub, and the delivery-ack route is POST /api/reference-submissions/:id/dispatch-log with no /admin prefix. Endpoints on this page are taken from the Hub development branch (server/routes/referenceTemplates.ts, server/routes/referenceSubmissions.ts).

## Ownership Boundaries

| Concern | Globus Hub (owns) | Applicant Portal (proxy) |
| --- | --- | --- |
| | | |

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

## Flows

### Template Resolution

At render time the Portal proxies GET /api/portal/reference-templates/resolve to obtain the active template(s) for the applicant's program and reference type. No local persistence; the previous upsertReferenceTemplateFromGlobus mirror is removed.

### Submission Initiation

When an applicant supplies referee details, the Portal proxies them to Globus via POST /api/reference-submissions (create + invite). Globus creates the submission, issues the referee token, and triggers outreach. No reference_submissions row is created in the Portal.

### Referee Token Flow

The referee opens the emailed link. The Portal proxies GET /api/portal/reference-submissions/lookup (Portal key + referee token) to load the submission and template, and POST /api/portal/reference-submissions/respond to submit the answers. Globus owns the token, the state machine, and completion; the Portal proxies both calls via the Globus SDK with no local state.

### Step Progress

Reference step status (requested / submitted / approved) is read from the Globus step-access snapshot via GET /api/portal/applications/:applicationId/step-access. No local sync of submission status is required or performed.

### Delivery Acks (n8n)

SendGrid dispatch of referee emails is owned by the n8n [Globus] Handler: Reference Domain workflow. Delivery acknowledgements return to the Hub via POST /api/reference-submissions/:id/dispatch-log — a callback, not an inbound ESP webhook. The Portal is not involved in dispatch or acks.

## Reference-Facing Pages

### ReferenceRespondPage (token, current)

The current referee experience. Token-based: it calls GET /api/portal/reference-submissions/lookup on load and POST /api/portal/reference-submissions/respond on submit. Fully stateless — all state lives on Globus, keyed by the referee token.

### ReferenceFormPage (legacy)

The legacy path keyed by applicationId / referenceNumber rather than a referee token. It is the surface most coupled to the deprecated local tables and is the primary candidate for removal once the token flow is the sole entry point.

## Endpoint Contract

Portal-proxied endpoints (applicant / referee facing). Portal-key auth is the server-to-server integrations.portal scope; the referee-token routes require the token in addition.

Hub-side initiation, outreach, and staff authoring routes. The create / remind / dispatch-log writes are intentionally portal-reachable under a portal.read scope with no requirePermission gate (there is deliberately no reference.* permission key) — do not "harden" these without an owner-scoped RBAC change.

## Deprecated Local State

These Applicant Portal tables are deprecated under the stateless model and are flagged for removal. Globus Hub is the sole source of truth for the data they mirrored.

| Table | Why deprecated |
| --- | --- |
| table | note |

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

Code paths in the Applicant Portal that still write to the deprecated tables (to be removed):

## Follow-Up Engineering

> **Removal is owning-repo work**
>
> Identifying and flagging the deprecated tables and code paths is documentation work and lives here. The actual removal of the local tables and the listed code paths is engineering work on the Applicant Portal repo (source branch decouplewebhooks) and must be filed as a follow-up ticket against that repo — not as a task on this docs-site repo.
