Commit Graph

91 Commits (756023e30450ab99cdf9544850cd7027613f18ac)

Author SHA1 Message Date
ahmed.mujtaba 331a4cb0fc Merge branch 'main' of https://git.utopiadeals.com/utopia-ai/HR-ATS-Portal into MERGE_NEW_UI 2026-09-11 18:38:56 +05:00
ahmed.mujtaba 80a3b290b9 forms done 2026-09-11 18:37:08 +05:00
Talha Ahmed 1f4ec4d451 Stop candidate profiles crashing on production payload shapes.
Deploy to S3 / deploy (push) Successful in 11m32s Details
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-11 16:51:36 +05:00
ahmed.mujtaba 79a479ba36 advanced to openai 2026-09-10 17:24:22 +05:00
ahmed.mujtaba de4d360e06 candidate inbopx,pipeline progress,cv bank 2026-09-10 16:25:32 +05:00
ahmed.mujtaba 34f15c7183 commit 2026-09-10 15:15:05 +05:00
ahmed.mujtaba 2efc2cdf3a corrected candiadte 2026-09-10 14:55:57 +05:00
ahmed.mujtaba 5fdc6031aa listing corrections 2026-09-09 20:16:25 +05:00
ahmed.mujtaba c0e4a94d58 total applications removed 2026-09-09 19:42:01 +05:00
ahmed.mujtaba 0e4902d486 offerws page 2026-09-09 19:19:05 +05:00
ahmed.mujtaba adcd3097f8 add abtcht additon 2026-09-09 14:04:01 +05:00
ahmed.mujtaba 79098aefd5 RESCAN IMPLEMENTED 2026-09-08 15:25:43 +05:00
ahmed.mujtaba d00ebcf6f5 filter appliede
CI / checks (push) Failing after 1m57s Details
CI / checks (pull_request) Failing after 1m53s Details
2026-09-07 18:42:15 +05:00
ahmed.mujtaba 3dd716c3d3 added onhold tab that sorts the unmatched cvs 2026-09-07 17:32:20 +05:00
ahmed.mujtaba 20f03aad3c Merge branch 'main' of https://git.utopiadeals.com/utopia-ai/HR-ATS-Portal into SQS_BROKER 2026-09-07 14:00:09 +05:00
Talha Ahmed 5b29e2b592 CV Bank: replace Talent Pool with a searchable, ranked bank of stored CVs
CI / checks (push) Failing after 3m12s Details
Deploy to S3 / checks (push) Failing after 2m24s Details
Deploy to S3 / deploy (push) Has been skipped Details
The bank used to be write-only: a CV uploaded with no job carried only its
full text, so nothing could search or rank it. Now the employment agent's
extraction (title, company, education, plus new skills and years_experience,
both clamped to what the resume actually states) is stored on the row, and
the bank is ranked against a job the moment that job opens.

- New CV Bank screen at /cvbank replaces Talent Pool; the inline bank card
  moves out of CV Import. One table, two populations: speculative uploads,
  and silver medalists (rejected applicants scoring >= CV_BANK_SILVER_FLOOR,
  read live from their application rather than copied).
- matching/ranking.py: the tier-1 keyword ranker moves out of
  talent/plugins.py so Find Talent and the bank share one implementation;
  talent/plugins.py re-exports it and its numbers are unchanged.
- Taskiq tasks in job.candidate.bank_tasks: backfill profiles for CVs
  banked before extraction existed, and rank the bank when a job opens so
  recruiters are told about matches above CV_BANK_SUGGEST_THRESHOLD.
  Retention (CV_BANK_RETENTION_MONTHS) is stamped on the row at upload; the
  sweep flags expired rows and never deletes.
- Migrations 029 (bank profile columns) and 030 (per-job bank matches).
- Routes: POST /candidate/cv-bank/score, GET /candidate/cv-bank/suggestions.
- README: The CV Bank, plus the retention and deletion policy.

Also in this change:
- Inbox, Sheet Forms: has_linkedin / has_resume filters, tri-valued so
  "no link" is a real filter and NULL rows are kept in it; tab badge counts
  now narrow with the list and the search box.
- Hiring-manager candidate rows carry the ATS score and band.
- Tests: analytics dashboard merge logic, employment extraction clamps,
  form-data filters, manager candidate serializer, CV Bank mapper.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 13:39:20 +05:00
