Job search, hiring, and CV management for desktop and Android.
JobOS brings job seekers and recruiters into one workflow: build a CV, discover opportunities, submit applications, and review candidates. It started as a lab project and grew into a Java application with two native clients and a shared backend. The project is open source and welcomes anyone who wants to learn, contribute, improve it, or build a fork.
Demo · Screen gallery · Features · Architecture · Getting started · Contributing · MIT license
▶ Watch the full JobOS demo on YouTube
A 20-second screenshot tour of job discovery, applications, CV editing, recruiter review, and notifications.
For a closer look, expand a gallery below and click any image to open the original screenshot.
The screenshots show desktop and Android views side by side where available. Each gallery follows a related part of the user journey.
1. Getting into JobOS: welcome, registration, and onboarding
Choose a role, create an account, and complete a seeker or company profile.
| Welcome | Desktop registration and seeker profile |
|---|---|
![]() |
![]() |
| Company profile, sign-in, and password recovery | Android registration and role setup |
![]() |
![]() |
2. Finding a job: discover, apply, and track progress
Start at the seeker dashboard, browse opportunities, inspect a listing, and apply with a CV and cover letter. Return to application history to follow the outcome.
| Seeker dashboard | Browse and filter jobs |
|---|---|
![]() |
![]() |
| Job details | Submit an application |
![]() |
![]() |
| Application history | Application details |
![]() |
![]() |
3. Building a CV: templates, editing, and export
Manage CVs, select a template, edit sections, and preview the exported document.
| CV manager and templates | CV editor |
|---|---|
![]() |
![]() |
| Exported document preview | |
![]() |
4. Hiring candidates: manage jobs and review applicants
Use the recruiter dashboard to manage listings, inspect applications, review candidate CVs, and maintain a company profile.
| Recruiter dashboard | Job management |
|---|---|
![]() |
![]() |
| Applicant review | Recruiter and company profiles |
![]() |
![]() |
5. Managing an account: plans, notifications, and settings
View credits and plans, follow application updates, and adjust account preferences. The plans screen demonstrates the project's credit and subscription model; payment processing is simulated.
| Credits and plans | Notifications |
|---|---|
![]() |
![]() |
| Settings | |
![]() |
| For job seekers | For recruiters |
|---|---|
| Search by location, salary, job type, work mode, and experience level | Create, edit, close, and reopen job posts |
| Save opportunities for later | Review applicants for each listing |
| Build CVs from templates and manage their sections | View candidate CVs from application details |
| Preview CVs and export them as PDFs | Update application status and follow hiring activity |
| Apply with a CV and cover letter; track application history | Maintain recruiter and company profiles |
Shared capabilities include JWT authentication with refresh tokens, device-specific sessions, role-based access checks, profile preferences, password recovery by email, and notification history. Android supports Firebase Cloud Messaging push notifications; the desktop client polls the API for updates.
Application statuses are PENDING, REVIEWED, SHORTLISTED, ACCEPTED, and REJECTED.
Project scope: JobOS is a lab-origin project available for continued development. Credit balances, template unlocking, and subscription records are implemented, while purchases use simulated flows without a payment gateway. Screenshots contain demonstration data and UI copy, including sample usage counts and plan benefits.
Both clients communicate with the same REST API. The backend owns authentication, authorization, business rules, and persistence; each client handles its native interface and local PDF generation.
flowchart LR
Desktop[JavaFX desktop] -->|HTTP / JSON| API[Spring Boot REST API]
Android[Native Android] -->|HTTP / JSON| API
API --> DB[(PostgreSQL)]
API --> FCM[Firebase Cloud Messaging]
FCM -->|Push notifications| Android
API --> SMTP[SMTP email]
| Component | Implementation |
|---|---|
| Backend | Java 25, Spring Boot 4.0.0, Spring Security, Spring Data JPA, PostgreSQL |
| Desktop | Java 25, JavaFX 25.0.1, FXML/CSS, OkHttp, Jackson, Apache PDFBox |
| Android | Native Java, AndroidX, Material Components, View Binding, OkHttp, Firebase Messaging; Android 7.0 / API 24 or newer |
| Shared contracts | Java DTOs and validation annotations used by the backend and desktop |
| Build | Gradle wrapper; root multi-project build plus a separate Android build |
The backend follows a controller → service → repository structure. Desktop views use FXML and controllers; Android organizes activities, fragments, and view models by feature. Android maintains its own API models rather than depending on the root shared module.
JobOS/
├── backend/src/main/
│ ├── java/com/jobos/backend/ # Controllers, services, entities, repositories, security
│ └── resources/ # Application configuration and email templates
├── desktop/src/main/
│ ├── java/com/jobos/desktop/ # JavaFX controllers, API services, and application state
│ └── resources/ # FXML views, CSS, and desktop configuration
├── android/ # Independent Gradle project; open in Android Studio
│ └── app/src/main/ # Native UI, network layer, models, and resources
├── shared/src/main/java/ # Backend and desktop DTOs
├── screenshots/ # Product screenshots, thumbnail, and demo GIF
├── DIARY.md # Development history
└── LICENSE # MIT license
- JDK 25 for the backend, desktop, and shared modules.
- PostgreSQL running locally, with permission to create a database and role.
- Android Studio and Android SDK 36 for the Android app. Use JDK 17 for its Gradle build; Android source compatibility is Java 11.
- A Firebase project for Android configuration and push notifications. Firebase is optional when running only the backend and desktop.
- An SMTP account if you want to exercise email password recovery.
The repository includes Gradle wrappers; no global Gradle installation is required.
git clone https://github.com/khalid999devs/JobOS.git
cd JobOSConnect to PostgreSQL as an administrator and run:
CREATE USER jobos WITH PASSWORD 'replace-with-your-local-password';
CREATE DATABASE jobos OWNER jobos;The backend currently uses Hibernate's ddl-auto: update to create and update tables. Startup seeders populate CV templates and subscription plans when those tables are empty.
Set these variables in the terminal where you will run the backend. They override the local defaults in application.yml.
export SPRING_DATASOURCE_URL='jdbc:postgresql://localhost:5432/jobos'
export SPRING_DATASOURCE_USERNAME='jobos'
export SPRING_DATASOURCE_PASSWORD='replace-with-your-local-password'
export JWT_SECRET="$(openssl rand -hex 32)"
./gradlew :backend:bootRunKeep the same JWT_SECRET between runs if you want previously issued tokens to remain valid. These instructions use shell environment variables; the application does not automatically load a root .env file.
The API listens at http://localhost:8080. In another terminal, check that it responds:
curl http://localhost:8080/api/healthOptional integrations, configured before starting the backend:
| Variable | Purpose |
|---|---|
FIREBASE_SERVICE_ACCOUNT_JSON_PATH |
Absolute path to your Firebase service-account JSON file. If unset, backend Firebase features are disabled. |
MAIL_USERNAME, MAIL_PASSWORD |
SMTP credentials for password-recovery emails. The default transport is Gmail SMTP on port 587. |
SPRING_MAIL_HOST, SPRING_MAIL_PORT |
Override the SMTP host and port for another provider. |
Keep service-account files under the ignored firebase-keys/ directory and keep credentials out of commits. FirebaseConfig.java also contains a project-specific Realtime Database URL; update it if you use your own Firebase database.
From a new terminal at the repository root:
./gradlew :desktop:runThe desktop client defaults to http://localhost:8080. Set JOBOS_API_BASE_URL to use another backend, and JOBOS_POLL_NOTIF_SECONDS to change the default 30-second notification polling interval.
- Open the
android/directory in Android Studio. - Register an Android app with package name
com.jobos.androidin your Firebase project and place itsgoogle-services.jsoninandroid/app/. - Install Android SDK 36 and let Gradle sync finish.
- Run on an emulator or a device with Android 7.0 or newer.
ApiConfig.java defaults to http://10.0.2.2:8080, which reaches the host machine from the Android emulator. For a physical device, change BASE_URL to your development machine's reachable LAN address and keep both devices on the same network.
Create separate recruiter and seeker accounts through the app. As the recruiter, complete a company profile and publish a job. As the seeker, create a CV, find the job, and submit an application. Return to the recruiter account to review the CV and update the application status, then check the seeker's application history and notifications.
Routes use the /api prefix. Most require an access token in the Authorization: Bearer <token> header; the backend also checks user roles and resource ownership.
| Route | Purpose |
|---|---|
GET /api/health |
Public health response |
/api/auth/* |
Registration, login, token refresh, logout, and password recovery |
/api/users/me, /api/users/me/preferences |
Profile and role-specific preferences |
/api/job-posts |
Recruiter job creation and management |
GET /api/job-posts/{id}/applicants |
Applicants for a recruiter's job |
POST /api/jobs/search, GET /api/jobs/{id} |
Job discovery and details |
/api/jobs/saved, /api/jobs/{id}/save |
Saved jobs |
POST /api/applications, GET /api/applications |
Submit and list applications |
PATCH /api/applications/{id}/status |
Update an application's status |
GET /api/applications/{applicationId}/cv |
Recruiter access to an applicant's CV |
/api/cvs, /api/cvs/{cvId}/sections |
CVs and their sections |
/api/cv-templates |
Template catalog and unlocking |
/api/notifications |
Notification history, read state, preferences, and FCM token registration |
/api/credits, /api/plans |
Credit balances, transactions, and demonstration subscriptions |
See the controllers for supported methods and the shared DTOs for request and response contracts.
Build the backend, desktop, and shared modules from the repository root:
./gradlew clean buildFor a focused compilation check:
./gradlew :backend:compileJava :desktop:compileJavaAndroid has its own wrapper and build lifecycle. After configuring its SDK and Firebase file:
cd android
./gradlew :app:assembleDebug :app:testDebugUnitTestAutomated test coverage is currently limited: the root modules have no committed test suites, and Android contains starter tests. A successful build is a compilation and packaging check; verify changes through the affected seeker and recruiter flows as well. The development diary records the project's implementation history.
JobOS is open to everyone. Bug reports, documentation fixes, accessibility improvements, tests, new features, and independent forks are welcome.
- Open an issue to report a bug or discuss a substantial change. Include reproduction steps and relevant platform details.
- Fork the repository and create a branch for your change.
- Keep changes focused, follow the surrounding code conventions, and update documentation when behavior or setup changes.
- Build the affected modules, verify the relevant workflows, and add meaningful tests where applicable.
- Open a pull request describing the problem, the change, and how you validated it. Include screenshots for UI changes.
Useful starting points include automated integration tests, reproducible development setup, accessibility, and improvements to CV editing and cross-platform behavior.
JobOS is licensed under the MIT License. You may use, study, modify, fork, distribute, and build on it, including for commercial purposes, provided you retain the copyright and permission notices. See the standard MIT terms or the repository's license file for the full text.




















