App Routes Reference
All routes live under src/app/. The locale prefix [locale] is always present and validated against supported locales.
Route groups
| Group | Path pattern | Purpose |
|---|---|---|
(app) | [locale]/(app)/... | Full authenticated app with drawer nav and org context |
(legal) | [locale]/(app)/(legal)/... | Static legal/info pages (no extra layout) |
event | [locale]/event/... | Post-auth event landing pages (sign-in gate, error screens) |
Page routes
Dashboard
| Route | URL example | Purpose |
|---|---|---|
[locale]/(app)/page.tsx | /en | Activity list (home). Deactivates expired activities on render. |
[locale]/(app)/orglist/page.tsx | /en/orglist | List of orgs the user belongs to. |
[locale]/(app)/e/orgchange/page.tsx | /en/e/orgchange | Switch active organization. |
Activity — view (public)
| Route | URL example | Purpose |
|---|---|---|
[locale]/(app)/v/page.tsx | /en/v | Public activity listing. |
[locale]/(app)/v/[id]/page.tsx | /en/v/abc123 | Public view of a single activity. |
Activity — edit (authenticated)
| Route | URL example | Purpose |
|---|---|---|
[locale]/(app)/e/page.tsx | /en/e | Edit landing; shows Clerk <SignIn> if unauthenticated. |
[locale]/(app)/e/new/page.tsx | /en/e/new | Create a new activity. |
[locale]/(app)/e/[id]/page.tsx | /en/e/abc123 | Edit an existing activity. |
Organization management (authenticated, org:admin)
| Route | URL example | Purpose |
|---|---|---|
[locale]/(app)/e/org/page.tsx | /en/e/org | Org settings overview. |
[locale]/(app)/e/org/new/page.tsx | /en/e/org/new | Create a new organization. |
[locale]/(app)/e/org/activitydefaults/page.tsx | /en/e/org/activitydefaults | Default values applied to new activities. |
[locale]/(app)/e/org/locales/page.tsx | /en/e/org/locales | Manage which locales the org supports. |
[locale]/(app)/e/org/contracts/page.tsx | /en/e/org/contracts | List data-processing contracts. |
[locale]/(app)/e/org/contracts/new/page.tsx | /en/e/org/contracts/new | Create a new contract. |
[locale]/(app)/e/org/partners/page.tsx | /en/e/org/partners | List data-processing partners. |
[locale]/(app)/e/org/partners/new/page.tsx | /en/e/org/partners/new | Create a new partner. |
[locale]/(app)/e/org/partners/[id]/page.tsx | /en/e/org/partners/abc123 | Edit a partner. |
Organizational units (authenticated)
| Route | URL example | Purpose |
|---|---|---|
[locale]/(app)/e/ou/new/page.tsx | /en/e/ou/new | Create a new OU. |
[locale]/(app)/e/ou/[id]/page.tsx | /en/e/ou/abc123 | View/edit an OU. |
Templates (authenticated)
| Route | URL example | Purpose |
|---|---|---|
[locale]/(app)/e/tmp/page.tsx | /en/e/tmp | List org templates. |
[locale]/(app)/e/tmp/[id]/page.tsx | /en/e/tmp/abc123 | View/edit a template. |
Legal & informational (public)
| Route | URL example | Purpose |
|---|---|---|
[locale]/(app)/(legal)/about/page.tsx | /en/about | About page. |
[locale]/(app)/(legal)/about/third-party-licenses/page.tsx | /en/about/third-party-licenses | Third-party software licenses. |
[locale]/(app)/(legal)/licenses/page.tsx | /en/licenses | App software licenses. |
[locale]/(app)/(legal)/privacy/page.tsx | /en/privacy | Privacy policy. |
[locale]/(app)/(legal)/terms/page.tsx | /en/terms | Terms of service. |
Documentation (public)
| Route | URL example | Purpose |
|---|---|---|
[locale]/(app)/docs/embedding/page.tsx | /en/docs/embedding | Guide for embedding activity declarations. |
Event / post-auth gates (public)
| Route | URL example | Purpose |
|---|---|---|
[locale]/event/sign-in/page.tsx | /en/event/sign-in | After-sign-in redirect: org:admin → /e, members → /. |
[locale]/event/sign-out/page.tsx | /en/event/sign-out | After-sign-out landing page. |
[locale]/event/language/page.tsx | /en/event/language | Language picker for users with a non-configured locale. |
[locale]/event/org-not-available/page.tsx | /en/event/org-not-available | Private org accessed while unauthenticated. |
[locale]/event/org-relay/page.tsx | /en/event/org-relay | Cross-org redirect relay. |
[locale]/event/organization-not-found/page.tsx | /en/event/organization-not-found | Org hostname does not resolve to a known org. |
[locale]/event/organization-blocked/page.tsx | /en/event/organization-blocked | Org is suspended/blocked. |
Google Forms integration
| Route | URL example | Purpose |
|---|---|---|
[locale]/gforms/page.tsx | /en/gforms | Google Forms add-on UI. Resolves user via resolveGformsUser. |
API / file-serving routes
Activity document export (Turnstile-protected)
| Route | Method | Purpose |
|---|---|---|
[locale]/[id]/route.ts | GET | Returns activity information or declaration as HTML. Query param type=activity-information|activity-declaration. |
[locale]/[id]/pdf/route.ts | GET | Returns activity information or declaration as PDF (Playwright renderer + pdf-lib). |
[locale]/(app)/ropa/route.ts | GET | Full ROPA PDF export for the org. Returns a hardcoded PDF for production/demo orgs, generates dynamically otherwise. |
[locale]/(app)/e/tmp/download/[id]/route.ts | GET | Downloads a template preview as an HTML file. |
Admin (requires x-admin-secret header)
| Route | Method | Purpose |
|---|---|---|
api/admin/cache-invalidate/route.ts | GET | Invalidates Next.js cache for a given shortName. |
api/admin/org/export/route.ts | GET | Exports org data as JSON or CSV. |
api/admin/org/import/route.ts | POST | Imports org data from JSON body or multipart/form-data ZIP. |
api/admin/recreate-org/[tenant]/route.ts | GET | Resets an org from its template. |
Google Forms API (Clerk session or ?email= dual-auth)
| Route | Method | Purpose |
|---|---|---|
api/gforms/activities/route.ts | GET | Lists activities for an org+locale. Query params: email, shortName, locale. |
api/gforms/clause/route.ts | POST | Generates a GDPR clause for an activity. Body: email, shortName, locale, activityId, formData. |
api/gforms/locales/[locale]/route.ts | GET | Returns GForms UI translations for a locale. No auth required. |
Utility
| Route | Method | Purpose |
|---|---|---|
api/locale-default/route.ts | GET | Returns the default locale for the org identified by the Host header. Used by the reverse proxy for root-path redirects. No auth. |
api/logo/[organizationId]/route.ts | GET | Serves a partner's logo PNG for the org identified by the Host header, with content-hash cache busting (?v=), ETag/304 and immutable caching. No auth — see Logo Serving. |
Webhooks
| Route | Method | Purpose |
|---|---|---|
api/webhooks/clerk/route.ts | POST | Handles Clerk webhook events: organization.created/updated/deleted, user.created/deleted. |