Skip to content

Commit 0f17380

Browse files
Merge pull request #102 from lokeshwardewangan/refactor/v2-architecture
v2 architecture: TypeScript server, schema migration, client polish
2 parents b75ec1e + b2b1773 commit 0f17380

298 files changed

Lines changed: 16353 additions & 10983 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.local.json

Lines changed: 0 additions & 14 deletions
This file was deleted.

.github/workflows/backend-ci.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,11 @@ jobs:
3333
- name: Check formatting
3434
run: npx prettier --check .
3535

36-
- name: Syntax sanity check
37-
run: node --check src/index.js
36+
- name: Typecheck
37+
run: npm run typecheck
38+
39+
- name: Build
40+
run: npm run build
41+
42+
- name: Test
43+
run: npm test

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,13 @@ Thumbs.db
4141
# Hosting platform build artifacts
4242
.netlify/
4343
.vercel/
44+
45+
# Claude Code — personal/per-machine state (team-shared settings, agents,
46+
# commands, and CLAUDE.md remain tracked)
47+
.claude/settings.local.json
48+
.claude/projects/
49+
.claude/memory/
50+
.claude/todos/
51+
.claude/shell-snapshots/
52+
.claude/statsig/
53+
.claude/ide/

CLAUDE.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Repo layout
6+
7+
Two independent npm projects under one repo. The root `package.json` only wires Husky — there is no root install, no workspaces, and no test runner. Run all commands from inside `client/` or `server/`.
8+
9+
- `client/` — Vite + React 18 + TypeScript SPA
10+
- `server/` — Express 4 + Mongoose API (ESM, `"type": "module"` in `server/package.json`)
11+
- `docker-compose.yml` — production stack (`mongo` + `server` + nginx-served `client`)
12+
13+
## Commands
14+
15+
Frontend (`cd client`):
16+
- `npm run dev` — Vite dev server on `:5173`
17+
- `npm run build``tsc -b && vite build` (the pre-commit hook runs this)
18+
- `npm run lint` — ESLint over `.ts`/`.tsx`
19+
- `npm run typecheck``tsc --noEmit`
20+
- `npm run format` — Prettier
21+
22+
Backend (`cd server`):
23+
- `npm run dev` — nodemon on `src/index.js`, expects `:5000`
24+
- `npm run start` — production start
25+
- `npm run format` — Prettier
26+
27+
There is **no test suite anywhere** — quality gates are lint + typecheck + build only. Adding tests is fine; place them as `*.test.tsx` next to the feature or in `__tests__/`.
28+
29+
Docker (production, from repo root): `docker compose up -d --build`. See README "Docker" section for full flow. Local dev does **not** use Docker.
30+
31+
## Architecture — non-obvious things
32+
33+
### Backend API surface is RPC-style, not REST
34+
35+
Routes mount at `/api/user` and `/api/user/report` ([server/src/app.js:41-42](server/src/app.js#L41-L42)) — note the **singular** `user`, despite what the README's tables show. Endpoints are verb-named actions (`/add-today-expenses`, `/get-all-users`, `/received-lent-money`, `/delete-active-session`), not resource paths. When adding endpoints, follow the existing `verifyJwtToken`-then-controller chaining in [server/src/routes/user.routes.js](server/src/routes/user.routes.js) rather than introducing REST conventions.
36+
37+
### Auth middleware is fragile
38+
39+
[server/src/middleware/auth.middleware.js](server/src/middleware/auth.middleware.js) reads the JWT from `Authorization: Bearer <token>` only (no cookie fallback, despite the commented-out code) and **swallows all errors via `console.log`** without calling `next(err)` or returning a response. A bad token currently causes the request to hang. If you touch auth, fix this rather than copying the pattern.
40+
41+
Every authenticated request also writes to `activeSessions.$.lastUsedAt` on the user doc — bulk endpoints will produce one extra Mongo write per call.
42+
43+
### Server is ESM, root is CommonJS
44+
45+
`server/package.json` declares `"type": "module"` so all `.js` files under `server/src` use `import`/`export` with explicit `.js` extensions (e.g. `from './app.js'`). The repo-root `package.json` says `"type": "commonjs"`, but it only holds Husky — don't get confused and switch the server back to require-syntax.
46+
47+
### Frontend state is split three ways
48+
49+
- **Redux Toolkit** ([client/src/app/store.ts](client/src/app/store.ts)) for UI/global client state — slices live in `client/src/features/<domain>/`.
50+
- **TanStack Query** for all server state (cache, mutations) — wired in [client/src/main.tsx](client/src/main.tsx).
51+
- **Formik + Yup** for form state and validation; schemas in `client/src/schemas/`.
52+
53+
Don't put server data in Redux. Don't add a second forms library.
54+
55+
### Path alias `@``client/src/`
56+
57+
Configured in [client/vite.config.ts:8-9](client/vite.config.ts#L8-L9). Always import internal modules as `@/components/...`, `@/features/...`, etc. — not relative `../../..` paths.
58+
59+
### Vite manualChunks has a known landmine
60+
61+
[client/vite.config.ts:14-31](client/vite.config.ts#L14-L31) splits `pdf` / `framer` / `charts` / `recharts`. The inline comment says **don't** split `react`/`react-dom` into their own chunk — it breaks with "Cannot read properties of undefined (reading 'forwardRef')" because some vendor modules touch React at module-eval time. Leave that alone.
62+
63+
### CORS is an allowlist regex, not a config var
64+
65+
[server/src/app.js:14-24](server/src/app.js#L14-L24) hardcodes `/\.lokeshwardewangan\.in$/` and `/\.vercel\.app$/`. Adding a new origin means editing this file — no env var exists for it.
66+
67+
### Backend response shape
68+
69+
All controllers throw `new ApiError(status, msg)` ([server/src/utils/ApiError.js](server/src/utils/ApiError.js)) for errors and return `new ApiResponse(status, data, msg)` ([server/src/utils/ApiResponse.js](server/src/utils/ApiResponse.js)) for success. Wrap async controllers in `asyncHandler` from [server/src/utils/asyncHandler.js](server/src/utils/asyncHandler.js) to forward rejections to Express. Keep this pattern when adding endpoints.
70+
71+
### Pre-commit hook is heavy
72+
73+
[.husky/pre-commit](.husky/pre-commit) runs `cd client && npm run build && npm run format && git add .` then `cd server && npm run format && git add .` on every commit. A full TypeScript compile + Vite build runs each time — expect ~15–40s per commit. If you need to bypass during a WIP commit, the user must opt in explicitly (no `--no-verify` unless asked).
74+
75+
### Sentry is initialized at module-load
76+
77+
[client/src/App.tsx:13-17](client/src/App.tsx#L13-L17) calls `Sentry.init` unconditionally at import time with `tracesSampleRate: 1.0` and `sendDefaultPii: true`. If `VITE_SENTRY_DSN` is unset, Sentry no-ops — but be aware that 100% trace sampling + PII is on by default in this codebase.
78+
79+
### Docker `VITE_*` are build-time only
80+
81+
In the compose stack ([docker-compose.yml:96-103](docker-compose.yml#L96-L103)), every `VITE_*` variable is passed as a `build.args` entry and inlined into the bundle when the client image builds. Changing them needs `docker compose build client` — a `restart` won't pick them up. The runtime API base for the dockerized client is `/api`, proxied by nginx to `server:5000` (no hardcoded host).
82+
83+
## Conventions
84+
85+
- Naming: PascalCase components, `useXxx` hooks, `xxxSlice` for Redux slices, `domain.routes.js` / `domain.controllers.js` / `domain.model.js` on the server.
86+
- Frontend is strict TypeScript — avoid `any` (the existing `state: any` in `App.tsx` is a wart, not a pattern to follow).
87+
- Commit messages use Conventional Commits (`feat:`, `fix:`, `chore:`, `perf:`, `docs:`). Branch names: `feature/...`, `fix/...`, `chore/...`.
88+
- Prettier config (from CONTRIBUTING.md): `semi: true`, `singleQuote: true`, `trailingComma: "es5"`, `tabWidth: 2`. `prettier-plugin-tailwindcss` reorders class names on save.

client/components.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
"cssVariables": true,
1111
"prefix": ""
1212
},
13+
"iconLibrary": "radix",
1314
"aliases": {
1415
"components": "@/components",
1516
"utils": "@/lib/utils",
1617
"ui": "@/components/ui",
1718
"lib": "@/lib",
1819
"hooks": "@/hooks"
20+
},
21+
"registries": {
22+
"@magicui": "https://magicui.design/r/{name}"
1923
}
2024
}

0 commit comments

Comments
 (0)