fix(api): use admin app URL for teacher auto-enroll email links (#771)
* fix(api): use admin app URL for teacher auto-enroll links Teacher payment-request emails now build course and grant-access URLs with getAppBaseUrl() instead of getDashboardBaseUrl(org), so links point at app.classroomio.com rather than a custom or tenant domain. Document the teacher vs student email link rule in AGENTS.md. Co-authored-by: Rotimi Best <[email protected]> * docs: surface email link URL rules where emails are wired Document getAppBaseUrl vs getDashboardBaseUrl in dashboard-url.ts, packages/email/README.md, enqueueTransactionalEmail JSDoc, and AGENTS.md so staff vs learner hosts are discoverable when building email links. Co-authored-by: Rotimi Best <[email protected]> --------- Co-authored-by: Cursor Agent <[email protected]> Co-authored-by: Rotimi Best <[email protected]>
This commit is contained in:
co-authored by
Rotimi Best
Cursor Agent
parent
e09b3caa8a
commit
0f23453f91
@@ -2,6 +2,21 @@ import { TENANT_ROOT_DOMAIN, BRAND_ROOT_DOMAIN } from '@cio/utils/constants/doma
|
||||
|
||||
import { env } from './env';
|
||||
|
||||
/**
|
||||
* Dashboard host helpers for links embedded in emails and other outbound URLs.
|
||||
*
|
||||
* Email templates only receive pre-built URLs in their `fields` — callers in
|
||||
* `apps/api` (or other services) choose the host here before enqueueing mail.
|
||||
*
|
||||
* - **Student/learner links** (course enroll, audience invites, login):
|
||||
* `getDashboardBaseUrl(org)` — org custom domain, tenant subdomain, or fallback.
|
||||
* - **Teacher/tutor/admin dashboard actions** (course management, grading, team
|
||||
* invites, auto-enroll): `getAppBaseUrl()` — admin app (`app.classroomio.com`
|
||||
* in cloud). Do not pass org `customDomain` or tenant `siteName`.
|
||||
*
|
||||
* See `packages/email/README.md` and `AGENTS.md` § Email link URLs.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Minimal org shape consumed by `getDashboardBaseUrl`. Accepts the three
|
||||
* fields that decide which host the org's URLs live on. All optional so
|
||||
@@ -14,8 +29,10 @@ export type DashboardOrg = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the base URL for the dashboard app, used for invite links, login
|
||||
* URLs, course URLs, and email-embedded links.
|
||||
* Returns the learner-facing dashboard base URL for an org.
|
||||
*
|
||||
* Use for **student/learner email links** (course enroll, audience invites,
|
||||
* login) so links land on the org's public site.
|
||||
*
|
||||
* Resolution order (highest precedence first):
|
||||
* 1. Org's verified `customDomain` → `https://<customDomain>`
|
||||
@@ -26,6 +43,8 @@ export type DashboardOrg = {
|
||||
*
|
||||
* `customDomain` wins over `DASHBOARD_ORIGIN` because per-org BYOD must
|
||||
* override the platform-wide self-hosted dashboard host for that org's URLs.
|
||||
*
|
||||
* For teacher/tutor/admin dashboard actions in email, use `getAppBaseUrl()`.
|
||||
*/
|
||||
export function getDashboardBaseUrl(org?: DashboardOrg): string {
|
||||
if (org?.customDomain && org.isCustomDomainVerified) {
|
||||
@@ -49,7 +68,12 @@ export function getDashboardBaseUrl(org?: DashboardOrg): string {
|
||||
|
||||
/**
|
||||
* Returns the admin dashboard origin (`app.classroomio.com` in cloud).
|
||||
* Use for team-member invite links (admin/tutor) — not student-facing URLs.
|
||||
*
|
||||
* Use for **teacher/tutor/admin email links** — course management, grading,
|
||||
* team invites, auto-enroll, and any other staff dashboard action. Staff sign
|
||||
* in on the admin app, not the org public site.
|
||||
*
|
||||
* Do not use for student/learner-facing links; use `getDashboardBaseUrl(org)`.
|
||||
*/
|
||||
export function getAppBaseUrl(): string {
|
||||
return getDashboardBaseUrl();
|
||||
|
||||
Reference in New Issue
Block a user