- Add AML scope note to Handoff - RN Multichain Probe (sanctions-only vs full KYT) - Add human-blocked section with 3 precise next steps for owner - Create Task 11 Pre-flight Inventory: library choice, dev/prod flow, admin UI gaps, backend gaps, risks, acceptance criteria
201 lines
11 KiB
Markdown
201 lines
11 KiB
Markdown
---
|
|
title: Project Structure
|
|
tags: [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 + Request Network checkout 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]].
|