Skip to content
_david edited this page Sep 26, 2026 · 3 revisions

Resume API — Backend Wiki

Node.js/TypeScript REST API for managing candidate CVs/resumes: JWT auth (cookie + Bearer, CSRF-protected), CRUD for 7 CV sections plus a job-application tracker and named CV profiles, PDF/DOCX export, Redis-backed rate limiting/token blacklist, LinkedIn-export import, and i18n (vi/en).

Version: 1.7.0 · Author: DatVT · License: ISC · Live: nodejs-resume-api-ts.onrender.com

Pages

  • Getting Started — clone, env setup, run locally (or via Docker), all npm scripts
  • Architecture — project structure, request/middleware flow, module layout
  • API Reference — every endpoint, grouped by area
  • Authentication — JWT (cookie + Bearer) flow, CSRF, token blacklist, session revocation, i18n messages
  • Data Models — Candidate + CV sections + Application/Profile/Visit, multi-language content shape, soft-delete
  • Security — protections in place, invariants, past incidents and fixes
  • Deployment — branching model, Render + GitHub Actions pipeline, Docker, known gotchas
  • Contributing — branch/PR conventions, testing, issue tracker

Tech stack at a glance

Layer Tech
Runtime Node.js >=20.19.0 <23.0.0 + TypeScript 5.5 (strict, CommonJS)
Framework Express 4.19
Database MongoDB + Mongoose 8.4
Cache / Blacklist Redis 4.6 (in-memory fallback if unset/unreachable)
Auth JWT (access + refresh, httpOnly cookie or Bearer), Bcrypt (12 rounds), double-submit CSRF
Validation Joi 17.13
PDF / DOCX Puppeteer 22.13 + PDFKit 0.15 + Pug 3.0 / docx 9.7
Uploads / parsing multer 2.3 (CV/image/LinkedIn-export uploads), adm-zip + csv-parse (LinkedIn export)
Logging Winston 3.19 + daily-rotate-file
Testing Jest 29 + ts-jest
i18n Hand-rolled (Accept-Language, vi default / en opt-in), 100+ message keys across auth/candidate/CV-section/images

What's new since 1.1.0

A lot has landed since the last full wiki pass (2026-08-21, v1.1.0):

  • CSRF + httpOnly cookie auth (#119, #134) — tokens can now travel as httpOnly cookies (needed once the frontend and API became genuinely cross-site), with a real double-submit CSRF check replacing the incidental protection that SameSite=strict used to provide.
  • Soft-delete + restore (#121) across every CV section — deletes are now recoverable (POST .../restore/:id) instead of permanent.
  • CV Profiles (#133) — a candidate can define named subsets ("Tổng hợp"/All by default, plus custom ones) of their Education/Experience/Project/Certificate/Award/Reference entries, and share a public link filtered to just one profile.
  • Job Application tracker (#132) — a private applications CV-section (applied/interview/offer/rejected pipeline), separate from the public CV.
  • LinkedIn export import (#141) — upload a LinkedIn "Data export" ZIP, get back parsed Education/Experience entries for the frontend to review before saving (stateless, nothing persisted server-side).
  • Vanity slug public profiles (#120) — GET /api/me/:slug-or-email, plus per-visit analytics (IP + geo).
  • Logout of all devices (#74), pagination/sort on CV-section lists (#73), DOCX export alongside PDF, and Docker support for local/dev/prod parity.
  • Two real security incidents were found and fixed via /code-review: a NoSQL-filter-collapse bug that could leak an arbitrary candidate's profile (#135), and a soft-delete bypass that let an already-deleted document still be mutated via update/patch (#136) — see Security for both.

See Security for incident writeups and Data Models for the current schema shape. Full technical evidence for every change lives in the repo at agent-hub/evidence/.

Clone this wiki locally