Build and Deploy a Job Board With Claude Code
Build a real job board with public job listings, candidate applications, private CV uploads and a protected hiring dashboard, then deploy it to Hostinger.
Roadmap & Resources
Plan the Job Board
Plan the Hiring App
Open your project in Claude Code, fill in the three fields, and use this prompt. It only plans — nothing changes yet.
Plan the Job Board
Tell Claude what kind of company is hiring, what job details matter and what candidates should provide before anything is built.
I want to build a real job board and lightweight hiring app with Claude Code. Company: {{COMPANY_TYPE}} Job information: {{JOB_INFORMATION}} Candidate application information: {{APPLICATION_INFORMATION}} Do NOT build anything yet. First inspect the existing project. If this is an empty or new project, inspect the available stack and configuration and plan the smallest appropriate implementation. 1. PUBLIC EXPERIENCE Plan: 1. A visitor opens the Careers or Jobs page 2. Sees the published open positions 3. Browses or filters them if that is useful 4. Opens one job 5. Reads the job details 6. Clicks Apply 7. Completes the application 8. Uploads a CV 9. Submits 10. Gets a clear confirmation Candidates do NOT need accounts. 2. HIRING TEAM EXPERIENCE Plan a proper protected Hiring Dashboard. The hiring team must NOT run normal operations by editing rows in the Supabase dashboard. Inside the application, authorized staff should be able to: - sign in - create jobs - edit jobs - publish and unpublish jobs - close jobs - see applications - open a candidate's details - securely view or download a CV - add private notes - change an applicant's status - mark a candidate Hired or Rejected 3. DATA MODEL Plan the minimum data required. The likely concepts are a JOB, an APPLICATION, and ADMIN / HIRING STAFF access, with the CV file kept in private Supabase Storage. Do not add a candidate account, a company table, an interview table or an offer table unless the approved MVP genuinely requires them. 4. JOB STATUS Use exactly three constrained states: DRAFT, PUBLISHED and CLOSED. A job must not become public merely because its row exists — publishing is intentional. Do not create arbitrary free-text publication states. 5. APPLICATION STATUS Use one simple hiring pipeline: NEW → REVIEWING → INTERVIEW → HIRED and REJECTED. Do not build a configurable applicant-tracking pipeline, and do not allow arbitrary editable status text. 6. SECURITY MODEL A PUBLIC VISITOR may: - read the published jobs - submit an application to a published, open job - upload their own CV through the safe submission flow A PUBLIC VISITOR must NOT: - read applications - read CVs - create or edit jobs - publish jobs - change an applicant's status - read internal notes - reach the Hiring Dashboard AUTHORIZED HIRING STAFF may: - manage jobs - read applications - access applicant CVs - add internal notes - update a candidate's status Being signed in is not the same as being hiring staff — plan a trusted staff check. Never put a Supabase Secret or service-role key in browser code. 7. NO AUTOMATED HIRING DECISIONS Do not plan candidate scoring, AI ranking, a fit score, a "best candidate" suggestion or automatic rejection. Do not plan anything that infers candidate quality from a name, age, photo, gender, nationality, disability or any other personal characteristic. The application presents candidate information; the hiring team decides. 8. EXCLUDED FROM VERSION 1 Do not plan: candidate accounts or candidate login, a recruiter marketplace, multiple companies or multi-tenancy, LinkedIn or Indeed integration, job syndication, email automation, interview scheduling, calendar integration, AI resume scoring, AI applicant ranking, AI interview questions, offer letters, e-signatures, payroll, employee onboarding, HR management, a team permissions matrix, analytics dashboards, video interviews, background checks or a referral system. Return: JOB BOARD PLAN Public pages: Hiring pages: Job fields: Application fields: Job statuses: Application statuses: Data model: CV Storage model: Hiring authorization: Public permissions: Staff permissions: Features deliberately excluded: Then return exactly one: READY TO BUILD or: NEEDS A DECISION Do not modify anything yet.
What type of company is hiring?
SaaS startup, marketing agency, restaurant, local business...
What should each job listing show?
Title, location, job type, salary range, description, requirements...
What should candidates provide when applying?
Name, email, phone, CV, portfolio, LinkedIn, short message...
Review the plan before continuing. Keep version 1 focused on jobs, applications and hiring workflow.
Confirm the MVP
Make sure the approved plan includes exactly this:
Public job listings
Job details
Candidate application
Private CV upload
Protected Hiring Dashboard
Job management
Applicant management
No unnecessary HR features
Set Up Supabase
Create or Reuse Supabase
If this project is already connected to the right Supabase project, reuse it — don't create a second one.
Open Supabase
https://supabase.link/r4gdwhi
Create a new project if you don't have one Open the project's Connect panel Copy the Project URL and the Publishable key Ask Claude Code which environment variable names this project uses, then add both values locally
IMPORTANT
The browser app only needs the Project URL and the Publishable key. A Secret key belongs only in a trusted server environment, and only where one is genuinely needed — never in browser code and never committed to GitHub.
Create the Hiring Data
Use this prompt in the same Claude Code session.
Create the Job Board Database
Create the smallest Supabase structure for jobs, candidate applications, private CVs and protected hiring access.
Using the approved job-board plan, create the minimum database, Storage and access rules. Reuse correct existing structures where appropriate. Do not duplicate existing profiles or admin infrastructure. Never print secret values. 1. JOBS Store only the fields approved in the plan. Typical fields where relevant: id, title, slug, location, employment type, salary or salary range only if approved, short summary, description, requirements, status, created_at, updated_at. Do not automatically add every possible HR field. 2. JOB PUBLICATION Constrain the status to draft, published and closed — not free text. Public visitors may read PUBLISHED jobs only. Draft and closed jobs must not leak merely because the frontend filters them out: the data and access layer must respect the publication state itself. 3. APPLICATIONS Store only the approved candidate information. Possible fields: id, job_id, name, email, phone if genuinely needed, portfolio or LinkedIn if approved, the candidate's message, the CV path or reference, status, private notes, created_at, updated_at. Do not collect unnecessary personal information. In particular do NOT ask for age, date of birth, marital status, gender, photo, ethnicity, religion or disability information — none of it belongs in this application. 4. CV / RESUME STORAGE Use a PRIVATE Supabase Storage bucket. A CV is a private candidate document. Do NOT make the bucket publicly readable and do NOT generate a permanent public URL for a resume. Use this project's established private-file pattern, so that only authorized hiring staff can retrieve a CV, through short-lived signed access requested at the moment it is opened. 5. UPLOAD RULES Apply proportionate restrictions: the approved document types, a reasonable maximum file size, and one CV per application unless the approved model needs another rule. Do not trust the filename extension alone. Never accept an executable. Use the current safe upload pattern where this project already has one. 6. APPLICATION SUBMISSION A public visitor may apply only to a job that is currently published and open. Trusted logic — not the browser — determines the job relationship, the initial status NEW, the timestamps and the private Storage path. The public browser must NOT be able to control the application status, the private notes, any staff field, an arbitrary CV path, or another candidate's record. 7. CLOSED JOB A closed or draft job must REJECT a new application on the trusted path. Do not rely on hiding the Apply button. 8. STAFF AUTHORIZATION Use real authenticated hiring/admin authorization. Do not treat every authenticated Supabase user as hiring staff. Do not rely on hidden routes, localStorage, frontend role checks or client-editable metadata. The database or server rules must enforce hiring permissions. Reuse the closest admin authorization pattern this project already uses. Tell me how to grant the FIRST hiring admin safely — for example one reviewed SQL statement run once in the Supabase SQL Editor — never through self-service sign-up. 9. PUBLIC APPLICATION READ Public visitors must NOT be able to list applications, read a candidate record, read a CV path, or read internal notes. Give me: 1. Tables reused 2. Tables created 3. Job publication and access model 4. Application submission model 5. CV Storage model 6. CV access model 7. Staff authorization model 8. Application status model 9. ONE reviewed SQL / migration block where appropriate 10. The Storage setup I need to do myself 11. Any RPC, server route or Edge Function required 12. Any blocker Do not use destructive DROP statements. If a table with the same name already exists, warn me instead of replacing it. Do not execute destructive database changes automatically, and do not build the UI yet.
IMPORTANT
A CV is a private document a real person trusted you with. Its bucket stays private and it never gets a permanent public link — staff open it through short-lived signed access, and nobody else can reach it at all.
Review the database plan and SQL, then apply it with your project's Supabase workflow — usually the SQL Editor in your Supabase project. Create the private Storage bucket the report asks for, then create your own staff account and grant it hiring access the way the report describes.
The tables and access rules exist in Supabase
The CV bucket exists and is private
My staff account has hiring access
Build the Public Job Board
Build the Jobs Experience
Build the Public Job Board
Build the careers page and reusable job details using real published Supabase jobs.
Build the public job-board experience from the approved plan, using the Supabase structure we just created. Reuse the current website design and components. Do not redesign unrelated pages. 1. JOBS PAGE Create or reuse an appropriate route — /careers or /jobs, whichever fits this project. Do not create duplicate Careers and Jobs sections unless the project genuinely needs both. 2. JOB LIST Load the real published jobs from Supabase. A card or row shows what is useful at a glance — typically the title, the location, the employment type and a short summary. Show a salary only if it is part of the approved data. Do not put every job field on the list. 3. FILTERING Add simple filters only if the approved job set benefits from them — for example location, employment type, or department if this company actually uses one. Do not build complex search infrastructure and do not add an external search provider. 4. JOB DETAIL Create ONE reusable dynamic job route. Do not generate a separate hardcoded page for each job. Show the approved fields: title, location, employment type, description, requirements, salary where provided, and a clear Apply call to action. 5. CLOSED AND DRAFT JOBS A public user must not reach a draft job by guessing its route. A closed job may show "This position is no longer accepting applications" ONLY if the approved model deliberately keeps closed job pages public. Otherwise do not expose it at all. Either way the Apply path must be closed on the server, not just visually. 6. RESPONSIVE The job list, the job detail and the Apply call to action must all stay usable on a phone. When you are finished, tell me which routes and components you created or reused, and exactly how a draft job is kept out of the public pages.
IMPORTANT
Hiding a draft job with an if-check in the browser is not privacy. Anyone can read the data the page requested, so an unpublished job has to be refused by the database itself.
Build the Application Flow
Add Job Applications
Let candidates safely apply to an open job and upload a private CV without creating an account.
Build the public candidate application flow for the current job, using the trusted submission path and the private Storage model we created earlier. 1. JOB RELATIONSHIP The application is tied to the job the candidate is currently viewing, through trusted logic. Do not let the public form choose an arbitrary hidden job id. 2. FIELDS Use only the approved application fields. Do not ask for unnecessary personal information, and do not add any of the sensitive fields we excluded. 3. CV Upload the CV through the approved PRIVATE Storage path. Never expose its Storage location on a public page and never make the bucket public. Validate the file type and size against the approved rules before accepting it. 4. SUBMIT On submit: validate the fields, validate that the job is still published and open, validate the CV, create the application, let trusted logic assign the status NEW, and associate the private CV with the application. Prevent an accidental double submission where that is practical. Handle a partial failure properly: do not create an application record that points at a CV upload that failed, and do not leave orphaned uploads behind unnecessarily. 5. SUCCESS Show a concise, professional confirmation such as "Application received. Thanks for applying." Do not promise an interview, an email reply or a response time — none of that is automated in this build. 6. FAILURE Keep the text the candidate already typed where that is practical. Say clearly when the CV type or size was rejected. Show a useful generic error for anything else, and never display raw database or Storage internals. Tell me where the job relationship is established, where the open/published check happens, and where the initial status is set.
Then run the app and check the public side works before you build the dashboard:
The careers page lists real published jobs
A job page opens and survives a refresh
Applying with a safe test CV shows the confirmation
An oversized or wrong-type file is rejected clearly
Checking the stored application in Supabase is fine while you test. The hiring team will use the dashboard you build next.
Build the Hiring Dashboard
Build Job Management
Build the Hiring Dashboard
Create the protected dashboard the company will use to publish jobs and manage candidates without touching Supabase directly.
Build the protected Hiring Dashboard using the approved staff authorization model. This is the company's normal hiring interface — it exists so nobody has to open Supabase to run hiring. 1. STAFF LOGIN Use Supabase Auth. If this project already has trusted staff or admin authentication, reuse it — do not add a second login system. Otherwise add the smallest secure staff sign-in. Candidates do not need accounts. Only hiring staff sign in. 2. DASHBOARD NAVIGATION Use two primary operational areas: Jobs and Applicants. Do not create unnecessary HR sections. 3. JOB LIST Show each job with its title, location and status, plus an application count and an updated or created date where those are easy and genuinely useful. Give clear actions: Edit, Publish, Unpublish, and Close. Do not expose raw database internals such as column names or ids the team does not need. 4. CREATE AND EDIT A JOB Let authorized staff create and edit the approved fields, and validate the important values. Make the publication control obvious, so a new job cannot become public before it is meant to. 5. CLOSE A JOB Closing a job must prevent new applications at the trusted database or server boundary — not merely by hiding the Apply button. 6. SECURITY Every dashboard route and every staff read is protected by the trusted staff check from the database layer. A signed-in non-staff user and a signed-out user must both be refused. Tell me which routes are protected, and where closing a job actually blocks a new application.
Then sign in with your staff account and check:
The dashboard opens for your staff account
Jobs and Applicants are both there
A signed-out visitor cannot reach the dashboard
Build Applicant Management
Add Applicant Management
Let hiring staff review candidate applications, private CVs, notes and hiring status from one protected dashboard.
Add applicant management to the protected Hiring Dashboard. 1. APPLICANT LIST Show the candidate name, the job applied for, the application date and the current status. Add simple filtering by job and by status. Do not build a complex applicant-search engine. 2. APPLICANT DETAIL Show the candidate's information, their application message, the job they applied for, the application date, the current status, the private notes and the CV action. 3. CV ACCESS Provide View CV or Download CV through the approved private-access mechanism — short-lived signed access requested when staff open it. Do not expose a permanent public CV URL, and never reveal Storage internals to candidates or public users. 4. APPLICATION STATUS Allow exactly: New, Reviewing, Interview, Hired, Rejected. Use controlled values — no arbitrary free-text statuses. 5. INTERNAL NOTES Let hiring staff save internal notes on a candidate. These notes are private: they must never appear on a public job page, in anything sent to a candidate, or in any public response. 6. NO AI RANKING Do NOT add a candidate score, an AI recommendation, a "best candidate" suggestion, a fit score or any automatic rejection. Do not rank or sort candidates by inferred quality, and do not infer anything from a name, age, photo, gender, nationality or disability. The dashboard presents candidate information to human hiring staff. People make hiring decisions. Tell me where the private notes are kept out of public responses, and confirm no scoring or ranking was introduced.
IMPORTANT
Don't let the app score, rank or auto-reject candidates. A model guessing who is worth interviewing will quietly repeat whatever bias is in the data, and a real person's job is on the other end of it. The dashboard shows you the application; you decide.
Test Job Administration
Prove publication actually controls what the public can reach.
Create a test job and leave it as a Draft
Public: the draft job is nowhere on the careers page
Public: opening its direct URL does not expose it
Publish it, and confirm it appears publicly
Close it, and confirm a new application is blocked
Test the Hiring Workflow
Run the Full Candidate Flow
One pass through the whole workflow, as the hiring team and then as a candidate.
Admin — sign in and create one test job:
Title: Frontend Developer
Location: Remote
Type: Full-time
Publish it
Candidate — open the public jobs page in a signed-out or incognito window:
Open Frontend Developer and click Apply
Apply as Test Candidate with a safe test PDF CV
Submit and see the confirmation
Admin — back in the Hiring Dashboard:
The new application appears for Frontend Developer
Open the candidate and view the CV
Add the note: Strong portfolio — schedule interview.
Move it New → Reviewing → Interview
Set a final test state: Hired or Rejected
Refresh — the note and the status are still there
Verify the Job Board
Verify the Hiring App
Verify job publication, private candidate data, CV access and hiring authorization before deployment.
Perform a focused verification of this job board and hiring app. Use test jobs and test applicants only. Do not add features. 1. PUBLIC JOBS - published jobs are public - draft jobs are not exposed - a closed job cannot accept a new application - a guessed draft job route does not expose a private listing 2. APPLICATIONS - a candidate can submit to an open published job - the initial status is New - a candidate cannot inject Hired, Rejected, private notes or any staff field - public users cannot list or read applications 3. CV STORAGE - a valid test CV uploads - an unsupported or oversized file is rejected according to the approved rules - the CV is NOT publicly accessible - authorized hiring staff can access it - unrelated or public users cannot access it 4. STAFF AUTHORIZATION - trusted staff can sign in - an unauthorized user cannot manage jobs - an unauthorized user cannot read applicants - an unauthorized user cannot access CVs - authorization is enforced beyond hidden UI — test the data layer directly 5. HIRING PIPELINE New → Reviewing → Interview → Hired, and Rejected, all persist correctly. 6. PRIVATE NOTES - staff can save notes - notes persist - no public or candidate-facing response ever includes them 7. AI / AUTOMATION CHECK Confirm no automated candidate ranking, scoring or hiring recommendation was introduced anywhere in the project. 8. SECRETS Confirm no Supabase Secret or service-role credential exists anywhere in browser code. Return exactly one: JOB BOARD VERIFIED or: NEEDS ATTENTION Use JOB BOARD VERIFIED only if public jobs work, the application works, CV privacy works, staff authorization works, the applicant pipeline works, and draft and private hiring data stay protected. If NEEDS ATTENTION, list only the remaining job-board and hiring issues.
Publish one final test job, submit one test application with a safe CV and verify it appears in the Hiring Dashboard before deployment.
Deploy to Hostinger
Deploy the Job Board
Before pushing to GitHub, check:
The project builds successfully
No .env or other secret files are being published
No Supabase Secret or service-role key is in browser code
You know the production environment variable names
A job URL still works after a refresh in a production build
Push the project to GitHub with Claude Code or your normal GitHub workflow. If it already has a repository, use it.
Deploy on Hostinger
Recommended plan: Business
USED IN TUTORIAL
https://www.hostg.xyz/SHK1P
Hostinger Websites Add Website Node.js Web App
Choose Import Git repository Connect GitHub and select the job board's repository Review the detected framework and build settings Add the environment variables with your project's exact names Click Deploy and wait for the result
IMPORTANT
Add the Supabase Project URL and Publishable key under the names your project already uses. Private server keys stay private — never rename one to a VITE_ or NEXT_PUBLIC_ variable to make the deployment work.
Fix a Failed Website or Web App Deployment with AI
Use this if the Hostinger deployment fails.
/video/fix-a-failed-website-or-web-app-deployment-with-ai
Test the Live Job Board
First add your live Hostinger URL in Supabase so staff sign-in works in production:
Supabase Authentication URL Configuration
Set the Site URL to your live URL and add it to the Redirect URLs. Then ask Claude Code to update any other production setting that depends on the live address. Then open the live site and check:
Public: the careers page loads and published jobs appear
Public: open a job and apply with a test CV
Public: the confirmation appears
Admin: sign in and see the test applicant
Admin: view the test CV, add a note, change the status
Admin: create, edit, publish and unpublish a job
Admin: a closed job blocks new applications
Privacy: a public user cannot read applications
Privacy: a public user cannot open the test CV
Privacy: a draft job stays private
Mobile: jobs and the application form both work
Mobile or tablet: the dashboard is still usable
Verify the Live Job Board
Check the complete live job-posting and candidate workflow on Hostinger before using it for real hiring.
Perform a focused production verification of this job board now that it is live on Hostinger. Do not add features. 1. GITHUB - the approved source is what is actually deployed - no real secret file is committed 2. HOSTINGER - the deployment succeeded - the intended repository and branch are connected - the build and runtime configuration are correct - every required environment variable is configured 3. SUPABASE - the production app uses the intended project - staff authentication works - staff authorization is enforced - private Storage works - no private credential is exposed client-side 4. PUBLIC JOBS - a published job appears - a draft job remains hidden - the job detail works - a direct job-route refresh works - a closed job rejects applications 5. APPLICATION - a safe test application succeeds - the CV uploads privately - the confirmation works 6. HIRING - the candidate appears in the dashboard - the private CV can be accessed only by authorized hiring staff - notes persist - status persists 7. ACCESS - public users cannot read applicant records - public users cannot access CVs - unauthorized users cannot manage jobs or applications Return exactly one: JOB BOARD LIVE or: NEEDS ATTENTION If JOB BOARD LIVE, summarize: job publishing, the application, CV privacy, the Hiring Dashboard, the candidate pipeline, and the deployment. If NEEDS ATTENTION, list only launch blockers.
Publish one final test job on the live site, submit a safe test application and confirm the candidate appears in the Hiring Dashboard before posting real positions.