mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-09-29 16:24:22 +10:00
* feat(deploy): support Vercel Hobby alongside Docker * fix(deploy): include PDFKit runtime font assets * docs(deploy): document Vercel and Docker setup * docs(deploy): record storage persistence checks * refactor(deploy): drop scheduled staging cleanup Staging uploads are deleted after finalization and expired ones are swept on each new upload, so the Vercel cron job, its route, and CRON_SECRET are no longer needed. The Deploy with Vercel wizard now asks for two secrets. * docs(deploy): restructure Vercel guides Split the Vercel page into a how-to with its environment reference, move the large RPC staging protocol to an API reference page, and move CI deployment checks to the contributing section. Point Deploy with Vercel buttons at main. * chore: remove agent planning records and fix web app description Delete superpowers plans/specs, ADRs, issue plans, execution briefs, domain context maps, and Europass research. Describe apps/web as a TanStack Router SPA served by apps/server. * refactor(deploy): simplify Vercel support code - Share one Redis client and key namespace through @reactive-resume/db/redis for API and auth instead of a second auth-only client. - Drop the auth seeding retry; the provider already treats concurrent inserts as no-ops and deployment preparation seeds before runtime. - Detect staging support from POST /api/storage/stage (404 on Docker) instead of a separate GET probe. - Read staged bodies directly; the signed upload already caps their size. - Close per-subscription Redis connections with disconnect() alone. - Check Blob health with one list call instead of write/read/delete. - Remove redundant tsdown onlyBundle list, dead namespace fallbacks, and the conditional spread in the health status. * fix(deploy): heal stopped runs with dead owners and keep auth up without Redis - Run owners refresh a Redis heartbeat until they release their claim. Stop requests reap the run immediately when the owner has stopped heartbeating, instead of leaving the thread blocked until the 15-minute TTL reaper. - Auth and oRPC rate limiters fall back to per-instance memory limits when Redis errors, instead of rejecting every login or failing requests. * ci: allow esbuild build for Vercel CLI and register deployment deps with knip pnpm 12 fails dlx installs with ignored build scripts, so allow esbuild explicitly. The server bundle keeps @vercel/blob, ioredis, and jose external, and api/index.mjs is the Vercel Function entry. * fix(web): send buffered RPC bodies instead of teed streams Reading a request clone turned the original body into a stream, which browsers send without inspectable request data and which needs duplex mode. Send the already buffered Blob for direct requests. * fix(web): send direct RPC bodies as bytes Blob request bodies are sent as data pipes, so browser tooling cannot inspect them. Buffer the original request as an ArrayBuffer and send those bytes; this restores the e2e save assertions that match on request data.
325 lines
10 KiB
Plaintext
325 lines
10 KiB
Plaintext
---
|
|
title: "Development setup"
|
|
description: "Set up a local development environment for Reactive Resume with pnpm, Docker services, environment variables, and the web and server apps."
|
|
---
|
|
|
|
<Info>
|
|
**Prerequisites**: - [Node.js](https://nodejs.org/) v24 - [pnpm](https://pnpm.io/) v11.21.0 -
|
|
[Docker](https://docs.docker.com/get-docker/) and Docker Compose - [Git](https://git-scm.com/)
|
|
</Info>
|
|
|
|
These steps set up Reactive Resume for local development, whether you're contributing to the project or customizing it for yourself.
|
|
|
|
---
|
|
|
|
## Setting up your development environment
|
|
|
|
<Steps>
|
|
<Step title="Clone the Repository">
|
|
```bash
|
|
git clone https://github.com/reactive-resume/reactive-resume.git reactive-resume
|
|
cd reactive-resume
|
|
```
|
|
</Step>
|
|
|
|
<Step title="Install Dependencies">
|
|
Install [pnpm](https://pnpm.io/installation) directly, then install the project dependencies:
|
|
|
|
```bash
|
|
pnpm install
|
|
```
|
|
</Step>
|
|
|
|
<Step title="Start Infrastructure Services">
|
|
If you want to run the app directly on your machine with `pnpm dev`, start only the infrastructure services:
|
|
|
|
```bash
|
|
docker compose -f compose.dev.yml up -d postgres redis seaweedfs seaweedfs_create_bucket
|
|
```
|
|
|
|
This starts the following infrastructure services:
|
|
- **PostgreSQL** — Database (port 5432)
|
|
- **Redis** — AI Agent workspace streams/state (port 6379)
|
|
- **SeaweedFS** — S3-compatible storage (port 8333)
|
|
|
|
<Info>
|
|
**From v5.1.0 onwards** — PDF generation now runs entirely in the browser via `@react-pdf/renderer`, so no Browserless or Chromium container is required for development.
|
|
</Info>
|
|
|
|
<Tip>
|
|
`compose.dev.yml` can also run the app in a development container with `docker compose -f compose.dev.yml up -d`.
|
|
Use the service-filtered command above when you want local editor tooling and `pnpm dev` on the host.
|
|
</Tip>
|
|
|
|
<Tip>
|
|
Wait for all services to be healthy before proceeding. Check with `docker compose -f compose.dev.yml ps`.
|
|
</Tip>
|
|
</Step>
|
|
|
|
<Step title="Configure Environment Variables">
|
|
Copy `.env.example` to `.env.local` in the project root:
|
|
|
|
```bash
|
|
cp .env.example .env.local
|
|
```
|
|
|
|
Then edit `.env.local` as needed. For local development on the host, set at minimum:
|
|
|
|
```bash
|
|
# Application
|
|
PORT=3000
|
|
SERVER_PORT=3001
|
|
APP_URL=http://localhost:3000
|
|
|
|
# Database
|
|
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
|
|
|
|
# Authentication
|
|
AUTH_SECRET=development-secret-change-in-production
|
|
|
|
# Storage (SeaweedFS)
|
|
S3_ACCESS_KEY_ID=seaweedfs
|
|
S3_SECRET_ACCESS_KEY=seaweedfs
|
|
S3_ENDPOINT=http://localhost:8333
|
|
S3_BUCKET=reactive-resume
|
|
S3_FORCE_PATH_STYLE=true
|
|
|
|
# Email (Mailpit for local development)
|
|
SMTP_HOST=localhost
|
|
SMTP_PORT=1025
|
|
SMTP_FROM="Reactive Resume <noreply@rxresu.me>"
|
|
|
|
# AI Agent workspace and saved AI providers
|
|
REDIS_URL=redis://localhost:6379
|
|
ENCRYPTION_SECRET=change-me-to-a-secure-agent-secret-in-production
|
|
```
|
|
|
|
<Tip>
|
|
**Email testing**: The development stack includes [Mailpit](https://mailpit.axllent.org/). Emails the app sends are captured there and viewable at [http://localhost:8025](http://localhost:8025), so nothing reaches a real address during development.
|
|
</Tip>
|
|
|
|
</Step>
|
|
|
|
<Step title="Run Database Migrations If Needed">
|
|
The server startup path runs migrations before serving traffic. To apply migrations manually without starting the app,
|
|
load `.env.local` with `dotenvx` because Drizzle Kit reads directly from `process.env`:
|
|
|
|
```bash
|
|
dotenvx run -f .env.local -- pnpm run db:migrate
|
|
```
|
|
</Step>
|
|
|
|
<Step title="Start the Development Server">
|
|
```bash
|
|
dotenvx run -f .env.local -- pnpm run dev
|
|
```
|
|
|
|
Your local Reactive Resume instance will be available at [http://localhost:3000](http://localhost:3000).
|
|
</Step>
|
|
</Steps>
|
|
|
|
---
|
|
|
|
## Available scripts
|
|
|
|
The scripts you will use most during development:
|
|
|
|
### Development
|
|
|
|
| Command | Description |
|
|
| ------------------------------ | ----------------------------------------------------------- |
|
|
| `dotenvx run -f .env.local -- pnpm dev` | Start the web and server development processes |
|
|
| `pnpm build` | Build the production web bundle and server bundle |
|
|
| `pnpm start` | Start the built production server |
|
|
| `pnpm typecheck` | Run TypeScript type checking |
|
|
| `pnpm test` | Run Vitest across workspaces |
|
|
| `pnpm exec biome check .` | Run a non-mutating Biome check |
|
|
| `pnpm check` | Run Biome with write/fix behavior (`--write --unsafe`) |
|
|
| `pnpm exec turbo boundaries` | Check workspace/package boundary rules |
|
|
|
|
### Database
|
|
|
|
| Command | Description |
|
|
| ---------------------- | -------------------------------------------- |
|
|
| `dotenvx run -f .env.local -- pnpm run db:generate` | Generate migration files from schema changes |
|
|
| `dotenvx run -f .env.local -- pnpm run db:migrate` | Apply pending migrations |
|
|
| `dotenvx run -f .env.local -- pnpm run db:studio` | Open Drizzle Studio (database GUI) |
|
|
|
|
### Internationalization
|
|
|
|
| Command | Description |
|
|
| ------------------------- | -------------------------------------- |
|
|
| `pnpm run lingui:extract` | Extract translatable strings from code |
|
|
|
|
## Understanding the project structure
|
|
|
|
```
|
|
reactive-resume/
|
|
├── apps/
|
|
│ ├── web/ # TanStack Router routes, web features, and browser UI
|
|
│ └── server/ # Hono production server, HTTP adapters, static serving
|
|
├── packages/
|
|
│ ├── api/ # oRPC features and business behavior
|
|
│ ├── auth/ # Better Auth configuration and helpers
|
|
│ ├── db/ # Drizzle client and schema
|
|
│ ├── docx/ # DOCX export generation
|
|
│ ├── mcp/ # MCP tools, prompts, resources, and metadata
|
|
│ ├── pdf/ # React PDF rendering and PDF generation adapters
|
|
│ ├── resume/ # Pure resume-domain helpers
|
|
│ ├── schema/ # Zod schemas and typed models
|
|
│ ├── ui/ # Shared Base UI/shadcn-style primitives
|
|
│ └── ...
|
|
├── tooling/ # Development-only scripts and repository tooling
|
|
├── migrations/ # Generated database migrations
|
|
├── docs/ # Documentation
|
|
└── data/ # Local development data and uploads
|
|
```
|
|
|
|
---
|
|
|
|
## Working with the database
|
|
|
|
### Viewing the database
|
|
|
|
Use Drizzle Studio to explore and manage your database:
|
|
|
|
```bash
|
|
dotenvx run -f .env.local -- pnpm run db:studio
|
|
```
|
|
|
|
This opens a web-based GUI at [https://local.drizzle.studio](https://local.drizzle.studio).
|
|
|
|
### Making schema changes
|
|
|
|
1. Edit the schema in `packages/db/src/schema/*`
|
|
2. Generate a migration:
|
|
```bash
|
|
dotenvx run -f .env.local -- pnpm run db:generate
|
|
```
|
|
3. Apply the migration:
|
|
```bash
|
|
dotenvx run -f .env.local -- pnpm run db:migrate
|
|
```
|
|
|
|
<Warning>Always review generated migrations before applying them, especially when working with existing data.</Warning>
|
|
|
|
---
|
|
|
|
## Working with translations
|
|
|
|
Reactive Resume uses [Lingui](https://lingui.dev/) for internationalization.
|
|
|
|
### Adding translatable text
|
|
|
|
Use the `t` macro for strings or `<Trans>` component for JSX:
|
|
|
|
```tsx
|
|
import { t } from "@lingui/core/macro";
|
|
import { Trans } from "@lingui/react/macro";
|
|
|
|
// For plain strings
|
|
const message = t`Hello, World!`;
|
|
|
|
// For JSX content
|
|
<Trans>Welcome to Reactive Resume</Trans>;
|
|
```
|
|
|
|
### Extracting translations
|
|
|
|
After adding new translatable text, extract them to the locale files:
|
|
|
|
```bash
|
|
pnpm run lingui:extract
|
|
```
|
|
|
|
Translation files live in `apps/web/locales`, in `.po` format.
|
|
|
|
---
|
|
|
|
## Code quality
|
|
|
|
### Linting & formatting
|
|
|
|
Uses [Biome](https://biomejs.dev/) for linting, formatting, import organization, and Tailwind class sorting:
|
|
|
|
```bash
|
|
# Non-mutating check
|
|
pnpm exec biome check .
|
|
|
|
# Project script with write/fix behavior
|
|
pnpm check
|
|
```
|
|
|
|
### Type checking
|
|
|
|
Run TypeScript type checking:
|
|
|
|
```bash
|
|
pnpm run typecheck
|
|
```
|
|
|
|
<Tip>
|
|
Configure your IDE to use Biome for formatting and lint diagnostics. The repo uses tabs, double quotes, 120-column
|
|
lines, and organized import groups.
|
|
</Tip>
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
<AccordionGroup>
|
|
<Accordion title="Port 3000 or 3001 is already in use">
|
|
The Vite web server uses `PORT` (default `3000`), and the Hono server uses `SERVER_PORT` (default `3001`).
|
|
Either stop the conflicting process or choose alternate ports:
|
|
```bash
|
|
PORT=3002 SERVER_PORT=3003 dotenvx run -f .env.local -- pnpm dev
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Database connection refused">
|
|
Ensure Docker containers are running:
|
|
```bash
|
|
docker compose -f compose.dev.yml ps
|
|
docker compose -f compose.dev.yml up -d
|
|
```
|
|
Check that PostgreSQL is healthy and accessible on port 5432.
|
|
</Accordion>
|
|
|
|
<Accordion title="S3/Storage errors">
|
|
Verify SeaweedFS is running and the bucket exists:
|
|
```bash
|
|
docker compose -f compose.dev.yml logs seaweedfs
|
|
docker compose -f compose.dev.yml logs seaweedfs_create_bucket
|
|
```
|
|
If the bucket wasn't created, restart the bucket creation service:
|
|
```bash
|
|
docker compose -f compose.dev.yml restart seaweedfs_create_bucket
|
|
```
|
|
</Accordion>
|
|
|
|
<Accordion title="Type errors after pulling changes">
|
|
The route tree may need regeneration. Run the dev server which auto-generates routes:
|
|
```bash
|
|
dotenvx run -f .env.local -- pnpm run dev
|
|
```
|
|
Or run type checking to see specific errors:
|
|
```bash
|
|
pnpm run typecheck
|
|
```
|
|
</Accordion>
|
|
|
|
</AccordionGroup>
|
|
|
|
---
|
|
|
|
## Next steps
|
|
|
|
<CardGroup cols={2}>
|
|
<Card title="Project Architecture" icon="folder-open" href="/contributing/architecture">
|
|
How the project and codebase are structured.
|
|
</Card>
|
|
<Card title="GitHub Repository" icon="github" href="https://github.com/reactive-resume/reactive-resume">
|
|
View the source code and contribute to the project.
|
|
</Card>
|
|
</CardGroup>
|