Codebase tour
A walk through the three main repos, so you know where a change belongs before you open a file. The supporting repos have their own repo pages.
How this page was verified
Read on 2026-09-15 from the backend src/ module tree and the two frontends' App Router trees. Paths are repo-relative.
Backend — def-exsport-backend
NestJS 10. Entry is src/main.ts → src/app.module.ts. Each business area is a module folder shaped as <domain>/<domain>.module.ts with resolvers/, services/, models/ (TypeORM entities) and dto/, and often controllers/ for REST.
| Module | Owns |
|---|---|
catalogs | products, articles (variants), heads/types/subtypes, categories, brands, series, collaborations, tags — and the WmsService for stock |
users | members, member addresses, the cart, stores, reference locations |
orders | orders, order items, order status, the payment-expiry cron |
payments | DOKU client and its webhook (REST only) |
deliveries | Biteship client and its webhook (REST only) |
promotions | vouchers, discounts, flash sales |
journals | blog content |
admins | admin users, roles, menus (RBAC), and the homepage / banners / CMS content |
public, storages, smtp, health, events, database, utils | file serving, S3/local storage, mail, liveness, domain events, DB config, helpers |
Three facts set the shape of the whole backend:
- GraphQL is code-first.
GraphQLModule.forRootusesautoSchemaFile: true, so the schema is generated at boot from decorators. There is noschema.gqlto read — boot the app to see the SDL. Only some modules are in the GraphQLinclude: admins, catalogs, users, orders, promotions, journals.deliveries,payments,public,health,storagesare REST-only. - The schema is the entities. TypeORM runs
synchronize: true; there is no migrations folder and no seed scripts. "Seeding" is a few REST endpoints (POST admins/seed-settings,POST vouchers/seed-voucher-types, …). - Two auth realms. Admin resolvers stack
@UseGuards(JwtAuthGuard, LastActivityGuard, RoleAbilityGuard); member resolvers useJwtMemberAuthGuard. There is no global guard. See API and auth.
Storefront GraphQL operations are prefixed front*; admin/CMS operations are plain. Create/update with a file upload is a REST controller (multipart), for example catalogs/products.
Storefront — def-exsport-frontend-storefront
Next.js 15 App Router under src/app/, path alias @/* → ./src/*. Most pages are client components that fetch through Apollo hooks; a few layout.tsx files are server components that only build SEO metadata. There is no SSG/ISR and no middleware.ts; route guarding is done inside pages.
Layout of the code:
src/app/— routes:/,/productsand/products/[slug],/series,/collaboration,/flash-sale,/sale,/new-arrival,/search,/checkout/shipping,/auth/*,/user/*(profile, address, my-order),/journals,/store-locator.src/lib/<domain>/— GraphQL documents (*.gql.ts) and types (*.type.ts), operations namedfront*.src/modules/<feature>/components/— feature UI;src/components/— the hand-built UI kit (Tailwind v4 + Headless UI, no component library).src/context/— five React contexts (cart,address,homepage,dialog,alert). No Redux/Zustand.- Auth is NextAuth (
src/app/auth.ts), Credentials provider →loginAsMember; the token rides in the NextAuth JWT session and is sent asBeareron every Apollo/axios call.
There is a cart, but no /cart route — the cart is a context and a slide-over.
Admin — def-exsport-frontend-admin
Next.js 15 App Router. Everything is under /admin; / redirects to /admin/dashboard. src/middleware.ts is a coarse "is logged in" gate.
src/app/admin/<area>/— listpage.tsxplusadd-*/edit-*/[slug]pages. Areas: products (+ variants), heads-types, categories, sub-categories, brands, tags, series, collaborations, members, orders (view only), stores, homepage, discounts, vouchers, flash-sales, journals, admins, roles.src/lib/<domain>/—index.ts(GraphQL),*.rest.ts(axios multipart for uploads),*.type.ts.src/modules/<area>/— forms and lists. UI is a vendored Metronic template plus Tailwind v3; there is no React component library, and modals/menus use Metronic's imperative JS.- RBAC is data-driven and client-side.
src/hooks/useAccess.tsxreadssession.user.me.role.menus[](each menu has view/add/update/delete/export). It hides sidebar items and guards pages; the backend enforces the same rights per resolver.
Two areas to know: the dashboard is a stub (renders a bare heading), and orders are view-only (src/lib/orders has queries, no mutations).
Naming quirks to preserve
Cite these as they are — they are real in the code: the storefront Apollo wrapper is appollo-wrapper.tsx (triple p) and its community route is /comunity; the admin vouchers domain is spelled vourchers (src/lib/vourchers, vourcer.rest.ts).