chore: heygermany customer project
This commit is contained in:
112
packages/sdk/config.ts
Normal file
112
packages/sdk/config.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Application configuration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Countries that are currently supported for document analysis
|
||||
* Uses ISO 3166-1 alpha-3 country codes
|
||||
*/
|
||||
export const SUPPORTED_COUNTRIES = [
|
||||
'DEU', // Germany
|
||||
'UKR', // Ukraine
|
||||
'PHL', // Philippines
|
||||
'TUR', // Turkey
|
||||
'BIH', // Bosnia & Herzegovina
|
||||
'ALB', // Albania
|
||||
'VNM', // Vietnam
|
||||
'MEX', // Mexico
|
||||
'IND', // India
|
||||
'TUN', // Tunisia
|
||||
'SYR', // Syria
|
||||
] as const
|
||||
|
||||
export const SUPPORTED_COUNTRY_NAMES: Record<(typeof SUPPORTED_COUNTRIES)[number], string> = {
|
||||
DEU: 'Germany',
|
||||
UKR: 'Ukraine',
|
||||
PHL: 'Philippines',
|
||||
TUR: 'Turkey',
|
||||
BIH: 'Bosnia & Herzegovina',
|
||||
ALB: 'Albania',
|
||||
VNM: 'Vietnam',
|
||||
MEX: 'Mexico',
|
||||
IND: 'India',
|
||||
TUN: 'Tunisia',
|
||||
SYR: 'Syria',
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported application locales
|
||||
* Maps locale codes to their display information
|
||||
*/
|
||||
export const SUPPORTED_LOCALES = {
|
||||
en: {
|
||||
code: 'en',
|
||||
name: 'English',
|
||||
flag: 'https://flagcdn.com/us.svg',
|
||||
},
|
||||
de: {
|
||||
code: 'de',
|
||||
name: 'Deutsch',
|
||||
flag: 'https://flagcdn.com/de.svg',
|
||||
},
|
||||
uk: {
|
||||
code: 'uk',
|
||||
name: 'Українська',
|
||||
flag: 'https://flagcdn.com/ua.svg',
|
||||
},
|
||||
fil: {
|
||||
code: 'fil',
|
||||
name: 'Filipino',
|
||||
flag: 'https://flagcdn.com/ph.svg',
|
||||
},
|
||||
tr: {
|
||||
code: 'tr',
|
||||
name: 'Türkçe',
|
||||
flag: 'https://flagcdn.com/tr.svg',
|
||||
},
|
||||
bs: {
|
||||
code: 'bs',
|
||||
name: 'Bosanski',
|
||||
flag: 'https://flagcdn.com/ba.svg',
|
||||
},
|
||||
sq: {
|
||||
code: 'sq',
|
||||
name: 'Shqip',
|
||||
flag: 'https://flagcdn.com/al.svg',
|
||||
},
|
||||
vi: {
|
||||
code: 'vi',
|
||||
name: 'Tiếng Việt',
|
||||
flag: 'https://flagcdn.com/vn.svg',
|
||||
},
|
||||
es: {
|
||||
code: 'es',
|
||||
name: 'Español',
|
||||
flag: 'https://flagcdn.com/mx.svg',
|
||||
},
|
||||
hi: {
|
||||
code: 'hi',
|
||||
name: 'हिन्दी',
|
||||
flag: 'https://flagcdn.com/in.svg',
|
||||
},
|
||||
ar: {
|
||||
code: 'ar',
|
||||
name: 'العربية',
|
||||
flag: 'https://flagcdn.com/tn.svg',
|
||||
},
|
||||
} as const
|
||||
|
||||
export const LOCALES = Object.keys(SUPPORTED_LOCALES) as SupportedLocale[]
|
||||
export const DEFAULT_LOCALE: SupportedLocale = 'en'
|
||||
|
||||
/**
|
||||
* Languages array for language selector components
|
||||
*/
|
||||
export const LANGUAGES = Object.values(SUPPORTED_LOCALES).map(locale => ({
|
||||
label: locale.name,
|
||||
value: locale.code,
|
||||
flag: locale.flag,
|
||||
}))
|
||||
|
||||
export type SupportedLocale = keyof typeof SUPPORTED_LOCALES
|
||||
export type SupportedCountry = typeof SUPPORTED_COUNTRIES[number]
|
||||
322
packages/sdk/db.ts
Normal file
322
packages/sdk/db.ts
Normal file
@@ -0,0 +1,322 @@
|
||||
export type UserRole = 'admin' | 'owner'
|
||||
|
||||
export type UserType = 'company' | 'backoffice' | 'candidate'
|
||||
|
||||
export type LanguageLevel =
|
||||
| 'NONE'
|
||||
| 'A_ONE'
|
||||
| 'A_TWO'
|
||||
| 'B_ONE'
|
||||
| 'B_TWO'
|
||||
| 'C_ONE'
|
||||
| 'C_TWO'
|
||||
|
||||
export type CandidateDocumentType =
|
||||
| 'education'
|
||||
| 'license'
|
||||
| 'language'
|
||||
| 'work_experience'
|
||||
| 'profile_image'
|
||||
|
||||
export type DocumentStatus = 'Missing' | 'Invalid' | 'Verified' | 'Unverified'
|
||||
|
||||
export type ApplicantStatus =
|
||||
| 'Initial'
|
||||
| 'Invalid'
|
||||
| 'Pending'
|
||||
| 'Complete'
|
||||
| 'Failed'
|
||||
|
||||
export type NurseRecognitionGermany =
|
||||
| 'nurse'
|
||||
| 'assistant_nurse'
|
||||
| 'nursing_helper'
|
||||
|
||||
export type NurseRecognitionHomeCountry =
|
||||
| 'nurse'
|
||||
| 'assistant_nurse'
|
||||
| 'nursing_helper'
|
||||
| 'none'
|
||||
|
||||
export type RecognitionLikelihood = 'low' | 'medium' | 'high'
|
||||
|
||||
export type ProfessionalRecognitionStatus =
|
||||
| 'NOT_STARTED'
|
||||
| 'IN_PROGRESS'
|
||||
| 'COMPLETED'
|
||||
|
||||
export type LanguageCode =
|
||||
| 'en'
|
||||
| 'ar'
|
||||
| 'bs'
|
||||
| 'fil'
|
||||
| 'hi'
|
||||
| 'es'
|
||||
| 'tr'
|
||||
| 'uk'
|
||||
| 'vi'
|
||||
|
||||
export type GermanState =
|
||||
| 'Baden-Württemberg'
|
||||
| 'Bayern'
|
||||
| 'Berlin'
|
||||
| 'Brandenburg'
|
||||
| 'Bremen'
|
||||
| 'Hamburg'
|
||||
| 'Hessen'
|
||||
| 'Mecklenburg-Vorpommern'
|
||||
| 'Niedersachsen'
|
||||
| 'Nordrhein-Westfalen'
|
||||
| 'Rheinland-Pfalz'
|
||||
| 'Saarland'
|
||||
| 'Sachsen'
|
||||
| 'Sachsen-Anhalt'
|
||||
| 'Schleswig-Holstein'
|
||||
| 'Thüringen'
|
||||
|
||||
export type RecognitionDossierStatus =
|
||||
| 'draft'
|
||||
| 'blocked'
|
||||
| 'ready'
|
||||
| 'generating'
|
||||
| 'generated'
|
||||
| 'unsupported'
|
||||
| 'failed'
|
||||
|
||||
export type RecognitionDossierDocumentCategory =
|
||||
| 'passport'
|
||||
| 'birth_certificate'
|
||||
| 'name_change_proof'
|
||||
| 'employer_intent'
|
||||
| 'medical_certificate'
|
||||
| 'police_clearance'
|
||||
| 'translation'
|
||||
| 'authority_form'
|
||||
| 'power_of_attorney'
|
||||
| 'waiver_form'
|
||||
| 'other'
|
||||
|
||||
export interface Candidate {
|
||||
candidateId: string
|
||||
email: string
|
||||
name: string
|
||||
stateWorkPreference: GermanState[] | null
|
||||
joinTalentPool: boolean | null
|
||||
livingInGermany: boolean | null
|
||||
euPassport: boolean | null
|
||||
countryEducation: string | null
|
||||
licenseProvided: boolean | null
|
||||
languageCertificateProvided: boolean | null
|
||||
languageSelfAssessmentLevel: LanguageLevel | null
|
||||
submittedAt: Date | null
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
phone: string | null
|
||||
dateOfBirth: Date | null
|
||||
currentResidence: string | null
|
||||
qualificationStatusHomeCountry: NurseRecognitionHomeCountry | null
|
||||
qualificationStatusGermany: NurseRecognitionGermany | null
|
||||
licenseMandatory: boolean | null
|
||||
durationRequirementsMet: boolean | null
|
||||
status: ApplicantStatus
|
||||
incompleteReminderSentAt: Date | null
|
||||
recognitionLikelihood: RecognitionLikelihood | null
|
||||
professionalRecognitionStatus: ProfessionalRecognitionStatus | null
|
||||
nationality: string | null
|
||||
languagesSpoken: LanguageCode[] | null
|
||||
statusChangedAt: Date
|
||||
lifecycleNotifications: unknown
|
||||
analysisLastRunAt: Date | null
|
||||
analysisInputFingerprint: string | null
|
||||
invalidatedAt: Date | null
|
||||
reuploadRequestedAt: Date | null
|
||||
reuploadedAt: Date | null
|
||||
failedPurgedAt: Date | null
|
||||
}
|
||||
|
||||
export interface CandidateDocument {
|
||||
documentId: string
|
||||
candidateId: string
|
||||
category: CandidateDocumentType
|
||||
title: string | null
|
||||
note: string | null
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileSize: number | null
|
||||
mimeType: string | null
|
||||
uploaded: boolean | null
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
ocrText: string | null
|
||||
ocrModel:
|
||||
| 'tesseract'
|
||||
| 'azure_cognitive'
|
||||
| 'aws_textract'
|
||||
| 'google_vision'
|
||||
| 'manual_entry'
|
||||
| null
|
||||
ocrStartedAt: Date | null
|
||||
ocrEndedAt: Date | null
|
||||
documentStatus: DocumentStatus
|
||||
}
|
||||
|
||||
export interface CandidateEducation {
|
||||
educationId: string
|
||||
candidateId: string
|
||||
institution: string | null
|
||||
country: string | null
|
||||
program: string | null
|
||||
completionDate: Date | null
|
||||
aiInstitution: string | null
|
||||
aiCountry: string | null
|
||||
aiProgram: string | null
|
||||
aiCompletionDate: Date | null
|
||||
aiExtractedBy:
|
||||
| 'gpt-five'
|
||||
| 'claude-three-opus'
|
||||
| 'claude-three-sonnet'
|
||||
| 'claude-three-haiku'
|
||||
| 'gemini-pro'
|
||||
| null
|
||||
aiExtractionDate: Date | null
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
nursingRelatedDegree: boolean | null
|
||||
accreditedUniversity: boolean | null
|
||||
accreditedStudyProgram: boolean | null
|
||||
aiNursingRelatedDegree: boolean | null
|
||||
aiAccreditedUniversity: boolean | null
|
||||
aiAccreditedStudyProgram: boolean | null
|
||||
hasTheory: boolean | null
|
||||
hasPractice: boolean | null
|
||||
durationHours: number | null
|
||||
isNursingFocus: boolean | null
|
||||
aiHasTheory: boolean | null
|
||||
aiHasPractice: boolean | null
|
||||
aiDurationHours: number | null
|
||||
aiIsNursingFocus: boolean | null
|
||||
}
|
||||
|
||||
export interface CandidateExperience {
|
||||
experienceId: string
|
||||
candidateId: string
|
||||
employerName: string | null
|
||||
roleTitle: string | null
|
||||
department: string | null
|
||||
startDate: Date | null
|
||||
endDate: Date | null
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
country: string | null
|
||||
city: string | null
|
||||
facilityType: string | null
|
||||
}
|
||||
|
||||
export interface CandidateLanguage {
|
||||
languageId: string
|
||||
candidateId: string
|
||||
level: LanguageLevel | null
|
||||
issuingBody: string | null
|
||||
issueDate: Date | null
|
||||
certifiedSkills: string | null
|
||||
aiLevel: LanguageLevel | null
|
||||
aiIssuingBody: string | null
|
||||
aiIssueDate: Date | null
|
||||
aiCertifiedSkills: string | null
|
||||
aiExtractedBy:
|
||||
| 'gpt-five'
|
||||
| 'claude-three-opus'
|
||||
| 'claude-three-sonnet'
|
||||
| 'claude-three-haiku'
|
||||
| 'gemini-pro'
|
||||
| null
|
||||
aiExtractionDate: Date | null
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
}
|
||||
|
||||
export interface CandidateLicense {
|
||||
licenseId: string
|
||||
candidateId: string
|
||||
licenseNumber: string | null
|
||||
issuingAuthority: string | null
|
||||
issueDate: Date | null
|
||||
expiryDate: Date | null
|
||||
status: string | null
|
||||
licenseType: string | null
|
||||
aiLicenseNumber: string | null
|
||||
aiIssuingAuthority: string | null
|
||||
aiIssueDate: Date | null
|
||||
aiExpiryDate: Date | null
|
||||
aiStatus: string | null
|
||||
aiLicenseType: string | null
|
||||
aiExtractedBy:
|
||||
| 'gpt-five'
|
||||
| 'claude-three-opus'
|
||||
| 'claude-three-sonnet'
|
||||
| 'claude-three-haiku'
|
||||
| 'gemini-pro'
|
||||
| null
|
||||
aiExtractionDate: Date | null
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
}
|
||||
|
||||
export interface RecognitionDossier {
|
||||
dossierId: string
|
||||
candidateId: string
|
||||
targetState: GermanState
|
||||
targetProfession: NurseRecognitionGermany
|
||||
status: RecognitionDossierStatus
|
||||
rulesVersion: string | null
|
||||
inputFingerprint: string | null
|
||||
generatedAt: Date | null
|
||||
packageFilePath: string | null
|
||||
submissionGuideJson: unknown
|
||||
checklistJson: unknown
|
||||
blockingIssuesJson: unknown
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
}
|
||||
|
||||
export interface RecognitionDossierDocument {
|
||||
documentId: string
|
||||
dossierId: string
|
||||
candidateId: string
|
||||
category: RecognitionDossierDocumentCategory
|
||||
title: string | null
|
||||
note: string | null
|
||||
filePath: string
|
||||
fileName: string
|
||||
fileSize: number | null
|
||||
mimeType: string | null
|
||||
uploaded: boolean | null
|
||||
documentStatus: DocumentStatus
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
}
|
||||
|
||||
export declare namespace DB {
|
||||
export type Candidate = import('./db.js').Candidate
|
||||
export type CandidateDocument = import('./db.js').CandidateDocument
|
||||
export type CandidateEducation = import('./db.js').CandidateEducation
|
||||
export type CandidateExperience = import('./db.js').CandidateExperience
|
||||
export type CandidateLanguage = import('./db.js').CandidateLanguage
|
||||
export type CandidateLicense = import('./db.js').CandidateLicense
|
||||
export type RecognitionDossier = import('./db.js').RecognitionDossier
|
||||
export type RecognitionDossierDocument = import('./db.js').RecognitionDossierDocument
|
||||
export type UserRole = import('./db.js').UserRole
|
||||
export type UserType = import('./db.js').UserType
|
||||
export type LanguageLevel = import('./db.js').LanguageLevel
|
||||
export type CandidateDocumentType = import('./db.js').CandidateDocumentType
|
||||
export type DocumentStatus = import('./db.js').DocumentStatus
|
||||
export type ApplicantStatus = import('./db.js').ApplicantStatus
|
||||
export type NurseRecognitionGermany = import('./db.js').NurseRecognitionGermany
|
||||
export type NurseRecognitionHomeCountry = import('./db.js').NurseRecognitionHomeCountry
|
||||
export type RecognitionLikelihood = import('./db.js').RecognitionLikelihood
|
||||
export type ProfessionalRecognitionStatus = import('./db.js').ProfessionalRecognitionStatus
|
||||
export type LanguageCode = import('./db.js').LanguageCode
|
||||
export type GermanState = import('./db.js').GermanState
|
||||
export type RecognitionDossierStatus = import('./db.js').RecognitionDossierStatus
|
||||
export type RecognitionDossierDocumentCategory = import('./db.js').RecognitionDossierDocumentCategory
|
||||
}
|
||||
149
packages/sdk/domain.ts
Normal file
149
packages/sdk/domain.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import type {
|
||||
ApplicantStatus,
|
||||
CandidateDocumentType,
|
||||
DocumentStatus,
|
||||
GermanState,
|
||||
LanguageCode,
|
||||
LanguageLevel,
|
||||
NurseRecognitionGermany,
|
||||
NurseRecognitionHomeCountry,
|
||||
ProfessionalRecognitionStatus,
|
||||
RecognitionDossierDocumentCategory,
|
||||
RecognitionDossierStatus,
|
||||
RecognitionLikelihood,
|
||||
UserRole,
|
||||
UserType,
|
||||
} from './db.js'
|
||||
|
||||
export const UserRoles = {
|
||||
ADMIN: 'admin',
|
||||
OWNER: 'owner',
|
||||
} as const satisfies Record<string, UserRole>
|
||||
|
||||
export const UserTypes = {
|
||||
COMPANY: 'company',
|
||||
BACKOFFICE: 'backoffice',
|
||||
CANDIDATE: 'candidate',
|
||||
} as const satisfies Record<string, UserType>
|
||||
|
||||
export const LanguageLevels = {
|
||||
NONE: 'NONE',
|
||||
A_ONE: 'A_ONE',
|
||||
A_TWO: 'A_TWO',
|
||||
B_ONE: 'B_ONE',
|
||||
B_TWO: 'B_TWO',
|
||||
C_ONE: 'C_ONE',
|
||||
C_TWO: 'C_TWO',
|
||||
} as const satisfies Record<string, LanguageLevel>
|
||||
|
||||
export const CandidateDocumentTypes = {
|
||||
EDUCATION: 'education',
|
||||
LICENSE: 'license',
|
||||
LANGUAGE: 'language',
|
||||
WORK_EXPERIENCE: 'work_experience',
|
||||
PROFILE_IMAGE: 'profile_image',
|
||||
} as const satisfies Record<string, CandidateDocumentType>
|
||||
|
||||
export const DocumentStatuses = {
|
||||
MISSING: 'Missing',
|
||||
INVALID: 'Invalid',
|
||||
VERIFIED: 'Verified',
|
||||
UNVERIFIED: 'Unverified',
|
||||
} as const satisfies Record<string, DocumentStatus>
|
||||
|
||||
export const ApplicantStatuses = {
|
||||
INITIAL: 'Initial',
|
||||
INVALID: 'Invalid',
|
||||
PENDING: 'Pending',
|
||||
COMPLETE: 'Complete',
|
||||
FAILED: 'Failed',
|
||||
} as const satisfies Record<string, ApplicantStatus>
|
||||
|
||||
export const NurseRecognitionGermanyValues = {
|
||||
NURSE: 'nurse',
|
||||
ASSISTANT_NURSE: 'assistant_nurse',
|
||||
NURSING_HELPER: 'nursing_helper',
|
||||
} as const satisfies Record<string, NurseRecognitionGermany>
|
||||
|
||||
export const NurseRecognitionHomeCountryValues = {
|
||||
NURSE: 'nurse',
|
||||
ASSISTANT_NURSE: 'assistant_nurse',
|
||||
NURSING_HELPER: 'nursing_helper',
|
||||
NONE: 'none',
|
||||
} as const satisfies Record<string, NurseRecognitionHomeCountry>
|
||||
|
||||
export const RecognitionLikelihoodValues = {
|
||||
LOW: 'low',
|
||||
MEDIUM: 'medium',
|
||||
HIGH: 'high',
|
||||
} as const satisfies Record<string, RecognitionLikelihood>
|
||||
|
||||
export const ProfessionalRecognitionStatuses = {
|
||||
NOT_STARTED: 'NOT_STARTED',
|
||||
IN_PROGRESS: 'IN_PROGRESS',
|
||||
COMPLETED: 'COMPLETED',
|
||||
} as const satisfies Record<string, ProfessionalRecognitionStatus>
|
||||
|
||||
export const GermanStates: Record<GermanState, GermanState> = {
|
||||
'Baden-Württemberg': 'Baden-Württemberg',
|
||||
Bayern: 'Bayern',
|
||||
Berlin: 'Berlin',
|
||||
Brandenburg: 'Brandenburg',
|
||||
Bremen: 'Bremen',
|
||||
Hamburg: 'Hamburg',
|
||||
Hessen: 'Hessen',
|
||||
'Mecklenburg-Vorpommern': 'Mecklenburg-Vorpommern',
|
||||
Niedersachsen: 'Niedersachsen',
|
||||
'Nordrhein-Westfalen': 'Nordrhein-Westfalen',
|
||||
'Rheinland-Pfalz': 'Rheinland-Pfalz',
|
||||
Saarland: 'Saarland',
|
||||
Sachsen: 'Sachsen',
|
||||
'Sachsen-Anhalt': 'Sachsen-Anhalt',
|
||||
'Schleswig-Holstein': 'Schleswig-Holstein',
|
||||
Thüringen: 'Thüringen',
|
||||
}
|
||||
|
||||
export const LanguageCodes: Record<Uppercase<LanguageCode>, LanguageCode> = {
|
||||
EN: 'en',
|
||||
AR: 'ar',
|
||||
BS: 'bs',
|
||||
FIL: 'fil',
|
||||
HI: 'hi',
|
||||
ES: 'es',
|
||||
TR: 'tr',
|
||||
UK: 'uk',
|
||||
VI: 'vi',
|
||||
}
|
||||
|
||||
export const RecognitionDossierStatuses = {
|
||||
DRAFT: 'draft',
|
||||
BLOCKED: 'blocked',
|
||||
READY: 'ready',
|
||||
GENERATING: 'generating',
|
||||
GENERATED: 'generated',
|
||||
UNSUPPORTED: 'unsupported',
|
||||
FAILED: 'failed',
|
||||
} as const satisfies Record<string, RecognitionDossierStatus>
|
||||
|
||||
export const RecognitionDossierDocumentCategories = {
|
||||
PASSPORT: 'passport',
|
||||
BIRTH_CERTIFICATE: 'birth_certificate',
|
||||
NAME_CHANGE_PROOF: 'name_change_proof',
|
||||
EMPLOYER_INTENT: 'employer_intent',
|
||||
MEDICAL_CERTIFICATE: 'medical_certificate',
|
||||
POLICE_CLEARANCE: 'police_clearance',
|
||||
TRANSLATION: 'translation',
|
||||
AUTHORITY_FORM: 'authority_form',
|
||||
POWER_OF_ATTORNEY: 'power_of_attorney',
|
||||
WAIVER_FORM: 'waiver_form',
|
||||
OTHER: 'other',
|
||||
} as const satisfies Record<string, RecognitionDossierDocumentCategory>
|
||||
|
||||
export const PilotGermanStates = [
|
||||
GermanStates.Bayern,
|
||||
GermanStates.Hessen,
|
||||
GermanStates.Niedersachsen,
|
||||
GermanStates['Baden-Württemberg'],
|
||||
GermanStates['Nordrhein-Westfalen'],
|
||||
GermanStates.Berlin,
|
||||
] as const
|
||||
4
packages/sdk/index.ts
Normal file
4
packages/sdk/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './db.js'
|
||||
export * from './domain.js'
|
||||
export * from './types.js'
|
||||
export * from './config.js'
|
||||
27
packages/sdk/package.json
Normal file
27
packages/sdk/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "@heygermany/sdk",
|
||||
"version": "0.0.0",
|
||||
"description": "The sdk methods shared by backend and frontend candidates",
|
||||
"license": "UNLICENSED",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"main": "index.ts",
|
||||
"repository": {
|
||||
"directory": "packages/api",
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/pikkujs/yarn-workspace-starter.git"
|
||||
},
|
||||
"author": "yasser.fadl@gmail.com",
|
||||
"scripts": {
|
||||
"tsc": "tsc",
|
||||
"ncu": "ncu"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pikku/fetch": "^0.12.6",
|
||||
"@pikku/websocket": "^0.12.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
67
packages/sdk/pikku/pikku-fetch.gen.ts
Normal file
67
packages/sdk/pikku/pikku-fetch.gen.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* This file was generated by @pikku/cli@0.12.76
|
||||
*/
|
||||
|
||||
import { CorePikkuFetch, HTTPMethod } from '@pikku/fetch'
|
||||
import type { HTTPWiringsMap, HTTPWiringHandlerOf, HTTPWiringsWithMethod } from '@heygermany/functions/.pikku/http/pikku-http-wirings-map.gen.d.js'
|
||||
|
||||
export class PikkuFetch extends CorePikkuFetch {
|
||||
public async post<Route extends HTTPWiringsWithMethod<'POST'>>(
|
||||
route: Route,
|
||||
...args: null extends HTTPWiringHandlerOf<Route, 'POST'>['input']
|
||||
? [data?: Exclude<HTTPWiringHandlerOf<Route, 'POST'>['input'], null>, options?: Omit<RequestInit, 'body'>]
|
||||
: [data: HTTPWiringHandlerOf<Route, 'POST'>['input'], options?: Omit<RequestInit, 'body'>]
|
||||
): Promise<HTTPWiringHandlerOf<Route, 'POST'>['output']> {
|
||||
const [data, options] = args;
|
||||
return super.api(route, 'POST', data, options);
|
||||
}
|
||||
|
||||
public async get<Route extends HTTPWiringsWithMethod<'GET'>>(
|
||||
route: Route,
|
||||
...args: null extends HTTPWiringHandlerOf<Route, 'GET'>['input']
|
||||
? [data?: Exclude<HTTPWiringHandlerOf<Route, 'GET'>['input'], null>, options?: Omit<RequestInit, 'body'>]
|
||||
: [data: HTTPWiringHandlerOf<Route, 'GET'>['input'], options?: Omit<RequestInit, 'body'>]
|
||||
): Promise<HTTPWiringHandlerOf<Route, 'GET'>['output']> {
|
||||
const [data, options] = args;
|
||||
return super.api(route, 'GET', data, options);
|
||||
}
|
||||
|
||||
public async patch<Route extends HTTPWiringsWithMethod<'PATCH'>>(
|
||||
route: Route,
|
||||
...args: null extends HTTPWiringHandlerOf<Route, 'PATCH'>['input']
|
||||
? [data?: Exclude<HTTPWiringHandlerOf<Route, 'PATCH'>['input'], null>, options?: Omit<RequestInit, 'body'>]
|
||||
: [data: HTTPWiringHandlerOf<Route, 'PATCH'>['input'], options?: Omit<RequestInit, 'body'>]
|
||||
): Promise<HTTPWiringHandlerOf<Route, 'PATCH'>['output']> {
|
||||
const [data, options] = args;
|
||||
return super.api(route, 'PATCH', data, options);
|
||||
}
|
||||
|
||||
public async head<Route extends HTTPWiringsWithMethod<'HEAD'>>(
|
||||
route: Route,
|
||||
...args: null extends HTTPWiringHandlerOf<Route, 'HEAD'>['input']
|
||||
? [data?: Exclude<HTTPWiringHandlerOf<Route, 'HEAD'>['input'], null>, options?: Omit<RequestInit, 'body'>]
|
||||
: [data: HTTPWiringHandlerOf<Route, 'HEAD'>['input'], options?: Omit<RequestInit, 'body'>]
|
||||
): Promise<HTTPWiringHandlerOf<Route, 'HEAD'>['output']> {
|
||||
const [data, options] = args;
|
||||
return super.api(route, 'HEAD', data, options);
|
||||
}
|
||||
|
||||
public async delete<Route extends HTTPWiringsWithMethod<'DELETE'>>(
|
||||
route: Route,
|
||||
...args: null extends HTTPWiringHandlerOf<Route, 'DELETE'>['input']
|
||||
? [data?: Exclude<HTTPWiringHandlerOf<Route, 'DELETE'>['input'], null>, options?: Omit<RequestInit, 'body'>]
|
||||
: [data: HTTPWiringHandlerOf<Route, 'DELETE'>['input'], options?: Omit<RequestInit, 'body'>]
|
||||
): Promise<HTTPWiringHandlerOf<Route, 'DELETE'>['output']> {
|
||||
const [data, options] = args;
|
||||
return super.api(route, 'DELETE', data, options);
|
||||
}
|
||||
|
||||
public async fetch<
|
||||
Route extends keyof HTTPWiringsMap,
|
||||
Method extends keyof HTTPWiringsMap[Route]
|
||||
>(route: Route, method: Method, data: HTTPWiringHandlerOf<Route, Method>['input'], options?: Omit<RequestInit, 'body'>): Promise<Response> {
|
||||
return await super.fetch(route, method as HTTPMethod, data, options);
|
||||
}
|
||||
}
|
||||
|
||||
export const pikkuFetch = new PikkuFetch();
|
||||
15
packages/sdk/tsconfig.json
Normal file
15
packages/sdk/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node"],
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"noEmit": false,
|
||||
"skipLibCheck": true,
|
||||
"rootDir": ".",
|
||||
"outDir": "dist"
|
||||
},
|
||||
"files": [],
|
||||
"include": ["**/*.ts", "**/*.d.ts"],
|
||||
"exclude": ["dist/**/*", "lib/**/*"]
|
||||
}
|
||||
408
packages/sdk/types.ts
Normal file
408
packages/sdk/types.ts
Normal file
@@ -0,0 +1,408 @@
|
||||
import type {
|
||||
ApplicantStatus,
|
||||
Candidate as DBCandidate,
|
||||
CandidateDocument,
|
||||
CandidateEducation,
|
||||
CandidateExperience,
|
||||
CandidateLanguage,
|
||||
CandidateLicense,
|
||||
DB,
|
||||
DocumentStatus,
|
||||
GermanState,
|
||||
LanguageCode,
|
||||
LanguageLevel,
|
||||
NurseRecognitionGermany,
|
||||
NurseRecognitionHomeCountry,
|
||||
ProfessionalRecognitionStatus,
|
||||
RecognitionDossierDocumentCategory,
|
||||
RecognitionDossierStatus,
|
||||
RecognitionLikelihood,
|
||||
} from './db.js'
|
||||
|
||||
export type CountriesMap = Record<string, string>
|
||||
|
||||
export interface ApplicationCandidateInfo {
|
||||
stateWorkPreference: GermanState[] | null
|
||||
joinTalentPool: boolean | null
|
||||
livingInGermany: boolean | null
|
||||
euPassport: boolean | null
|
||||
countryEducation: string | null
|
||||
submittedAt: Date | null
|
||||
languagesSpoken: LanguageCode[] | null
|
||||
nationality: string | null
|
||||
currentResidence: string | null
|
||||
professionalRecognitionStatus: ProfessionalRecognitionStatus | null
|
||||
qualificationStatusGermany: NurseRecognitionGermany | null
|
||||
recognitionLikelihood: RecognitionLikelihood | null
|
||||
}
|
||||
|
||||
export type ApplicationCandidateLanguage = Pick<
|
||||
DBCandidate,
|
||||
'languageCertificateProvided' | 'languageSelfAssessmentLevel'
|
||||
> & {
|
||||
languageCertificates: CandidateDocument[]
|
||||
}
|
||||
|
||||
export interface ApplicationCandidateLicense {
|
||||
licenses: CandidateDocument[]
|
||||
licenseProvided: boolean | null
|
||||
}
|
||||
|
||||
export interface ApplicationCandidateEducation {
|
||||
education: CandidateDocument[]
|
||||
}
|
||||
|
||||
export interface ApplicationCandidateWorkExperience {
|
||||
workExperience: CandidateDocument[]
|
||||
}
|
||||
|
||||
export type PublicCandidateExperience = {
|
||||
employerName: string | null
|
||||
roleTitle: string | null
|
||||
department: string | null
|
||||
country: string | null
|
||||
city: string | null
|
||||
facilityType: string | null
|
||||
startDate: Date | null
|
||||
endDate: Date | null
|
||||
}
|
||||
|
||||
export interface PublicCandidateEducationSummary {
|
||||
institution: string | null
|
||||
program: string | null
|
||||
country: string | null
|
||||
completionDate: Date | null
|
||||
nursingRelatedDegree: boolean | null
|
||||
}
|
||||
|
||||
export interface PublicCandidateInfo {
|
||||
candidateId: string
|
||||
name: string
|
||||
stateWorkPreference: GermanState[] | null
|
||||
joinTalentPool: boolean | null
|
||||
livingInGermany: boolean | null
|
||||
euPassport: boolean | null
|
||||
countryEducation: string | null
|
||||
submittedAt: Date | null
|
||||
languagesSpoken: LanguageCode[] | null
|
||||
nationality: string | null
|
||||
currentResidence: string | null
|
||||
professionalRecognitionStatus: ProfessionalRecognitionStatus | null
|
||||
qualificationStatusGermany: NurseRecognitionGermany | null
|
||||
recognitionLikelihood: RecognitionLikelihood | null
|
||||
languageSelfAssessmentLevel: LanguageLevel | null
|
||||
languageCertificateProvided: boolean | null
|
||||
qualificationStatusHomeCountry: NurseRecognitionHomeCountry | null
|
||||
createdAt: Date | null
|
||||
age: number | null
|
||||
hasVerifiedLicense: boolean
|
||||
profileImageUrl: string | null
|
||||
totalExperienceMonths: number | null
|
||||
experience: PublicCandidateExperience[]
|
||||
education: PublicCandidateEducationSummary | null
|
||||
}
|
||||
|
||||
export interface ApplicationCandidateData {
|
||||
name: string
|
||||
candidateId: string
|
||||
dateOfBirth: Date | null
|
||||
submittedAt: Date | null
|
||||
status: ApplicantStatus
|
||||
stateWorkPreference: GermanState[] | null
|
||||
joinTalentPool: boolean | null
|
||||
livingInGermany: boolean | null
|
||||
euPassport: boolean | null
|
||||
countryEducation: string | null
|
||||
languagesSpoken: LanguageCode[] | null
|
||||
nationality: string | null
|
||||
currentResidence: string | null
|
||||
professionalRecognitionStatus: ProfessionalRecognitionStatus | null
|
||||
qualificationStatusGermany: NurseRecognitionGermany | null
|
||||
recognitionLikelihood: RecognitionLikelihood | null
|
||||
languageCertificateProvided: boolean | null
|
||||
languageSelfAssessmentLevel: LanguageLevel | null
|
||||
languageCertificates: CandidateDocument[]
|
||||
education: CandidateDocument[]
|
||||
licenses: CandidateDocument[]
|
||||
workExperience: CandidateDocument[]
|
||||
}
|
||||
|
||||
export type QualificationCardStatus =
|
||||
| 'completed'
|
||||
| 'required'
|
||||
| 'in-progress'
|
||||
| 'optional'
|
||||
|
||||
export type QualificationCard = {
|
||||
title: string
|
||||
description: string
|
||||
status: QualificationCardStatus
|
||||
progress?: number // 0-100 only when status === 'in-progress'
|
||||
requirements: string[]
|
||||
steps?: string[]
|
||||
}
|
||||
|
||||
export type NextStepItem = {
|
||||
title: string
|
||||
subtitle: string
|
||||
costs: string
|
||||
button?: string
|
||||
buttonimprove?: string
|
||||
buttonjoin?: string
|
||||
}
|
||||
|
||||
export type NextSteps = {
|
||||
gethelp: NextStepItem
|
||||
connect: NextStepItem
|
||||
documents?: NextStepItem
|
||||
submit?: NextStepItem
|
||||
compensatory?: NextStepItem
|
||||
german?: NextStepItem
|
||||
}
|
||||
|
||||
export type CandidateResults = {
|
||||
education: QualificationCard
|
||||
license: QualificationCard
|
||||
language: QualificationCard
|
||||
experience: QualificationCard
|
||||
copies: QualificationCard
|
||||
originals: QualificationCard
|
||||
joinTalentPool: boolean | null
|
||||
nextSteps: NextSteps | null
|
||||
textContent: {
|
||||
renderPath: string | null
|
||||
hero: string
|
||||
result: string
|
||||
explanation: string[]
|
||||
recognition?: string[]
|
||||
notes: {
|
||||
afterExplanation: string[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface CandidateLifecycleAnalysisNotification {
|
||||
issues?: string[]
|
||||
updated_at?: string
|
||||
updatedAt?: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
export type CandidateLifecycleNotifications = Record<string, unknown> & {
|
||||
analysis?: CandidateLifecycleAnalysisNotification
|
||||
}
|
||||
|
||||
export interface BackOfficeDocuments {
|
||||
analysis: {
|
||||
education: CandidateEducation | null
|
||||
license: CandidateLicense | null
|
||||
language: CandidateLanguage | null
|
||||
experience: CandidateExperience | null
|
||||
}
|
||||
documents: {
|
||||
education: Array<CandidateDocument>
|
||||
license: Array<CandidateDocument>
|
||||
language: Array<CandidateDocument>
|
||||
experience: Array<CandidateDocument>
|
||||
}
|
||||
}
|
||||
|
||||
export interface BackOfficeCandidateListItem {
|
||||
candidateId: string
|
||||
email: string
|
||||
name: string
|
||||
stateWorkPreference: GermanState[] | null
|
||||
joinTalentPool: boolean | null
|
||||
livingInGermany: boolean | null
|
||||
euPassport: boolean | null
|
||||
countryEducation: string | null
|
||||
licenseProvided: boolean | null
|
||||
languageCertificateProvided: boolean | null
|
||||
languageSelfAssessmentLevel: LanguageLevel | null
|
||||
submittedAt: Date | null
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
phone: string | null
|
||||
dateOfBirth: Date | null
|
||||
currentResidence: string | null
|
||||
qualificationStatusHomeCountry: NurseRecognitionHomeCountry | null
|
||||
qualificationStatusGermany: NurseRecognitionGermany | null
|
||||
licenseMandatory: boolean | null
|
||||
durationRequirementsMet: boolean | null
|
||||
status: ApplicantStatus
|
||||
incompleteReminderSentAt: Date | null
|
||||
recognitionLikelihood: RecognitionLikelihood | null
|
||||
professionalRecognitionStatus: ProfessionalRecognitionStatus | null
|
||||
nationality: string | null
|
||||
languagesSpoken: LanguageCode[] | null
|
||||
statusChangedAt: Date
|
||||
analysisLastRunAt: Date | null
|
||||
analysisInputFingerprint: string | null
|
||||
invalidatedAt: Date | null
|
||||
reuploadRequestedAt: Date | null
|
||||
reuploadedAt: Date | null
|
||||
failedPurgedAt: Date | null
|
||||
}
|
||||
|
||||
export interface BackOfficeCandidate {
|
||||
candidateId: string
|
||||
email: string
|
||||
name: string
|
||||
stateWorkPreference: GermanState[] | null
|
||||
joinTalentPool: boolean | null
|
||||
livingInGermany: boolean | null
|
||||
euPassport: boolean | null
|
||||
countryEducation: string | null
|
||||
licenseProvided: boolean | null
|
||||
languageCertificateProvided: boolean | null
|
||||
languageSelfAssessmentLevel: LanguageLevel | null
|
||||
submittedAt: Date | null
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
phone: string | null
|
||||
dateOfBirth: Date | null
|
||||
currentResidence: string | null
|
||||
qualificationStatusHomeCountry: NurseRecognitionHomeCountry | null
|
||||
qualificationStatusGermany: NurseRecognitionGermany | null
|
||||
licenseMandatory: boolean | null
|
||||
durationRequirementsMet: boolean | null
|
||||
status: ApplicantStatus
|
||||
incompleteReminderSentAt: Date | null
|
||||
recognitionLikelihood: RecognitionLikelihood | null
|
||||
professionalRecognitionStatus: ProfessionalRecognitionStatus | null
|
||||
nationality: string | null
|
||||
languagesSpoken: LanguageCode[] | null
|
||||
statusChangedAt: Date
|
||||
analysisLastRunAt: Date | null
|
||||
analysisInputFingerprint: string | null
|
||||
invalidatedAt: Date | null
|
||||
reuploadRequestedAt: Date | null
|
||||
reuploadedAt: Date | null
|
||||
failedPurgedAt: Date | null
|
||||
analysis: {
|
||||
education: CandidateEducation | null
|
||||
license: CandidateLicense | null
|
||||
language: CandidateLanguage | null
|
||||
experience: CandidateExperience | null
|
||||
}
|
||||
documents: {
|
||||
education: Array<CandidateDocument>
|
||||
license: Array<CandidateDocument>
|
||||
language: Array<CandidateDocument>
|
||||
experience: Array<CandidateDocument>
|
||||
}
|
||||
lifecycleNotifications?: CandidateLifecycleNotifications | null
|
||||
}
|
||||
|
||||
export interface RecognitionDossierBlockingIssue {
|
||||
code: string
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface RecognitionDossierChecklistItem {
|
||||
id: string
|
||||
label: string
|
||||
status: string
|
||||
message: string | null
|
||||
source: string | null
|
||||
sourceLabel: string | null
|
||||
required: boolean
|
||||
notes: string[]
|
||||
}
|
||||
|
||||
export interface RecognitionDossierSubmissionGuide {
|
||||
authorityName: string | null
|
||||
authorityWebsiteUrl: string | null
|
||||
submissionMode: string | null
|
||||
submissionUrl: string | null
|
||||
postalAddress: string[]
|
||||
contactEmail: string | null
|
||||
contactPhone: string | null
|
||||
notes: string[]
|
||||
lastVerifiedAt: string | null
|
||||
}
|
||||
|
||||
export interface RecognitionDossierDocumentSummary {
|
||||
documentId: string
|
||||
candidateId: string
|
||||
dossierId: string
|
||||
category: RecognitionDossierDocumentCategory
|
||||
title: string | null
|
||||
note: string | null
|
||||
fileName: string
|
||||
fileSize: number | null
|
||||
mimeType: string | null
|
||||
uploaded: boolean
|
||||
documentStatus: DocumentStatus
|
||||
createdAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
}
|
||||
|
||||
export interface RecognitionDossierSummary {
|
||||
dossierId: string
|
||||
candidateId: string
|
||||
targetState: GermanState
|
||||
targetProfession: NurseRecognitionGermany
|
||||
status: RecognitionDossierStatus
|
||||
rulesVersion: string | null
|
||||
generatedAt: Date | null
|
||||
lastUpdatedAt: Date | null
|
||||
hasPackage: boolean
|
||||
blockingIssues: RecognitionDossierBlockingIssue[]
|
||||
}
|
||||
|
||||
export interface RecognitionDossierDetail extends RecognitionDossierSummary {
|
||||
supported: boolean
|
||||
packageFilePath: string | null
|
||||
downloadUrl: string | null
|
||||
submissionGuide: RecognitionDossierSubmissionGuide | null
|
||||
checklist: RecognitionDossierChecklistItem[]
|
||||
documents: RecognitionDossierDocumentSummary[]
|
||||
}
|
||||
|
||||
export interface GetCandidateResult {
|
||||
name: string
|
||||
qualificationStatusGermany: NurseRecognitionGermany | null
|
||||
qualificationStatusHomeCountry: NurseRecognitionHomeCountry | null
|
||||
euPassport: boolean | null
|
||||
livingInGermany: boolean | null
|
||||
licenseMandatory: boolean | null
|
||||
joinTalentPool: boolean | null
|
||||
nursingRelatedDegree: boolean | null
|
||||
accreditedUniversity: boolean | null
|
||||
accreditedStudyProgram: boolean | null
|
||||
docs: {
|
||||
cv: DocumentStatus
|
||||
language: DocumentStatus
|
||||
license: DocumentStatus
|
||||
}
|
||||
structuredTraining: {
|
||||
hasDuration: boolean | null
|
||||
isNursingFocus: boolean | null
|
||||
hasTheoryHours: boolean | null
|
||||
hasPracticeHours: boolean | null
|
||||
overallStatus: boolean | null
|
||||
}
|
||||
languageAssessmentType: 'certificate' | 'self_assessment' | null
|
||||
isValid: boolean
|
||||
languageLevel?: LanguageLevel | null
|
||||
}
|
||||
|
||||
export interface GetBackOfficeCandidatesOutput {
|
||||
total: number
|
||||
data: BackOfficeCandidateListItem[]
|
||||
}
|
||||
|
||||
export interface GetCompanyCandidatesOutput {
|
||||
total: number
|
||||
data: PublicCandidateInfo[]
|
||||
}
|
||||
|
||||
export type BackendTranslationNamespace = 'cards' | 'misc' | 'outputs'
|
||||
|
||||
export interface BackendTranslationBundle {
|
||||
locale: string
|
||||
namespace: BackendTranslationNamespace
|
||||
content: Record<string, unknown>
|
||||
updatedAt: Date
|
||||
}
|
||||
Reference in New Issue
Block a user