@dolusoft/hirebase-mcp 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +261 -0
- package/dist/application/dto/candidate-summary.d.ts +10 -0
- package/dist/application/dto/candidate-summary.js +2 -0
- package/dist/application/dto/candidate-summary.js.map +1 -0
- package/dist/application/dto/extracted-cv.d.ts +46 -0
- package/dist/application/dto/extracted-cv.js +2 -0
- package/dist/application/dto/extracted-cv.js.map +1 -0
- package/dist/application/dto/filter-input.d.ts +7 -0
- package/dist/application/dto/filter-input.js +2 -0
- package/dist/application/dto/filter-input.js.map +1 -0
- package/dist/application/dto/index.d.ts +5 -0
- package/dist/application/dto/index.js +2 -0
- package/dist/application/dto/index.js.map +1 -0
- package/dist/application/dto/search-results.d.ts +13 -0
- package/dist/application/dto/search-results.js +2 -0
- package/dist/application/dto/search-results.js.map +1 -0
- package/dist/application/dto/stats.d.ts +10 -0
- package/dist/application/dto/stats.js +2 -0
- package/dist/application/dto/stats.js.map +1 -0
- package/dist/application/ports/document-parser.d.ts +8 -0
- package/dist/application/ports/document-parser.js +2 -0
- package/dist/application/ports/document-parser.js.map +1 -0
- package/dist/application/ports/embedding-service.d.ts +4 -0
- package/dist/application/ports/embedding-service.js +2 -0
- package/dist/application/ports/embedding-service.js.map +1 -0
- package/dist/application/ports/export-service.d.ts +5 -0
- package/dist/application/ports/export-service.js +2 -0
- package/dist/application/ports/export-service.js.map +1 -0
- package/dist/application/ports/index.d.ts +4 -0
- package/dist/application/ports/index.js +2 -0
- package/dist/application/ports/index.js.map +1 -0
- package/dist/application/ports/structured-extractor.d.ts +4 -0
- package/dist/application/ports/structured-extractor.js +2 -0
- package/dist/application/ports/structured-extractor.js.map +1 -0
- package/dist/application/use-cases/add-cv.d.ts +16 -0
- package/dist/application/use-cases/add-cv.js +113 -0
- package/dist/application/use-cases/add-cv.js.map +1 -0
- package/dist/application/use-cases/add-job-posting.d.ts +17 -0
- package/dist/application/use-cases/add-job-posting.js +27 -0
- package/dist/application/use-cases/add-job-posting.js.map +1 -0
- package/dist/application/use-cases/add-pipeline-note.d.ts +15 -0
- package/dist/application/use-cases/add-pipeline-note.js +34 -0
- package/dist/application/use-cases/add-pipeline-note.js.map +1 -0
- package/dist/application/use-cases/add-to-pipeline.d.ts +18 -0
- package/dist/application/use-cases/add-to-pipeline.js +54 -0
- package/dist/application/use-cases/add-to-pipeline.js.map +1 -0
- package/dist/application/use-cases/bulk-add-cvs.d.ts +14 -0
- package/dist/application/use-cases/bulk-add-cvs.js +32 -0
- package/dist/application/use-cases/bulk-add-cvs.js.map +1 -0
- package/dist/application/use-cases/delete-cv.d.ts +10 -0
- package/dist/application/use-cases/delete-cv.js +21 -0
- package/dist/application/use-cases/delete-cv.js.map +1 -0
- package/dist/application/use-cases/export-results.d.ts +9 -0
- package/dist/application/use-cases/export-results.js +21 -0
- package/dist/application/use-cases/export-results.js.map +1 -0
- package/dist/application/use-cases/filter-candidates.d.ts +9 -0
- package/dist/application/use-cases/filter-candidates.js +51 -0
- package/dist/application/use-cases/filter-candidates.js.map +1 -0
- package/dist/application/use-cases/get-candidate-history.d.ts +25 -0
- package/dist/application/use-cases/get-candidate-history.js +36 -0
- package/dist/application/use-cases/get-candidate-history.js.map +1 -0
- package/dist/application/use-cases/get-cv-chunks.d.ts +15 -0
- package/dist/application/use-cases/get-cv-chunks.js +18 -0
- package/dist/application/use-cases/get-cv-chunks.js.map +1 -0
- package/dist/application/use-cases/get-cv-detail.d.ts +7 -0
- package/dist/application/use-cases/get-cv-detail.js +15 -0
- package/dist/application/use-cases/get-cv-detail.js.map +1 -0
- package/dist/application/use-cases/get-cv-versions.d.ts +9 -0
- package/dist/application/use-cases/get-cv-versions.js +18 -0
- package/dist/application/use-cases/get-cv-versions.js.map +1 -0
- package/dist/application/use-cases/get-pending-actions.d.ts +23 -0
- package/dist/application/use-cases/get-pending-actions.js +50 -0
- package/dist/application/use-cases/get-pending-actions.js.map +1 -0
- package/dist/application/use-cases/get-pipeline.d.ts +27 -0
- package/dist/application/use-cases/get-pipeline.js +40 -0
- package/dist/application/use-cases/get-pipeline.js.map +1 -0
- package/dist/application/use-cases/get-stats.d.ts +13 -0
- package/dist/application/use-cases/get-stats.js +50 -0
- package/dist/application/use-cases/get-stats.js.map +1 -0
- package/dist/application/use-cases/index.d.ts +23 -0
- package/dist/application/use-cases/index.js +24 -0
- package/dist/application/use-cases/index.js.map +1 -0
- package/dist/application/use-cases/list-cvs.d.ts +8 -0
- package/dist/application/use-cases/list-cvs.js +20 -0
- package/dist/application/use-cases/list-cvs.js.map +1 -0
- package/dist/application/use-cases/list-job-postings.d.ts +7 -0
- package/dist/application/use-cases/list-job-postings.js +10 -0
- package/dist/application/use-cases/list-job-postings.js.map +1 -0
- package/dist/application/use-cases/manage-tags.d.ts +7 -0
- package/dist/application/use-cases/manage-tags.js +36 -0
- package/dist/application/use-cases/manage-tags.js.map +1 -0
- package/dist/application/use-cases/match-candidates.d.ts +27 -0
- package/dist/application/use-cases/match-candidates.js +92 -0
- package/dist/application/use-cases/match-candidates.js.map +1 -0
- package/dist/application/use-cases/semantic-search.d.ts +11 -0
- package/dist/application/use-cases/semantic-search.js +40 -0
- package/dist/application/use-cases/semantic-search.js.map +1 -0
- package/dist/application/use-cases/set-pending-action.d.ts +13 -0
- package/dist/application/use-cases/set-pending-action.js +24 -0
- package/dist/application/use-cases/set-pending-action.js.map +1 -0
- package/dist/application/use-cases/update-cv.d.ts +17 -0
- package/dist/application/use-cases/update-cv.js +103 -0
- package/dist/application/use-cases/update-cv.js.map +1 -0
- package/dist/application/use-cases/update-job-posting.d.ts +19 -0
- package/dist/application/use-cases/update-job-posting.js +28 -0
- package/dist/application/use-cases/update-job-posting.js.map +1 -0
- package/dist/application/use-cases/update-pipeline-status.d.ts +14 -0
- package/dist/application/use-cases/update-pipeline-status.js +38 -0
- package/dist/application/use-cases/update-pipeline-status.js.map +1 -0
- package/dist/domain/entities/application-event.d.ts +11 -0
- package/dist/domain/entities/application-event.js +2 -0
- package/dist/domain/entities/application-event.js.map +1 -0
- package/dist/domain/entities/application.d.ts +13 -0
- package/dist/domain/entities/application.js +2 -0
- package/dist/domain/entities/application.js.map +1 -0
- package/dist/domain/entities/candidate.d.ts +26 -0
- package/dist/domain/entities/candidate.js +2 -0
- package/dist/domain/entities/candidate.js.map +1 -0
- package/dist/domain/entities/cv-chunk.d.ts +10 -0
- package/dist/domain/entities/cv-chunk.js +2 -0
- package/dist/domain/entities/cv-chunk.js.map +1 -0
- package/dist/domain/entities/cv-version.d.ts +7 -0
- package/dist/domain/entities/cv-version.js +2 -0
- package/dist/domain/entities/cv-version.js.map +1 -0
- package/dist/domain/entities/index.d.ts +6 -0
- package/dist/domain/entities/index.js +2 -0
- package/dist/domain/entities/index.js.map +1 -0
- package/dist/domain/entities/job-posting.d.ts +14 -0
- package/dist/domain/entities/job-posting.js +2 -0
- package/dist/domain/entities/job-posting.js.map +1 -0
- package/dist/domain/repositories/application-event-repository.d.ts +7 -0
- package/dist/domain/repositories/application-event-repository.js +2 -0
- package/dist/domain/repositories/application-event-repository.js.map +1 -0
- package/dist/domain/repositories/application-repository.d.ts +12 -0
- package/dist/domain/repositories/application-repository.js +2 -0
- package/dist/domain/repositories/application-repository.js.map +1 -0
- package/dist/domain/repositories/candidate-repository.d.ts +12 -0
- package/dist/domain/repositories/candidate-repository.js +2 -0
- package/dist/domain/repositories/candidate-repository.js.map +1 -0
- package/dist/domain/repositories/chunk-repository.d.ts +13 -0
- package/dist/domain/repositories/chunk-repository.js +2 -0
- package/dist/domain/repositories/chunk-repository.js.map +1 -0
- package/dist/domain/repositories/index.d.ts +6 -0
- package/dist/domain/repositories/index.js +2 -0
- package/dist/domain/repositories/index.js.map +1 -0
- package/dist/domain/repositories/job-posting-repository.d.ts +9 -0
- package/dist/domain/repositories/job-posting-repository.js +2 -0
- package/dist/domain/repositories/job-posting-repository.js.map +1 -0
- package/dist/domain/repositories/version-repository.d.ts +6 -0
- package/dist/domain/repositories/version-repository.js +2 -0
- package/dist/domain/repositories/version-repository.js.map +1 -0
- package/dist/domain/value-objects/certification.d.ts +5 -0
- package/dist/domain/value-objects/certification.js +2 -0
- package/dist/domain/value-objects/certification.js.map +1 -0
- package/dist/domain/value-objects/contact-info.d.ts +5 -0
- package/dist/domain/value-objects/contact-info.js +2 -0
- package/dist/domain/value-objects/contact-info.js.map +1 -0
- package/dist/domain/value-objects/education.d.ts +7 -0
- package/dist/domain/value-objects/education.js +2 -0
- package/dist/domain/value-objects/education.js.map +1 -0
- package/dist/domain/value-objects/experience.d.ts +7 -0
- package/dist/domain/value-objects/experience.js +2 -0
- package/dist/domain/value-objects/experience.js.map +1 -0
- package/dist/domain/value-objects/index.d.ts +7 -0
- package/dist/domain/value-objects/index.js +2 -0
- package/dist/domain/value-objects/index.js.map +1 -0
- package/dist/domain/value-objects/language.d.ts +4 -0
- package/dist/domain/value-objects/language.js +2 -0
- package/dist/domain/value-objects/language.js.map +1 -0
- package/dist/domain/value-objects/links.d.ts +6 -0
- package/dist/domain/value-objects/links.js +2 -0
- package/dist/domain/value-objects/links.js.map +1 -0
- package/dist/domain/value-objects/project.d.ts +5 -0
- package/dist/domain/value-objects/project.js +2 -0
- package/dist/domain/value-objects/project.js.map +1 -0
- package/dist/infrastructure/ai/index.d.ts +2 -0
- package/dist/infrastructure/ai/index.js +3 -0
- package/dist/infrastructure/ai/index.js.map +1 -0
- package/dist/infrastructure/ai/openai-embedding-service.d.ts +8 -0
- package/dist/infrastructure/ai/openai-embedding-service.js +39 -0
- package/dist/infrastructure/ai/openai-embedding-service.js.map +1 -0
- package/dist/infrastructure/ai/openai-structured-extractor.d.ts +9 -0
- package/dist/infrastructure/ai/openai-structured-extractor.js +163 -0
- package/dist/infrastructure/ai/openai-structured-extractor.js.map +1 -0
- package/dist/infrastructure/config/app-config.d.ts +9 -0
- package/dist/infrastructure/config/app-config.js +15 -0
- package/dist/infrastructure/config/app-config.js.map +1 -0
- package/dist/infrastructure/export/csv-export-service.d.ts +6 -0
- package/dist/infrastructure/export/csv-export-service.js +24 -0
- package/dist/infrastructure/export/csv-export-service.js.map +1 -0
- package/dist/infrastructure/parsers/docx-parser.d.ts +5 -0
- package/dist/infrastructure/parsers/docx-parser.js +17 -0
- package/dist/infrastructure/parsers/docx-parser.js.map +1 -0
- package/dist/infrastructure/parsers/index.d.ts +3 -0
- package/dist/infrastructure/parsers/index.js +4 -0
- package/dist/infrastructure/parsers/index.js.map +1 -0
- package/dist/infrastructure/parsers/ocr-service.d.ts +8 -0
- package/dist/infrastructure/parsers/ocr-service.js +65 -0
- package/dist/infrastructure/parsers/ocr-service.js.map +1 -0
- package/dist/infrastructure/parsers/pdf-parser.d.ts +5 -0
- package/dist/infrastructure/parsers/pdf-parser.js +44 -0
- package/dist/infrastructure/parsers/pdf-parser.js.map +1 -0
- package/dist/infrastructure/persistence/database.d.ts +20 -0
- package/dist/infrastructure/persistence/database.js +156 -0
- package/dist/infrastructure/persistence/database.js.map +1 -0
- package/dist/infrastructure/persistence/index.d.ts +6 -0
- package/dist/infrastructure/persistence/index.js +7 -0
- package/dist/infrastructure/persistence/index.js.map +1 -0
- package/dist/infrastructure/persistence/lancedb-application-event-repository.d.ts +16 -0
- package/dist/infrastructure/persistence/lancedb-application-event-repository.js +85 -0
- package/dist/infrastructure/persistence/lancedb-application-event-repository.js.map +1 -0
- package/dist/infrastructure/persistence/lancedb-application-repository.d.ts +21 -0
- package/dist/infrastructure/persistence/lancedb-application-repository.js +151 -0
- package/dist/infrastructure/persistence/lancedb-application-repository.js.map +1 -0
- package/dist/infrastructure/persistence/lancedb-candidate-repository.d.ts +21 -0
- package/dist/infrastructure/persistence/lancedb-candidate-repository.js +169 -0
- package/dist/infrastructure/persistence/lancedb-candidate-repository.js.map +1 -0
- package/dist/infrastructure/persistence/lancedb-chunk-repository.d.ts +18 -0
- package/dist/infrastructure/persistence/lancedb-chunk-repository.js +105 -0
- package/dist/infrastructure/persistence/lancedb-chunk-repository.js.map +1 -0
- package/dist/infrastructure/persistence/lancedb-job-posting-repository.d.ts +21 -0
- package/dist/infrastructure/persistence/lancedb-job-posting-repository.js +128 -0
- package/dist/infrastructure/persistence/lancedb-job-posting-repository.js.map +1 -0
- package/dist/infrastructure/persistence/lancedb-version-repository.d.ts +13 -0
- package/dist/infrastructure/persistence/lancedb-version-repository.js +62 -0
- package/dist/infrastructure/persistence/lancedb-version-repository.js.map +1 -0
- package/dist/interface/cli/index.d.ts +2 -0
- package/dist/interface/cli/index.js +17 -0
- package/dist/interface/cli/index.js.map +1 -0
- package/dist/interface/dashboard/call-context.d.ts +4 -0
- package/dist/interface/dashboard/call-context.js +26 -0
- package/dist/interface/dashboard/call-context.js.map +1 -0
- package/dist/interface/dashboard/event-bus.d.ts +7 -0
- package/dist/interface/dashboard/event-bus.js +16 -0
- package/dist/interface/dashboard/event-bus.js.map +1 -0
- package/dist/interface/dashboard/events.d.ts +30 -0
- package/dist/interface/dashboard/events.js +2 -0
- package/dist/interface/dashboard/events.js.map +1 -0
- package/dist/interface/dashboard/html.d.ts +1 -0
- package/dist/interface/dashboard/html.js +1007 -0
- package/dist/interface/dashboard/html.js.map +1 -0
- package/dist/interface/dashboard/public/200.html +1 -0
- package/dist/interface/dashboard/public/404.html +1 -0
- package/dist/interface/dashboard/public/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-8KeALpAu2nWJknvJhMk31fqE06iajfSeiM57lsZAo5g.woff +0 -0
- package/dist/interface/dashboard/public/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-CAyrLGU3kauAbzcFnj2Cv_iAPV8wT2NEvNmrA_77Up0.woff +0 -0
- package/dist/interface/dashboard/public/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-Cbq5YGF_nsoQo6qYm9EhA3p-oINRUqlXhACZ2Wh4BBE.woff +0 -0
- package/dist/interface/dashboard/public/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-G1pKsfAhfeIECsLbuPUckyz92yuHFKi9rmiwlRl8Tb0.woff +0 -0
- package/dist/interface/dashboard/public/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-OnaIl8fChu9Cb4bpYiOA4dK_W7eeMCjXQOWR8tUhXJ0.woff +0 -0
- package/dist/interface/dashboard/public/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-kzEiBeXQ06q7fC06p1Y4RaOpLlRWCnHcCcSaqFMJ6fc.woff +0 -0
- package/dist/interface/dashboard/public/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-rmd8_oLeTXCNUhiFyy1UYsogNo6QYBr9dQHrhl_hLbs.woff +0 -0
- package/dist/interface/dashboard/public/_fonts/1ZTlEDqU4DtwDJiND8f6qaugUpa0RIDvQl-v7iM6l54-wjJHhPsTzX4mZm37l7bbvLDtOEIT1R38DKPlwV_Z34A.woff +0 -0
- package/dist/interface/dashboard/public/_fonts/57NSSoFy1VLVs2gqly8Ls9awBnZMFyXGrefpmqvdqmc-zJfbBtpgM4cDmcXBsqZNW79_kFnlpPd62b48glgdydA.woff2 +0 -0
- package/dist/interface/dashboard/public/_fonts/8VR2wSMN-3U4NbWAVYXlkRV6hA0jFBXP-0RtL3X7fko-x2gYI4qfmkRdxyQQUPaBZdZdgl1TeVrquF_TxHeM4lM.woff2 +0 -0
- package/dist/interface/dashboard/public/_fonts/GsKUclqeNLJ96g5AU593ug6yanivOiwjW_7zESNPChw-jHA4tBeM1bjF7LATGUpfBuSTyomIFrWBTzjF7txVYfg.woff2 +0 -0
- package/dist/interface/dashboard/public/_fonts/Ld1FnTo3yTIwDyGfTQ5-Fws9AWsCbKfMvgxduXr7JcY-W25bL8NF1fjpLRSOgJb7RoZPHqGQNwMTM7S9tHVoxx8.woff2 +0 -0
- package/dist/interface/dashboard/public/_fonts/NdzqRASp2bovDUhQT1IRE_EMqKJ2KYQdTCfFcBvL8yw-KhwZiS86o3fErOe5GGMExHUemmI_dBfaEFxjISZrBd0.woff2 +0 -0
- package/dist/interface/dashboard/public/_fonts/iTkrULNFJJkTvihIg1Vqi5IODRH_9btXCioVF5l98I8-AndUyau2HR2felA_ra8V2mutQgschhasE5FD1dXGJX8.woff2 +0 -0
- package/dist/interface/dashboard/public/_nuxt/BtFgTcXQ.js +30 -0
- package/dist/interface/dashboard/public/_nuxt/CdJZeyak.js +30 -0
- package/dist/interface/dashboard/public/_nuxt/D9vxbU2B.js +1 -0
- package/dist/interface/dashboard/public/_nuxt/DHg6ig_T.js +1 -0
- package/dist/interface/dashboard/public/_nuxt/DhFk2_Al.js +1 -0
- package/dist/interface/dashboard/public/_nuxt/DlAUqK2U.js +1 -0
- package/dist/interface/dashboard/public/_nuxt/DtX-aPBA.js +1 -0
- package/dist/interface/dashboard/public/_nuxt/DvCMYK3d.js +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/latest.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/027020ec-4e7d-4fc7-8447-19800f7d0bac.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/18e19101-a96b-41dc-b602-f9a8f013a036.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/2fd3d0d3-6004-4659-9055-d27aa6656fd3.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/54792d4b-ca55-4b5d-b0dd-1d7dc34de344.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/5959a14b-2494-4e0d-be28-fef9adfd889d.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/60cda583-d704-4d4e-b37e-7ab337e3b6cc.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/64d05a43-99ec-4c22-934e-071b310b968f.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/6c1632a5-f0af-41e3-9d88-12294e03a0b9.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/6c80982c-5e2c-446c-aaf6-7000a976e493.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/79161adb-748c-4d36-a031-a71899a56ecd.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/84e5a87d-4ae5-48dd-8d5e-5b1fe89f7243.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/86082677-a11d-4acf-ab04-c3c067a71622.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/8892e611-c2b4-425b-a6a5-988314d8da4d.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/9bfe6b22-73f8-4584-b13d-ed1df5600e12.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/a39bf957-ddae-41a6-a183-08292363098b.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/b0bf7fc4-02c1-46fd-acca-f4458feed978.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/b2847d83-b695-45d4-9dca-d7498158a501.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/c8382eda-1354-4f92-b6d0-5b5b9f43354a.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/e707aa44-7202-413d-bcd5-1538b5b56570.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/ea661002-05ab-4bfb-b02f-c91bb721c5e9.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/f2f23a12-a792-480e-922a-ee8b73dc0310.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/f6503b83-d731-40f8-9110-c1599663b3ba.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/builds/meta/feac6d04-6bc5-4fa4-a241-79e897d7f8c1.json +1 -0
- package/dist/interface/dashboard/public/_nuxt/entry.BSUaoqsu.css +1 -0
- package/dist/interface/dashboard/public/_nuxt/entry.Bl31cpjT.css +1 -0
- package/dist/interface/dashboard/public/_nuxt/error-404.B6WzzNMA.css +1 -0
- package/dist/interface/dashboard/public/_nuxt/error-500.CVIcHofV.css +1 -0
- package/dist/interface/dashboard/public/_nuxt/index.BH5Gbe6q.css +1 -0
- package/dist/interface/dashboard/public/_nuxt/index.TQmbXYdV.css +1 -0
- package/dist/interface/dashboard/public/_nuxt/qq1iUjth.js +1 -0
- package/dist/interface/dashboard/public/favicon.ico +0 -0
- package/dist/interface/dashboard/public/index.html +1 -0
- package/dist/interface/dashboard/server.d.ts +11 -0
- package/dist/interface/dashboard/server.js +145 -0
- package/dist/interface/dashboard/server.js.map +1 -0
- package/dist/interface/dashboard/tool-wrapper.d.ts +4 -0
- package/dist/interface/dashboard/tool-wrapper.js +96 -0
- package/dist/interface/dashboard/tool-wrapper.js.map +1 -0
- package/dist/interface/mcp/server.d.ts +2 -0
- package/dist/interface/mcp/server.js +109 -0
- package/dist/interface/mcp/server.js.map +1 -0
- package/dist/interface/mcp/tools/add-cv.d.ts +3 -0
- package/dist/interface/mcp/tools/add-cv.js +21 -0
- package/dist/interface/mcp/tools/add-cv.js.map +1 -0
- package/dist/interface/mcp/tools/add-job-posting.d.ts +3 -0
- package/dist/interface/mcp/tools/add-job-posting.js +38 -0
- package/dist/interface/mcp/tools/add-job-posting.js.map +1 -0
- package/dist/interface/mcp/tools/add-pipeline-note.d.ts +3 -0
- package/dist/interface/mcp/tools/add-pipeline-note.js +32 -0
- package/dist/interface/mcp/tools/add-pipeline-note.js.map +1 -0
- package/dist/interface/mcp/tools/add-to-pipeline.d.ts +3 -0
- package/dist/interface/mcp/tools/add-to-pipeline.js +28 -0
- package/dist/interface/mcp/tools/add-to-pipeline.js.map +1 -0
- package/dist/interface/mcp/tools/bulk-add-cvs.d.ts +3 -0
- package/dist/interface/mcp/tools/bulk-add-cvs.js +28 -0
- package/dist/interface/mcp/tools/bulk-add-cvs.js.map +1 -0
- package/dist/interface/mcp/tools/delete-cv.d.ts +3 -0
- package/dist/interface/mcp/tools/delete-cv.js +20 -0
- package/dist/interface/mcp/tools/delete-cv.js.map +1 -0
- package/dist/interface/mcp/tools/delete-job-posting.d.ts +3 -0
- package/dist/interface/mcp/tools/delete-job-posting.js +27 -0
- package/dist/interface/mcp/tools/delete-job-posting.js.map +1 -0
- package/dist/interface/mcp/tools/export-results.d.ts +3 -0
- package/dist/interface/mcp/tools/export-results.js +23 -0
- package/dist/interface/mcp/tools/export-results.js.map +1 -0
- package/dist/interface/mcp/tools/filter-candidates.d.ts +3 -0
- package/dist/interface/mcp/tools/filter-candidates.js +32 -0
- package/dist/interface/mcp/tools/filter-candidates.js.map +1 -0
- package/dist/interface/mcp/tools/get-candidate-history.d.ts +3 -0
- package/dist/interface/mcp/tools/get-candidate-history.js +22 -0
- package/dist/interface/mcp/tools/get-candidate-history.js.map +1 -0
- package/dist/interface/mcp/tools/get-cv-chunks.d.ts +3 -0
- package/dist/interface/mcp/tools/get-cv-chunks.js +26 -0
- package/dist/interface/mcp/tools/get-cv-chunks.js.map +1 -0
- package/dist/interface/mcp/tools/get-cv-detail.d.ts +3 -0
- package/dist/interface/mcp/tools/get-cv-detail.js +23 -0
- package/dist/interface/mcp/tools/get-cv-detail.js.map +1 -0
- package/dist/interface/mcp/tools/get-cv-versions.d.ts +3 -0
- package/dist/interface/mcp/tools/get-cv-versions.js +20 -0
- package/dist/interface/mcp/tools/get-cv-versions.js.map +1 -0
- package/dist/interface/mcp/tools/get-job-posting.d.ts +3 -0
- package/dist/interface/mcp/tools/get-job-posting.js +26 -0
- package/dist/interface/mcp/tools/get-job-posting.js.map +1 -0
- package/dist/interface/mcp/tools/get-pending-actions.d.ts +3 -0
- package/dist/interface/mcp/tools/get-pending-actions.js +19 -0
- package/dist/interface/mcp/tools/get-pending-actions.js.map +1 -0
- package/dist/interface/mcp/tools/get-pipeline.d.ts +3 -0
- package/dist/interface/mcp/tools/get-pipeline.js +22 -0
- package/dist/interface/mcp/tools/get-pipeline.js.map +1 -0
- package/dist/interface/mcp/tools/get-server-status.d.ts +3 -0
- package/dist/interface/mcp/tools/get-server-status.js +38 -0
- package/dist/interface/mcp/tools/get-server-status.js.map +1 -0
- package/dist/interface/mcp/tools/get-stats.d.ts +3 -0
- package/dist/interface/mcp/tools/get-stats.js +19 -0
- package/dist/interface/mcp/tools/get-stats.js.map +1 -0
- package/dist/interface/mcp/tools/list-cvs.d.ts +3 -0
- package/dist/interface/mcp/tools/list-cvs.js +32 -0
- package/dist/interface/mcp/tools/list-cvs.js.map +1 -0
- package/dist/interface/mcp/tools/list-job-postings.d.ts +3 -0
- package/dist/interface/mcp/tools/list-job-postings.js +19 -0
- package/dist/interface/mcp/tools/list-job-postings.js.map +1 -0
- package/dist/interface/mcp/tools/manage-tags.d.ts +3 -0
- package/dist/interface/mcp/tools/manage-tags.js +24 -0
- package/dist/interface/mcp/tools/manage-tags.js.map +1 -0
- package/dist/interface/mcp/tools/match-candidates.d.ts +3 -0
- package/dist/interface/mcp/tools/match-candidates.js +23 -0
- package/dist/interface/mcp/tools/match-candidates.js.map +1 -0
- package/dist/interface/mcp/tools/reset-database.d.ts +3 -0
- package/dist/interface/mcp/tools/reset-database.js +35 -0
- package/dist/interface/mcp/tools/reset-database.js.map +1 -0
- package/dist/interface/mcp/tools/semantic-search.d.ts +3 -0
- package/dist/interface/mcp/tools/semantic-search.js +27 -0
- package/dist/interface/mcp/tools/semantic-search.js.map +1 -0
- package/dist/interface/mcp/tools/set-pending-action.d.ts +3 -0
- package/dist/interface/mcp/tools/set-pending-action.js +36 -0
- package/dist/interface/mcp/tools/set-pending-action.js.map +1 -0
- package/dist/interface/mcp/tools/update-cv.d.ts +3 -0
- package/dist/interface/mcp/tools/update-cv.js +23 -0
- package/dist/interface/mcp/tools/update-cv.js.map +1 -0
- package/dist/interface/mcp/tools/update-job-posting.d.ts +3 -0
- package/dist/interface/mcp/tools/update-job-posting.js +42 -0
- package/dist/interface/mcp/tools/update-job-posting.js.map +1 -0
- package/dist/interface/mcp/tools/update-pipeline-status.d.ts +3 -0
- package/dist/interface/mcp/tools/update-pipeline-status.js +41 -0
- package/dist/interface/mcp/tools/update-pipeline-status.js.map +1 -0
- package/dist/interface/mcp/types.d.ts +26 -0
- package/dist/interface/mcp/types.js +2 -0
- package/dist/interface/mcp/types.js.map +1 -0
- package/dist/shared/errors/index.d.ts +32 -0
- package/dist/shared/errors/index.js +56 -0
- package/dist/shared/errors/index.js.map +1 -0
- package/dist/shared/types/index.d.ts +19 -0
- package/dist/shared/types/index.js +2 -0
- package/dist/shared/types/index.js.map +1 -0
- package/dist/shared/utils/chunking.d.ts +3 -0
- package/dist/shared/utils/chunking.js +89 -0
- package/dist/shared/utils/chunking.js.map +1 -0
- package/dist/shared/utils/file-storage.d.ts +8 -0
- package/dist/shared/utils/file-storage.js +49 -0
- package/dist/shared/utils/file-storage.js.map +1 -0
- package/dist/shared/utils/index.d.ts +3 -0
- package/dist/shared/utils/index.js +4 -0
- package/dist/shared/utils/index.js.map +1 -0
- package/dist/shared/utils/text.d.ts +5 -0
- package/dist/shared/utils/text.js +21 -0
- package/dist/shared/utils/text.js.map +1 -0
- package/package.json +72 -0
package/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# HireBase
|
|
2
|
+
|
|
3
|
+
AI-powered recruitment platform built as an MCP Server. Parses CVs, extracts structured data with GPT, stores them in a LanceDB vector database, and manages the entire hiring pipeline — from candidate matching to interview scheduling.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
**DDD + Clean Architecture** with clear separation of concerns:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
src/
|
|
11
|
+
├── domain/ # Entities, Value Objects, Repository Interfaces
|
|
12
|
+
├── application/ # Use Cases, Ports, DTOs
|
|
13
|
+
├── infrastructure/ # LanceDB, OpenAI, PDF/DOCX/OCR Parsers
|
|
14
|
+
├── interface/ # MCP Server, Tools, Dashboard, CLI
|
|
15
|
+
└── shared/ # Errors, Types, Utilities
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Design Principle:** MCP Server = Data layer (parse, store, search, return). The AI client using the tools handles analysis, ranking strategy, and match explanations.
|
|
19
|
+
|
|
20
|
+
## Tech Stack
|
|
21
|
+
|
|
22
|
+
| Technology | Purpose |
|
|
23
|
+
|---|---|
|
|
24
|
+
| TypeScript 5.9 | Language |
|
|
25
|
+
| LanceDB | Vector database (embedded, serverless) |
|
|
26
|
+
| OpenAI `text-embedding-3-large` | 3072-dim embeddings |
|
|
27
|
+
| OpenAI `gpt-5-mini` | Structured CV extraction (Responses API) |
|
|
28
|
+
| MCP SDK | Model Context Protocol server |
|
|
29
|
+
| Nuxt 4 + Nuxt UI | Real-time dashboard |
|
|
30
|
+
| unpdf | PDF text extraction |
|
|
31
|
+
| mammoth | DOCX text extraction |
|
|
32
|
+
| Tesseract.js | OCR for image-based PDFs |
|
|
33
|
+
|
|
34
|
+
## MCP Tools (27)
|
|
35
|
+
|
|
36
|
+
### CV Management
|
|
37
|
+
|
|
38
|
+
| Tool | Description |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `add_cv` | Parse CV file (PDF/DOCX), extract structured data, embed, store |
|
|
41
|
+
| `update_cv` | Update existing CV, archive old version |
|
|
42
|
+
| `delete_cv` | Delete candidate and all related data |
|
|
43
|
+
| `get_cv_detail` | Full candidate data with download URL |
|
|
44
|
+
| `get_cv_chunks` | CV section chunks with optional section filter |
|
|
45
|
+
| `get_cv_versions` | Version history |
|
|
46
|
+
| `list_cvs` | Paginated candidate list with sorting |
|
|
47
|
+
| `manage_tags` | Add/remove/list tags |
|
|
48
|
+
|
|
49
|
+
### Search & Matching
|
|
50
|
+
|
|
51
|
+
| Tool | Description |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `semantic_search` | Vector similarity search with optional section filter |
|
|
54
|
+
| `filter_candidates` | Structured filtering (skills, location, experience, languages, tags) |
|
|
55
|
+
| `match_candidates` | Composite scoring: semantic similarity + skill overlap + loyalty factor |
|
|
56
|
+
| `export_results` | Export as JSON or CSV |
|
|
57
|
+
|
|
58
|
+
### Job Posting Management
|
|
59
|
+
|
|
60
|
+
| Tool | Description |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `add_job_posting` | Create job posting with required/preferred skills and metadata |
|
|
63
|
+
| `list_job_postings` | List all job postings |
|
|
64
|
+
| `get_job_posting` | Retrieve specific job posting details |
|
|
65
|
+
| `update_job_posting` | Update existing job posting |
|
|
66
|
+
| `delete_job_posting` | Delete a job posting |
|
|
67
|
+
|
|
68
|
+
### Recruitment Pipeline
|
|
69
|
+
|
|
70
|
+
| Tool | Description |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `add_to_pipeline` | Add candidate to a job posting pipeline |
|
|
73
|
+
| `update_pipeline_status` | Update application status |
|
|
74
|
+
| `add_pipeline_note` | Add notes, call attempts, or interview records |
|
|
75
|
+
| `set_pending_action` | Track pending actions with due dates and owner (us/candidate) |
|
|
76
|
+
| `get_pipeline` | Full pipeline view for a job posting |
|
|
77
|
+
| `get_candidate_history` | Candidate's recruitment history across all postings |
|
|
78
|
+
| `get_pending_actions` | All overdue and upcoming pending actions |
|
|
79
|
+
|
|
80
|
+
**Pipeline statuses:** `new` → `contacted` → `unreachable` · `not_interested` · `interview_scheduled` → `no_show` · `interviewed` → `rejected` · `offer_sent` → `hired`
|
|
81
|
+
|
|
82
|
+
### System
|
|
83
|
+
|
|
84
|
+
| Tool | Description |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `get_stats` | Database statistics (candidates, skills, locations, etc.) |
|
|
87
|
+
| `get_server_status` | Server info, dashboard URL, connected clients |
|
|
88
|
+
| `reset_database` | Drop and recreate all tables |
|
|
89
|
+
|
|
90
|
+
## How It Works
|
|
91
|
+
|
|
92
|
+
### CV Ingestion
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
CV File (PDF/DOCX/Scanned PDF)
|
|
96
|
+
│
|
|
97
|
+
▼
|
|
98
|
+
[1] Parse text (unpdf / mammoth / Tesseract.js OCR)
|
|
99
|
+
│
|
|
100
|
+
▼
|
|
101
|
+
[2] Extract structured data (GPT-5 mini)
|
|
102
|
+
│ name, experience, education, skills, languages...
|
|
103
|
+
▼
|
|
104
|
+
[3] Chunk into sections
|
|
105
|
+
│ summary, each experience, education, skills, projects, certifications, full text
|
|
106
|
+
▼
|
|
107
|
+
[4] Generate embeddings (text-embedding-3-large, 3072d)
|
|
108
|
+
│
|
|
109
|
+
▼
|
|
110
|
+
[5] Store in LanceDB (candidates + cv_chunks + cv_versions)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Candidate Matching
|
|
114
|
+
|
|
115
|
+
`match_candidates` uses a composite scoring algorithm:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
compositeScore = (0.5 × vectorScore) + (0.3 × skillOverlap) + (0.2 × loyaltyFactor)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
| Component | Weight | Description |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| Vector Score | 50% | Semantic similarity between CV and job description |
|
|
124
|
+
| Skill Overlap | 30% | Ratio of matched required skills to total required skills |
|
|
125
|
+
| Loyalty Factor | 20% | Candidate stability: `stable` = 1.0, `moderate` = 0.7, `flight_risk` = 0.4 |
|
|
126
|
+
|
|
127
|
+
### Recruitment Pipeline
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
Job Posting
|
|
131
|
+
│
|
|
132
|
+
▼
|
|
133
|
+
[1] match_candidates → ranked candidate list
|
|
134
|
+
│
|
|
135
|
+
▼
|
|
136
|
+
[2] add_to_pipeline → create applications (status: new)
|
|
137
|
+
│
|
|
138
|
+
▼
|
|
139
|
+
[3] update_pipeline_status → track progress through hiring stages
|
|
140
|
+
│ add_pipeline_note → log calls, interviews, notes
|
|
141
|
+
│ set_pending_action → assign follow-up tasks
|
|
142
|
+
▼
|
|
143
|
+
[4] get_pending_actions → monitor overdue/upcoming items
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Dashboard
|
|
147
|
+
|
|
148
|
+
HireBase includes a real-time dashboard built with **Nuxt 4 + Nuxt UI + Tailwind CSS**. The dashboard connects via WebSocket and provides live tracking of MCP tool executions.
|
|
149
|
+
|
|
150
|
+
Enable via environment variable:
|
|
151
|
+
|
|
152
|
+
```env
|
|
153
|
+
DASHBOARD_ENABLED=true
|
|
154
|
+
DASHBOARD_PORT=61496
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The dashboard URL is available in `get_server_status` output.
|
|
158
|
+
|
|
159
|
+
## Database Schema
|
|
160
|
+
|
|
161
|
+
LanceDB tables:
|
|
162
|
+
|
|
163
|
+
| Table | Purpose |
|
|
164
|
+
|---|---|
|
|
165
|
+
| `candidates` | Candidate profiles (name, email, skills, experience, loyalty score, tags) |
|
|
166
|
+
| `cv_chunks` | Searchable CV sections with 3072-dim vector embeddings |
|
|
167
|
+
| `cv_versions` | Archived CV versions for update history |
|
|
168
|
+
| `job_postings` | Job listings with required/preferred skills and status |
|
|
169
|
+
| `applications` | Pipeline records linking candidates to jobs with status tracking |
|
|
170
|
+
| `application_events` | Audit trail: status changes, call attempts, interview records |
|
|
171
|
+
|
|
172
|
+
## Installation
|
|
173
|
+
|
|
174
|
+
### npm (recommended)
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
npm install -g @dolusoft/hirebase-mcp
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### From source
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
git clone https://github.com/dolusoft/hirebase.git
|
|
184
|
+
cd hirebase
|
|
185
|
+
pnpm install
|
|
186
|
+
pnpm build
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Prerequisites
|
|
190
|
+
|
|
191
|
+
- Node.js >= 22
|
|
192
|
+
- OpenAI API Key
|
|
193
|
+
|
|
194
|
+
## MCP Configuration
|
|
195
|
+
|
|
196
|
+
### Claude Code (npx)
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
claude mcp add hirebase -- npx -y @dolusoft/hirebase-mcp
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Then set your OpenAI API key:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"mcpServers": {
|
|
207
|
+
"hirebase": {
|
|
208
|
+
"command": "npx",
|
|
209
|
+
"args": ["-y", "@dolusoft/hirebase-mcp"],
|
|
210
|
+
"env": {
|
|
211
|
+
"OPENAI_API_KEY": "sk-your-key"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Claude Desktop
|
|
219
|
+
|
|
220
|
+
Add to your Claude Desktop config (`claude_desktop_config.json`):
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
{
|
|
224
|
+
"mcpServers": {
|
|
225
|
+
"hirebase": {
|
|
226
|
+
"command": "npx",
|
|
227
|
+
"args": ["-y", "@dolusoft/hirebase-mcp"],
|
|
228
|
+
"env": {
|
|
229
|
+
"OPENAI_API_KEY": "sk-your-key",
|
|
230
|
+
"LANCEDB_PATH": "./data/lancedb"
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Environment Variables
|
|
238
|
+
|
|
239
|
+
| Variable | Default | Description |
|
|
240
|
+
|---|---|---|
|
|
241
|
+
| `OPENAI_API_KEY` | *required* | OpenAI API key |
|
|
242
|
+
| `LANCEDB_PATH` | `./data/lancedb` | LanceDB storage path |
|
|
243
|
+
| `EMBEDDING_MODEL` | `text-embedding-3-large` | Embedding model |
|
|
244
|
+
| `EXTRACTION_MODEL` | `gpt-5-mini` | CV extraction model |
|
|
245
|
+
| `DASHBOARD_ENABLED` | `true` | Enable real-time dashboard |
|
|
246
|
+
| `DASHBOARD_PORT` | `0` (random) | Dashboard server port |
|
|
247
|
+
|
|
248
|
+
## Key Design Decisions
|
|
249
|
+
|
|
250
|
+
- **LanceDB has no UPDATE** — update is implemented as delete + add at repository level
|
|
251
|
+
- **Complex fields stored as JSON strings** — skills, experience, etc. serialized in Utf8 columns
|
|
252
|
+
- **Batch embedding** — all chunks embedded in a single OpenAI API call
|
|
253
|
+
- **Seed rows** — tables use `__seed__` rows for schema inference, filtered out in queries
|
|
254
|
+
- **Versioning** — old CV data archived before updates, full history accessible
|
|
255
|
+
- **Section-level chunking** — each work experience is a separate chunk for granular matching
|
|
256
|
+
- **OCR fallback** — image-based PDFs automatically processed with Tesseract.js
|
|
257
|
+
- **Composite scoring** — matching combines semantic, skill-based, and loyalty signals
|
|
258
|
+
|
|
259
|
+
## License
|
|
260
|
+
|
|
261
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidate-summary.js","sourceRoot":"","sources":["../../../src/application/dto/candidate-summary.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface ExtractedCv {
|
|
2
|
+
name: string;
|
|
3
|
+
email?: string;
|
|
4
|
+
phone?: string;
|
|
5
|
+
location?: string;
|
|
6
|
+
summary?: string;
|
|
7
|
+
experience: {
|
|
8
|
+
company: string;
|
|
9
|
+
position: string;
|
|
10
|
+
startDate?: string;
|
|
11
|
+
endDate?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
}[];
|
|
14
|
+
education: {
|
|
15
|
+
institution: string;
|
|
16
|
+
degree?: string;
|
|
17
|
+
field?: string;
|
|
18
|
+
startDate?: string;
|
|
19
|
+
endDate?: string;
|
|
20
|
+
}[];
|
|
21
|
+
skills: string[];
|
|
22
|
+
languages: {
|
|
23
|
+
language: string;
|
|
24
|
+
level?: string;
|
|
25
|
+
}[];
|
|
26
|
+
certifications: {
|
|
27
|
+
name: string;
|
|
28
|
+
issuer?: string;
|
|
29
|
+
date?: string;
|
|
30
|
+
}[];
|
|
31
|
+
projects: {
|
|
32
|
+
name: string;
|
|
33
|
+
description?: string;
|
|
34
|
+
technologies?: string[];
|
|
35
|
+
}[];
|
|
36
|
+
links?: {
|
|
37
|
+
linkedin?: string;
|
|
38
|
+
github?: string;
|
|
39
|
+
portfolio?: string;
|
|
40
|
+
other?: string[];
|
|
41
|
+
};
|
|
42
|
+
totalExperienceYears?: number;
|
|
43
|
+
avgTenureMonths?: number;
|
|
44
|
+
shortStintCount?: number;
|
|
45
|
+
loyaltyScore?: 'stable' | 'moderate' | 'flight_risk';
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extracted-cv.js","sourceRoot":"","sources":["../../../src/application/dto/extracted-cv.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-input.js","sourceRoot":"","sources":["../../../src/application/dto/filter-input.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { ExtractedCv } from './extracted-cv.js';
|
|
2
|
+
export type { SearchResultDto, SearchInput } from './search-results.js';
|
|
3
|
+
export type { FilterInput } from './filter-input.js';
|
|
4
|
+
export type { CandidateSummaryDto } from './candidate-summary.js';
|
|
5
|
+
export type { StatsDto } from './stats.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/application/dto/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface SearchResultDto {
|
|
2
|
+
candidateId: string;
|
|
3
|
+
candidateName: string;
|
|
4
|
+
sectionType: string;
|
|
5
|
+
content: string;
|
|
6
|
+
score: number;
|
|
7
|
+
metadata: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface SearchInput {
|
|
10
|
+
query: string;
|
|
11
|
+
limit?: number;
|
|
12
|
+
sectionType?: string;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-results.js","sourceRoot":"","sources":["../../../src/application/dto/search-results.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface StatsDto {
|
|
2
|
+
totalCandidates: number;
|
|
3
|
+
totalChunks: number;
|
|
4
|
+
skillCounts: Record<string, number>;
|
|
5
|
+
locationCounts: Record<string, number>;
|
|
6
|
+
avgExperienceYears: number;
|
|
7
|
+
tagCounts: Record<string, number>;
|
|
8
|
+
totalApplications: number;
|
|
9
|
+
totalApplicationEvents: number;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/application/dto/stats.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-parser.js","sourceRoot":"","sources":["../../../src/application/ports/document-parser.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding-service.js","sourceRoot":"","sources":["../../../src/application/ports/embedding-service.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-service.js","sourceRoot":"","sources":["../../../src/application/ports/export-service.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { IDocumentParser, ParsedDocument } from './document-parser.js';
|
|
2
|
+
export type { IEmbeddingService } from './embedding-service.js';
|
|
3
|
+
export type { IStructuredExtractor } from './structured-extractor.js';
|
|
4
|
+
export type { IExportService } from './export-service.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/application/ports/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structured-extractor.js","sourceRoot":"","sources":["../../../src/application/ports/structured-extractor.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ICandidateRepository } from '../../domain/repositories/candidate-repository.js';
|
|
2
|
+
import type { IChunkRepository } from '../../domain/repositories/chunk-repository.js';
|
|
3
|
+
import type { Candidate } from '../../domain/entities/candidate.js';
|
|
4
|
+
import type { IDocumentParser } from '../ports/document-parser.js';
|
|
5
|
+
import type { IEmbeddingService } from '../ports/embedding-service.js';
|
|
6
|
+
import type { IStructuredExtractor } from '../ports/structured-extractor.js';
|
|
7
|
+
export type ProgressCallback = (step: string, message: string) => void;
|
|
8
|
+
export declare class AddCvUseCase {
|
|
9
|
+
private candidateRepo;
|
|
10
|
+
private chunkRepo;
|
|
11
|
+
private parsers;
|
|
12
|
+
private embeddingService;
|
|
13
|
+
private extractor;
|
|
14
|
+
constructor(candidateRepo: ICandidateRepository, chunkRepo: IChunkRepository, parsers: IDocumentParser[], embeddingService: IEmbeddingService, extractor: IStructuredExtractor);
|
|
15
|
+
execute(filePath: string, onProgress?: ProgressCallback): Promise<Candidate>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
import { detectFileType } from '../../shared/utils/text.js';
|
|
3
|
+
import { createChunks } from '../../shared/utils/chunking.js';
|
|
4
|
+
import { UnsupportedFileTypeError, DuplicateCandidateError, DocumentParseError } from '../../shared/errors/index.js';
|
|
5
|
+
import { storeOriginalFile, resolveFilePath } from '../../shared/utils/file-storage.js';
|
|
6
|
+
export class AddCvUseCase {
|
|
7
|
+
candidateRepo;
|
|
8
|
+
chunkRepo;
|
|
9
|
+
parsers;
|
|
10
|
+
embeddingService;
|
|
11
|
+
extractor;
|
|
12
|
+
constructor(candidateRepo, chunkRepo, parsers, embeddingService, extractor) {
|
|
13
|
+
this.candidateRepo = candidateRepo;
|
|
14
|
+
this.chunkRepo = chunkRepo;
|
|
15
|
+
this.parsers = parsers;
|
|
16
|
+
this.embeddingService = embeddingService;
|
|
17
|
+
this.extractor = extractor;
|
|
18
|
+
}
|
|
19
|
+
async execute(filePath, onProgress) {
|
|
20
|
+
// Resolve Unicode NFC/NFD filename normalization differences
|
|
21
|
+
const resolvedPath = await resolveFilePath(filePath);
|
|
22
|
+
const fileType = detectFileType(resolvedPath);
|
|
23
|
+
const parser = this.parsers.find((p) => p.supports(fileType));
|
|
24
|
+
if (!parser) {
|
|
25
|
+
throw new UnsupportedFileTypeError(fileType);
|
|
26
|
+
}
|
|
27
|
+
onProgress?.('parsing', `Parsing ${fileType.toUpperCase()} file...`);
|
|
28
|
+
const { text: rawText } = await parser.parse(resolvedPath);
|
|
29
|
+
if (!rawText || rawText.trim().length < 50) {
|
|
30
|
+
throw new DocumentParseError(`No extractable text found in ${resolvedPath}. The file may contain images that could not be processed.`);
|
|
31
|
+
}
|
|
32
|
+
onProgress?.('extracting', 'Extracting structured data with AI...');
|
|
33
|
+
const extracted = await this.extractor.extract(rawText);
|
|
34
|
+
onProgress?.('checking_duplicates', 'Checking for duplicate candidates...');
|
|
35
|
+
if (extracted.email) {
|
|
36
|
+
const existing = await this.candidateRepo.findByEmail(extracted.email);
|
|
37
|
+
if (existing) {
|
|
38
|
+
throw new DuplicateCandidateError(extracted.email);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const candidateId = nanoid();
|
|
42
|
+
const now = new Date().toISOString();
|
|
43
|
+
onProgress?.('chunking', 'Creating text chunks...');
|
|
44
|
+
const chunkInputs = createChunks(extracted, rawText);
|
|
45
|
+
const chunkTexts = chunkInputs.map((c) => c.content);
|
|
46
|
+
onProgress?.('embedding', `Generating embeddings for ${chunkTexts.length} chunks...`);
|
|
47
|
+
const vectors = await this.embeddingService.embedBatch(chunkTexts);
|
|
48
|
+
const candidate = {
|
|
49
|
+
id: candidateId,
|
|
50
|
+
name: extracted.name,
|
|
51
|
+
contact: {
|
|
52
|
+
email: extracted.email,
|
|
53
|
+
phone: extracted.phone,
|
|
54
|
+
location: extracted.location,
|
|
55
|
+
},
|
|
56
|
+
summary: extracted.summary,
|
|
57
|
+
experience: extracted.experience.map((e) => ({
|
|
58
|
+
company: e.company,
|
|
59
|
+
position: e.position,
|
|
60
|
+
startDate: e.startDate,
|
|
61
|
+
endDate: e.endDate,
|
|
62
|
+
description: e.description,
|
|
63
|
+
})),
|
|
64
|
+
education: extracted.education.map((e) => ({
|
|
65
|
+
institution: e.institution,
|
|
66
|
+
degree: e.degree,
|
|
67
|
+
field: e.field,
|
|
68
|
+
startDate: e.startDate,
|
|
69
|
+
endDate: e.endDate,
|
|
70
|
+
})),
|
|
71
|
+
skills: extracted.skills,
|
|
72
|
+
languages: extracted.languages,
|
|
73
|
+
certifications: extracted.certifications,
|
|
74
|
+
projects: extracted.projects,
|
|
75
|
+
links: extracted.links,
|
|
76
|
+
tags: [],
|
|
77
|
+
experienceYears: extracted.totalExperienceYears,
|
|
78
|
+
avgTenureMonths: extracted.avgTenureMonths,
|
|
79
|
+
shortStintCount: extracted.shortStintCount,
|
|
80
|
+
loyaltyScore: extracted.loyaltyScore,
|
|
81
|
+
originalFilePath: undefined, // set after save
|
|
82
|
+
sourceFile: filePath,
|
|
83
|
+
fileType,
|
|
84
|
+
rawText,
|
|
85
|
+
createdAt: now,
|
|
86
|
+
updatedAt: now,
|
|
87
|
+
version: 1,
|
|
88
|
+
};
|
|
89
|
+
const chunks = chunkInputs.map((input, i) => ({
|
|
90
|
+
id: nanoid(),
|
|
91
|
+
candidateId,
|
|
92
|
+
sectionType: input.sectionType,
|
|
93
|
+
content: input.content,
|
|
94
|
+
vector: vectors[i],
|
|
95
|
+
metadata: input.metadata,
|
|
96
|
+
createdAt: now,
|
|
97
|
+
}));
|
|
98
|
+
onProgress?.('saving', 'Saving to database...');
|
|
99
|
+
// Store original file
|
|
100
|
+
let originalFilePath;
|
|
101
|
+
try {
|
|
102
|
+
originalFilePath = await storeOriginalFile(resolvedPath, candidateId);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Non-fatal: file copy failure shouldn't block CV processing
|
|
106
|
+
}
|
|
107
|
+
const finalCandidate = { ...candidate, originalFilePath };
|
|
108
|
+
await this.candidateRepo.save(finalCandidate);
|
|
109
|
+
await this.chunkRepo.saveMany(chunks);
|
|
110
|
+
return finalCandidate;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=add-cv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-cv.js","sourceRoot":"","sources":["../../../src/application/use-cases/add-cv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IJobPostingRepository } from '../../domain/repositories/job-posting-repository.js';
|
|
2
|
+
import type { JobPosting } from '../../domain/entities/job-posting.js';
|
|
3
|
+
export interface AddJobPostingInput {
|
|
4
|
+
title: string;
|
|
5
|
+
description: string;
|
|
6
|
+
rawText?: string;
|
|
7
|
+
requirements?: string;
|
|
8
|
+
requiredSkills: string[];
|
|
9
|
+
preferredSkills?: string[];
|
|
10
|
+
location?: string;
|
|
11
|
+
salaryRange?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class AddJobPostingUseCase {
|
|
14
|
+
private jobPostingRepo;
|
|
15
|
+
constructor(jobPostingRepo: IJobPostingRepository);
|
|
16
|
+
execute(input: AddJobPostingInput): Promise<JobPosting>;
|
|
17
|
+
}
|