chore: heygermany customer project
Some checks failed
Main / Setup and Test (push) Has been cancelled
Main / Build Website (push) Has been cancelled

This commit is contained in:
e2e
2026-07-11 10:35:04 +02:00
commit 3bb535efe8
394 changed files with 38048 additions and 0 deletions

112
packages/sdk/config.ts Normal file
View 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
View 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
View 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
View 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
View 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"
}
}

View 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();

View 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
View 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
}