Appearance
ποΈ Touli β Project Structure β
Nx monorepo Β· Next.js web client Β· Express REST API Β· shared TypeScript libraries Β· AWS CDK infrastructure
There is a separate app,
apps/mobile(Expo / React Native), documented on its own page β it shareslibs/typeswith this side of the monorepo but has its own screen/routing/lib conventions.
Contents β
- Overview
- Architecture flow
- Full folder tree
- Frontend β
apps/client - Backend β
apps/server - Shared libraries β
libs/ - Infrastructure β
libs/cdk - Path aliases
- Tech stack
Overview β
| Area | Path | What it is |
|---|---|---|
| π Frontend | apps/client | Next.js 16 App Router β SSR/SSG public site + admin dashboard |
| π₯οΈ Backend | apps/server | Express 5 REST API + PostgreSQL (Sequelize) |
| π± Mobile | apps/mobile | Expo / React Native app β see its own doc |
π¦ libs/types | shared | TypeScript interfaces, enums, DTOs, API path constants β imported by client, server, and mobile |
π¨ libs/ui | client-only | Ant Designβbased component library (atoms β molecules β organisms) |
ποΈ libs/models | server-only | Sequelize database models |
π libs/seo | client-only | Structured-data (JSON-LD) schema builders + metadata helpers |
βοΈ libs/cdk | infra | AWS CDK stacks β VPC, ECS, RDS, ECR, pipelines, WAF, CloudWatch |
Architecture flow β
mermaid
flowchart LR
U["π§ Browser"] --> C["apps/client\nNext.js Β· SSR/SSG Β· Zustand"]
C --> S["apps/server\nExpress Β· JWT Β· REST API"]
S --> DB[("PostgreSQL\nvia libs/models")]
S --> AWS["AWS S3 / SES"]
M["π± apps/mobile\nExpo"] --> S
style U fill:#fce7f3,stroke:#db2777
style C fill:#eff6ff,stroke:#2563eb
style S fill:#f0fdf4,stroke:#16a34a
style DB fill:#fef3c7,stroke:#d97706
style AWS fill:#fce7f3,stroke:#db2777
style M fill:#eff6ff,stroke:#2563eblibs/types is imported by both apps/client and apps/server (and apps/mobile) so request/response shapes can never drift between them. libs/cdk provisions the AWS infrastructure both apps deploy onto but is never imported by application code at runtime.
Full folder tree β
text
touli/
βββ apps/
β βββ client/ # Next.js 16 web app
β βββ server/ # Express 5 REST API
β βββ mobile/ # Expo app β see docs/mobile/project-structure.md
β βββ client-e2e/ # Playwright E2E (client)
β βββ server-e2e/ # Jest E2E (server API)
βββ libs/
β βββ types/ # @workspace/types β shared interfaces, enums, DTOs, API constants
β βββ ui/ # @workspace/ui β Ant Design component library (client-only)
β βββ models/ # @workspace/models β Sequelize models (server-only)
β βββ seo/ # @workspace/seo β JSON-LD schema + metadata helpers (client-only)
β βββ cdk/ # AWS CDK app β infrastructure as code (not an Nx-buildable lib)
βββ docs/ # guides/, mobile/, architecture/
βββ tools/scripts/ # Repo automation (e.g. run-mobile-expo.mjs)
βββ nx.json Β· tsconfig.base.json # Nx + path-alias config
βββ package.json # Workspace root β single yarn install for the whole repoFrontend β apps/client β
Next.js 16, App Router, Turbopack.
text
apps/client/src/
βββ app/ # App Router β route groups, layouts, pages
β βββ layout.tsx # Root layout β providers, fonts, i18n
β βββ (auth)/ # Route group β no navbar/footer
β β βββ layout.tsx
β β βββ login/page.tsx
β βββ (main)/ # Route group β Navbar + Footer shell
β β βββ page.tsx # Home page
β βββ admin/ # Admin dashboard (currently a single placeholder route)
β βββ page.tsx
βββ components/
β βββ layouts/ # navbar.tsx, footer.tsx
β βββ modals/ # modalWrapper.tsx (global portal), sampleModal.tsx, common/sortingModal.tsx
β βββ auth/ # AuthHydration.tsx
β βββ common/ # Shared micro-components
βββ store/ # Zustand β one *.store.ts per domain
β βββ auth/ Β· user/ Β· adminUsers/ Β· filter/ Β· common/
β βββ app.store.ts
βββ services/ # Axios-based API clients
β βββ httpClient.service.ts # Browser-side axios instance
β βββ httpServer.service.ts # Server-side axios instance (SSR/route handlers)
β βββ auth/ # auth.client.service.ts Β· auth.proxy.service.ts Β· auth.service.ts Β· socialAuth.client.service.ts
β βββ user/ # user.client.service.ts Β· user.server.service.ts
β βββ common/ # common.server.service.ts Β· utils.service.ts
βββ constants/ # routes, navbar/footer menu IDs, cookie keys, locale, image paths, regex
βββ data/layouts/ # NAVBAR_MENU_CONFIG, footer link/social configs (consume constants/)
βββ hooks/ # useInfiniteScroll, useIsMobileDevice, useModalScrollLock, usePageFilters, useSectionData, useTableUrlState
βββ utils/
β βββ common/ # account, date, file-extension, service-error helpers
β βββ cookies/ # client + server cookie helpers
β βββ crypto/ # cookie encryption
βββ functions/ # renderEmptyValue, toQueryString, getDashboardHref, handleDestination, persistClientAuthSession
βββ config/ # axiosInstance.config.ts
βββ providers/ # antdConfigProvider.tsx
βββ layouts/ # authLayout.tsx
βββ i18n/ # request.ts (next-intl)
βββ assets/ # icon.ts, svgIcons.tsx
βββ proxy.ts / proxy.server.ts # Next.js API-route proxying to apps/server
βββ styles/globals.cssBackend β apps/server β
Express 5, layered routes β controllers β services β dao, PostgreSQL via libs/models (Sequelize).
text
apps/server/src/
βββ main.ts # Entry point
βββ servers/http.server.ts # HTTP server bootstrap
βββ routes/ # auth Β· users Β· profile Β· parentalConsent Β· challenge Β· points Β· utils Β· routes.ts (aggregator)
βββ controllers/ # One per route file above
βββ services/ # auth Β· users Β· profile Β· parentalConsent Β· challenge Β· points Β· email Β· utils
βββ dao/ # auth Β· users Β· userRole Β· refreshToken Β· userConsent Β· challenge Β· challengeInterest Β·
β challengeSubmission Β· deedSubmission Β· giftInterest Β· pointsWallet Β· userChallenge Β· walletTransaction
βββ migrations/ # Umzug migration scripts + migrator.ts CLI
β βββ scripts/ # e.g. initial-schema, seed-roles, challenges-schema, points-schema, ...
βββ templates/ # Email templates (parental consent, consent response)
βββ common/
β βββ middleware/ # auth Β· permission Β· validation Β· rateLimit
β βββ constants/ # errors Β· status(HTTP) Β· environment Β· points
β βββ enums/ # order Β· sequelizeErrors
β βββ interfaces/ # authenticatedRequest/-User Β· error Β· status Β· email
β βββ responses/ # success.response.ts
β βββ handler/ # cb / cbError response envelope
β βββ types/
βββ config/ # app.config.ts, jwt.config.ts, sql.config.ts
βββ loaders/ # express.loader.ts, sql.loader.ts (DB connection)
βββ utils/ # aws.utils.ts (S3/SES), winston.utils.ts, error.utils.ts, http.utils.ts
βββ certificates/ # RDS TLS CA bundleShared libraries β libs/ β
libs/types β @workspace/types/* β
Imported by client, server, and mobile. Organized by kind, then by domain:
text
libs/types/src/
βββ interfaces/ auth Β· user Β· common Β· layouts Β· challenge Β· points
βββ dto/ auth Β· user Β· common Β· utils Β· onboarding Β· challenge Β· points
βββ enums/ auth Β· user Β· common Β· challenge Β· points
βββ constants/api/ common Β· utils Β· auth Β· users Β· challenge Β· points Β· api.constants.ts (base paths)
βββ responses/ login Β· logout Β· register Β· emailVerification Β· userStatslibs/ui β @workspace/ui/* (client-only) β
Ant Designβbased component library, three atomic tiers, each theme-tokenized under components/tokens/antd/:
- Atoms (26): Badge, Breadcrumb, Button, Cascader, Checkbox, Divider, Dropdown, FallbackImage, Icon, IconButton, Input, Message, PopConfirm, Progress, QRCode, Radio, Rate, Select, Skeleton, Spin, Tag, Text, TextArea, TimeStampPicker, Toggle, Tooltip
- Molecules (18): Alert, Card, Carousel, Drawer, Empty, Flex, Grid, Menu, Modal, Notification, Pagination, Popover, Result, Segmented, Steps, Tab, Tour, Upload
- Organisms (3): Form (+ FormItem, FormList), Sider, Table
Plus hooks/ (useWindowSize), icons/ (shared SVG logos), utils/.
libs/models β @workspace/models (server-only) β
text
libs/models/src/
βββ user.model.ts Β· auth.model.ts Β· userRole.model.ts Β· refreshToken.model.ts Β· userConsent.model.ts
βββ challenge.model.ts Β· challengeCategory.model.ts Β· challengeTask.model.ts Β· challengeSubmission.model.ts
βββ userChallenge.model.ts Β· userTaskProgress.model.ts
βββ challengeInterest.model.ts Β· giftInterest.model.ts
βββ deedSubmission.model.ts Β· pointsWallet.model.ts Β· walletTransaction.model.ts
βββ index.ts # Barrel exportlibs/seo β @workspace/seo (client-only) β
JSON-LD structured-data schema builders (article, breadcrumb, faq, organization, website) + metadata generators, consumed by apps/client's page components for SEO.
Infrastructure β libs/cdk β
A standalone AWS CDK app (not built through Nx's normal app/lib pipeline β it has its own package.json, cdk.json, tsconfig.json) that provisions the environment apps/server and apps/client deploy onto:
text
libs/cdk/
βββ bin/ # cdk.ts (app entry), pipeline.ts
βββ lib/
β βββ stacks/ # client Β· server Β· server-pipeline Β· pipeline Β· network Β· security Β·
β β storage Β· common-resources Β· observability Β· config
β βββ factories/ # app-factory.ts β wires stacks together per environment
βββ resources/ # Reusable constructs: acm, cloudwatch, db (RDS), ec2, ecr, ecs,
β iam, policies, s3, security-groups, ssm, vpc, waf
βββ config/ # demo / dev / staging / prod environment configs (JSON)
βββ src/interfaces/ # repo, securityGroups, serverConfig, config interfacesDeploys: VPC + security groups β RDS (Postgres) β ECR + ECS (server) β ALB + WAF β CloudWatch alarms, with separate CodePipeline stacks for client and server CI/CD.
Path aliases β
Defined once in tsconfig.base.json, available to every app/lib in the workspace.
| Alias | Resolves to | Used by |
|---|---|---|
@client/* | apps/client/src/* | Client |
@workspace/server/* | apps/server/src/* | Server |
@workspace/models / @workspace/models/* | libs/models/src/* | Server |
@workspace/types/constants/* | libs/types/src/constants/* | Client Β· Server Β· Mobile |
@workspace/types/dto/* | libs/types/src/dto/* | Client Β· Server Β· Mobile |
@workspace/types/enums/* | libs/types/src/enums/* | Client Β· Server Β· Mobile |
@workspace/types/interfaces/* | libs/types/src/interfaces/* | Client Β· Server Β· Mobile |
@workspace/types/responses (/*) | libs/types/src/responses/* | Client Β· Server |
@workspace/ui/components/{atoms,molecules,organisms}/* | libs/ui/src/components/ui-lib/antd/* | Client |
@workspace/ui/hooks/* Β· @workspace/ui/utils/* | libs/ui/src/{hooks,utils}/* | Client |
@workspace/seo (/*) | libs/seo/src/* | Client |
Mobile (apps/mobile) resolves @workspace/types/* the same way but uses its own @/lib/* / @/features/* aliases for app-local code β see mobile project structure.
Tech stack β
| Layer | Library | Version |
|---|---|---|
| Monorepo | Nx | 20.7.1 |
| Language | TypeScript | 5.8.3 (client/server) |
| Frontend framework | Next.js | 16.2.4 (Turbopack) |
| Frontend framework | React | 19.1.4 |
| UI library | Ant Design | 6.3.7 |
| Styling | Tailwind CSS | 4.2.4 |
| Client state | Zustand | 5.0.3 |
| i18n | next-intl | 4.11.0 |
| HTTP | axios | 1.15.2 |
| Backend framework | Express | 5.1.0 |
| ORM | Sequelize / sequelize-typescript | 6.37.8 / 2.1.6 |
| Database | PostgreSQL (pg) | 8.13.1 |
| Auth | Passport.js + jsonwebtoken | 0.7.0 / 9.0.2 |
| Migrations | Umzug | 3.8.3 |
| Logging | Winston | 3.17.0 |
| Cloud SDK | @aws-sdk/client-s3, client-ses | 3.980.0 |
| Validation | Zod | 4.3.5 |
| Rate limiting | express-rate-limit | 8.5.2 |
| Infra | AWS CDK | see libs/cdk/package.json |
| Testing | Jest / Playwright / Testing Library | 29.7.0 / 1.36.0 / β |
| Tooling | ESLint + Prettier, Husky, Yarn 1.22.22 | β |
Touli Β· keep this file (and docs/mobile/project-structure.md) in sync when app/lib structure changes