CLAUDE.md
CLAUDE.md
Important: PRD Workflow
Always read prd.md at the start of any session. This document tracks tasks and their status.
When making changes to the codebase:
- Check if the change relates to a planned item in the PRD
- After implementing, move the task to "Completed" with date and brief note
- Add new tasks to "Planned" section
- Update
CHANGELOG.mdwith a summary of changes
Keep the PRD concise and task-focused:
- Use tables for task lists (not long paragraphs)
- Brief notes only (1 line per task)
- No detailed implementation specs - those belong in code comments or separate docs
- Focus on: what was done, what's planned, current status
Git & Release Conventions
Releases are automated with release-please (config in release-please-config.json,
version tracked in .release-please-manifest.json). The version history on GitHub
(tags + Releases) is generated from commit messages, so commit/PR hygiene is what makes
it work — treat the rules below as required, not optional.
Conventional Commits — always. Every commit and PR title MUST follow Conventional Commits, because release-please derives the version bump and CHANGELOG from them:
feat: ...→ minor bump (lands under Added)fix: ...→ patch bump (lands under Fixed)perf:→ Performance ·refactor:→ Changedfeat!: ...or aBREAKING CHANGE:footer → major bumpchore:/ci:/build:/docs:/test:/style:→ no release (hidden from CHANGELOG)- A commit with none of these prefixes is invisible to release-please and silently dropped from the changelog — never use freeform commit subjects.
Branch & merge flow:
- Feature branches →
develop→main. Releases are cut frommainonly. - PRs are squash-merged, and the PR title is the Conventional Commit that ends up
in history. Write the PR title accordingly (e.g.
feat: bilingual blog support). - Never commit or push directly to
mainordevelop— always via PR.
Do NOT edit by hand (release-please owns them): version in package.json,
.release-please-manifest.json, and the auto-generated version sections of
CHANGELOG.md. To ship a release, merge the chore(release): x.y.z PR that
release-please opens on main. Manual changelog notes (if any) go under [Unreleased].
Before opening a PR, make sure the CI gate passes — npx tsc --noEmit must be clean
(the .github/workflows/ci.yml typecheck job blocks merge). npm run lint is not yet a
gate (pre-existing errors tracked in prd.md), but don't add new lint errors.
Project Overview
RentNGo is a car rental platform with VIP transfer services for the Romanian market. Built with Next.js 16, Convex, and Clerk v7 authentication. Supports Romanian (default) and English.
Commands
This project uses mise for tool version management, env vars, and task running. See mise.toml for all tasks.
| 1 | mise dev # Start development (frontend + backend) |
| 2 | mise build # Build for production |
| 3 | mise lint # Run linter |
| 4 | mise run check # Lint + format check + typecheck |
| 5 | mise run convex:deploy # Deploy backend |
Fallback (no mise installed):
| 1 | bun run dev # Start development (frontend + backend) |
| 2 | bun run build # Build for production |
| 3 | bun run lint # Run linter |
| 4 | bunx convex deploy # Deploy backend |
| 5 | bun run typecheck:fast # tsgo, fast + advisory; run the real `bun run typecheck` (tsc) before a PR |
Package manager: bun is PM + script-runner only — Node stays the runtime. bun install
and bun run <script> are fine, but never pass --bun to next or convex (both have
open bugs under the bun runtime — Convex WS 101 on deploy, Next 16 build resolution errors).
Scripts invoke next/convex via the default shebang, so they run under Node.
Project Structure
| 1 | app/ |
| 2 | ├── [locale]/ # Public routes with i18n (ro/en) |
| 3 | │ ├── cars/ # Vehicle browsing |
| 4 | │ ├── reservation/ # Booking flow |
| 5 | │ └── transfers/ # VIP transfers |
| 6 | ├── admin/ # Admin dashboard (no i18n) |
| 7 | |
| 8 | convex/ # Backend functions & schema |
| 9 | components/ # React components |
| 10 | hooks/ # Custom React hooks |
| 11 | lib/ # Utilities |
| 12 | messages/ # Translations (en.json, ro.json) |
Key Concepts
Routing: Public pages use /[locale]/ prefix. Admin routes have no locale prefix.
Database: Convex with tables for users, vehicles, vehicleClasses, reservations, transfers, seasons, blogs.
Authentication: Clerk with admin access controlled by hardcoded user IDs in middleware.ts.
Pricing:
- Vehicles use
pricingTiersarray (tiered daily rates based on rental length) - Seasonal multipliers applied from
seasonstable - Transfers priced by distance via Mapbox
Defaults:
- Default location: "Aeroport Cluj-Napoca"
- Default pickup/return time: 10:00
Convex Conventions
- Use
query,mutation,actionwrappers withargsandreturnsvalidators - Reference functions via
api.filename.functionName - Use indexes for filtering (defined in
schema.ts) - For detailed guidelines, see
.cursor/rules/convex_rules.mdc
Environment Variables
| 1 | NEXT_PUBLIC_CONVEX_URL |
| 2 | NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY |
| 3 | CLERK_SECRET_KEY |
| 4 | CLERK_JWT_ISSUER_DOMAIN |
| 5 | RESEND_API_KEY |
| 6 | NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN |
| 7 | NEXT_PUBLIC_GTM_ID |
This project uses Convex as its backend.
When working on Convex code, always read convex/_generated/ai/guidelines.md first for important guidelines on how to correctly use Convex APIs and patterns. The file contains rules that override what you may have learned about Convex from training data.
Convex agent skills for common tasks can be installed by running npx convex ai-files install.