$ Credential Flow · Architecture
The OAuth token lifecycle, the four HTTP endpoints, and the layered protections on every write.
## TOKEN_LIFECYCLE
On its first Salesforce call since starting, the API requests an access token from Salesforce’s OAuth token endpoint using the configured Consumer Key and Secret, then caches it in memory. Every subsequent call reuses that cached token — it is not refetched on every request — until it’s expired or about to expire, at which point the API requests a fresh one before making the call. This is the actual protocol mechanic this case study exists to demonstrate: the token request, its expiry, and when to refetch, not that a Python package can be installed.
## HTTP_ENDPOINTS
| Endpoint | Behavior |
|---|---|
GET /salesforce/loan-applications | Lists existing records, queried live from Salesforce on every call. |
POST /salesforce/loan-applications | Creates a new record, stamping Submitted Date server-side and defaulting Status to Draft if omitted. |
PATCH /salesforce/loan-applications/{id} | Updates only the Status field — every other field, including the Flow-controlled Decision Date, stays untouched. |
DELETE /salesforce/loan-applications/{id} | Deletes a record — but only after checking its Status server-side (see below). |
## WRITE_PROTECTIONS
Both write endpoints apply the same layered protections used elsewhere on this site: a honeypot field, a minimum-fill-time check, per-IP rate limiting, and a profanity blocklist on the Applicant and Account name fields. Status is restricted to the settable values (Draft, Submitted, Under Review, Approved, Denied) on both create and update — Archived is reachable only by editing Salesforce directly, never through either endpoint.
## ARCHIVED_RECORD_DELETE_PROTECTION
The delete endpoint checks a record’s current Status server-side and refuses to delete it if that Status is Archived — regardless of what any caller sends, and regardless of whether the request originates from this site’s own UI or a direct API call. Archived records are the original seed data; this protection keeps them permanently intact so the live demo always has a stable baseline to show, no matter what a visitor does through the create/update/delete actions.