ahmed.mujtaba ac49a903ae . 2026-09-04 21:00:54 +05:00
ahmed.mujtaba 6b4ad6b0dd Implement application history retrieval for candidates and enhance reapplication tracking
- Added methods to retrieve application history by email across various sources (inbox, manual uploads, form data).
- Introduced new serializers for application history items and overall history.
- Updated candidate and inbox views to include application history in responses.
- Enhanced frontend components to display reapplication badges and previous application details.
- Adjusted API endpoints to support fetching application history based on email input.
2026-09-04 19:06:22 +05:00
ahmed.mujtaba 4086bbdeb4 permission module base applied 2026-09-04 16:48:30 +05:00
ahmed.mujtaba 0558af52c4 . 2026-09-04 16:10:56 +05:00
Talha Ahmed 0d209315ab Candidates: show ATS score, stage and recruiter instead of just an email column
Deploy to S3 / deploy (push) Successful in 34s Details
The recruiter table was user-centric (GET /candidate/fetch/users), so it could
only ever render account fields - name, email, created date. Everything a
recruiter actually triages on lives on the application, not the user.

Point the table at GET /candidate/fetch and map application rows through a new
toApplicationListView, adding Job, ATS (score + band chip), Stage and Recruiter
columns. Stage and band become real filters; the dead Department facet is gone.

Manual uploads came back unscored because the list path never joined the ATS
results, so attach scores there and expose ai_score/recommendation from the
manager serializer, deriving the band from the score when the model omitted it.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 20:59:04 +05:00
ahmed.mujtaba 6c1d4c848e dater format done 2026-09-03 18:16:30 +05:00
ahmed.mujtaba a33f4e18fc add pagination inhistory 2026-09-02 17:00:44 +05:00
ahmed.mujtaba c7d630875c add history 2026-09-02 15:33:20 +05:00
ahmed.mujtaba b0d280ec86 Merge branch 'main' of https://git.utopiadeals.com/utopia-ai/HR-ATS-Portal into Add_ATS_Order_by 2026-09-02 13:45:29 +05:00
ahmed.mujtaba 8c5549a201 Add Progress bar 2026-09-02 13:33:11 +05:00
Talha Ahmed f9fd88c5aa Dashboard redesign: org-wide activity summary with applications-per-job
Backend: new GET /analytics/applications-per-job/fetch (analytics.view) counting
inbox + manual-upload applications per job on the same basis as the funnel, with
zero-application open reqs included. Per-job group-bys added to Inbox_Messages,
Manual_UPLOAD_CANDIDATE; JobPosts.list_open_reqs for the zero-fill.

Frontend: Dashboard rewritten as a filterable summary (Week/Month/Quarter/Year +
department) - My Tasks, Today's Schedule and Quick Actions removed; 8 KPI tiles
(Hires and Offers Sent now shown); Applications per Job hero row-list; pipeline
card refed from /analytics/funnel so it obeys filters; Offer Book, Needs
Attention and Recent Activity cards added. ChartCard and time ranges extracted
to shared modules used by both Dashboard and Analytics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 22:23:38 +05:00
ahmed.mujtaba 9b5c2c8053 . 2026-09-01 18:25:53 +05:00
Talha Ahmed 7e76fb7874 Find Talent: Apify spend tracking + responsive fixes
- talent_runs.cost_usd records each run's actual charge (usageTotalUsd),
  accumulated across the broadened re-run ladder (migration 018).
- GET /talent/account: live balance and cycle spend from Apify
  /users/me/limits (nulls when Apify is unreachable) plus the observed
  $/profile over recorded runs.
- Header shows Balance / Spent / $-per-profile chips that refresh with
  every search; the run status line shows the last search's cost and the
  confirm dialog estimates from the live average.
- Responsive: toolbar controls stack edge-to-edge and candidate card
  footers wrap instead of clipping their buttons on phones.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 17:29:10 +05:00
ahmed.mujtaba 8380be0d8a recieved time implemented 2026-08-31 15:51:52 +05:00
Talha Ahmed 4b93246d43 Find Talent: shortlist sourced profiles for outreach
Manual outreach funnel on talent_profiles (sourced -> shortlisted ->
contacted, one-step undo) tracked per profile with who/when stamps.
New PATCH /talent/profiles/outreach behind talent.edit; Find Talent
screen gains All/Shortlisted/Contacted tabs, a star to shortlist and
a check to record that the recruiter messaged the person on LinkedIn
(the app itself sends nothing). Re-runs never reset outreach state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 14:34:23 +05:00
ahmed.mujtaba bb056456fc the pipeline and dashboard synced 2026-08-31 00:27:27 +05:00
ahmed.mujtaba 4b84ae4a30 recruiterhub activity improvement 2026-08-30 23:24:00 +05:00
ahmed.mujtaba fd53730efe add hiring manager added 2026-08-30 21:49:08 +05:00
ahmed.mujtaba 7f3735362e talentpool filter workds 2026-08-30 20:50:06 +05:00
ahmed.mujtaba db176cf672 is approved and file uplaod done 2026-08-28 20:02:38 +05:00
ahmed.mujtaba e4c5ffec20 is_approved, and file_pat aded 2026-08-28 19:36:22 +05:00
ahmed.mujtaba fef9fa827b candidate s3 lkinked 2026-08-28 18:10:28 +05:00
ahmed.mujtaba 12fa4f87fc Merge branch 'main' of https://git.utopiadeals.com/utopia-ai/HR-ATS-Portal into RELIMIt 2026-08-28 16:28:55 +05:00
ahmed.mujtaba b5d2b05a6d Hiring manager 2026-08-28 15:54:21 +05:00
ahmed.mujtaba 7e07df18ca s3 configured pending testing 2026-08-28 13:32:25 +05:00
Talha Ahmed 1ae5249d18 CV bank: production-safe file storage + candidates visibility
Deploy to S3 / deploy (push) Successful in 37s Details
The banked PDF now lives IN the database (new cv_bank_files table,
manual migration 010, auto-applied at startup) instead of the container
filesystem, so production redeploys cannot lose a stored CV; upload
writes row + bytes in one commit and creates no disk file at all. New
GET /candidate/cv-bank/file serves the bytes for both download and the
in-app preview.

