Personal career operations system
CareerTrack
Deployed Release Candidate2026
I built CareerTrack to keep opportunities, hiring-stage history, interviews, contacts, offers, private documents, and employment records in one personal career workspace.
- My contribution
- Solo Developer / Software Engineer
- Primary users
- People organizing their job search and career records.
- Project evidence
- Recorded hiring history
- Server-side sessions
- Private document storage
Technology stack
- Next.js
- React
- TypeScript
- Tailwind CSS
- Node.js
- Express
- PostgreSQL
- Prisma
- Zod
Problem & Solution
Scattered career information
I kept finding opportunities, recruiter conversations, interview notes, and documents across job boards, emails, spreadsheets, and bookmarks. An application status by itself did not keep that context together.
One structured workspace
I built the frontend, REST API, relational model, Authentication, and private document handling. Each application dossier connects hiring history, people, interviews, offers, notes, and documents. A career brief carries that journey into employment history.
Application Screens
Use the previous and next buttons, left and right arrow keys, or swipe or drag horizontally to browse. Home and End jump to the first and last screen. Select the image to enlarge it.
Opportunity Desk
Career direction, active opportunities, and follow-ups in one daily view.
The Career Workflow
- 01Opportunity
- 02Application
- 03Hiring journey
- 04Offer
- 05Employment
- 06Career history
This is the lifecycle the workspace supports. Users record actual stage changes, offers, and employment. Applications can skip stages, be rejected, or be withdrawn.
Production Architecture
User's browser
Vercel
Next.js frontend
Same-origin /api/* rewriteRailway
Express API / Node.js
Neon PostgreSQL
Relational data / Prisma ORM
Cloudflare R2
Private document storage
- Frontend
- Next.js App Router, React, TypeScript, Tailwind CSS
- Backend & data
- Node.js, Express, TypeScript, Zod, PostgreSQL, Prisma
Engineering Decisions
One browser origin across separate hostsVercel forwards /api requests to the Railway API.
I kept the frontend and API as separate applications in a pnpm monorepo. A same-origin rewrite handles the generated hosting domains while preserving host-only, Secure, HttpOnly, SameSite=Lax session cookies and exact-origin CSRF checks. Browser traffic stays on the CareerTrack domain.
Revocable sessions and explicit identity linkingThe server controls sessions; users choose when to connect Google.
I used an opaque session token in an HttpOnly cookie, while PostgreSQL stores its SHA-256 hash. Logout revokes the session. Google sign-in uses OIDC with state, nonce, and PKCE. A matching email does not silently merge accounts; an authenticated user must explicitly connect Google. The initial API deployment uses one replica because OAuth replay state and some rate limits are process-local.
Private files with an API authorization boundaryDocument metadata lives in PostgreSQL; file bytes stay in private R2 storage.
I made the API verify authentication and ownership before returning a document. A storage interface supports local development and S3-compatible production storage. Users can upload, replace, and link documents; PDFs support preview, while DOC/DOCX use authorized download. Database updates and object cleanup are separate operations, so orphan-file reconciliation remains an operational follow-up.
Recorded workflow history and honest insightsStage changes preserve history, and insights use events that actually exist.
I used a transaction to update the current application status and add a history entry, with conflict checks for stale changes. Career Intelligence counts explicitly recorded milestones without inferring skipped stages. Response timing describes recorded status movement, and small source groups show limited-data labels. Offers and accepted applications can be managed alongside linked employment records without inventing future career events.
Testing & Release Readiness
My release-candidate verification passed 60 focused API tests and 26 frontend tests. I also ran type checking, linting, production builds, and verification of six Prisma migrations. Production acceptance covered sessions, Google sign-in and linking, persistent records, and private document handling.
Deployed Release Candidate / beta
v1.0 remains pending. Before a broader release, I still need to add email ownership verification and explicit career defaults for new accounts. New accounts currently default to “Actively Job Hunting”; the planned correction will let users choose their own career direction.
What I Learned
Building CareerTrack showed me that interface design is only one part of a full application. I also had to think about Authentication boundaries, record ownership, workflow integrity, migrations, private storage, and deployment across providers. Testing production behavior and describing the release honestly taught me as much as building the screens.