mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-14 06:47:00 +10:00
62f8270b3e
commit b2b0470a1d9267d042ec0ac66523c6635bf5b199
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 13:13:38 2026 +0200
chore: update .gitignore to include .vite-hooks and modify pnpm-lock.yaml for dependencies
commit d28fadb5cd8706c874e616102878b4a394ec84c1
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 13:08:04 2026 +0200
fix: remove timestamp conflict guard
commit c6998d9dbab19d09d3c8054feef1d2e4117555eb
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 12:11:51 2026 +0200
chore(release): v5.1.5
commit f33d168711804880e1f12e88d24290aae16cc258
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 11:58:35 2026 +0200
revert: compose.yml
commit d961e6535811a10c335525fb33a08d03e737278d
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 11:58:08 2026 +0200
refactor(agent): replace 'revert' terminology with 'restore' for clarity, resolves #3086
commit 17f351171be218e33f01c469d95e4164d4c8dc57
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 11:10:41 2026 +0200
refactor(pdf): simplify sidebar section filtering and update summary feature logic
commit d55179b9d76879e3204de185e8b53fadd0a107ed
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 09:53:37 2026 +0200
chore: update pnpm-lock.yaml and turbo.json
commit 7cade6980e1a04352536bd44ef773f338c4ef599
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 09:38:30 2026 +0200
fix(polyfill): add tested polyfill for Map Upsert methods
commit 26d175bb9c53d93225d1e907678445252c13d660
Merge: 1cf33dc6c 5b1297fa2
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 09:23:29 2026 +0200
Merge remote-tracking branch 'origin/main' into feat/explore-hono-orpc-migration
# Conflicts:
# packages/api/src/services/agent-url.ts
# packages/runtime-externals/package.json
commit 1cf33dc6c9d81735730ad656e16dab6501c6d6a1
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Tue May 19 09:22:12 2026 +0200
chore: preserve branch changes before main sync
commit b380a4b00fdbcdd81ff4f8ef72b330fd027ccda5
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Mon May 18 07:50:28 2026 +0200
chore: lot of fixes for monorepo migration
commit 8fcf0ec64e1c29572ebaff494338368bfcf75760
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 13:57:17 2026 +0200
chore: update knip version and refine web app routing with new SEO endpoints
commit 234e68086ff15610a93877354c98e2c020364533
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 12:10:06 2026 +0200
refactor(auth): update OAuth routes to include API prefix and remove unused schema endpoint
commit 91c84b9a8496b0ce21d71cae9f8b2a027638c9ac
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 11:54:29 2026 +0200
chore: update dependencies and enhance PWA metadata in web app
commit 150117d4a5a9dd6cd92c64891aad8cae90f6a7af
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 11:12:35 2026 +0200
docs: revise manifest-only pwa testing scope
commit 6b939a55661aec9dd8122b184e4b60a5c7325fb5
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 11:11:33 2026 +0200
docs: add manifest-only pwa design
commit 1422e1fc96c400948b273210a1067251087d15d4
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 11:05:04 2026 +0200
chore(dev): simplify server proxy config
commit bc2ff5a9f6fda41e6c40333c8f163aa23a6c5e48
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 11:04:50 2026 +0200
docs: add unsafe oauth redirect plan
commit 445359ebe9b96c1515bf1c4c3f73ba8a8448ec12
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 11:04:34 2026 +0200
feat(auth): add unsafe oauth redirect flag
commit 73fffdd24598e56b2793f7657919bc794835892e
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 10:55:02 2026 +0200
docs: design unsafe oauth redirect flag
commit c0066aa19c15fc8a4c8e5179ed49889c117519f4
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 10:22:04 2026 +0200
chore: update translation source paths
commit 9033da082418d252aafd6c2eed72f71f014be3d9
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 10:09:25 2026 +0200
refactor(arch): react spa + hono migration
commit 6f27936c11bda895977dc63ee550c3346d4ce24b
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Fri May 15 01:10:47 2026 +0200
docs: add docker nightly tagging design
commit ecc1fd9a88a0ee1dca2f1977dfc17f74527fe1da
Author: Amruth Pillai <im.amruth@gmail.com>
Date: Thu May 14 20:05:44 2026 +0200
feat: migrate to hono spa server
143 lines
12 KiB
Markdown
143 lines
12 KiB
Markdown
# AGENTS.md
|
|
|
|
## Cursor Cloud specific instructions
|
|
|
|
### Overview
|
|
|
|
Reactive Resume is a pnpm monorepo (Turborepo) with two deployable apps: `apps/web` (TanStack Start / React 19 / Vite) and `apps/server` (Hono / Node.js). The production Docker image runs a single Node.js process on port 3000, with `apps/server` mounting the API/auth/MCP/static routes and serving the built web app.
|
|
|
|
Internal packages are source-consumed through `package.json` export maps that point at `src` files. Do not assume package-local `dist` output exists unless a package explicitly adds it.
|
|
|
|
### Prerequisites
|
|
|
|
- **Node.js 24** (matches Dockerfile `ARG NODE_VERSION=24`). Use `nvm install 24 && nvm use 24` if needed.
|
|
- **Docker** is required to run PostgreSQL. Start it with `sudo dockerd &` if the daemon isn't running.
|
|
- **pnpm 11.1.2** is managed via corepack (`corepack enable`).
|
|
|
|
### Codebase map
|
|
|
|
- `apps/web` owns TanStack Start routes, Vite config, PWA setup, oRPC browser client wiring, web features, and the resume builder UI.
|
|
- `apps/server` owns the production Hono app, route composition, auth/RPC/MCP/OpenAPI handlers, static uploads, schema JSON, web-dist fallback serving, and startup checks.
|
|
- `packages/api` contains oRPC routers, DTOs, rate limiting, and feature-owned API modules under `packages/api/src/features/*`. The router export at `@reactive-resume/api/routers` aggregates those feature routers for `/api/rpc`.
|
|
- `packages/auth` contains Better Auth config, auth helper functions, and exported auth types. The server auth adapter in `apps/server/src/http/auth.ts` delegates to `auth.handler`.
|
|
- `packages/db` contains the Drizzle client and schema. Migration files live at the repo root in `migrations/`.
|
|
- `packages/env` defines server environment validation and auto-loads the root `.env` for app/server code.
|
|
- `packages/schema` contains Zod schemas and typed resume/page/template models.
|
|
- `packages/pdf` contains the React PDF document, font registration, shared template primitives, template implementations, and browser/server PDF generation adapters. PDF.js viewer UI stays in `apps/web`.
|
|
- `packages/resume` contains pure resume-domain behavior such as JSON Patch helpers and social-network icon mapping.
|
|
- `packages/docx` contains DOCX export generation.
|
|
- `packages/mcp` contains MCP tools, prompts, resources, server-card generation, and tool metadata.
|
|
- `packages/ui` contains shared Base UI/shadcn-style components and hooks.
|
|
- `packages/fonts`, `packages/email`, `packages/import`, `packages/ai`, `packages/utils`, and `packages/config` provide focused support surfaces. Prefer their existing exports over adding cross-package shortcuts.
|
|
- Development-only scripts live in `tooling/`, not under `packages/`, so packages only contain code bundled by the app/runtime.
|
|
|
|
### Web app conventions
|
|
|
|
- Routes are file-based under `apps/web/src/routes`. Do not hand-edit `apps/web/src/routeTree.gen.ts`; it is generated by TanStack Router tooling.
|
|
- Server-owned HTTP behavior lives in `apps/server/src/{http,rpc,mcp,openapi,static,startup}`. Keep API/RPC/auth/MCP/static route wiring in `apps/server`, not in web routes.
|
|
- `apps/web/src/router.tsx` initializes router context with `queryClient`, `orpc`, `theme`, `locale`, `session`, and `flags`. Reuse route context where possible instead of refetching these concerns ad hoc.
|
|
- The builder shell lives under `apps/web/src/routes/builder/$resumeId`. The nested preview route is client-only (`ssr: false`), while the public resume route `apps/web/src/routes/$username/$slug.tsx` uses `ssr: "data-only"`.
|
|
- Browser-only resume preview code lives under `apps/web/src/features/resume/preview`, and public resume PDF viewer code lives under `apps/web/src/features/resume/public`. Keep PDF.js/canvas/browser APIs out of SSR paths and out of `packages/pdf`.
|
|
- The isomorphic oRPC client is in `apps/web/src/libs/orpc/client.ts`; server calls use an in-process router client and browser calls use `/api/rpc` with credentials included.
|
|
|
|
### Package and feature boundaries
|
|
|
|
- Workspace dependencies must go through package names and package export maps. Do not import another workspace's `src` tree through repository paths, `@reactive-resume/*/src/*`, or TypeScript path aliases.
|
|
- `turbo boundaries` is the executable package-boundary check. Workspace-level `turbo.json` files declare coarse tags:
|
|
- `app:web` for the TanStack Start app.
|
|
- `app:server` and `runtime:server` for the Node/Hono process.
|
|
- `runtime:server` for server-only packages such as API/auth/db/env/email/MCP.
|
|
- `runtime:browser` for browser-only shared UI.
|
|
- `runtime:universal` for environment-neutral domain packages.
|
|
- `role:domain`, `role:infra`, `role:adapter`, `role:api`, `role:rendering`, and `role:tooling` for package intent.
|
|
- Browser/server runtime-specific code should live behind explicit export subpaths such as `@reactive-resume/pdf/browser`, `@reactive-resume/pdf/server`, or `@reactive-resume/env/server`. Keep root exports environment-neutral unless the package is intentionally server-only.
|
|
- Wildcard exports are allowed only for leaf libraries whose public surface is intentionally file-like, currently `@reactive-resume/ui/components/*`, `@reactive-resume/ui/hooks/*`, and schema resume model files. Prefer explicit exports for packages that own runtime behavior.
|
|
- Add new API procedures and business logic inside the owning `packages/api/src/features/*` module. Keep route wiring, DTO usage, helpers, and services colocated by feature/capability, then expose only intentional public surfaces through `packages/api/package.json`. Prefer `protectedProcedure` from `packages/api/src/context.ts` for authenticated procedures.
|
|
- Add database columns/tables in `packages/db/src/schema/*`, then generate root-level migrations with `dotenvx run -f .env.local -- pnpm db:generate`.
|
|
- Add or change resume data shape in `packages/schema/src/resume/*` first, then update API DTOs, importers, PDF rendering, and web forms that consume that shape.
|
|
- Add or rename templates in all relevant places: `packages/schema/src/templates.ts`, `packages/pdf/src/templates/index.ts`, template source under `packages/pdf/src/templates/<name>/`, and static previews under `apps/web/public/templates/{jpg,pdf}`.
|
|
- Resume JSON Patch behavior belongs in `@reactive-resume/resume/patch`; do not put resume-domain helpers in `@reactive-resume/utils`.
|
|
- DOCX export behavior belongs in `@reactive-resume/docx`; do not put DOCX builders in `@reactive-resume/utils`.
|
|
- Shared PDF section filtering lives in `packages/pdf/src/templates/shared/filtering.ts`. Keep template-specific visual exceptions in the owning template directory unless multiple templates need the same behavior.
|
|
- `packages/pdf/src/hooks/use-register-fonts.ts` owns React PDF font registration, standard PDF font handling, CJK fallback stacks, and global hyphenation behavior.
|
|
- PDF generation helpers live behind `@reactive-resume/pdf/browser` and `@reactive-resume/pdf/server`; locale-specific section-title resolution stays in the caller.
|
|
- MCP implementation belongs in `@reactive-resume/mcp`; app packages must not import MCP implementation from another app's source tree.
|
|
- `packages/utils` has narrowly exported helpers. If another package needs a utility, add an explicit export path instead of importing private files.
|
|
|
|
Placement decision tree:
|
|
|
|
1. If the change is a web route, route loader, or user-facing web workflow, start in `apps/web/src/routes` or `apps/web/src/features`.
|
|
2. If the change is a server HTTP route/adapter, startup check, static handler, MCP transport, or OpenAPI/well-known handler, start in `apps/server/src`.
|
|
3. If it is authenticated API behavior, put the contract and implementation in the owning `packages/api/src/features/*` module.
|
|
4. If it is pure resume data behavior with no DB, HTTP, DOM, or PDF renderer dependency, put it in `packages/resume`.
|
|
5. If it renders resume PDFs, put shared React PDF/template code in `packages/pdf`; put PDF.js viewer/canvas UI in `apps/web/src/features/resume`.
|
|
6. If it creates DOCX exports, put it in `packages/docx`.
|
|
7. If it exposes MCP tools/prompts/resources, put it in `packages/mcp`.
|
|
8. If it is a generic UI primitive or hook, put it in `packages/ui`; if it is workflow-specific UI, keep it in the owning web feature.
|
|
9. If it is a narrow cross-cutting helper, add an explicit `packages/utils` export only after checking that no domain package is a better owner.
|
|
|
|
### Database
|
|
|
|
PostgreSQL runs via Docker Compose:
|
|
|
|
```
|
|
sudo docker compose -f compose.dev.yml up -d postgres
|
|
```
|
|
|
|
The dev default connection string is `postgresql://postgres:postgres@localhost:5432/postgres`.
|
|
|
|
**Important**: `drizzle-kit` (used by `pnpm db:migrate`) reads `DATABASE_URL` from `process.env` directly — it does **not** auto-load the `.env` file. Run migration commands through `dotenvx`, for example `dotenvx run -f .env.local -- pnpm db:migrate`, so `DATABASE_URL` is present in the process environment.
|
|
|
|
The production server runs migrations during startup before serving traffic. Manual `pnpm db:migrate` is mainly for first setup, migration debugging, or applying migrations without starting the app.
|
|
|
|
### Environment
|
|
|
|
Copy `.env.example` to `.env`. The three required variables are:
|
|
|
|
- `APP_URL` (default `http://localhost:3000`)
|
|
- `DATABASE_URL` (default `postgresql://postgres:postgres@localhost:5432/postgres`)
|
|
- `AUTH_SECRET` (any non-empty string)
|
|
|
|
S3/SeaweedFS is optional. If `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, and `S3_BUCKET` are all set, the app uses S3-compatible storage. The checked-in `.env.example` sets SeaweedFS defaults, so either start the `seaweedfs` compose service too or comment out those S3 vars to use local filesystem storage under `<workspace>/data`. `LOCAL_STORAGE_PATH` must be absolute when set.
|
|
|
|
When running dev servers or migration commands, prefix the command with `dotenvx run -f .env.local --`. For example: `dotenvx run -f .env.local -- pnpm dev`. Tests, typechecks, linters, boundary checks, and `pnpm build` do not need this prefix by default. If one of those commands fails because a specific environment variable is required, rerun it with the `dotenvx run -f .env.local --` prefix.
|
|
|
|
### Common commands
|
|
|
|
| Task | Command |
|
|
|------|---------|
|
|
| Install deps | `pnpm install` |
|
|
| Start Postgres only | `sudo docker compose -f compose.dev.yml up -d postgres` |
|
|
| Start Postgres + SeaweedFS | `sudo docker compose -f compose.dev.yml up -d postgres seaweedfs seaweedfs_create_bucket` |
|
|
| Generate migrations | `dotenvx run -f .env.local -- pnpm db:generate` |
|
|
| Run migrations | `dotenvx run -f .env.local -- pnpm db:migrate` |
|
|
| Dev server | `dotenvx run -f .env.local -- pnpm dev` (starts on port 3000) |
|
|
| Web dev server only | `dotenvx run -f .env.local -- pnpm dev:web` |
|
|
| Lint/format | `pnpm check` (Biome) |
|
|
| Boundary check | `pnpm exec turbo boundaries` |
|
|
| Tests | `pnpm test` (Vitest) |
|
|
| Build | `pnpm build` |
|
|
| Typecheck | `pnpm typecheck` |
|
|
|
|
For focused validation, prefer package filters before repo-wide commands, for example:
|
|
|
|
```
|
|
pnpm --filter web typecheck
|
|
pnpm --filter @reactive-resume/pdf test
|
|
pnpm --filter @reactive-resume/api test
|
|
pnpm exec turbo boundaries
|
|
```
|
|
|
|
Vitest test paths are package-relative when running through `pnpm --filter <package> test -- <path>`.
|
|
|
|
### Gotchas
|
|
|
|
- The server startup path auto-runs migrations before serving traffic, so `pnpm db:migrate` is mainly needed for first-time setup, migration debugging, or applying migrations without starting the app.
|
|
- Email sending requires SMTP config; without it, emails are logged to console. This is fine for dev — the app still functions, but email verification links appear in server logs.
|
|
- The `lefthook.yml` pre-commit hook runs `biome check` on staged files. Run `pnpm check` before committing to avoid hook failures.
|
|
- `pnpm check` is write-capable (`biome check --write --unsafe .`). Call that out when using it, and use narrower Biome commands if you need a non-mutating inspection.
|
|
- Biome uses tabs, double quotes, line width 120, organized import groups, and sorted Tailwind classes for `clsx`, `cva`, and `cn`.
|
|
- Most packages use `tsgo --noEmit` for typechecking and `vitest run --passWithNoTests` for tests.
|
|
- There may be unrelated local edits in the worktree. Inspect `git status --short` first and avoid reverting files you did not touch.
|
|
- **New env vars require a `turbo.json` entry.** Turborepo 2.x runs in strict env mode by default — it filters out env vars that are not listed in `globalEnv` (or task-level `env`/`passThroughEnv`). Any new environment variable added to `packages/env/src/server.ts` must also be added to the `globalEnv` array in `turbo.json`, or the variable will be `undefined` inside child processes at runtime even if it is correctly set in the OS/container environment.
|