01 · Translink, Brisbane · PurpleTalk
Translink smart-card customer portal
Customer portal for a public-transit smart-card system, on Next.js 16, GraphQL and a headless CMS.
Context
A customer portal for the Translink public-transit smart-card system in Brisbane. Customers activate cards, manage journeys, pay and review transaction history. Data comes from third-party transit APIs. Non-technical teams manage multilingual content themselves.
My role
I architected the frontend: the App Router structure, the GraphQL data layer, the design system, and the test and CI/CD pipeline.
Architecture
Architecture, left to right. Client: Customer → Frontend: Next.js 16 · App Router → Data: GraphQL layer, Payload CMS 3 → Sources: Third-party transit APIs, PostgreSQL.
Key decisions
- 01
ISR with Server Components
Pages render on the server and are cached with ISR. [WHY: ask Saif — why ISR over full SSR?]
- 02
GraphQL codegen over third-party APIs
Types are generated from the GraphQL schema, so the shape of third-party transit data is checked at compile time instead of at runtime.
- 03
Payload CMS with live preview
FAQs, localisation, SEO, themes and feature flags live in CMS collections. Non-technical teams manage multilingual content across environments without a deploy.
Results
- Shipped card activation, journeys, payments and transaction history in one portal.
- Non-technical teams manage multilingual content themselves, with live preview.
- AI-assisted development with Copilot, under strict review of generated code, let a lean team meet accelerated timelines.
Stack
- Next.js 16
- React 19
- React Server Components
- GraphQL (Apollo Client + codegen)
- Payload CMS 3
- PostgreSQL
- Radix UI
- Shadcn/UI
- Tailwind
- next-intl
- Sentry
- Cypress
- Storybook
- Chromatic
- Docker
- Bitbucket Pipelines
- AWS
- Nx