@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.js","sourceRoot":"","sources":["../../../src/domain/value-objects/links.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/domain/value-objects/project.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IEmbeddingService } from '../../application/ports/embedding-service.js';
|
|
2
|
+
export declare class OpenAiEmbeddingService implements IEmbeddingService {
|
|
3
|
+
private client;
|
|
4
|
+
private model;
|
|
5
|
+
constructor(apiKey: string, model?: string);
|
|
6
|
+
embed(text: string): Promise<number[]>;
|
|
7
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { EmbeddingError } from '../../shared/errors/index.js';
|
|
3
|
+
export class OpenAiEmbeddingService {
|
|
4
|
+
client;
|
|
5
|
+
model;
|
|
6
|
+
constructor(apiKey, model = 'text-embedding-3-large') {
|
|
7
|
+
this.client = new OpenAI({ apiKey });
|
|
8
|
+
this.model = model;
|
|
9
|
+
}
|
|
10
|
+
async embed(text) {
|
|
11
|
+
try {
|
|
12
|
+
const response = await this.client.embeddings.create({
|
|
13
|
+
model: this.model,
|
|
14
|
+
input: text,
|
|
15
|
+
});
|
|
16
|
+
return response.data[0].embedding;
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
throw new EmbeddingError('Failed to generate embedding', error);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async embedBatch(texts) {
|
|
23
|
+
if (texts.length === 0)
|
|
24
|
+
return [];
|
|
25
|
+
try {
|
|
26
|
+
const response = await this.client.embeddings.create({
|
|
27
|
+
model: this.model,
|
|
28
|
+
input: texts,
|
|
29
|
+
});
|
|
30
|
+
return response.data
|
|
31
|
+
.sort((a, b) => a.index - b.index)
|
|
32
|
+
.map((d) => d.embedding);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
throw new EmbeddingError('Failed to generate batch embeddings', error);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=openai-embedding-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-embedding-service.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/openai-embedding-service.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,OAAO,sBAAsB;IACzB,MAAM,CAAS;IACf,KAAK,CAAS;IAEtB,YAAY,MAAc,EAAE,QAAgB,wBAAwB;QAClE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;gBACnD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,cAAc,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAe;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAElC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;gBACnD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,IAAI;iBACjB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;iBACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,cAAc,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IStructuredExtractor } from '../../application/ports/structured-extractor.js';
|
|
2
|
+
import type { ExtractedCv } from '../../application/dto/extracted-cv.js';
|
|
3
|
+
export declare class OpenAiStructuredExtractor implements IStructuredExtractor {
|
|
4
|
+
private client;
|
|
5
|
+
private model;
|
|
6
|
+
constructor(apiKey: string, model?: string);
|
|
7
|
+
extract(rawText: string): Promise<ExtractedCv>;
|
|
8
|
+
private mapToExtractedCv;
|
|
9
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { zodTextFormat } from 'openai/helpers/zod';
|
|
4
|
+
import { ExtractionError } from '../../shared/errors/index.js';
|
|
5
|
+
const CvExtractionSchema = z.object({
|
|
6
|
+
name: z.string(),
|
|
7
|
+
email: z.string().nullable(),
|
|
8
|
+
phone: z.string().nullable(),
|
|
9
|
+
location: z.string().nullable(),
|
|
10
|
+
summary: z.string().nullable(),
|
|
11
|
+
experience: z.array(z.object({
|
|
12
|
+
company: z.string(),
|
|
13
|
+
position: z.string(),
|
|
14
|
+
start_date: z.string().nullable(),
|
|
15
|
+
end_date: z.string().nullable(),
|
|
16
|
+
description: z.string().nullable(),
|
|
17
|
+
})),
|
|
18
|
+
education: z.array(z.object({
|
|
19
|
+
institution: z.string(),
|
|
20
|
+
degree: z.string().nullable(),
|
|
21
|
+
field: z.string().nullable(),
|
|
22
|
+
start_date: z.string().nullable(),
|
|
23
|
+
end_date: z.string().nullable(),
|
|
24
|
+
})),
|
|
25
|
+
skills: z.array(z.string()),
|
|
26
|
+
languages: z.array(z.object({
|
|
27
|
+
language: z.string(),
|
|
28
|
+
level: z.string().nullable(),
|
|
29
|
+
})),
|
|
30
|
+
certifications: z.array(z.object({
|
|
31
|
+
name: z.string(),
|
|
32
|
+
issuer: z.string().nullable(),
|
|
33
|
+
date: z.string().nullable(),
|
|
34
|
+
})),
|
|
35
|
+
projects: z.array(z.object({
|
|
36
|
+
name: z.string(),
|
|
37
|
+
description: z.string().nullable(),
|
|
38
|
+
technologies: z.array(z.string()).nullable(),
|
|
39
|
+
})),
|
|
40
|
+
links: z
|
|
41
|
+
.object({
|
|
42
|
+
linkedin: z.string().nullable(),
|
|
43
|
+
github: z.string().nullable(),
|
|
44
|
+
portfolio: z.string().nullable(),
|
|
45
|
+
other: z.array(z.string()).nullable(),
|
|
46
|
+
})
|
|
47
|
+
.nullable(),
|
|
48
|
+
total_experience_years: z.number().nullable(),
|
|
49
|
+
avg_tenure_months: z.number().nullable(),
|
|
50
|
+
short_stint_count: z.number().nullable(),
|
|
51
|
+
loyalty_score: z.enum(['stable', 'moderate', 'flight_risk']).nullable(),
|
|
52
|
+
});
|
|
53
|
+
const SYSTEM_PROMPT = `You are an expert CV/resume parser and hiring analyst. Extract structured data from the CV text below.
|
|
54
|
+
|
|
55
|
+
## Output Rules
|
|
56
|
+
|
|
57
|
+
**Language & Format — ALL output must be in English regardless of the CV language.**
|
|
58
|
+
- location: "City, Country" format (e.g. "Istanbul, Turkey" not "İstanbul/Türkiye")
|
|
59
|
+
- Dates: "MMM YYYY" format (e.g. "Jan 2022", "Present" for current roles)
|
|
60
|
+
- Skills: use the official/common name (e.g. "React" not "ReactJS", "Next.js" not "Nextjs", "TypeScript" not "TS", "PostgreSQL" not "Postgres")
|
|
61
|
+
- Do NOT duplicate skills — each skill appears exactly once
|
|
62
|
+
|
|
63
|
+
**Summary**
|
|
64
|
+
- If the CV has a summary/profile section, extract it as-is (translated to English if needed).
|
|
65
|
+
- If NO summary exists, generate a concise 2-3 sentence professional summary from the CV content.
|
|
66
|
+
|
|
67
|
+
**Experience Calculation**
|
|
68
|
+
- total_experience_years: sum of all non-overlapping work periods. If roles overlap in time, count that period only once. Round to 1 decimal.
|
|
69
|
+
|
|
70
|
+
**Job Loyalty Assessment**
|
|
71
|
+
- avg_tenure_months: average duration in months across all positions. Round to nearest integer.
|
|
72
|
+
- short_stint_count: number of positions lasting less than 12 months (exclude current/ongoing roles).
|
|
73
|
+
- loyalty_score: rate overall job loyalty:
|
|
74
|
+
- "stable": avg tenure >= 24 months AND short stints <= 1
|
|
75
|
+
- "moderate": avg tenure >= 12 months OR short stints <= 2
|
|
76
|
+
- "flight_risk": avg tenure < 12 months OR short stints >= 3
|
|
77
|
+
|
|
78
|
+
**General**
|
|
79
|
+
- Extract ALL skills mentioned anywhere in the CV (job descriptions, projects, skill sections).
|
|
80
|
+
- For languages, include proficiency level if mentioned (e.g. "Native", "B2", "Fluent").
|
|
81
|
+
- Return data in the exact schema format requested.`;
|
|
82
|
+
export class OpenAiStructuredExtractor {
|
|
83
|
+
client;
|
|
84
|
+
model;
|
|
85
|
+
constructor(apiKey, model = 'gpt-5-mini') {
|
|
86
|
+
this.client = new OpenAI({ apiKey });
|
|
87
|
+
this.model = model;
|
|
88
|
+
}
|
|
89
|
+
async extract(rawText) {
|
|
90
|
+
try {
|
|
91
|
+
const response = await this.client.responses.parse({
|
|
92
|
+
model: this.model,
|
|
93
|
+
input: [
|
|
94
|
+
{ role: 'developer', content: SYSTEM_PROMPT },
|
|
95
|
+
{ role: 'user', content: rawText },
|
|
96
|
+
],
|
|
97
|
+
text: {
|
|
98
|
+
format: zodTextFormat(CvExtractionSchema, 'cv_extraction'),
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
const parsed = response.output_parsed;
|
|
102
|
+
if (!parsed) {
|
|
103
|
+
throw new Error('No parsed output from OpenAI');
|
|
104
|
+
}
|
|
105
|
+
return this.mapToExtractedCv(parsed);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
if (error instanceof ExtractionError)
|
|
109
|
+
throw error;
|
|
110
|
+
throw new ExtractionError('Failed to extract structured CV data', error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
mapToExtractedCv(parsed) {
|
|
114
|
+
const n = (v) => v ?? undefined;
|
|
115
|
+
return {
|
|
116
|
+
name: parsed.name,
|
|
117
|
+
email: n(parsed.email),
|
|
118
|
+
phone: n(parsed.phone),
|
|
119
|
+
location: n(parsed.location),
|
|
120
|
+
summary: n(parsed.summary),
|
|
121
|
+
experience: parsed.experience.map((e) => ({
|
|
122
|
+
company: e.company,
|
|
123
|
+
position: e.position,
|
|
124
|
+
startDate: n(e.start_date),
|
|
125
|
+
endDate: n(e.end_date),
|
|
126
|
+
description: n(e.description),
|
|
127
|
+
})),
|
|
128
|
+
education: parsed.education.map((e) => ({
|
|
129
|
+
institution: e.institution,
|
|
130
|
+
degree: n(e.degree),
|
|
131
|
+
field: n(e.field),
|
|
132
|
+
startDate: n(e.start_date),
|
|
133
|
+
endDate: n(e.end_date),
|
|
134
|
+
})),
|
|
135
|
+
skills: parsed.skills,
|
|
136
|
+
languages: parsed.languages.map((l) => ({
|
|
137
|
+
language: l.language,
|
|
138
|
+
level: n(l.level),
|
|
139
|
+
})),
|
|
140
|
+
certifications: parsed.certifications.map((c) => ({
|
|
141
|
+
name: c.name,
|
|
142
|
+
issuer: n(c.issuer),
|
|
143
|
+
date: n(c.date),
|
|
144
|
+
})),
|
|
145
|
+
projects: parsed.projects.map((p) => ({
|
|
146
|
+
name: p.name,
|
|
147
|
+
description: n(p.description),
|
|
148
|
+
technologies: n(p.technologies),
|
|
149
|
+
})),
|
|
150
|
+
links: parsed.links ? {
|
|
151
|
+
linkedin: n(parsed.links.linkedin),
|
|
152
|
+
github: n(parsed.links.github),
|
|
153
|
+
portfolio: n(parsed.links.portfolio),
|
|
154
|
+
other: n(parsed.links.other),
|
|
155
|
+
} : undefined,
|
|
156
|
+
totalExperienceYears: n(parsed.total_experience_years),
|
|
157
|
+
avgTenureMonths: n(parsed.avg_tenure_months),
|
|
158
|
+
shortStintCount: n(parsed.short_stint_count),
|
|
159
|
+
loyaltyScore: n(parsed.loyalty_score),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=openai-structured-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-structured-extractor.js","sourceRoot":"","sources":["../../../src/infrastructure/ai/openai-structured-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function loadConfig() {
|
|
2
|
+
const openaiApiKey = process.env.OPENAI_API_KEY;
|
|
3
|
+
if (!openaiApiKey) {
|
|
4
|
+
throw new Error('OPENAI_API_KEY environment variable is required');
|
|
5
|
+
}
|
|
6
|
+
return {
|
|
7
|
+
openaiApiKey,
|
|
8
|
+
lancedbPath: process.env.LANCEDB_PATH ?? './data/lancedb',
|
|
9
|
+
embeddingModel: process.env.EMBEDDING_MODEL ?? 'text-embedding-3-small',
|
|
10
|
+
extractionModel: process.env.EXTRACTION_MODEL ?? 'gpt-5-mini',
|
|
11
|
+
dashboardEnabled: process.env.DASHBOARD_ENABLED !== 'false',
|
|
12
|
+
dashboardPort: parseInt(process.env.DASHBOARD_PORT ?? '0', 10),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=app-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../../src/infrastructure/config/app-config.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,UAAU;IACxB,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAChD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,OAAO;QACL,YAAY;QACZ,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,gBAAgB;QACzD,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB;QACvE,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,YAAY;QAC7D,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,OAAO;QAC3D,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,GAAG,EAAE,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { IExportService } from '../../application/ports/export-service.js';
|
|
2
|
+
import type { Candidate } from '../../domain/entities/candidate.js';
|
|
3
|
+
import type { ExportFormat } from '../../shared/types/index.js';
|
|
4
|
+
export declare class CsvExportService implements IExportService {
|
|
5
|
+
export(candidates: Candidate[], format: ExportFormat): string;
|
|
6
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Papa from 'papaparse';
|
|
2
|
+
export class CsvExportService {
|
|
3
|
+
export(candidates, format) {
|
|
4
|
+
if (format === 'json') {
|
|
5
|
+
return JSON.stringify(candidates, null, 2);
|
|
6
|
+
}
|
|
7
|
+
const rows = candidates.map((c) => ({
|
|
8
|
+
id: c.id,
|
|
9
|
+
name: c.name,
|
|
10
|
+
email: c.contact.email ?? '',
|
|
11
|
+
phone: c.contact.phone ?? '',
|
|
12
|
+
location: c.contact.location ?? '',
|
|
13
|
+
skills: c.skills.join('; '),
|
|
14
|
+
experience_years: c.experienceYears ?? '',
|
|
15
|
+
education: c.education
|
|
16
|
+
.map((e) => [e.degree, e.field ? `in ${e.field}` : '', `at ${e.institution}`].filter(Boolean).join(' '))
|
|
17
|
+
.join('; '),
|
|
18
|
+
tags: c.tags.join('; '),
|
|
19
|
+
created_at: c.createdAt,
|
|
20
|
+
}));
|
|
21
|
+
return Papa.unparse(rows);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=csv-export-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-export-service.js","sourceRoot":"","sources":["../../../src/infrastructure/export/csv-export-service.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,MAAM,OAAO,gBAAgB;IAC3B,MAAM,CAAC,UAAuB,EAAE,MAAoB;QAClD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YAC5B,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE;YAC5B,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE;YAClC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAC3B,gBAAgB,EAAE,CAAC,CAAC,eAAe,IAAI,EAAE;YACzC,SAAS,EAAE,CAAC,CAAC,SAAS;iBACnB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;iBACvG,IAAI,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACvB,UAAU,EAAE,CAAC,CAAC,SAAS;SACxB,CAAC,CAAC,CAAC;QAEJ,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import mammoth from 'mammoth';
|
|
2
|
+
import { DocumentParseError } from '../../shared/errors/index.js';
|
|
3
|
+
export class DocxParser {
|
|
4
|
+
supports(fileType) {
|
|
5
|
+
return fileType === 'docx';
|
|
6
|
+
}
|
|
7
|
+
async parse(filePath) {
|
|
8
|
+
try {
|
|
9
|
+
const result = await mammoth.extractRawText({ path: filePath });
|
|
10
|
+
return { text: result.value };
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
throw new DocumentParseError(`Failed to parse DOCX: ${filePath}`, error);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=docx-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docx-parser.js","sourceRoot":"","sources":["../../../src/infrastructure/parsers/docx-parser.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,OAAO,UAAU;IACrB,QAAQ,CAAC,QAAgB;QACvB,OAAO,QAAQ,KAAK,MAAM,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YAChE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,kBAAkB,CAAC,yBAAyB,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/parsers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performs OCR on an image-based PDF by extracting embedded images
|
|
3
|
+
* and running Tesseract.js recognition on each page.
|
|
4
|
+
*
|
|
5
|
+
* Only call this when the PDF is confirmed to be image-based
|
|
6
|
+
* (valid PDF with pages but no extractable text).
|
|
7
|
+
*/
|
|
8
|
+
export declare function ocrPdfBuffer(pdfData: Uint8Array, pageCount: number): Promise<string | null>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { extractImages } from 'unpdf';
|
|
2
|
+
import { createCanvas, ImageData } from '@napi-rs/canvas';
|
|
3
|
+
import { createWorker } from 'tesseract.js';
|
|
4
|
+
/**
|
|
5
|
+
* Performs OCR on an image-based PDF by extracting embedded images
|
|
6
|
+
* and running Tesseract.js recognition on each page.
|
|
7
|
+
*
|
|
8
|
+
* Only call this when the PDF is confirmed to be image-based
|
|
9
|
+
* (valid PDF with pages but no extractable text).
|
|
10
|
+
*/
|
|
11
|
+
export async function ocrPdfBuffer(pdfData, pageCount) {
|
|
12
|
+
const worker = await createWorker('tur+eng');
|
|
13
|
+
const texts = [];
|
|
14
|
+
try {
|
|
15
|
+
for (let pageNum = 1; pageNum <= pageCount; pageNum++) {
|
|
16
|
+
const images = await extractImages(pdfData, pageNum);
|
|
17
|
+
if (!images || images.length === 0)
|
|
18
|
+
continue;
|
|
19
|
+
for (const img of images) {
|
|
20
|
+
const pngBuffer = imageToPng(img.data, img.width, img.height, img.channels);
|
|
21
|
+
const { data: { text }, } = await worker.recognize(pngBuffer);
|
|
22
|
+
if (text.trim()) {
|
|
23
|
+
texts.push(text.trim());
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
await worker.terminate();
|
|
30
|
+
}
|
|
31
|
+
const combined = texts.join('\n\n');
|
|
32
|
+
return combined.trim().length >= 50 ? combined : null;
|
|
33
|
+
}
|
|
34
|
+
/** Converts raw pixel data (1/3/4 channels) to a PNG buffer. */
|
|
35
|
+
function imageToPng(data, width, height, channels) {
|
|
36
|
+
const rgbaData = toRgba(data, channels);
|
|
37
|
+
const canvas = createCanvas(width, height);
|
|
38
|
+
const ctx = canvas.getContext('2d');
|
|
39
|
+
const imageData = new ImageData(rgbaData, width, height);
|
|
40
|
+
ctx.putImageData(imageData, 0, 0);
|
|
41
|
+
return canvas.toBuffer('image/png');
|
|
42
|
+
}
|
|
43
|
+
/** Converts 1/3/4-channel pixel data to RGBA. */
|
|
44
|
+
function toRgba(data, channels) {
|
|
45
|
+
if (channels === 4)
|
|
46
|
+
return data;
|
|
47
|
+
const pixelCount = data.length / channels;
|
|
48
|
+
const rgba = new Uint8ClampedArray(pixelCount * 4);
|
|
49
|
+
for (let i = 0, j = 0; i < data.length; i += channels, j += 4) {
|
|
50
|
+
if (channels === 3) {
|
|
51
|
+
rgba[j] = data[i];
|
|
52
|
+
rgba[j + 1] = data[i + 1];
|
|
53
|
+
rgba[j + 2] = data[i + 2];
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Grayscale (1 channel)
|
|
57
|
+
rgba[j] = data[i];
|
|
58
|
+
rgba[j + 1] = data[i];
|
|
59
|
+
rgba[j + 2] = data[i];
|
|
60
|
+
}
|
|
61
|
+
rgba[j + 3] = 255;
|
|
62
|
+
}
|
|
63
|
+
return rgba;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=ocr-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ocr-service.js","sourceRoot":"","sources":["../../../src/infrastructure/parsers/ocr-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { extractText, getDocumentProxy } from 'unpdf';
|
|
3
|
+
import { DocumentParseError } from '../../shared/errors/index.js';
|
|
4
|
+
import { ocrPdfBuffer } from './ocr-service.js';
|
|
5
|
+
export class PdfParser {
|
|
6
|
+
supports(fileType) {
|
|
7
|
+
return fileType === 'pdf';
|
|
8
|
+
}
|
|
9
|
+
async parse(filePath) {
|
|
10
|
+
let buffer;
|
|
11
|
+
try {
|
|
12
|
+
buffer = await readFile(filePath);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
throw new DocumentParseError(`Failed to read PDF file: ${filePath}`, error);
|
|
16
|
+
}
|
|
17
|
+
let totalPages;
|
|
18
|
+
let text;
|
|
19
|
+
try {
|
|
20
|
+
const pdf = await getDocumentProxy(new Uint8Array(buffer));
|
|
21
|
+
const result = await extractText(pdf, { mergePages: true });
|
|
22
|
+
totalPages = result.totalPages;
|
|
23
|
+
text = result.text;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
// PDF is invalid or corrupted — do NOT attempt OCR
|
|
27
|
+
throw new DocumentParseError(`Failed to parse PDF: ${filePath}`, error);
|
|
28
|
+
}
|
|
29
|
+
// Detect image-based PDF: valid PDF with pages but no extractable text
|
|
30
|
+
if (totalPages > 0 && (!text || text.trim().length < 50)) {
|
|
31
|
+
try {
|
|
32
|
+
const ocrText = await ocrPdfBuffer(new Uint8Array(buffer), totalPages);
|
|
33
|
+
if (ocrText) {
|
|
34
|
+
return { text: ocrText, pageCount: totalPages };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// OCR failed — fall through and return whatever text we have
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { text, pageCount: totalPages };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=pdf-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-parser.js","sourceRoot":"","sources":["../../../src/infrastructure/parsers/pdf-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,OAAO,SAAS;IACpB,QAAQ,CAAC,QAAgB;QACvB,OAAO,QAAQ,KAAK,KAAK,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,kBAAkB,CAAC,4BAA4B,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,UAAkB,CAAC;QACvB,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;YAC/B,IAAI,GAAG,MAAM,CAAC,IAAc,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,mDAAmD;YACnD,MAAM,IAAI,kBAAkB,CAAC,wBAAwB,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;QAC1E,CAAC;QAED,uEAAuE;QACvE,IAAI,UAAU,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;gBACvE,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;gBAClD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,6DAA6D;YAC/D,CAAC;QACH,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Connection, Table } from '@lancedb/lancedb';
|
|
2
|
+
export declare function configureVectorDimension(embeddingModel: string): void;
|
|
3
|
+
export declare function getDatabase(dbPath: string): Promise<Connection>;
|
|
4
|
+
export declare function getOrCreateTable(db: Connection, tableName: string, seedData?: Record<string, unknown>[]): Promise<Table>;
|
|
5
|
+
export declare function getCandidateSeedRow(): Record<string, unknown>[];
|
|
6
|
+
export declare function getChunkSeedRow(): Record<string, unknown>[];
|
|
7
|
+
export declare function getVersionSeedRow(): Record<string, unknown>[];
|
|
8
|
+
export declare function getJobPostingSeedRow(): Record<string, unknown>[];
|
|
9
|
+
export declare function getApplicationSeedRow(): Record<string, unknown>[];
|
|
10
|
+
export declare function getApplicationEventSeedRow(): Record<string, unknown>[];
|
|
11
|
+
export declare const TABLE_NAMES: {
|
|
12
|
+
readonly candidates: "candidates";
|
|
13
|
+
readonly chunks: "cv_chunks";
|
|
14
|
+
readonly versions: "cv_versions";
|
|
15
|
+
readonly jobPostings: "job_postings";
|
|
16
|
+
readonly applications: "applications";
|
|
17
|
+
readonly applicationEvents: "application_events";
|
|
18
|
+
};
|
|
19
|
+
export declare function getVectorDimension(): number;
|
|
20
|
+
export declare function resetAllTables(db: Connection): Promise<void>;
|