Skip to content

Commit 3b9040b

Browse files
authored
Merge pull request #2 from huntflow/INT-146_applicant_hook_model
[INT-146] Add applicant hook request model
2 parents 11d518c + 07bc40f commit 3b9040b

12 files changed

+682
-1
lines changed

models/__init__.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from . import consts
2+
from .applicant import ApplicantHookRequest
3+
4+
__all__ = [
5+
"consts",
6+
"ApplicantHookRequest",
7+
]

models/applicant.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from typing import List
2+
3+
from pydantic import BaseModel
4+
5+
from models.base import BaseHuntflowWebhookRequest, WebhookMetaInfoBase
6+
from models.common_models.applicant import Applicant, ApplicantLog, ApplicantTag
7+
from models.consts import ApplicantWebhookActionType
8+
9+
10+
class ApplicantEvent(BaseModel):
11+
applicant: Applicant
12+
applicant_log: ApplicantLog
13+
applicant_tags: List[ApplicantTag]
14+
15+
16+
class ApplicantHookRequestMeta(WebhookMetaInfoBase):
17+
webhook_action: ApplicantWebhookActionType
18+
19+
20+
class ApplicantHookRequest(BaseHuntflowWebhookRequest):
21+
event: ApplicantEvent
22+
meta: ApplicantHookRequestMeta

models/base.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from typing import Dict, Optional
2+
3+
from pydantic import BaseModel, Field
4+
5+
from models.consts import WebhookEventType
6+
7+
8+
class Account(BaseModel):
9+
id: int = Field(..., description="Account ID", example=1)
10+
name: str = Field(..., description="Account name", example="Huntflow")
11+
nick: str = Field(..., description="Account nick", example="HF")
12+
13+
14+
class Author(BaseModel):
15+
id: int = Field(..., description="Account ID", example=1)
16+
email: str = Field(..., description="Account owner email", example="[email protected]")
17+
name: str = Field(..., description="Account owner name", example="John")
18+
meta: Optional[Dict] = Field(None, description="Additional data", example={"data": "data"})
19+
20+
21+
class WebhookMetaInfoBase(BaseModel):
22+
account: Account
23+
author: Author
24+
event_type: WebhookEventType = Field(
25+
...,
26+
description="Webhook event type",
27+
example=WebhookEventType.APPLICANT,
28+
)
29+
version: str = Field(..., description="Webhook version", example="2.0")
30+
retry: int = Field(..., description="Webhook retry count", example=1)
31+
event_id: str = Field(..., description="Event ID", example="1")
32+
33+
34+
class BaseHuntflowWebhookRequest(BaseModel):
35+
changes: Optional[Dict] = Field(..., description="Data changes", example={"id": 2})
36+
meta: WebhookMetaInfoBase

models/common_models/__init__.py

Whitespace-only changes.

models/common_models/applicant.py

+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
from datetime import date, datetime
2+
from typing import Any, Dict, List, Optional
3+
4+
from pydantic import BaseModel, Field
5+
6+
from models.common_models.calendar_event import ApplicantLogCalendarEvent
7+
from models.common_models.hf_base import AccountFile
8+
from models.common_models.survey_questionary import SurveyQuestionary
9+
from models.common_models.vacancy import Vacancy
10+
from models.consts import AgreementState, ApplicantLogType, SurveyType
11+
12+
13+
class ApplicantSocial(BaseModel):
14+
id: int = Field(..., description="Social ID", example=1)
15+
social_type: str = Field(..., description="Social type", example="TELEGRAM")
16+
value: str = Field(..., description="Social nick/email", example="test_tg")
17+
verified: bool = Field(..., description="Verification flag", example=True)
18+
verification_date: Optional[datetime] = Field(
19+
None,
20+
description="Verification datetime",
21+
example=datetime(1970, 1, 1, 1, 1, 1),
22+
)
23+
24+
25+
class ApplicantPDAgreement(BaseModel):
26+
state: Optional[AgreementState] = Field(
27+
None,
28+
description="Agreement state",
29+
example=AgreementState.NOT_SENT,
30+
)
31+
decision_date: Optional[datetime] = Field(
32+
None,
33+
description="Decision date",
34+
example=datetime(1970, 1, 1, 1, 1, 1),
35+
)
36+
37+
38+
class VacancyApplicantStatus(BaseModel):
39+
id: int = Field(..., description="Status ID", example=1)
40+
name: str = Field(..., description="Status name", example="hired")
41+
42+
43+
class ApplicantPhoto(AccountFile):
44+
pass
45+
46+
47+
class Applicant(BaseModel):
48+
id: int = Field(..., description="Applicant ID", example=1)
49+
email: Optional[str] = Field(None, description="Applicant's email", example="[email protected]")
50+
first_name: str = Field(..., description="Applicant's firstname", example="test_name")
51+
last_name: str = Field(..., description="Applicant's lastname", example="test")
52+
middle_name: Optional[str] = Field(None, description="Applicant's patronymic", example="test")
53+
position: Optional[str] = Field(None, description="Applicant's current job", example="test")
54+
birthday: Optional[date] = Field(
55+
None,
56+
description="Applicant's birthday",
57+
example=date(1970, 1, 1),
58+
)
59+
company: Optional[str] = Field(
60+
None,
61+
description="Last company the applicant worked for",
62+
example="test",
63+
)
64+
money: Optional[str] = Field(None, description="Desired salary of the applicant", example="10$")
65+
phone: Optional[str] = Field(None, description="Applicant's phone", example="+99999999")
66+
skype: Optional[str] = Field(None, description="Applicant's skype", example="test_skype")
67+
photo: Optional[ApplicantPhoto] = Field(None, description="Applicant's photo")
68+
social: List[ApplicantSocial] = Field([], description="Applicant social media list")
69+
questionary: Optional[datetime] = Field(
70+
None,
71+
description="Date of filling / changing additional information",
72+
example=datetime(1970, 1, 1, 1, 1, 1, 1),
73+
)
74+
pd_agreement: Optional[ApplicantPDAgreement] = Field(
75+
None,
76+
description="Agreement on the processing of personal data",
77+
)
78+
values: Optional[Dict[str, Any]] = Field(
79+
None,
80+
description="Additional applicant fields",
81+
example={"favorite_language": "python"},
82+
)
83+
84+
85+
class Respondent(BaseModel):
86+
account_id: int = Field(..., description="Account ID", example=1)
87+
custom_id: int = Field(..., description="Custom ID", example=1)
88+
name: Optional[str] = Field(None, description="Respondent name", example="John")
89+
email: str = Field(..., description="Respondent email", example="[email protected]")
90+
91+
92+
class Survey(BaseModel):
93+
id: int = Field(..., description="Survey ID", example=1)
94+
name: str = Field(..., description="Survey name", example="test")
95+
type: SurveyType = Field(..., description="Survey type", example=SurveyType.TYPE_A)
96+
created: datetime = Field(
97+
...,
98+
description="Date the survey was created",
99+
example=datetime(1970, 1, 1, 1, 1, 1),
100+
)
101+
updated: Optional[datetime] = Field(
102+
None,
103+
description="Date the survey was changed",
104+
example=datetime(1970, 1, 1, 1, 1, 1),
105+
)
106+
active: bool = Field(..., description="Active flag", example=True)
107+
108+
109+
class SurveyAnswerOfTypeA(BaseModel):
110+
id: int = Field(..., description="Survey answer ID", example=1)
111+
respondent: Respondent
112+
survey: Survey
113+
created: datetime = Field(
114+
...,
115+
description="Date of the questionnaire",
116+
example=datetime(1970, 1, 1, 1, 1, 1),
117+
)
118+
updated: Optional[datetime] = Field(
119+
...,
120+
description="Date the questionnaire was modified",
121+
example=datetime(1970, 1, 1, 1, 1, 1),
122+
)
123+
values: Optional[Dict[str, Any]] = Field(
124+
None,
125+
description="Survey results",
126+
example={"question": "answer"},
127+
)
128+
129+
130+
class RejectionReason(BaseModel):
131+
id: int = Field(..., description="Rejection reason ID", example=1)
132+
name: str = Field(..., description="Rejection reason name", example="Too far")
133+
134+
135+
class ApplicantLog(BaseModel):
136+
id: int = Field(..., description="Applicant log ID", example=1)
137+
type: ApplicantLogType = Field(
138+
...,
139+
description="Applicant log type",
140+
example=ApplicantLogType.STATUS,
141+
)
142+
status: Optional[VacancyApplicantStatus] = None
143+
employment_date: Optional[date] = Field(
144+
None,
145+
description="Applicant employment date",
146+
example=date(1970, 1, 1),
147+
)
148+
removed: Optional[datetime] = Field(
149+
None,
150+
description="Record delete date time",
151+
example=datetime(1970, 1, 1, 1, 1, 1),
152+
)
153+
comment: Optional[str] = Field(None, description="Comment", example="comment")
154+
created: datetime = Field(
155+
...,
156+
description="Log creation date time",
157+
example=datetime(1970, 1, 1, 1, 1, 1),
158+
)
159+
source: Optional[str]
160+
files: List[AccountFile] = Field([], description="List of uploaded files")
161+
survey_answer_of_type_a: Optional[SurveyAnswerOfTypeA] = None
162+
rejection_reason: Optional[RejectionReason] = None
163+
survey_questionary: Optional[SurveyQuestionary] = None
164+
calendar_event: Optional[ApplicantLogCalendarEvent] = None
165+
vacancy: Optional[Vacancy] = None
166+
167+
168+
class ApplicantTag(BaseModel):
169+
id: int = Field(..., description="Tag ID", example=1)
170+
name: str = Field(..., description="Tag name", example="COOL")
171+
color: str = Field(..., description="Tag color", example="000000")
+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
from datetime import datetime
2+
from typing import List, Optional
3+
4+
from pydantic import BaseModel, Field
5+
6+
from models.consts import (
7+
CalendarEventReminderMethod,
8+
CalendarEventStatus,
9+
CalendarEventType,
10+
Transparency,
11+
)
12+
13+
14+
class CalendarEventCreator(BaseModel):
15+
displayName: Optional[str] = Field(
16+
None,
17+
description="Event creator name",
18+
example="John",
19+
)
20+
email: str = Field(..., description="Event creator email", example="[email protected]")
21+
self: Optional[bool] = Field(
22+
False,
23+
description="Flag indicating that you are the creator of the event",
24+
example=False,
25+
)
26+
27+
28+
class CalendarEventAttendee(BaseModel):
29+
contact_id: Optional[int] = Field(None, description="Attendee contact ID", example=1)
30+
displayName: Optional[str] = Field(None, description="Attendee display name", example="John")
31+
email: Optional[str] = Field(None, description="Attendee email", example="[email protected]")
32+
member: Optional[int] = Field(None, description="Coworker ID", example=1)
33+
name: Optional[str] = Field(None, description="Attendee name", example="John")
34+
order: Optional[int] = Field(None, description="Attendee order", example=1)
35+
resource: bool = Field(..., description="Attendee resource flag", example=False)
36+
responseStatus: Optional[CalendarEventStatus] = Field(
37+
None,
38+
description="Attendee response status",
39+
example=CalendarEventStatus.accepted,
40+
)
41+
42+
43+
class Conference(BaseModel):
44+
id: int = Field(..., description="Conference ID", example=1)
45+
topic: Optional[str] = Field(None, description="Conference topic", example="Interview")
46+
auth_type: Optional[str] = Field(None, description="Conference venue", example="ZOOM")
47+
state: Optional[str] = Field(
48+
None,
49+
)
50+
start_time: Optional[datetime] = Field(
51+
None,
52+
description="Conference start",
53+
example=datetime(1970, 1, 1, 1, 1, 1),
54+
)
55+
end_time: Optional[datetime] = Field(
56+
None,
57+
description="Conference end",
58+
example=datetime(1970, 1, 1, 1, 1, 1),
59+
)
60+
timezone: Optional[str] = Field(None, description="Conference timezone", example="Africa/Accra")
61+
created: datetime = Field(
62+
...,
63+
description="Conference creation datetime",
64+
example=datetime(1970, 1, 1, 1, 1, 1),
65+
)
66+
changed: Optional[datetime] = Field(
67+
None,
68+
description="Conference change datetime",
69+
example=datetime(1970, 1, 1, 1, 1, 1),
70+
)
71+
foreign: Optional[str] = Field(
72+
None,
73+
description="Foreign conference ID",
74+
example="conference_id",
75+
)
76+
link: Optional[str] = Field(
77+
None,
78+
description="Conference link",
79+
example="https://conference/link",
80+
)
81+
access_code: Optional[str] = Field(
82+
None,
83+
description="Conference access code",
84+
example="conference_code",
85+
)
86+
87+
88+
class CalendarEventReminder(BaseModel):
89+
method: CalendarEventReminderMethod = Field(
90+
...,
91+
description="Reminder method",
92+
example=CalendarEventReminderMethod.popup,
93+
)
94+
minutes: int = Field(
95+
...,
96+
description="How many minutes in advance to remind about the event",
97+
example=1,
98+
)
99+
100+
101+
class ApplicantLogCalendarEvent(BaseModel):
102+
id: int = Field(..., description="Calendar event ID", example=1)
103+
name: Optional[str] = Field(None, description="Event name", example="Test Name")
104+
description: Optional[str] = Field(
105+
None,
106+
description="Event description",
107+
example="Interview with John Doe",
108+
)
109+
status: CalendarEventStatus = Field(
110+
...,
111+
description="Event status",
112+
example=CalendarEventStatus.accepted,
113+
)
114+
event_type: CalendarEventType = Field(
115+
...,
116+
description="Event type",
117+
example=CalendarEventType.interview,
118+
)
119+
start: datetime = Field(
120+
...,
121+
description="Event start date and time",
122+
example=datetime(1970, 1, 1, 1, 1, 1),
123+
)
124+
end: datetime = Field(
125+
...,
126+
description="Event end date and time",
127+
example=datetime(1970, 1, 1, 1, 1, 1),
128+
)
129+
timezone: Optional[str] = Field(None, description="Event time zone", example="Africa/Accra")
130+
attendees: List[CalendarEventAttendee] = Field(
131+
[],
132+
description="Event attendees (participants)",
133+
)
134+
created: datetime = Field(
135+
...,
136+
description="Date and time of event creation",
137+
example=datetime(1970, 1, 1, 1, 1, 1),
138+
)
139+
creator: Optional[CalendarEventCreator] = Field(None, description="Event creator")
140+
reminders: List[CalendarEventReminder] = Field(
141+
[],
142+
description="List of reminders",
143+
)
144+
all_day: bool = Field(
145+
...,
146+
description="Flag indicating that the event is scheduled for the whole day",
147+
example=False,
148+
)
149+
foreign: Optional[str] = Field(None, description="Foreign event ID", example="f1")
150+
recurrence: Optional[List] = None
151+
etag: Optional[str] = Field(None, description="Event Etag", example=1633413621888)
152+
location: Optional[str] = Field(None, description="Event location", example="Some location")
153+
transparency: Transparency = Field(
154+
...,
155+
description="Event transparency (availability)",
156+
example=Transparency.busy,
157+
)
158+
conference: Optional[Conference] = Field(None, description="Event conference data")

0 commit comments

Comments
 (0)