Per user request, banking a CV with a detectable email also creates or
reactivates the candidate account (same pattern as manual add, no setup
email), so banked people appear on the Candidates screen; a CV without
an email still banks fine, account-less. Existing bank rows were
backfilled locally.

E2E-verified: upload -> bank row + DB bytes + zero disk files, preview
and download served from the DB, candidate visible on the Candidates
screen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 19:38:40 +05:00
Talha Ahmed 0b19f3ce08 CV bank: in-app preview — view a stored CV without downloading
Deploy to S3 / deploy (push) Successful in 37s Details
Each bank row gains an eye action that opens the PDF in a modal iframe.
fetchBlobUrl learned an optional MIME re-type: /documents/download sends
octet-stream, which would trigger a download instead of the inline
viewer, so the blob is re-wrapped as application/pdf. Object URL revoked
on close. Download and remove actions unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 19:26:31 +05:00
ahmed.mujtaba d47e90b9ec . 2026-08-27 19:21:33 +05:00
Talha Ahmed 9f610a9078 CV bank: private storage for No-Job CV imports
Deploy to S3 / deploy (push) Successful in 36s Details
Storing a CV without a job no longer rides the cv_upload pipeline, which
created a candidate user account and an inbox row — stored CVs were
leaking into the Candidates screen. New cv-bank endpoints instead write
apply_via=cv_bank rows in manual_upload_candidate (nullable user/job
FKs): file + parsed text only, no account, no inbox entry, no scoring,
and email is optional (captured when the CV contains one). The CV Import
screen now shows the bank itself below the dropzone — browse, download
(existing /documents/download route) and delete.

E2E-verified: uploads land as BANKED rows with user_id NULL, zero new
accounts or inbox rows, UI delete works, Candidates screen unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 19:20:38 +05:00
Talha Ahmed d1ca1e933d CV Import: No-Job mode — store CVs in the CV bank
Deploy to S3 / deploy (push) Successful in 36s Details
The job picker gains a No job / store in CV bank option: files upload
one-per-request through the existing POST /candidate/cv_upload pipeline
(email auto-detected from the CV, saved as an UNASSIGNED inbox item with
background job suggestions) instead of being scored. Queue rows show
Stored plus the detected email; a CV with no detectable email fails
alone with a clear message. In this mode the scored grid gives way to a
panel linking Job Matching and the Inbox, where stored CVs are browsed
and later assigned. Also guarded the matcher enqueue in ingest_upload:
with the broker down the upload used to 500 after the row was inserted.

E2E-verified: two CVs stored (emails detected), rows visible in DB with
assigned_job_post_id NULL, both surfaced in Job Matching and the Inbox.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 19:11:13 +05:00
ahmed.mujtaba d5a51a28b0 / 2026-08-27 18:54:40 +05:00
ahmed.mujtaba b10d02f325 . 2026-08-27 17:59:21 +05:00
Talha Ahmed e6a82aaa23 Job posts: persist and display the cover image
Deploy to S3 / deploy (push) Successful in 32s Details
The create modal collected an image but dropped it. Now POST
/job/image/upload stores it on disk keyed by the post id (uuid-validated,
5 MB / png-jpg-webp-gif, replace-on-reupload; no DB migration) and GET
/job/image/fetch serves it. The create flow uploads right after the row
exists, image failure downgrades to a toast instead of failing the create,
and Job Details renders the cover via an authorized blob fetch.

E2E-verified: upload 200, fetch 200, cover renders in Job Details.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 16:17:55 +05:00
Talha Ahmed c22ea4c689 Job posts: remove the salary field
Deploy to S3 / deploy (push) Successful in 36s Details
Dropped from the create and edit modals, the detail drawer, the frontend
job mapper, and the composed publish text (which otherwise printed
Salary: Anonymous on every post). Backend model/API still tolerate the
column, so older clients and stored rows are unaffected.

UI-verified live: modal has no salary field, create POST carries no
salary key, cover-image upload previews and the post lands successfully.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 16:09:30 +05:00