Skip to content

Xavviieerr/Tailr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

95 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tailr

TypeScript Node.js Prisma Postgres

Tailr is a desktop-first resume/CV builder: a React/Vite frontend paired with a TypeScript Express backend (Prisma + Postgres). This repository highlights production-ready backend engineering: typed DB access, connection pooling, auth integration, layered services, and operational build strategies.

demo


Why this project (backend focus)

  • Demonstrates practical backend engineering: TypeScript-driven safety, Prisma schema design, a custom DB adapter with pg.Pool to manage connections, and a build strategy that keeps Prisma client resolution predictable across dev and prod.
  • Shows tradeoffs and pragmatic choices: JSON payloads for flexible CV content, generated Prisma client location for reliable compiled outputs, and middleware-based concerns (auth, rate-limiting, validation).

Tech stack

  • Backend: Node.js, Express, TypeScript
  • ORM: Prisma (Postgres) with @prisma/adapter-pg and pg pooling
  • Auth: Clerk
  • Frontend: React + Vite (context), Redux
  • Notifications (client): react-toastify

Architecture

  • Monorepo: client/ (frontend) and server/ (backend).
  • Server layout (src):
    • src/server.ts, src/app.ts — app bootstrap and route mounting
    • src/lib/prisma.ts — Prisma client factory handling dev vs compiled locations and pooling
    • src/middleware/* — auth, rate limiting, and helpers
    • src/modules/* — domain folders (controllers → services → repositories)
    • src/generated/prisma — generated Prisma client (compiled into dist/src/generated/prisma)

Request flow (example: update CV):

  1. Express route receives request and runs middleware (auth, rate limit).
  2. Controller validates input and calls appropriate service.
  3. Service orchestrates business logic and calls repository.
  4. Repository uses Prisma client to interact with Postgres.

Prisma & build strategy

  • We generate the Prisma client into server/src/generated/prisma during development so tsc compiles it into dist/src/generated/prisma for production.
  • src/lib/prisma.ts attempts to load the generated client from several locations (compiled and source) and falls back to @prisma/client where appropriate. This pattern keeps runtime import paths robust across ts-node dev and compiled dist production.
  • CI recommendation: run npx prisma generate before npm run build (or add it into the build script) to ensure generated client is present.

Setup & Run (local development)

Prereqs: Node 18+, PostgreSQL

Server:

cd server
npm install
# set server/.env with DATABASE_URL and Clerk keys
npx prisma generate
npx prisma migrate dev   # or `npx prisma db push` for quick iteration
npm run dev

Client:

cd client
npm install
# set VITE_CLERK_PUBLISHABLE_KEY in client/.env
npm run dev

Production build (server):

cd server
npx prisma generate
npm run build
npm start

Example server/.env:

DATABASE_URL=postgresql://user:password@localhost:5432/tailr_dev
CLERK_SECRET=pk_test_XXXXXXXXXXXXXXXX

APIs & data model (summary)

  • Important endpoints:

    • GET /api/cvs — list the authenticated user's CVs
    • GET /api/cvs/:id — retrieve a single CV owned by the user
    • POST /api/cvs — create a new CV (owner = authenticated user)
    • PATCH /api/cvs/:id — update CV content (owner-checked)
    • DELETE /api/cvs/:id — delete CV (owner-checked)
  • Data model (Prisma):

    • User (id, firstName, lastName, email, clerkId, timestamps)
    • Cv (id, userId, name, jobTitle, company, content: Json, timestamps)

Design note: storing content as JSON gives frontend flexibility for templates/sections while preserving relational owners and indexes.


Security, validation & reliability

  • Auth: Clerk integration enforces identity; middleware extracts clerkUserId for downstream checks.
  • Authorization: services/repositories confirm userId ownership prior to mutations.
  • Rate limiting & global guards protect endpoints from abuse.
  • Input validation occurs at controller/service boundaries; Prisma ensures parameterized queries to avoid injection.

Observability & scaling

  • Logging: critical errors and lifecycle events are logged — swap in pino/winston for structured logs.
  • Metrics: instrument controllers/services for request durations, DB latency; export Prometheus metrics in production.
  • Scaling: keep app stateless; use connection pooling (pg.Pool) and consider PgBouncer for large horizontal scale to avoid DB connection limits.

Contributing

  • Open issues for bugs or feature requests.
  • Send PRs with tests and a clear description of changes.

License

This repository is provided as-is. Add a license file if you intend to publish.

About

"Tailr" tailors your resume to every job post, saving you hours of manual tweaking.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages