ketannnn commited on
Commit
1ca9ba2
·
1 Parent(s): c1dbdc6

feat: define ORM models for JD, Candidate, MatchResult with Alembic migration

Browse files
backend/src/models/__init__.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from .jd import JobDescription
2
+ from .candidate import Candidate
3
+ from .match_result import MatchResult
4
+
5
+ __all__ = ["JobDescription", "Candidate", "MatchResult"]
backend/src/models/candidate.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uuid
2
+ from datetime import datetime
3
+ from sqlalchemy import String, Text, DateTime, JSON, Float, Integer, Boolean, func
4
+ from sqlalchemy.orm import Mapped, mapped_column
5
+ from sqlalchemy.dialects.postgresql import UUID
6
+ from ..database import Base
7
+
8
+
9
+ class Candidate(Base):
10
+ __tablename__ = "candidates"
11
+
12
+ id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
13
+ external_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
14
+
15
+ name: Mapped[str | None] = mapped_column(String(255), nullable=True)
16
+ email: Mapped[str | None] = mapped_column(String(255), nullable=True)
17
+
18
+ looking_for: Mapped[str | None] = mapped_column(String(100), nullable=True)
19
+ currently_employed: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
20
+ notice_period: Mapped[str | None] = mapped_column(String(100), nullable=True)
21
+ open_to_working_at: Mapped[str | None] = mapped_column(String(255), nullable=True)
22
+ role_type: Mapped[str | None] = mapped_column(String(100), nullable=True)
23
+ engineer_type: Mapped[str | None] = mapped_column(String(100), nullable=True)
24
+
25
+ years_of_experience: Mapped[float | None] = mapped_column(Float, nullable=True)
26
+ programming_languages: Mapped[list] = mapped_column(JSON, default=list)
27
+ backend_frameworks: Mapped[list] = mapped_column(JSON, default=list)
28
+ frontend_technologies: Mapped[list] = mapped_column(JSON, default=list)
29
+ gen_ai_experience: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
30
+ recent_experience_type: Mapped[str | None] = mapped_column(String(100), nullable=True)
31
+ education_status: Mapped[str | None] = mapped_column(String(100), nullable=True)
32
+ degree: Mapped[str | None] = mapped_column(String(255), nullable=True)
33
+
34
+ parsed_summary: Mapped[str | None] = mapped_column(Text, nullable=True)
35
+ parsed_skills: Mapped[str | None] = mapped_column(Text, nullable=True)
36
+ parsed_work_experience: Mapped[list] = mapped_column(JSON, default=list)
37
+
38
+ most_recent_company: Mapped[str | None] = mapped_column(String(255), nullable=True)
39
+ most_recent_company_description: Mapped[str | None] = mapped_column(Text, nullable=True)
40
+ most_recent_company_is_funded: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
41
+ most_recent_company_is_product_company: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
42
+ most_recent_company_total_funding: Mapped[float | None] = mapped_column(Float, nullable=True)
43
+ most_recent_company_funding_status: Mapped[str | None] = mapped_column(String(100), nullable=True)
44
+
45
+ time_in_current_company: Mapped[float | None] = mapped_column(Float, nullable=True)
46
+ is_actively_or_passively_looking: Mapped[str | None] = mapped_column(String(100), nullable=True)
47
+
48
+ growth_velocity: Mapped[float] = mapped_column(Float, default=0.5)
49
+ embedding_hash: Mapped[str | None] = mapped_column(String(64), nullable=True)
50
+ qdrant_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
51
+
52
+ created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
53
+ updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
backend/src/models/jd.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uuid
2
+ from datetime import datetime
3
+ from sqlalchemy import String, Text, DateTime, JSON, Float, Integer, func
4
+ from sqlalchemy.orm import Mapped, mapped_column
5
+ from sqlalchemy.dialects.postgresql import UUID, ARRAY
6
+ from ..database import Base
7
+
8
+
9
+ class JobDescription(Base):
10
+ __tablename__ = "job_descriptions"
11
+
12
+ id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
13
+ title: Mapped[str] = mapped_column(String(255))
14
+ raw_text: Mapped[str] = mapped_column(Text)
15
+ parsed_requirements: Mapped[dict] = mapped_column(JSON, default=dict)
16
+ required_skills: Mapped[list] = mapped_column(JSON, default=list)
17
+ min_yoe: Mapped[float | None] = mapped_column(Float, nullable=True)
18
+ max_yoe: Mapped[float | None] = mapped_column(Float, nullable=True)
19
+ role_type: Mapped[str | None] = mapped_column(String(100), nullable=True)
20
+ engineer_type: Mapped[str | None] = mapped_column(String(100), nullable=True)
21
+ location: Mapped[str | None] = mapped_column(String(255), nullable=True)
22
+ remote_allowed: Mapped[bool | None] = mapped_column(nullable=True)
23
+ jd_quality: Mapped[dict] = mapped_column(JSON, default=dict)
24
+ embedding_text: Mapped[str | None] = mapped_column(Text, nullable=True)
25
+ qdrant_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
26
+ status: Mapped[str] = mapped_column(String(32), default="pending")
27
+ created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
28
+ updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
backend/src/models/match_result.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uuid
2
+ from datetime import datetime
3
+ from sqlalchemy import String, DateTime, JSON, Float, ForeignKey, func
4
+ from sqlalchemy.orm import Mapped, mapped_column
5
+ from sqlalchemy.dialects.postgresql import UUID
6
+ from ..database import Base
7
+
8
+
9
+ class MatchResult(Base):
10
+ __tablename__ = "match_results"
11
+
12
+ id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
13
+ jd_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("job_descriptions.id", ondelete="CASCADE"), index=True)
14
+ candidate_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("candidates.id", ondelete="CASCADE"), index=True)
15
+
16
+ rank: Mapped[int | None] = mapped_column(nullable=True)
17
+ stage1_score: Mapped[float] = mapped_column(Float, default=0.0)
18
+ stage2_score: Mapped[float | None] = mapped_column(Float, nullable=True)
19
+ final_score: Mapped[float] = mapped_column(Float, default=0.0)
20
+
21
+ component_scores: Mapped[dict] = mapped_column(JSON, default=dict)
22
+ gaps: Mapped[list] = mapped_column(JSON, default=list)
23
+ explanation: Mapped[str | None] = mapped_column(String, nullable=True)
24
+ explanation_generated_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
25
+
26
+ weights_used: Mapped[dict] = mapped_column(JSON, default=dict)
27
+ created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())