Skip to content

Public patient acceptance

The public view of a budget that the patient opens from the link they receive by email or messaging. No app session is required; the page authenticates via a token + a second-factor numeric code per ADR 0006. From here the patient can review the budget, download the PDF, and accept or reject it.

This screen is for the patient, not for clinic staff. We document it here so the front desk knows what the patient sees when the link is forwarded to them.

At a glance

  • Two-factor. The patient enters the numeric code the clinic provided (you configure it from the budget detail under Set public code). POST /verify is rate-limited and, on success, sets an HttpOnly session cookie scoped to /api/v1/public/budgets/{token}. The cookie cannot unlock a different budget.
  • Idempotent first view. The first time the patient opens the page (after verifying) we publish budget.viewed with a timestamp. Reopening does not emit more events.
  • Patient actions. Accept and Reject are public actions: they create the signature record and publish budget.accepted / budget.rejected. Acceptance generates the signed PDF and stores its SHA-256 as a tamper-evident fingerprint.
  • Signed PDF. After acceptance, Download signed PDF calls GET /pdf/signed with the cookie. Capped at 10 downloads per minute per token; each hit is logged in BudgetAccessLog.

What the patient sees

  1. A welcome screen with the clinic name and a code field.
  2. After verifying: header with clinic + patient, line items with totals, validity, and assigned professional.
  3. Accept and Reject buttons (Reject asks for a reason).
  4. Download PDF of the budget.

How to help a patient who is stuck

Clinic-side actions.

  • Resend link from the detail: Resend. Publishes budget.reminder_sent.
  • Change or generate a new public code from Set public code.
  • Unlock after too many failed attempts — endpoint POST /unlock-public (button on the detail when a lockout is active).

Permissions

This is a public screen: no DentalPin permissions are tied to it. The clinic-side actions that support it require budget.write in the clinic (send, resend, set/change code, unlock).

Troubleshooting

  • "Wrong code" repeatedly. The patient is mistyping the code; after a few attempts the link is temporarily locked. Unlock it from the detail.
  • Patient accepts but no signed PDF. The signed PDF is generated on accept; ask them to refresh after a few seconds. If it persists, check BudgetAccessLog for errors.
  • Session expired. The cookie is per-token and short-lived. If the patient closes the browser they will have to re-enter the code.