hirebase-mcp 1.0.0
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 +133 -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 +43 -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 +8 -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 +15 -0
- package/dist/application/use-cases/add-cv.js +88 -0
- package/dist/application/use-cases/add-cv.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-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-stats.d.ts +9 -0
- package/dist/application/use-cases/get-stats.js +42 -0
- package/dist/application/use-cases/get-stats.js.map +1 -0
- package/dist/application/use-cases/index.d.ts +13 -0
- package/dist/application/use-cases/index.js +14 -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/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/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/update-cv.d.ts +17 -0
- package/dist/application/use-cases/update-cv.js +94 -0
- package/dist/application/use-cases/update-cv.js.map +1 -0
- package/dist/domain/entities/candidate.d.ts +22 -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 +3 -0
- package/dist/domain/entities/index.js +2 -0
- package/dist/domain/entities/index.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 +3 -0
- package/dist/domain/repositories/index.js +2 -0
- package/dist/domain/repositories/index.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 +117 -0
- package/dist/infrastructure/ai/openai-structured-extractor.js.map +1 -0
- package/dist/infrastructure/config/app-config.d.ts +7 -0
- package/dist/infrastructure/config/app-config.js +13 -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 +2 -0
- package/dist/infrastructure/parsers/index.js +3 -0
- package/dist/infrastructure/parsers/index.js.map +1 -0
- package/dist/infrastructure/parsers/pdf-parser.d.ts +5 -0
- package/dist/infrastructure/parsers/pdf-parser.js +20 -0
- package/dist/infrastructure/parsers/pdf-parser.js.map +1 -0
- package/dist/infrastructure/persistence/database.d.ts +12 -0
- package/dist/infrastructure/persistence/database.js +77 -0
- package/dist/infrastructure/persistence/database.js.map +1 -0
- package/dist/infrastructure/persistence/index.d.ts +4 -0
- package/dist/infrastructure/persistence/index.js +5 -0
- package/dist/infrastructure/persistence/index.js.map +1 -0
- package/dist/infrastructure/persistence/lancedb-candidate-repository.d.ts +20 -0
- package/dist/infrastructure/persistence/lancedb-candidate-repository.js +158 -0
- package/dist/infrastructure/persistence/lancedb-candidate-repository.js.map +1 -0
- package/dist/infrastructure/persistence/lancedb-chunk-repository.d.ts +17 -0
- package/dist/infrastructure/persistence/lancedb-chunk-repository.js +102 -0
- package/dist/infrastructure/persistence/lancedb-chunk-repository.js.map +1 -0
- package/dist/infrastructure/persistence/lancedb-version-repository.d.ts +12 -0
- package/dist/infrastructure/persistence/lancedb-version-repository.js +59 -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 +14 -0
- package/dist/interface/cli/index.js.map +1 -0
- package/dist/interface/mcp/server.d.ts +2 -0
- package/dist/interface/mcp/server.js +63 -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 +20 -0
- package/dist/interface/mcp/tools/add-cv.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/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-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 +20 -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-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/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/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/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/types.d.ts +16 -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/index.d.ts +2 -0
- package/dist/shared/utils/index.js +3 -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 +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# HireBase
|
|
2
|
+
|
|
3
|
+
AI-powered CV search engine built as an MCP Server. Stores CVs in LanceDB vector database, extracts structured data with GPT, and finds the best-matching candidates for any job description using semantic search.
|
|
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 Parsers
|
|
14
|
+
├── interface/ # MCP Server, Tools, CLI Entry Point
|
|
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
|
+
| unpdf | PDF text extraction |
|
|
30
|
+
| mammoth | DOCX text extraction |
|
|
31
|
+
|
|
32
|
+
## MCP Tools
|
|
33
|
+
|
|
34
|
+
| Tool | Description |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `add_cv` | Parse CV file (PDF/DOCX), extract structured data, embed, store |
|
|
37
|
+
| `bulk_add_cvs` | Process all CVs in a directory |
|
|
38
|
+
| `update_cv` | Update existing CV, archive old version |
|
|
39
|
+
| `semantic_search` | Vector similarity search with optional section filter |
|
|
40
|
+
| `filter_candidates` | Structured filtering (skills, location, experience, languages, tags) |
|
|
41
|
+
| `get_cv_detail` | Full candidate data |
|
|
42
|
+
| `get_cv_chunks` | CV section chunks |
|
|
43
|
+
| `list_cvs` | Paginated candidate list |
|
|
44
|
+
| `delete_cv` | Delete candidate and all related data |
|
|
45
|
+
| `manage_tags` | Add/remove/list tags |
|
|
46
|
+
| `get_cv_versions` | Version history |
|
|
47
|
+
| `get_stats` | Database statistics |
|
|
48
|
+
| `export_results` | Export as JSON or CSV |
|
|
49
|
+
|
|
50
|
+
## How It Works
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
CV File (PDF/DOCX)
|
|
54
|
+
│
|
|
55
|
+
▼
|
|
56
|
+
[1] Parse text (unpdf / mammoth)
|
|
57
|
+
│
|
|
58
|
+
▼
|
|
59
|
+
[2] Extract structured data (GPT-5 mini)
|
|
60
|
+
│ name, experience, education, skills, languages...
|
|
61
|
+
▼
|
|
62
|
+
[3] Chunk into sections
|
|
63
|
+
│ summary, each experience, education, skills, projects, certifications, full text
|
|
64
|
+
▼
|
|
65
|
+
[4] Generate embeddings (text-embedding-3-large, 3072d)
|
|
66
|
+
│
|
|
67
|
+
▼
|
|
68
|
+
[5] Store in LanceDB (candidates + cv_chunks + cv_versions tables)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Search flow (driven by AI client):**
|
|
72
|
+
1. AI analyzes job description
|
|
73
|
+
2. Calls `filter_candidates` for hard requirements
|
|
74
|
+
3. Calls `semantic_search` with job description text
|
|
75
|
+
4. Cross-references results
|
|
76
|
+
5. Gets full details with `get_cv_detail`
|
|
77
|
+
6. Produces match explanation
|
|
78
|
+
|
|
79
|
+
## Setup
|
|
80
|
+
|
|
81
|
+
### Prerequisites
|
|
82
|
+
|
|
83
|
+
- Node.js >= 22
|
|
84
|
+
- pnpm
|
|
85
|
+
- OpenAI API Key
|
|
86
|
+
|
|
87
|
+
### Install & Build
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pnpm install
|
|
91
|
+
pnpm build
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Environment Variables
|
|
95
|
+
|
|
96
|
+
```env
|
|
97
|
+
OPENAI_API_KEY=sk-your-key-here
|
|
98
|
+
LANCEDB_PATH=./data/lancedb # optional, default: ./data/lancedb
|
|
99
|
+
EMBEDDING_MODEL=text-embedding-3-large # optional
|
|
100
|
+
EXTRACTION_MODEL=gpt-5-mini # optional
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### MCP Configuration
|
|
104
|
+
|
|
105
|
+
Add to your Claude Code or Claude Desktop config:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"mcpServers": {
|
|
110
|
+
"hirebase": {
|
|
111
|
+
"command": "node",
|
|
112
|
+
"args": ["<path-to-project>/dist/interface/cli/index.js"],
|
|
113
|
+
"env": {
|
|
114
|
+
"OPENAI_API_KEY": "sk-your-key",
|
|
115
|
+
"LANCEDB_PATH": "<path-to-project>/data/lancedb"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Key Design Decisions
|
|
123
|
+
|
|
124
|
+
- **LanceDB has no UPDATE** — update is implemented as delete + add at repository level
|
|
125
|
+
- **Complex fields stored as JSON strings** — skills, experience, etc. serialized in Utf8 columns
|
|
126
|
+
- **Batch embedding** — all chunks embedded in a single OpenAI API call
|
|
127
|
+
- **Seed rows** — tables use `__seed__` rows for schema inference, filtered out in queries
|
|
128
|
+
- **Versioning** — old CV data archived before updates, full history accessible
|
|
129
|
+
- **Section-level chunking** — each work experience is a separate chunk for granular matching
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidate-summary.js","sourceRoot":"","sources":["../../../src/application/dto/candidate-summary.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
}
|
|
@@ -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 @@
|
|
|
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,15 @@
|
|
|
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 declare class AddCvUseCase {
|
|
8
|
+
private candidateRepo;
|
|
9
|
+
private chunkRepo;
|
|
10
|
+
private parsers;
|
|
11
|
+
private embeddingService;
|
|
12
|
+
private extractor;
|
|
13
|
+
constructor(candidateRepo: ICandidateRepository, chunkRepo: IChunkRepository, parsers: IDocumentParser[], embeddingService: IEmbeddingService, extractor: IStructuredExtractor);
|
|
14
|
+
execute(filePath: string): Promise<Candidate>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
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 } from '../../shared/errors/index.js';
|
|
5
|
+
export class AddCvUseCase {
|
|
6
|
+
candidateRepo;
|
|
7
|
+
chunkRepo;
|
|
8
|
+
parsers;
|
|
9
|
+
embeddingService;
|
|
10
|
+
extractor;
|
|
11
|
+
constructor(candidateRepo, chunkRepo, parsers, embeddingService, extractor) {
|
|
12
|
+
this.candidateRepo = candidateRepo;
|
|
13
|
+
this.chunkRepo = chunkRepo;
|
|
14
|
+
this.parsers = parsers;
|
|
15
|
+
this.embeddingService = embeddingService;
|
|
16
|
+
this.extractor = extractor;
|
|
17
|
+
}
|
|
18
|
+
async execute(filePath) {
|
|
19
|
+
const fileType = detectFileType(filePath);
|
|
20
|
+
const parser = this.parsers.find((p) => p.supports(fileType));
|
|
21
|
+
if (!parser) {
|
|
22
|
+
throw new UnsupportedFileTypeError(fileType);
|
|
23
|
+
}
|
|
24
|
+
const { text: rawText } = await parser.parse(filePath);
|
|
25
|
+
const extracted = await this.extractor.extract(rawText);
|
|
26
|
+
if (extracted.email) {
|
|
27
|
+
const existing = await this.candidateRepo.findByEmail(extracted.email);
|
|
28
|
+
if (existing) {
|
|
29
|
+
throw new DuplicateCandidateError(extracted.email);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const candidateId = nanoid();
|
|
33
|
+
const now = new Date().toISOString();
|
|
34
|
+
const chunkInputs = createChunks(extracted, rawText);
|
|
35
|
+
const chunkTexts = chunkInputs.map((c) => c.content);
|
|
36
|
+
const vectors = await this.embeddingService.embedBatch(chunkTexts);
|
|
37
|
+
const candidate = {
|
|
38
|
+
id: candidateId,
|
|
39
|
+
name: extracted.name,
|
|
40
|
+
contact: {
|
|
41
|
+
email: extracted.email,
|
|
42
|
+
phone: extracted.phone,
|
|
43
|
+
location: extracted.location,
|
|
44
|
+
},
|
|
45
|
+
summary: extracted.summary,
|
|
46
|
+
experience: extracted.experience.map((e) => ({
|
|
47
|
+
company: e.company,
|
|
48
|
+
position: e.position,
|
|
49
|
+
startDate: e.startDate,
|
|
50
|
+
endDate: e.endDate,
|
|
51
|
+
description: e.description,
|
|
52
|
+
})),
|
|
53
|
+
education: extracted.education.map((e) => ({
|
|
54
|
+
institution: e.institution,
|
|
55
|
+
degree: e.degree,
|
|
56
|
+
field: e.field,
|
|
57
|
+
startDate: e.startDate,
|
|
58
|
+
endDate: e.endDate,
|
|
59
|
+
})),
|
|
60
|
+
skills: extracted.skills,
|
|
61
|
+
languages: extracted.languages,
|
|
62
|
+
certifications: extracted.certifications,
|
|
63
|
+
projects: extracted.projects,
|
|
64
|
+
links: extracted.links,
|
|
65
|
+
tags: [],
|
|
66
|
+
experienceYears: extracted.totalExperienceYears,
|
|
67
|
+
sourceFile: filePath,
|
|
68
|
+
fileType,
|
|
69
|
+
rawText,
|
|
70
|
+
createdAt: now,
|
|
71
|
+
updatedAt: now,
|
|
72
|
+
version: 1,
|
|
73
|
+
};
|
|
74
|
+
const chunks = chunkInputs.map((input, i) => ({
|
|
75
|
+
id: nanoid(),
|
|
76
|
+
candidateId,
|
|
77
|
+
sectionType: input.sectionType,
|
|
78
|
+
content: input.content,
|
|
79
|
+
vector: vectors[i],
|
|
80
|
+
metadata: input.metadata,
|
|
81
|
+
createdAt: now,
|
|
82
|
+
}));
|
|
83
|
+
await this.candidateRepo.save(candidate);
|
|
84
|
+
await this.chunkRepo.saveMany(chunks);
|
|
85
|
+
return candidate;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# 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,14 @@
|
|
|
1
|
+
import type { Candidate } from '../../domain/entities/candidate.js';
|
|
2
|
+
import { AddCvUseCase } from './add-cv.js';
|
|
3
|
+
export interface BulkAddResult {
|
|
4
|
+
succeeded: Candidate[];
|
|
5
|
+
failed: {
|
|
6
|
+
file: string;
|
|
7
|
+
error: string;
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
export declare class BulkAddCvsUseCase {
|
|
11
|
+
private addCvUseCase;
|
|
12
|
+
constructor(addCvUseCase: AddCvUseCase);
|
|
13
|
+
execute(directoryPath: string): Promise<BulkAddResult>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { readdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
export class BulkAddCvsUseCase {
|
|
4
|
+
addCvUseCase;
|
|
5
|
+
constructor(addCvUseCase) {
|
|
6
|
+
this.addCvUseCase = addCvUseCase;
|
|
7
|
+
}
|
|
8
|
+
async execute(directoryPath) {
|
|
9
|
+
const entries = await readdir(directoryPath);
|
|
10
|
+
const cvFiles = entries.filter((f) => {
|
|
11
|
+
const ext = f.toLowerCase().split('.').pop();
|
|
12
|
+
return ext === 'pdf' || ext === 'docx';
|
|
13
|
+
});
|
|
14
|
+
const succeeded = [];
|
|
15
|
+
const failed = [];
|
|
16
|
+
for (const file of cvFiles) {
|
|
17
|
+
const filePath = join(directoryPath, file);
|
|
18
|
+
try {
|
|
19
|
+
const candidate = await this.addCvUseCase.execute(filePath);
|
|
20
|
+
succeeded.push(candidate);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
failed.push({
|
|
24
|
+
file,
|
|
25
|
+
error: error instanceof Error ? error.message : String(error),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { succeeded, failed };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=bulk-add-cvs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk-add-cvs.js","sourceRoot":"","sources":["../../../src/application/use-cases/bulk-add-cvs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AASjC,MAAM,OAAO,iBAAiB;IACR;IAApB,YAAoB,YAA0B;QAA1B,iBAAY,GAAZ,YAAY,CAAc;IAAG,CAAC;IAElD,KAAK,CAAC,OAAO,CAAC,aAAqB;QACjC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACnC,MAAM,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC7C,OAAO,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,SAAS,GAAgB,EAAE,CAAC;QAClC,MAAM,MAAM,GAAsC,EAAE,CAAC;QAErD,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC5D,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI;oBACJ,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ICandidateRepository } from '../../domain/repositories/candidate-repository.js';
|
|
2
|
+
import type { IChunkRepository } from '../../domain/repositories/chunk-repository.js';
|
|
3
|
+
import type { IVersionRepository } from '../../domain/repositories/version-repository.js';
|
|
4
|
+
export declare class DeleteCvUseCase {
|
|
5
|
+
private candidateRepo;
|
|
6
|
+
private chunkRepo;
|
|
7
|
+
private versionRepo;
|
|
8
|
+
constructor(candidateRepo: ICandidateRepository, chunkRepo: IChunkRepository, versionRepo: IVersionRepository);
|
|
9
|
+
execute(candidateId: string): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CandidateNotFoundError } from '../../shared/errors/index.js';
|
|
2
|
+
export class DeleteCvUseCase {
|
|
3
|
+
candidateRepo;
|
|
4
|
+
chunkRepo;
|
|
5
|
+
versionRepo;
|
|
6
|
+
constructor(candidateRepo, chunkRepo, versionRepo) {
|
|
7
|
+
this.candidateRepo = candidateRepo;
|
|
8
|
+
this.chunkRepo = chunkRepo;
|
|
9
|
+
this.versionRepo = versionRepo;
|
|
10
|
+
}
|
|
11
|
+
async execute(candidateId) {
|
|
12
|
+
const candidate = await this.candidateRepo.findById(candidateId);
|
|
13
|
+
if (!candidate) {
|
|
14
|
+
throw new CandidateNotFoundError(candidateId);
|
|
15
|
+
}
|
|
16
|
+
await this.chunkRepo.deleteByCandidateId(candidateId);
|
|
17
|
+
await this.versionRepo.deleteByCandidateId(candidateId);
|
|
18
|
+
await this.candidateRepo.delete(candidateId);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=delete-cv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete-cv.js","sourceRoot":"","sources":["../../../src/application/use-cases/delete-cv.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,MAAM,OAAO,eAAe;IAEhB;IACA;IACA;IAHV,YACU,aAAmC,EACnC,SAA2B,EAC3B,WAA+B;QAF/B,kBAAa,GAAb,aAAa,CAAsB;QACnC,cAAS,GAAT,SAAS,CAAkB;QAC3B,gBAAW,GAAX,WAAW,CAAoB;IACtC,CAAC;IAEJ,KAAK,CAAC,OAAO,CAAC,WAAmB;QAC/B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACjE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,sBAAsB,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;QACxD,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ICandidateRepository } from '../../domain/repositories/candidate-repository.js';
|
|
2
|
+
import type { IExportService } from '../ports/export-service.js';
|
|
3
|
+
import type { ExportFormat } from '../../shared/types/index.js';
|
|
4
|
+
export declare class ExportResultsUseCase {
|
|
5
|
+
private candidateRepo;
|
|
6
|
+
private exportService;
|
|
7
|
+
constructor(candidateRepo: ICandidateRepository, exportService: IExportService);
|
|
8
|
+
execute(candidateIds: string[], format: ExportFormat): Promise<string>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CandidateNotFoundError } from '../../shared/errors/index.js';
|
|
2
|
+
export class ExportResultsUseCase {
|
|
3
|
+
candidateRepo;
|
|
4
|
+
exportService;
|
|
5
|
+
constructor(candidateRepo, exportService) {
|
|
6
|
+
this.candidateRepo = candidateRepo;
|
|
7
|
+
this.exportService = exportService;
|
|
8
|
+
}
|
|
9
|
+
async execute(candidateIds, format) {
|
|
10
|
+
const candidates = [];
|
|
11
|
+
for (const id of candidateIds) {
|
|
12
|
+
const candidate = await this.candidateRepo.findById(id);
|
|
13
|
+
if (!candidate) {
|
|
14
|
+
throw new CandidateNotFoundError(id);
|
|
15
|
+
}
|
|
16
|
+
candidates.push(candidate);
|
|
17
|
+
}
|
|
18
|
+
return this.exportService.export(candidates, format);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=export-results.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-results.js","sourceRoot":"","sources":["../../../src/application/use-cases/export-results.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,MAAM,OAAO,oBAAoB;IAErB;IACA;IAFV,YACU,aAAmC,EACnC,aAA6B;QAD7B,kBAAa,GAAb,aAAa,CAAsB;QACnC,kBAAa,GAAb,aAAa,CAAgB;IACpC,CAAC;IAEJ,KAAK,CAAC,OAAO,CAAC,YAAsB,EAAE,MAAoB;QACxD,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,sBAAsB,CAAC,EAAE,CAAC,CAAC;YACvC,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ICandidateRepository } from '../../domain/repositories/candidate-repository.js';
|
|
2
|
+
import type { FilterInput } from '../dto/filter-input.js';
|
|
3
|
+
import type { CandidateSummaryDto } from '../dto/candidate-summary.js';
|
|
4
|
+
export declare class FilterCandidatesUseCase {
|
|
5
|
+
private candidateRepo;
|
|
6
|
+
constructor(candidateRepo: ICandidateRepository);
|
|
7
|
+
execute(input: FilterInput): Promise<CandidateSummaryDto[]>;
|
|
8
|
+
private toSummary;
|
|
9
|
+
}
|