Imported from beratersari/swyngora (
frontend/AGENTS.md). Install upstream withnpx skills add beratersari/swyngora --skill frontend. Copyright stays with the author.
AGENTS.md — frontend/
Package conventions for the product web UI. Closest AGENTS.md wins under this tree; user chat overrides docs. Root AGENTS.md still applies for Git Flow, SemVer, and monorepo rules.
1. Role
React SPA that talks to the Go backend via OpenAPI-described HTTP. Not simple-frontend/.
2. Stack (mandatory)
| Concern | Choice |
|---|---|
| UI kit | Ant Design (antd) — wrap in Atomic components when practical |
| Charts | TradingView Lightweight Charts (lightweight-charts) |
| UI structure | Atomic Design (atoms → molecules → organisms → templates → pages) |
| File split (UI) | Prefixed colocation: Name.tsx, Name.types.ts, Name.styles.ts, Name.constants.ts, Name.helpers.ts, Name.test.tsx |
| Shared non-UI | src/libs/{api,realtime,hooks,utils,types} |
| Server state | RTK Query only for backend REST — lives in libs/api. Use rtkCurrent (not .data) for symbol/venue/book-keyed reads so a previous arg is not treated as live. |
| Types from backend | Generated into libs/api/generated/ from OpenAPI |
| Bundle | Vite + React + TypeScript |
| Design system | Tokens + Text + Skeleton + motion — docs/design/frontend-design-system.md |
| Styling | styled-components only — colocate *.styles.ts (no CSS/CSS modules) |
| Brand colors | Light CoinMarketCap-like: paper #FFFFFF / blue #3861FB / up #16C784 / down #EA3943 — see styles/tokens/colors.ts |
| Loading | All content components support isLoading → Skeleton |
| Localization | i18next + react-i18next under src/libs/i18n/ — locale JSON catalogs; no hard-coded UI copy |
Decision record: project-management/decisions/001-antd-and-lightweight-charts.md
Design system: docs/design/frontend-design-system.md
3. Folder map (Option A — no features/)
| Path | Role |
|---|---|
src/components/atoms |
Design-system primitives |
src/components/molecules |
Small compositions / chart hosts |
src/components/organisms |
Domain UI sections (markets table, detail panels) — props only |
src/components/templates |
Layout shells without data |
src/components/pages |
Route screens — RTK Query only here |
src/libs/api/ |
baseApi, store, endpoints, OpenAPI generated |
src/libs/hooks/ |
Shared React hooks |
src/libs/utils/ |
Pure helpers (incl. candle → chart mappers) |
src/libs/types/ |
Shared view/re-export types |
src/app/ |
Providers (Redux, Ant ConfigProvider), router |
src/config/ |
Env + app constants |
src/libs/i18n/ |
i18n init, locale JSON (en, tr), Ant Design locale bridge |
Do not use src/features/ for product UI. Domain widgets live under organisms; screens under pages. Revisit feature folders only when multiple product areas need isolation (e.g. markets + watchlist + paper + AI).
UI strings: use useTranslation / t('namespace:key') — catalogs in libs/i18n/locales/. Exchange ids and symbols stay untranslated.
Full design: docs/design/frontend-system-design.md.
Local tasks: project-management/.
File naming (searchable colocation)
Every component module uses the component name as a prefix so search/filter finds related files easily:
components/atoms/Text/
├── Text.tsx # component
├── Text.types.ts # props / local types
├── Text.styles.ts # styled-components
├── Text.constants.ts # local constants (not bare constants.ts)
├── Text.helpers.ts # pure helpers (not bare helpers.ts)
├── Text.test.tsx # tests
└── index.ts # public barrel
| Suffix | Purpose |
|---|---|
Name.tsx |
Component |
Name.types.ts |
Props, view models |
Name.styles.ts |
styled-components |
Name.constants.ts |
Magic values, defaults |
Name.helpers.ts |
Pure functions |
Name.test.tsx |
Unit tests |
Do not use bare constants.ts / helpers.ts / styles.ts inside component folders — always prefix with the component name.
App-level config may use src/config/constants.ts (not a component).
4. Ant Design rules
- App-wide theme via
ConfigProviderinapp/providers.tsx(INIT-8). - Prefer Atomic wrappers (
components/atoms/Button, etc.) over rawantddeep in the tree — organisms may use antd Table/Form when wrappers do not exist yet; promote wrappers as patterns stabilize. - Use Ant Design Table, Tabs, Form, Select, Input, Layout, Typography, Tag, Pagination, Spin, Alert for markets UI.
- Do not mix a second full UI kit (MUI, Chakra, etc.) without a decision doc.
5. Chart rules (Lightweight Charts)
- Dependency:
lightweight-charts(INIT-9). - Mount charts in a dedicated molecule/organism (e.g. candle chart host); do not put chart lifecycle in atoms that only render icons/text.
- Map API candle strings → chart numbers in
libs/utils. - Primary use: OHLCV from
GET /api/v1/market/candleson detail views (later epic). Markets list phase uses tables, not charts. - Do not add ECharts/Recharts/Chart.js as a second default without a new decision.
6. Hard rules
- API layer only under
libs/api— never under components or afeatures/*/apitree. - Shared hooks under
libs/hooks. - Shared pure code under
libs/utils. - Do not call
fetch/axios/ RTK from atoms, molecules, or organisms — pages only. - Do not hand-edit
libs/api/generated/. - Do not hand-maintain long-term API DTOs that duplicate OpenAPI.
- libs must not import pages or organisms.
- No upward Atomic imports (atoms must not import organisms/pages).
- No
src/features/unless the team explicitly revisits Option B (feature-owned pages). - User-visible work lands with tests and docs.
- Keep this file and
README.mdaccurate after structural/stack changes.
7. Preferred imports
import { useListSpotMarketsQuery } from '@/libs/api';
import { useDocumentVisible } from '@/libs/hooks';
import { formatPrice } from '@/libs/utils';
import { Button } from '@/components/atoms/Button';
import { MarketsTable } from '@/components/organisms/MarketsTable';
8. First epics
| Order | Epic | Local PM |
|---|---|---|
| 1 | Project initialization | project-management/epics/frontend-project-initialization.md |
| 2 | Multi-exchange spot markets | project-management/epics/multi-exchange-spot-markets.md |
Do not implement Epic 2 UI before Epic 1 acceptance criteria pass.
9. Local run (post-init)
cd backend && go run ./cmd/server
cd frontend && npm install && npm run dev
10. Codegen
npm run codegen:api
# output: src/libs/api/generated/
11. Format / lint / test
npm run format # Prettier write
npm run format:check # CI check
npm run lint # ESLint (+ eslint-config-prettier)
npm test # Vitest
npm run test:coverage # Vitest + @vitest/coverage-v8 (line + branch)
Config: .prettierrc.json · ignore: .prettierignore
Do not format src/libs/api/generated/.
Env (optional): VITE_API_BASE_URL, VITE_CLIENT_ID (watchlist X-Client-Id).
Vite on WSL /mnt/c: server.watch.usePolling is on so HMR sees Windows-FS writes. Restart npm run dev if the browser still serves a stale module.
Last updated: 2026-08-11