Files
nick-doc/07 - Development/Project Structure.md
2026-05-23 20:35:34 +03:30

11 KiB

title, tags
title tags
Project Structure
development

Project Structure

A bird's-eye view of both repos. For deep dives, follow the cross-links to Backend Architecture and Frontend Architecture.


Backend — /Users/mojtabaheidari/code/backend

A service-oriented Express 5 app. Each business domain owns a folder under src/services/ containing its routes, controllers, services, and (sometimes) its own models. Cross-cutting concerns live in src/shared/ and src/infrastructure/.

backend/
├── src/
│   ├── app.ts                  # Express bootstrap: middleware, routes, Socket.IO, startup
│   ├── config/                 # Sentry init (loaded before anything else)
│   ├── controllers/            # Thin HTTP controllers for orphan endpoints (disputes, points)
│   ├── routes/                 # Router exports for orphan controllers above
│   ├── models/                 # Mongoose schemas (single source of truth for data)
│   ├── infrastructure/
│   │   ├── database/           # Mongo connection + admin bootstrap
│   │   └── socket/             # Socket.IO server adapter & emitter helpers
│   ├── services/               # Domain services — see breakdown below
│   ├── shared/
│   │   ├── config/             # Typed `config` object (env loader)
│   │   ├── middleware/         # auth, errorHandler, rate limit, request logger
│   │   ├── types/              # Cross-domain type aliases
│   │   └── utils/              # Helpers reused across services
│   ├── utils/                  # logger, currencyUtils, videoHelpers
│   ├── seeds/                  # Idempotent data seeders
│   └── scripts/                # One-off operational scripts (TS + sh)
├── __tests__/                  # Jest suites (see Testing)
├── scripts/                    # Shell scripts (build/push, version, ngrok, reset)
├── nginx/                      # Nginx conf (production compose)
├── mongo-init/                 # Mongo initdb.d JS (one-time bootstrap)
├── uploads/                    # User uploads — mounted as volume
├── Dockerfile.dev              # Hot-reload image (ts-node + nodemon)
├── Dockerfile.prod             # Multi-stage build image (compiled JS, non-root user)
├── docker-compose.dev.yml      # Local stack: backend + mongo + redis
├── docker-compose.production.yml # Prod stack: nginx + backend + frontend + mongo + redis
├── .gitea/workflows/           # Gitea Actions CI
├── healthcheck.js              # Container HEALTHCHECK probe
├── eslint.config.js            # Flat ESLint config (TS strict)
├── jest.config.js              # ts-jest preset
└── package.json

src/services/ folders

Each service folder follows the same shape: <service>Routes.ts, <service>Controller.ts, <service>Service.ts, sometimes a <service>Repository.ts and an index.ts barrel.

Folder Purpose
address/ CRUD for buyer/seller addresses (max 3 per user)
admin/ Admin-only data-cleanup + diagnostic endpoints
ai/ OpenAI-backed assistants (offer suggestions, content moderation)
auth/ Login, signup, refresh, Google OAuth, passkey/WebAuthn, temp verification
blockchain/ Generic wallet/chain helpers shared by payment providers
blog/ Public blog posts, comments, video helpers
chat/ Realtime messaging between buyers & sellers
delivery/ Delivery tracking + shipping events
dispute/ Dispute opening, evidence upload, arbitration
email/ Nodemailer service + transactional templates
file/ Multer uploads + Sharp image processing
marketplace/ Purchase requests, seller offers, accept/reject, categories
notification/ In-app notifications + delivery (socket + email)
payment/ Payment orchestration; sub-folders shkeeper/, depay/, web3/
points/ Reputation points + level config
redis/ Redis client wrapper (caching, rate counters)
user/ Profile, settings, role management

src/models/

Each .ts file is a Mongoose model — see Data Models for full schema docs. Highlights:

  • User, Address, Category — identity & taxonomy
  • PurchaseRequest, SellerOffer, RequestTemplate — marketplace core
  • Payment, PointTransaction, LevelConfig — money + reputation
  • Chat, Notification, Dispute, Review, BlogPost, ShopSettings, TempVerification — supporting domains

src/seeds/

Idempotent, runnable via npm run seed:*. See Scripts#seed-scripts.


Frontend — /Users/mojtabaheidari/code/frontend

Next.js 16 App Router with the src/ layout. The structure follows the Minimal v7 template: pages in app/, page-level UI in sections/, reusable atoms in components/, and a strong split between server data fetchers (actions/) and client UI.

frontend/
├── src/
│   ├── app/                    # Next.js App Router — route groups: (auth) (dashboard) post shop
│   │   ├── layout.tsx          # Root layout (providers, font, metadata)
│   │   ├── page.tsx            # Landing page
│   │   ├── auth/               # /auth/* routes
│   │   ├── dashboard/          # /dashboard/* routes (authenticated)
│   │   ├── post/               # Public blog posts
│   │   ├── shop/               # Public shop pages
│   │   ├── error/              # Custom error route
│   │   ├── loading.tsx         # Global loading skeleton
│   │   └── not-found.tsx       # 404
│   ├── sections/               # Page-level UI grouped by domain
│   │   ├── account/ address/ blog/ chat/ dispute/ error/
│   │   ├── overview/ payment/ points/
│   │   ├── request/ request-template/ shop-settings/ user/
│   ├── components/             # Reusable UI atoms & molecules (MUI-based)
│   │   ├── hook-form/          # RHF-wrapped MUI inputs (RHFTextField, RHFSelect, …)
│   │   ├── iconify/            # The single icon component (use only this)
│   │   ├── animate/ carousel/ chart/ custom-* / nav-section/
│   │   ├── upload/ file/ image/ markdown/ editor/ map/ video-player/
│   │   └── …                   # see full list in the codebase
│   ├── contexts/               # Top-level React contexts (socket-context.tsx)
│   ├── hooks/                  # Generic hooks: useBoolean, useSetState, useSnackbar, useSocket
│   ├── lib/                    # axios.ts — singleton API client with interceptors
│   ├── locales/                # i18n: langs/, i18n-provider, server.ts, use-locales
│   ├── layouts/                # AppShell variants: auth-centered, auth-split, dashboard, main, simple
│   ├── theme/                  # MUI theme (core + with-settings overrides)
│   ├── settings/               # Theme-switcher drawer + persisted user settings
│   ├── actions/                # Server-side / shared async API calls (axios)
│   ├── auth/                   # JWT / OAuth / passkey context, guards, hooks, services
│   ├── socket/                 # Socket.IO client, hooks, components, contexts
│   ├── web3/                   # WalletConnect + Alchemy + DePay glue
│   ├── routes/                 # Static path constants (paths object)
│   ├── utils/                  # logger, format-number, format-time, localStorage, …
│   ├── types/                  # Shared TS types (mirrors backend models where useful)
│   ├── assets/                 # SVGs, illustrations
│   ├── _mock/                  # Mock data for storybooks / tests
│   ├── global-config.ts        # Read-only app config (name, version, paths)
│   └── global.css              # Tailwind-less global styles
├── public/                     # Static assets served at /
├── e2e/                        # Playwright specs
├── __tests__/                  # Jest + RTL specs (organised by domain)
├── scripts/                    # Shell scripts (deploy, debug, version, console-log migration)
├── docs/                       # In-repo design notes (not the Obsidian vault)
├── doc/                        # Legacy docs folder
├── Dockerfile                  # Production multi-stage Next.js build
├── Dockerfile.dev              # Dev image (yarn dev on port 3000)
├── next.config.ts              # Standalone output, image domains, Sentry integration
├── playwright.config.ts        # E2E test config
├── jest.config.js              # Jest + jsdom + RTL
├── eslint.config.mjs           # Flat ESLint with perfectionist sorting
├── prettier.config.mjs         # Prettier config
├── .commitlintrc.json          # Conventional commits enforcement
├── sentry.client.config.ts     # Browser Sentry init
├── sentry.server.config.ts     # Server runtime Sentry init
└── sentry.edge.config.ts       # Edge runtime Sentry init

src/sections/ vs src/components/

A common confusion when first navigating the codebase:

  • components/ — generic, reused everywhere, no business logic. (e.g. Iconify, RHFTextField, EmptyContent.)
  • sections/ — page-level UI bound to a domain. (e.g. sections/payment/CheckoutSummary.tsx.) Sections may import from components/ but not the other way around.

src/auth/ vs src/socket/ vs src/web3/

These are feature-bundles that ship their own context, hooks, services, and components together. Treat each like an internal package — import only from its index.ts barrel.

Routes & API

  • routes/paths.ts — every URL the app navigates to, expressed as a typed object.
  • lib/axios.ts — the single axios instance with auth interceptor and base URL from NEXT_PUBLIC_API_URL.
  • actions/*.ts — async functions wrapping axios calls; consumed by both server components and client components.

Repository layout (top-level)

~/code/
├── backend/        # this repo
├── frontend/       # this repo
└── docs/           # this Obsidian vault

The production docker-compose.yml lives in backend/ but references ../frontend for the frontend build context — keep both folders as siblings.


Where to add new things

You want to add… Put it under…
A new public API route backend/src/services/<domain>/<domain>Routes.ts (or a new domain folder)
A new Mongo schema backend/src/models/<Name>.ts + export from models/index.ts
A reusable UI component frontend/src/components/<kebab-name>/ with index.ts + component.tsx + types.ts
A page-specific block frontend/src/sections/<domain>/
A new dashboard page frontend/src/app/dashboard/<route>/page.tsx
A shared hook frontend/src/hooks/use-<name>.ts
A one-shot ops script backend/scripts/<name>.sh (operational) or backend/src/scripts/<name>.ts (touches DB)
A seed script backend/src/seeds/<name>.ts and add an npm run seed:<name> entry

For the architectural rationale behind these splits see Backend Architecture and Frontend Architecture.