Compare commits
No commits in common. "4f4187eba49e83481386a2cadaf3eea0e08e7f36" and "1531a05de00b90351c067f0c378fe2c342b1f5a7" have entirely different histories.
4f4187eba4
...
1531a05de0
@ -1,19 +1,27 @@
|
|||||||
import React, { useState, useRef, JSX } from 'react';
|
import React, { useState, useEffect, useRef, JSX } from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Typography,
|
Typography,
|
||||||
|
Paper,
|
||||||
TextField,
|
TextField,
|
||||||
Grid,
|
Grid,
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogContentText,
|
||||||
|
DialogActions,
|
||||||
|
IconButton,
|
||||||
useTheme,
|
useTheme,
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
Chip,
|
Chip,
|
||||||
|
Divider,
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
LinearProgress,
|
LinearProgress,
|
||||||
Stack,
|
Stack,
|
||||||
Paper,
|
Alert
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import {
|
import {
|
||||||
SyncAlt,
|
SyncAlt,
|
||||||
@ -28,22 +36,21 @@ import {
|
|||||||
CloudUpload,
|
CloudUpload,
|
||||||
Description,
|
Description,
|
||||||
Business,
|
Business,
|
||||||
|
LocationOn,
|
||||||
Work,
|
Work,
|
||||||
CheckCircle,
|
CheckCircle,
|
||||||
Star
|
Star
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
|
import DescriptionIcon from '@mui/icons-material/Description';
|
||||||
import FileUploadIcon from '@mui/icons-material/FileUpload';
|
import FileUploadIcon from '@mui/icons-material/FileUpload';
|
||||||
|
|
||||||
import { useAuth } from 'hooks/AuthContext';
|
import { useAuth } from 'hooks/AuthContext';
|
||||||
import { useAppState, useSelectedJob } from 'hooks/GlobalContext';
|
import { useAppState, useSelectedCandidate, useSelectedJob } from 'hooks/GlobalContext';
|
||||||
import { BackstoryElementProps } from './BackstoryTab';
|
import { BackstoryElementProps } from './BackstoryTab';
|
||||||
import { LoginRequired } from 'components/ui/LoginRequired';
|
import { LoginRequired } from 'components/ui/LoginRequired';
|
||||||
|
|
||||||
import * as Types from 'types/types';
|
import * as Types from 'types/types';
|
||||||
import { StyledMarkdown } from './StyledMarkdown';
|
|
||||||
import { JobInfo } from './ui/JobInfo';
|
|
||||||
import { Scrollable } from './Scrollable';
|
|
||||||
|
|
||||||
const VisuallyHiddenInput = styled('input')({
|
const VisuallyHiddenInput = styled('input')({
|
||||||
clip: 'rect(0 0 0 0)',
|
clip: 'rect(0 0 0 0)',
|
||||||
@ -107,27 +114,35 @@ const getIcon = (type: Types.ApiActivityType) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
interface JobCreatorProps extends BackstoryElementProps {
|
interface JobCreator extends BackstoryElementProps {
|
||||||
onSave?: (job: Types.Job) => void;
|
onSave?: (job: Types.Job) => void;
|
||||||
}
|
}
|
||||||
const JobCreator = (props: JobCreatorProps) => {
|
const JobCreator = (props: JobCreator) => {
|
||||||
const { user, apiClient } = useAuth();
|
const { user, apiClient } = useAuth();
|
||||||
const { onSave } = props;
|
const { onSave } = props;
|
||||||
|
const { selectedCandidate } = useSelectedCandidate();
|
||||||
const { selectedJob, setSelectedJob } = useSelectedJob();
|
const { selectedJob, setSelectedJob } = useSelectedJob();
|
||||||
const { setSnack } = useAppState();
|
const { setSnack } = useAppState();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
const isTablet = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
|
|
||||||
|
const [openUploadDialog, setOpenUploadDialog] = useState<boolean>(false);
|
||||||
const [jobDescription, setJobDescription] = useState<string>('');
|
const [jobDescription, setJobDescription] = useState<string>('');
|
||||||
const [jobRequirements, setJobRequirements] = useState<Types.JobRequirements | null>(null);
|
const [jobRequirements, setJobRequirements] = useState<Types.JobRequirements | null>(null);
|
||||||
const [jobTitle, setJobTitle] = useState<string>('');
|
const [jobTitle, setJobTitle] = useState<string>('');
|
||||||
const [company, setCompany] = useState<string>('');
|
const [company, setCompany] = useState<string>('');
|
||||||
const [summary, setSummary] = useState<string>('');
|
const [summary, setSummary] = useState<string>('');
|
||||||
const [job, setJob] = useState<Types.Job | null>(null);
|
const [jobLocation, setJobLocation] = useState<string>('');
|
||||||
|
const [jobId, setJobId] = useState<string>('');
|
||||||
const [jobStatus, setJobStatus] = useState<string>('');
|
const [jobStatus, setJobStatus] = useState<string>('');
|
||||||
const [jobStatusIcon, setJobStatusIcon] = useState<JSX.Element>(<></>);
|
const [jobStatusIcon, setJobStatusIcon] = useState<JSX.Element>(<></>);
|
||||||
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
}, [jobTitle, jobDescription, company]);
|
||||||
|
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
|
||||||
@ -143,10 +158,8 @@ const JobCreator = (props: JobCreatorProps) => {
|
|||||||
setJobStatusIcon(getIcon(status.activity));
|
setJobStatusIcon(getIcon(status.activity));
|
||||||
setJobStatus(status.content);
|
setJobStatus(status.content);
|
||||||
},
|
},
|
||||||
onMessage: (jobMessage: Types.JobRequirementsMessage) => {
|
onMessage: (job: Types.Job) => {
|
||||||
const job: Types.Job = jobMessage.job
|
|
||||||
console.log('onMessage - job', job);
|
console.log('onMessage - job', job);
|
||||||
setJob(job);
|
|
||||||
setCompany(job.company || '');
|
setCompany(job.company || '');
|
||||||
setJobDescription(job.description);
|
setJobDescription(job.description);
|
||||||
setSummary(job.summary || '');
|
setSummary(job.summary || '');
|
||||||
@ -320,9 +333,8 @@ const JobCreator = (props: JobCreatorProps) => {
|
|||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
};
|
};
|
||||||
setIsProcessing(true);
|
setIsProcessing(true);
|
||||||
const jobMessage = await apiClient.createJob(newJob);
|
const job = await apiClient.createJob(newJob);
|
||||||
setIsProcessing(false);
|
setIsProcessing(false);
|
||||||
const job: Types.Job = jobMessage.job;
|
|
||||||
onSave ? onSave(job) : setSelectedJob(job);
|
onSave ? onSave(job) : setSelectedJob(job);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -345,6 +357,10 @@ const JobCreator = (props: JobCreatorProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderJobCreation = () => {
|
const renderJobCreation = () => {
|
||||||
|
if (!user) {
|
||||||
|
return <Box>You must be logged in</Box>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{
|
<Box sx={{
|
||||||
mx: 'auto', p: { xs: 2, sm: 3 },
|
mx: 'auto', p: { xs: 2, sm: 3 },
|
||||||
@ -484,6 +500,21 @@ const JobCreator = (props: JobCreatorProps) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Grid> */}
|
</Grid> */}
|
||||||
|
|
||||||
|
<Grid size={{ xs: 12, md: 6 }}>
|
||||||
|
<Box sx={{ display: 'flex', gap: 2, alignItems: 'flex-end', height: '100%' }}>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={handleSave}
|
||||||
|
disabled={!jobTitle || !company || !jobDescription || isProcessing}
|
||||||
|
fullWidth={isMobile}
|
||||||
|
size="large"
|
||||||
|
startIcon={<CheckCircle />}
|
||||||
|
>
|
||||||
|
Save Job
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@ -517,27 +548,7 @@ const JobCreator = (props: JobCreatorProps) => {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
display: "flex", flexDirection: "column"
|
display: "flex", flexDirection: "column"
|
||||||
}}>
|
}}>
|
||||||
{job === null && renderJobCreation()}
|
{selectedJob === null && renderJobCreation()}
|
||||||
{job &&
|
|
||||||
<Box sx={{ display: "flex", flexDirection: "column" }}>
|
|
||||||
<Box sx={{ display: 'flex', gap: 2, alignItems: 'flex-end', height: '100%' }}>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
onClick={handleSave}
|
|
||||||
disabled={!jobTitle || !company || !jobDescription || isProcessing}
|
|
||||||
fullWidth={isMobile}
|
|
||||||
size="large"
|
|
||||||
startIcon={<CheckCircle />}
|
|
||||||
>
|
|
||||||
Save Job
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ display: "flex", flexDirection: "row", flexShrink: 1, gap: 1 }}>
|
|
||||||
<Paper elevation={1} sx={{ p: 1, m: 1, flexGrow: 1 }}><Scrollable><JobInfo job={job} /></Scrollable></Paper>
|
|
||||||
<Paper elevation={1} sx={{ p: 1, m: 1, flexGrow: 1 }}><Scrollable><StyledMarkdown content={job.description} /></Scrollable></Paper>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
import { useMediaQuery } from '@mui/material';
|
import { useMediaQuery } from '@mui/material';
|
||||||
import { Job, JobFull } from 'types/types';
|
import { JobFull } from 'types/types';
|
||||||
import { CopyBubble } from "components/CopyBubble";
|
import { CopyBubble } from "components/CopyBubble";
|
||||||
import { rest } from 'lodash';
|
import { rest } from 'lodash';
|
||||||
import { AIBanner } from 'components/ui/AIBanner';
|
import { AIBanner } from 'components/ui/AIBanner';
|
||||||
@ -17,7 +17,7 @@ import { DeleteConfirmation } from '../DeleteConfirmation';
|
|||||||
import { Build, CheckCircle, Description, Psychology, Star, Work } from '@mui/icons-material';
|
import { Build, CheckCircle, Description, Psychology, Star, Work } from '@mui/icons-material';
|
||||||
|
|
||||||
interface JobInfoProps {
|
interface JobInfoProps {
|
||||||
job: Job | JobFull;
|
job: JobFull;
|
||||||
sx?: SxProps;
|
sx?: SxProps;
|
||||||
action?: string;
|
action?: string;
|
||||||
elevation?: number;
|
elevation?: number;
|
||||||
@ -153,7 +153,7 @@ const JobInfo: React.FC<JobInfoProps> = (props: JobInfoProps) => {
|
|||||||
>
|
>
|
||||||
<CardContent sx={{ display: "flex", flexGrow: 1, p: 3, height: '100%', flexDirection: 'column', alignItems: 'stretch', position: "relative" }}>
|
<CardContent sx={{ display: "flex", flexGrow: 1, p: 3, height: '100%', flexDirection: 'column', alignItems: 'stretch', position: "relative" }}>
|
||||||
{variant !== "small" && <>
|
{variant !== "small" && <>
|
||||||
{'location' in job &&
|
{job.location &&
|
||||||
<Typography variant="body2" sx={{ mb: 1 }}>
|
<Typography variant="body2" sx={{ mb: 1 }}>
|
||||||
<strong>Location:</strong> {job.location.city}, {job.location.state || job.location.country}
|
<strong>Location:</strong> {job.location.city}, {job.location.state || job.location.country}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -83,7 +83,7 @@ const LoginPage: React.FC<BackstoryPageProps> = (props: BackstoryPageProps) => {
|
|||||||
Session ID: {guest.sessionId}
|
Session ID: {guest.sessionId}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<Typography variant="body2" color="text.secondary">
|
||||||
Created: {guest.createdAt?.toLocaleString()}
|
Created: {guest.createdAt.toLocaleString()}
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -39,7 +39,6 @@ const TOKEN_STORAGE = {
|
|||||||
PENDING_VERIFICATION_EMAIL: 'pendingVerificationEmail'
|
PENDING_VERIFICATION_EMAIL: 'pendingVerificationEmail'
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
// Streaming Types and Interfaces
|
// Streaming Types and Interfaces
|
||||||
// ============================
|
// ============================
|
||||||
@ -648,12 +647,12 @@ class ApiClient {
|
|||||||
// Job Methods with Date Conversion
|
// Job Methods with Date Conversion
|
||||||
// ============================
|
// ============================
|
||||||
|
|
||||||
createJobFromDescription(job_description: string, streamingOptions?: StreamingOptions<Types.JobRequirementsMessage>): StreamingResponse<Types.JobRequirementsMessage> {
|
createJobFromDescription(job_description: string, streamingOptions?: StreamingOptions<Types.Job>): StreamingResponse<Types.Job> {
|
||||||
const body = JSON.stringify(job_description);
|
const body = JSON.stringify(job_description);
|
||||||
return this.streamify<Types.JobRequirementsMessage>('/jobs/from-content', body, streamingOptions, "JobRequirementsMessage");
|
return this.streamify<Types.Job>('/jobs/from-content', body, streamingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
async createJob(job: Omit<Types.Job, 'id' | 'datePosted' | 'views' | 'applicationCount'>): Promise<Types.JobRequirementsMessage> {
|
async createJob(job: Omit<Types.Job, 'id' | 'datePosted' | 'views' | 'applicationCount'>): Promise<Types.Job> {
|
||||||
const body = JSON.stringify(formatApiRequest(job));
|
const body = JSON.stringify(formatApiRequest(job));
|
||||||
const response = await fetch(`${this.baseUrl}/jobs`, {
|
const response = await fetch(`${this.baseUrl}/jobs`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -661,7 +660,7 @@ class ApiClient {
|
|||||||
body: body
|
body: body
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.handleApiResponseWithConversion<Types.JobRequirementsMessage>(response, 'JobRequirementsMessage');
|
return this.handleApiResponseWithConversion<Types.Job>(response, 'Job');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getJob(id: string): Promise<Types.Job> {
|
async getJob(id: string): Promise<Types.Job> {
|
||||||
@ -885,10 +884,10 @@ class ApiClient {
|
|||||||
'Authorization': this.defaultHeaders['Authorization']
|
'Authorization': this.defaultHeaders['Authorization']
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return this.streamify<Types.DocumentMessage>('/candidates/documents/upload', formData, streamingOptions, "DocumentMessage");
|
return this.streamify<Types.DocumentMessage>('/candidates/documents/upload', formData, streamingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
createJobFromFile(file: File, streamingOptions?: StreamingOptions<Types.JobRequirementsMessage>): StreamingResponse<Types.JobRequirementsMessage> {
|
createJobFromFile(file: File, streamingOptions?: StreamingOptions<Types.Job>): StreamingResponse<Types.Job> {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
formData.append('filename', file.name);
|
formData.append('filename', file.name);
|
||||||
@ -899,7 +898,7 @@ class ApiClient {
|
|||||||
'Authorization': this.defaultHeaders['Authorization']
|
'Authorization': this.defaultHeaders['Authorization']
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return this.streamify<Types.JobRequirementsMessage>('/jobs/upload', formData, streamingOptions, "JobRequirementsMessage");
|
return this.streamify<Types.Job>('/jobs/upload', formData, streamingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
getJobRequirements(jobId: string, streamingOptions?: StreamingOptions<Types.DocumentMessage>): StreamingResponse<Types.DocumentMessage> {
|
getJobRequirements(jobId: string, streamingOptions?: StreamingOptions<Types.DocumentMessage>): StreamingResponse<Types.DocumentMessage> {
|
||||||
@ -907,7 +906,7 @@ class ApiClient {
|
|||||||
...streamingOptions,
|
...streamingOptions,
|
||||||
headers: this.defaultHeaders,
|
headers: this.defaultHeaders,
|
||||||
};
|
};
|
||||||
return this.streamify<Types.DocumentMessage>(`/jobs/requirements/${jobId}`, null, streamingOptions, "DocumentMessage");
|
return this.streamify<Types.DocumentMessage>(`/jobs/requirements/${jobId}`, null, streamingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
generateResume(candidateId: string, skills: Types.SkillAssessment[], streamingOptions?: StreamingOptions<Types.ChatMessageResume>): StreamingResponse<Types.ChatMessageResume> {
|
generateResume(candidateId: string, skills: Types.SkillAssessment[], streamingOptions?: StreamingOptions<Types.ChatMessageResume>): StreamingResponse<Types.ChatMessageResume> {
|
||||||
@ -916,7 +915,7 @@ class ApiClient {
|
|||||||
...streamingOptions,
|
...streamingOptions,
|
||||||
headers: this.defaultHeaders,
|
headers: this.defaultHeaders,
|
||||||
};
|
};
|
||||||
return this.streamify<Types.ChatMessageResume>(`/candidates/${candidateId}/generate-resume`, body, streamingOptions, "ChatMessageResume");
|
return this.streamify<Types.ChatMessageResume>(`/candidates/${candidateId}/generate-resume`, body, streamingOptions);
|
||||||
}
|
}
|
||||||
candidateMatchForRequirement(candidate_id: string, requirement: string,
|
candidateMatchForRequirement(candidate_id: string, requirement: string,
|
||||||
streamingOptions?: StreamingOptions<Types.ChatMessageSkillAssessment>)
|
streamingOptions?: StreamingOptions<Types.ChatMessageSkillAssessment>)
|
||||||
@ -926,7 +925,7 @@ class ApiClient {
|
|||||||
...streamingOptions,
|
...streamingOptions,
|
||||||
headers: this.defaultHeaders,
|
headers: this.defaultHeaders,
|
||||||
};
|
};
|
||||||
return this.streamify<Types.ChatMessageSkillAssessment>(`/candidates/${candidate_id}/skill-match`, body, streamingOptions, "ChatMessageSkillAssessment");
|
return this.streamify<Types.ChatMessageSkillAssessment>(`/candidates/${candidate_id}/skill-match`, body, streamingOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateCandidateDocument(document: Types.Document) : Promise<Types.Document> {
|
async updateCandidateDocument(document: Types.Document) : Promise<Types.Document> {
|
||||||
@ -1227,7 +1226,7 @@ class ApiClient {
|
|||||||
* @param options callbacks, headers, and method
|
* @param options callbacks, headers, and method
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
streamify<T = Types.ChatMessage[]>(api: string, data: BodyInit | null, options: StreamingOptions<T> = {}, modelType?: string) : StreamingResponse<T> {
|
streamify<T = Types.ChatMessage[]>(api: string, data: BodyInit | null, options: StreamingOptions<T> = {}) : StreamingResponse<T> {
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
const signal = options.signal || abortController.signal;
|
const signal = options.signal || abortController.signal;
|
||||||
const headers = options.headers || null;
|
const headers = options.headers || null;
|
||||||
@ -1309,8 +1308,8 @@ class ApiClient {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'done':
|
case 'done':
|
||||||
const message = (modelType ? convertFromApi<T>(incoming, modelType) : incoming) as T;
|
const message = Types.convertApiMessageFromApi(incoming) as T;
|
||||||
finalMessage = message;
|
finalMessage = message as any;
|
||||||
try {
|
try {
|
||||||
options.onMessage?.(message);
|
options.onMessage?.(message);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -1362,7 +1361,7 @@ class ApiClient {
|
|||||||
options: StreamingOptions = {}
|
options: StreamingOptions = {}
|
||||||
): StreamingResponse {
|
): StreamingResponse {
|
||||||
const body = JSON.stringify(formatApiRequest(chatMessage));
|
const body = JSON.stringify(formatApiRequest(chatMessage));
|
||||||
return this.streamify(`/chat/sessions/${chatMessage.sessionId}/messages/stream`, body, options, "ChatMessage")
|
return this.streamify(`/chat/sessions/${chatMessage.sessionId}/messages/stream`, body, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1471,6 +1470,7 @@ class ApiClient {
|
|||||||
// ============================
|
// ============================
|
||||||
// Error Handling Helper
|
// Error Handling Helper
|
||||||
// ============================
|
// ============================
|
||||||
|
|
||||||
async handleRequest<T>(requestFn: () => Promise<Response>, modelType?: string): Promise<T> {
|
async handleRequest<T>(requestFn: () => Promise<Response>, modelType?: string): Promise<T> {
|
||||||
try {
|
try {
|
||||||
const response = await requestFn();
|
const response = await requestFn();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Generated TypeScript types from Pydantic models
|
// Generated TypeScript types from Pydantic models
|
||||||
// Source: src/backend/models.py
|
// Source: src/backend/models.py
|
||||||
// Generated on: 2025-06-10T02:48:12.087485
|
// Generated on: 2025-06-09T20:36:06.432367
|
||||||
// DO NOT EDIT MANUALLY - This file is auto-generated
|
// DO NOT EDIT MANUALLY - This file is auto-generated
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
@ -161,8 +161,8 @@ export interface BaseUser {
|
|||||||
fullName: string;
|
fullName: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
location?: Location;
|
location?: Location;
|
||||||
createdAt?: Date;
|
createdAt: Date;
|
||||||
updatedAt?: Date;
|
updatedAt: Date;
|
||||||
lastLogin?: Date;
|
lastLogin?: Date;
|
||||||
profileImage?: string;
|
profileImage?: string;
|
||||||
status: "active" | "inactive" | "pending" | "banned";
|
status: "active" | "inactive" | "pending" | "banned";
|
||||||
@ -185,8 +185,8 @@ export interface Candidate {
|
|||||||
fullName: string;
|
fullName: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
location?: Location;
|
location?: Location;
|
||||||
createdAt?: Date;
|
createdAt: Date;
|
||||||
updatedAt?: Date;
|
updatedAt: Date;
|
||||||
lastLogin?: Date;
|
lastLogin?: Date;
|
||||||
profileImage?: string;
|
profileImage?: string;
|
||||||
status: "active" | "inactive" | "pending" | "banned";
|
status: "active" | "inactive" | "pending" | "banned";
|
||||||
@ -219,8 +219,8 @@ export interface CandidateAI {
|
|||||||
fullName: string;
|
fullName: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
location?: Location;
|
location?: Location;
|
||||||
createdAt?: Date;
|
createdAt: Date;
|
||||||
updatedAt?: Date;
|
updatedAt: Date;
|
||||||
lastLogin?: Date;
|
lastLogin?: Date;
|
||||||
profileImage?: string;
|
profileImage?: string;
|
||||||
status: "active" | "inactive" | "pending" | "banned";
|
status: "active" | "inactive" | "pending" | "banned";
|
||||||
@ -353,8 +353,6 @@ export interface ChatMessageResume {
|
|||||||
tunables?: Tunables;
|
tunables?: Tunables;
|
||||||
metadata: ChatMessageMetaData;
|
metadata: ChatMessageMetaData;
|
||||||
resume: string;
|
resume: string;
|
||||||
systemPrompt?: string;
|
|
||||||
prompt?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChatMessageSkillAssessment {
|
export interface ChatMessageSkillAssessment {
|
||||||
@ -569,8 +567,8 @@ export interface Employer {
|
|||||||
fullName: string;
|
fullName: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
location?: Location;
|
location?: Location;
|
||||||
createdAt?: Date;
|
createdAt: Date;
|
||||||
updatedAt?: Date;
|
updatedAt: Date;
|
||||||
lastLogin?: Date;
|
lastLogin?: Date;
|
||||||
profileImage?: string;
|
profileImage?: string;
|
||||||
status: "active" | "inactive" | "pending" | "banned";
|
status: "active" | "inactive" | "pending" | "banned";
|
||||||
@ -622,8 +620,8 @@ export interface Guest {
|
|||||||
fullName: string;
|
fullName: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
location?: Location;
|
location?: Location;
|
||||||
createdAt?: Date;
|
createdAt: Date;
|
||||||
updatedAt?: Date;
|
updatedAt: Date;
|
||||||
lastLogin?: Date;
|
lastLogin?: Date;
|
||||||
profileImage?: string;
|
profileImage?: string;
|
||||||
status: "active" | "inactive" | "pending" | "banned";
|
status: "active" | "inactive" | "pending" | "banned";
|
||||||
@ -684,8 +682,8 @@ export interface InterviewFeedback {
|
|||||||
weaknesses: Array<string>;
|
weaknesses: Array<string>;
|
||||||
recommendation: "strong_hire" | "hire" | "no_hire" | "strong_no_hire";
|
recommendation: "strong_hire" | "hire" | "no_hire" | "strong_no_hire";
|
||||||
comments: string;
|
comments: string;
|
||||||
createdAt?: Date;
|
createdAt: Date;
|
||||||
updatedAt?: Date;
|
updatedAt: Date;
|
||||||
isVisible: boolean;
|
isVisible: boolean;
|
||||||
skillAssessments?: Array<SkillAssessment>;
|
skillAssessments?: Array<SkillAssessment>;
|
||||||
}
|
}
|
||||||
@ -714,8 +712,8 @@ export interface Job {
|
|||||||
company?: string;
|
company?: string;
|
||||||
description: string;
|
description: string;
|
||||||
requirements?: JobRequirements;
|
requirements?: JobRequirements;
|
||||||
createdAt?: Date;
|
createdAt: Date;
|
||||||
updatedAt?: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface JobApplication {
|
export interface JobApplication {
|
||||||
@ -744,12 +742,12 @@ export interface JobFull {
|
|||||||
company?: string;
|
company?: string;
|
||||||
description: string;
|
description: string;
|
||||||
requirements?: JobRequirements;
|
requirements?: JobRequirements;
|
||||||
createdAt?: Date;
|
createdAt: Date;
|
||||||
updatedAt?: Date;
|
updatedAt: Date;
|
||||||
location: Location;
|
location: Location;
|
||||||
salaryRange?: SalaryRange;
|
salaryRange?: SalaryRange;
|
||||||
employmentType: "full-time" | "part-time" | "contract" | "internship" | "freelance";
|
employmentType: "full-time" | "part-time" | "contract" | "internship" | "freelance";
|
||||||
datePosted?: Date;
|
datePosted: Date;
|
||||||
applicationDeadline?: Date;
|
applicationDeadline?: Date;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
applicants?: Array<JobApplication>;
|
applicants?: Array<JobApplication>;
|
||||||
@ -786,7 +784,11 @@ export interface JobRequirementsMessage {
|
|||||||
status: "streaming" | "status" | "done" | "error";
|
status: "streaming" | "status" | "done" | "error";
|
||||||
type: "binary" | "text" | "json";
|
type: "binary" | "text" | "json";
|
||||||
timestamp?: Date;
|
timestamp?: Date;
|
||||||
job: Job;
|
title?: string;
|
||||||
|
summary?: string;
|
||||||
|
company?: string;
|
||||||
|
description: string;
|
||||||
|
requirements?: JobRequirements;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface JobResponse {
|
export interface JobResponse {
|
||||||
@ -899,8 +901,8 @@ export interface RAGConfiguration {
|
|||||||
embeddingModel: string;
|
embeddingModel: string;
|
||||||
vectorStoreType: "chroma";
|
vectorStoreType: "chroma";
|
||||||
retrievalParameters: RetrievalParameters;
|
retrievalParameters: RetrievalParameters;
|
||||||
createdAt?: Date;
|
createdAt: Date;
|
||||||
updatedAt?: Date;
|
updatedAt: Date;
|
||||||
version: number;
|
version: number;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
}
|
}
|
||||||
@ -1076,14 +1078,14 @@ export interface WorkExperience {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
// Date and Nested Model Conversion Functions
|
// Date Conversion Functions
|
||||||
// ============================
|
// ============================
|
||||||
|
|
||||||
// These functions convert API responses to properly typed objects
|
// These functions convert API responses to properly typed objects
|
||||||
// with Date objects instead of ISO date strings and nested model conversions
|
// with Date objects instead of ISO date strings
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert Analytics from API response
|
* Convert Analytics from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertAnalyticsFromApi(data: any): Analytics {
|
export function convertAnalyticsFromApi(data: any): Analytics {
|
||||||
@ -1096,7 +1098,7 @@ export function convertAnalyticsFromApi(data: any): Analytics {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ApiMessage from API response
|
* Convert ApiMessage from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertApiMessageFromApi(data: any): ApiMessage {
|
export function convertApiMessageFromApi(data: any): ApiMessage {
|
||||||
@ -1109,7 +1111,7 @@ export function convertApiMessageFromApi(data: any): ApiMessage {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ApplicationDecision from API response
|
* Convert ApplicationDecision from API response, parsing date fields
|
||||||
* Date fields: date
|
* Date fields: date
|
||||||
*/
|
*/
|
||||||
export function convertApplicationDecisionFromApi(data: any): ApplicationDecision {
|
export function convertApplicationDecisionFromApi(data: any): ApplicationDecision {
|
||||||
@ -1122,7 +1124,7 @@ export function convertApplicationDecisionFromApi(data: any): ApplicationDecisio
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert Attachment from API response
|
* Convert Attachment from API response, parsing date fields
|
||||||
* Date fields: uploadedAt
|
* Date fields: uploadedAt
|
||||||
*/
|
*/
|
||||||
export function convertAttachmentFromApi(data: any): Attachment {
|
export function convertAttachmentFromApi(data: any): Attachment {
|
||||||
@ -1135,22 +1137,8 @@ export function convertAttachmentFromApi(data: any): Attachment {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert AuthResponse from API response
|
* Convert Authentication from API response, parsing date fields
|
||||||
* Nested models: user (Candidate)
|
|
||||||
*/
|
|
||||||
export function convertAuthResponseFromApi(data: any): AuthResponse {
|
|
||||||
if (!data) return data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
// Convert nested Candidate model
|
|
||||||
user: convertCandidateFromApi(data.user),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert Authentication from API response
|
|
||||||
* Date fields: resetPasswordExpiry, lastPasswordChange, lockedUntil
|
* Date fields: resetPasswordExpiry, lastPasswordChange, lockedUntil
|
||||||
* Nested models: refreshTokens (RefreshToken)
|
|
||||||
*/
|
*/
|
||||||
export function convertAuthenticationFromApi(data: any): Authentication {
|
export function convertAuthenticationFromApi(data: any): Authentication {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1163,12 +1151,10 @@ export function convertAuthenticationFromApi(data: any): Authentication {
|
|||||||
lastPasswordChange: new Date(data.lastPasswordChange),
|
lastPasswordChange: new Date(data.lastPasswordChange),
|
||||||
// Convert lockedUntil from ISO string to Date
|
// Convert lockedUntil from ISO string to Date
|
||||||
lockedUntil: data.lockedUntil ? new Date(data.lockedUntil) : undefined,
|
lockedUntil: data.lockedUntil ? new Date(data.lockedUntil) : undefined,
|
||||||
// Convert nested RefreshToken model
|
|
||||||
refreshTokens: data.refreshTokens.map((item: any) => convertRefreshTokenFromApi(item)),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert BaseUser from API response
|
* Convert BaseUser from API response, parsing date fields
|
||||||
* Date fields: lastActivity, createdAt, updatedAt, lastLogin
|
* Date fields: lastActivity, createdAt, updatedAt, lastLogin
|
||||||
*/
|
*/
|
||||||
export function convertBaseUserFromApi(data: any): BaseUser {
|
export function convertBaseUserFromApi(data: any): BaseUser {
|
||||||
@ -1179,15 +1165,15 @@ export function convertBaseUserFromApi(data: any): BaseUser {
|
|||||||
// Convert lastActivity from ISO string to Date
|
// Convert lastActivity from ISO string to Date
|
||||||
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
||||||
// Convert createdAt from ISO string to Date
|
// Convert createdAt from ISO string to Date
|
||||||
createdAt: data.createdAt ? new Date(data.createdAt) : undefined,
|
createdAt: new Date(data.createdAt),
|
||||||
// Convert updatedAt from ISO string to Date
|
// Convert updatedAt from ISO string to Date
|
||||||
updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,
|
updatedAt: new Date(data.updatedAt),
|
||||||
// Convert lastLogin from ISO string to Date
|
// Convert lastLogin from ISO string to Date
|
||||||
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert BaseUserWithType from API response
|
* Convert BaseUserWithType from API response, parsing date fields
|
||||||
* Date fields: lastActivity
|
* Date fields: lastActivity
|
||||||
*/
|
*/
|
||||||
export function convertBaseUserWithTypeFromApi(data: any): BaseUserWithType {
|
export function convertBaseUserWithTypeFromApi(data: any): BaseUserWithType {
|
||||||
@ -1200,9 +1186,8 @@ export function convertBaseUserWithTypeFromApi(data: any): BaseUserWithType {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert Candidate from API response
|
* Convert Candidate from API response, parsing date fields
|
||||||
* Date fields: lastActivity, createdAt, updatedAt, lastLogin, availabilityDate
|
* Date fields: lastActivity, createdAt, updatedAt, lastLogin, availabilityDate
|
||||||
* Nested models: experience (WorkExperience), education (Education), certifications (Certification), jobApplications (JobApplication)
|
|
||||||
*/
|
*/
|
||||||
export function convertCandidateFromApi(data: any): Candidate {
|
export function convertCandidateFromApi(data: any): Candidate {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1212,27 +1197,18 @@ export function convertCandidateFromApi(data: any): Candidate {
|
|||||||
// Convert lastActivity from ISO string to Date
|
// Convert lastActivity from ISO string to Date
|
||||||
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
||||||
// Convert createdAt from ISO string to Date
|
// Convert createdAt from ISO string to Date
|
||||||
createdAt: data.createdAt ? new Date(data.createdAt) : undefined,
|
createdAt: new Date(data.createdAt),
|
||||||
// Convert updatedAt from ISO string to Date
|
// Convert updatedAt from ISO string to Date
|
||||||
updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,
|
updatedAt: new Date(data.updatedAt),
|
||||||
// Convert lastLogin from ISO string to Date
|
// Convert lastLogin from ISO string to Date
|
||||||
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
||||||
// Convert availabilityDate from ISO string to Date
|
// Convert availabilityDate from ISO string to Date
|
||||||
availabilityDate: data.availabilityDate ? new Date(data.availabilityDate) : undefined,
|
availabilityDate: data.availabilityDate ? new Date(data.availabilityDate) : undefined,
|
||||||
// Convert nested WorkExperience model
|
|
||||||
experience: data.experience ? convertWorkExperienceFromApi(data.experience) : undefined,
|
|
||||||
// Convert nested Education model
|
|
||||||
education: data.education ? convertEducationFromApi(data.education) : undefined,
|
|
||||||
// Convert nested Certification model
|
|
||||||
certifications: data.certifications ? convertCertificationFromApi(data.certifications) : undefined,
|
|
||||||
// Convert nested JobApplication model
|
|
||||||
jobApplications: data.jobApplications ? convertJobApplicationFromApi(data.jobApplications) : undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert CandidateAI from API response
|
* Convert CandidateAI from API response, parsing date fields
|
||||||
* Date fields: lastActivity, createdAt, updatedAt, lastLogin, availabilityDate
|
* Date fields: lastActivity, createdAt, updatedAt, lastLogin, availabilityDate
|
||||||
* Nested models: experience (WorkExperience), education (Education), certifications (Certification)
|
|
||||||
*/
|
*/
|
||||||
export function convertCandidateAIFromApi(data: any): CandidateAI {
|
export function convertCandidateAIFromApi(data: any): CandidateAI {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1242,49 +1218,17 @@ export function convertCandidateAIFromApi(data: any): CandidateAI {
|
|||||||
// Convert lastActivity from ISO string to Date
|
// Convert lastActivity from ISO string to Date
|
||||||
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
||||||
// Convert createdAt from ISO string to Date
|
// Convert createdAt from ISO string to Date
|
||||||
createdAt: data.createdAt ? new Date(data.createdAt) : undefined,
|
createdAt: new Date(data.createdAt),
|
||||||
// Convert updatedAt from ISO string to Date
|
// Convert updatedAt from ISO string to Date
|
||||||
updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,
|
updatedAt: new Date(data.updatedAt),
|
||||||
// Convert lastLogin from ISO string to Date
|
// Convert lastLogin from ISO string to Date
|
||||||
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
||||||
// Convert availabilityDate from ISO string to Date
|
// Convert availabilityDate from ISO string to Date
|
||||||
availabilityDate: data.availabilityDate ? new Date(data.availabilityDate) : undefined,
|
availabilityDate: data.availabilityDate ? new Date(data.availabilityDate) : undefined,
|
||||||
// Convert nested WorkExperience model
|
|
||||||
experience: data.experience ? convertWorkExperienceFromApi(data.experience) : undefined,
|
|
||||||
// Convert nested Education model
|
|
||||||
education: data.education ? convertEducationFromApi(data.education) : undefined,
|
|
||||||
// Convert nested Certification model
|
|
||||||
certifications: data.certifications ? convertCertificationFromApi(data.certifications) : undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert CandidateListResponse from API response
|
* Convert Certification from API response, parsing date fields
|
||||||
* Nested models: data (Candidate)
|
|
||||||
*/
|
|
||||||
export function convertCandidateListResponseFromApi(data: any): CandidateListResponse {
|
|
||||||
if (!data) return data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
// Convert nested Candidate model
|
|
||||||
data: data.data ? convertCandidateFromApi(data.data) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert CandidateResponse from API response
|
|
||||||
* Nested models: data (Candidate)
|
|
||||||
*/
|
|
||||||
export function convertCandidateResponseFromApi(data: any): CandidateResponse {
|
|
||||||
if (!data) return data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
// Convert nested Candidate model
|
|
||||||
data: data.data ? convertCandidateFromApi(data.data) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert Certification from API response
|
|
||||||
* Date fields: issueDate, expirationDate
|
* Date fields: issueDate, expirationDate
|
||||||
*/
|
*/
|
||||||
export function convertCertificationFromApi(data: any): Certification {
|
export function convertCertificationFromApi(data: any): Certification {
|
||||||
@ -1299,7 +1243,7 @@ export function convertCertificationFromApi(data: any): Certification {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ChatMessage from API response
|
* Convert ChatMessage from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertChatMessageFromApi(data: any): ChatMessage {
|
export function convertChatMessageFromApi(data: any): ChatMessage {
|
||||||
@ -1312,7 +1256,7 @@ export function convertChatMessageFromApi(data: any): ChatMessage {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ChatMessageError from API response
|
* Convert ChatMessageError from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertChatMessageErrorFromApi(data: any): ChatMessageError {
|
export function convertChatMessageErrorFromApi(data: any): ChatMessageError {
|
||||||
@ -1325,7 +1269,7 @@ export function convertChatMessageErrorFromApi(data: any): ChatMessageError {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ChatMessageRagSearch from API response
|
* Convert ChatMessageRagSearch from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertChatMessageRagSearchFromApi(data: any): ChatMessageRagSearch {
|
export function convertChatMessageRagSearchFromApi(data: any): ChatMessageRagSearch {
|
||||||
@ -1338,7 +1282,7 @@ export function convertChatMessageRagSearchFromApi(data: any): ChatMessageRagSea
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ChatMessageResume from API response
|
* Convert ChatMessageResume from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertChatMessageResumeFromApi(data: any): ChatMessageResume {
|
export function convertChatMessageResumeFromApi(data: any): ChatMessageResume {
|
||||||
@ -1351,9 +1295,8 @@ export function convertChatMessageResumeFromApi(data: any): ChatMessageResume {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ChatMessageSkillAssessment from API response
|
* Convert ChatMessageSkillAssessment from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
* Nested models: skillAssessment (SkillAssessment)
|
|
||||||
*/
|
*/
|
||||||
export function convertChatMessageSkillAssessmentFromApi(data: any): ChatMessageSkillAssessment {
|
export function convertChatMessageSkillAssessmentFromApi(data: any): ChatMessageSkillAssessment {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1362,12 +1305,10 @@ export function convertChatMessageSkillAssessmentFromApi(data: any): ChatMessage
|
|||||||
...data,
|
...data,
|
||||||
// Convert timestamp from ISO string to Date
|
// Convert timestamp from ISO string to Date
|
||||||
timestamp: data.timestamp ? new Date(data.timestamp) : undefined,
|
timestamp: data.timestamp ? new Date(data.timestamp) : undefined,
|
||||||
// Convert nested SkillAssessment model
|
|
||||||
skillAssessment: convertSkillAssessmentFromApi(data.skillAssessment),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ChatMessageStatus from API response
|
* Convert ChatMessageStatus from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertChatMessageStatusFromApi(data: any): ChatMessageStatus {
|
export function convertChatMessageStatusFromApi(data: any): ChatMessageStatus {
|
||||||
@ -1380,7 +1321,7 @@ export function convertChatMessageStatusFromApi(data: any): ChatMessageStatus {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ChatMessageStreaming from API response
|
* Convert ChatMessageStreaming from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertChatMessageStreamingFromApi(data: any): ChatMessageStreaming {
|
export function convertChatMessageStreamingFromApi(data: any): ChatMessageStreaming {
|
||||||
@ -1393,7 +1334,7 @@ export function convertChatMessageStreamingFromApi(data: any): ChatMessageStream
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ChatMessageUser from API response
|
* Convert ChatMessageUser from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertChatMessageUserFromApi(data: any): ChatMessageUser {
|
export function convertChatMessageUserFromApi(data: any): ChatMessageUser {
|
||||||
@ -1406,7 +1347,7 @@ export function convertChatMessageUserFromApi(data: any): ChatMessageUser {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert ChatSession from API response
|
* Convert ChatSession from API response, parsing date fields
|
||||||
* Date fields: createdAt, lastActivity
|
* Date fields: createdAt, lastActivity
|
||||||
*/
|
*/
|
||||||
export function convertChatSessionFromApi(data: any): ChatSession {
|
export function convertChatSessionFromApi(data: any): ChatSession {
|
||||||
@ -1421,7 +1362,7 @@ export function convertChatSessionFromApi(data: any): ChatSession {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert DataSourceConfiguration from API response
|
* Convert DataSourceConfiguration from API response, parsing date fields
|
||||||
* Date fields: lastRefreshed
|
* Date fields: lastRefreshed
|
||||||
*/
|
*/
|
||||||
export function convertDataSourceConfigurationFromApi(data: any): DataSourceConfiguration {
|
export function convertDataSourceConfigurationFromApi(data: any): DataSourceConfiguration {
|
||||||
@ -1434,7 +1375,7 @@ export function convertDataSourceConfigurationFromApi(data: any): DataSourceConf
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert Document from API response
|
* Convert Document from API response, parsing date fields
|
||||||
* Date fields: uploadDate
|
* Date fields: uploadDate
|
||||||
*/
|
*/
|
||||||
export function convertDocumentFromApi(data: any): Document {
|
export function convertDocumentFromApi(data: any): Document {
|
||||||
@ -1447,22 +1388,8 @@ export function convertDocumentFromApi(data: any): Document {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert DocumentListResponse from API response
|
* Convert DocumentMessage from API response, parsing date fields
|
||||||
* Nested models: documents (Document)
|
|
||||||
*/
|
|
||||||
export function convertDocumentListResponseFromApi(data: any): DocumentListResponse {
|
|
||||||
if (!data) return data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
// Convert nested Document model
|
|
||||||
documents: data.documents.map((item: any) => convertDocumentFromApi(item)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert DocumentMessage from API response
|
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
* Nested models: document (Document)
|
|
||||||
*/
|
*/
|
||||||
export function convertDocumentMessageFromApi(data: any): DocumentMessage {
|
export function convertDocumentMessageFromApi(data: any): DocumentMessage {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1471,12 +1398,10 @@ export function convertDocumentMessageFromApi(data: any): DocumentMessage {
|
|||||||
...data,
|
...data,
|
||||||
// Convert timestamp from ISO string to Date
|
// Convert timestamp from ISO string to Date
|
||||||
timestamp: data.timestamp ? new Date(data.timestamp) : undefined,
|
timestamp: data.timestamp ? new Date(data.timestamp) : undefined,
|
||||||
// Convert nested Document model
|
|
||||||
document: convertDocumentFromApi(data.document),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert EditHistory from API response
|
* Convert EditHistory from API response, parsing date fields
|
||||||
* Date fields: editedAt
|
* Date fields: editedAt
|
||||||
*/
|
*/
|
||||||
export function convertEditHistoryFromApi(data: any): EditHistory {
|
export function convertEditHistoryFromApi(data: any): EditHistory {
|
||||||
@ -1489,7 +1414,7 @@ export function convertEditHistoryFromApi(data: any): EditHistory {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert Education from API response
|
* Convert Education from API response, parsing date fields
|
||||||
* Date fields: startDate, endDate
|
* Date fields: startDate, endDate
|
||||||
*/
|
*/
|
||||||
export function convertEducationFromApi(data: any): Education {
|
export function convertEducationFromApi(data: any): Education {
|
||||||
@ -1504,9 +1429,8 @@ export function convertEducationFromApi(data: any): Education {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert Employer from API response
|
* Convert Employer from API response, parsing date fields
|
||||||
* Date fields: lastActivity, createdAt, updatedAt, lastLogin
|
* Date fields: lastActivity, createdAt, updatedAt, lastLogin
|
||||||
* Nested models: jobs (Job)
|
|
||||||
*/
|
*/
|
||||||
export function convertEmployerFromApi(data: any): Employer {
|
export function convertEmployerFromApi(data: any): Employer {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1516,30 +1440,15 @@ export function convertEmployerFromApi(data: any): Employer {
|
|||||||
// Convert lastActivity from ISO string to Date
|
// Convert lastActivity from ISO string to Date
|
||||||
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
||||||
// Convert createdAt from ISO string to Date
|
// Convert createdAt from ISO string to Date
|
||||||
createdAt: data.createdAt ? new Date(data.createdAt) : undefined,
|
createdAt: new Date(data.createdAt),
|
||||||
// Convert updatedAt from ISO string to Date
|
// Convert updatedAt from ISO string to Date
|
||||||
updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,
|
updatedAt: new Date(data.updatedAt),
|
||||||
// Convert lastLogin from ISO string to Date
|
// Convert lastLogin from ISO string to Date
|
||||||
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
||||||
// Convert nested Job model
|
|
||||||
jobs: data.jobs ? convertJobFromApi(data.jobs) : undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert EmployerResponse from API response
|
* Convert Guest from API response, parsing date fields
|
||||||
* Nested models: data (Employer)
|
|
||||||
*/
|
|
||||||
export function convertEmployerResponseFromApi(data: any): EmployerResponse {
|
|
||||||
if (!data) return data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
// Convert nested Employer model
|
|
||||||
data: data.data ? convertEmployerFromApi(data.data) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert Guest from API response
|
|
||||||
* Date fields: lastActivity, createdAt, updatedAt, lastLogin
|
* Date fields: lastActivity, createdAt, updatedAt, lastLogin
|
||||||
*/
|
*/
|
||||||
export function convertGuestFromApi(data: any): Guest {
|
export function convertGuestFromApi(data: any): Guest {
|
||||||
@ -1550,30 +1459,16 @@ export function convertGuestFromApi(data: any): Guest {
|
|||||||
// Convert lastActivity from ISO string to Date
|
// Convert lastActivity from ISO string to Date
|
||||||
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
lastActivity: data.lastActivity ? new Date(data.lastActivity) : undefined,
|
||||||
// Convert createdAt from ISO string to Date
|
// Convert createdAt from ISO string to Date
|
||||||
createdAt: data.createdAt ? new Date(data.createdAt) : undefined,
|
createdAt: new Date(data.createdAt),
|
||||||
// Convert updatedAt from ISO string to Date
|
// Convert updatedAt from ISO string to Date
|
||||||
updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,
|
updatedAt: new Date(data.updatedAt),
|
||||||
// Convert lastLogin from ISO string to Date
|
// Convert lastLogin from ISO string to Date
|
||||||
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
lastLogin: data.lastLogin ? new Date(data.lastLogin) : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert GuestSessionResponse from API response
|
* Convert InterviewFeedback from API response, parsing date fields
|
||||||
* Nested models: user (Guest)
|
|
||||||
*/
|
|
||||||
export function convertGuestSessionResponseFromApi(data: any): GuestSessionResponse {
|
|
||||||
if (!data) return data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
// Convert nested Guest model
|
|
||||||
user: convertGuestFromApi(data.user),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert InterviewFeedback from API response
|
|
||||||
* Date fields: createdAt, updatedAt
|
* Date fields: createdAt, updatedAt
|
||||||
* Nested models: skillAssessments (SkillAssessment)
|
|
||||||
*/
|
*/
|
||||||
export function convertInterviewFeedbackFromApi(data: any): InterviewFeedback {
|
export function convertInterviewFeedbackFromApi(data: any): InterviewFeedback {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1581,17 +1476,14 @@ export function convertInterviewFeedbackFromApi(data: any): InterviewFeedback {
|
|||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
// Convert createdAt from ISO string to Date
|
// Convert createdAt from ISO string to Date
|
||||||
createdAt: data.createdAt ? new Date(data.createdAt) : undefined,
|
createdAt: new Date(data.createdAt),
|
||||||
// Convert updatedAt from ISO string to Date
|
// Convert updatedAt from ISO string to Date
|
||||||
updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,
|
updatedAt: new Date(data.updatedAt),
|
||||||
// Convert nested SkillAssessment model
|
|
||||||
skillAssessments: data.skillAssessments ? convertSkillAssessmentFromApi(data.skillAssessments) : undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert InterviewSchedule from API response
|
* Convert InterviewSchedule from API response, parsing date fields
|
||||||
* Date fields: scheduledDate, endDate
|
* Date fields: scheduledDate, endDate
|
||||||
* Nested models: feedback (InterviewFeedback)
|
|
||||||
*/
|
*/
|
||||||
export function convertInterviewScheduleFromApi(data: any): InterviewSchedule {
|
export function convertInterviewScheduleFromApi(data: any): InterviewSchedule {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1602,14 +1494,11 @@ export function convertInterviewScheduleFromApi(data: any): InterviewSchedule {
|
|||||||
scheduledDate: new Date(data.scheduledDate),
|
scheduledDate: new Date(data.scheduledDate),
|
||||||
// Convert endDate from ISO string to Date
|
// Convert endDate from ISO string to Date
|
||||||
endDate: new Date(data.endDate),
|
endDate: new Date(data.endDate),
|
||||||
// Convert nested InterviewFeedback model
|
|
||||||
feedback: data.feedback ? convertInterviewFeedbackFromApi(data.feedback) : undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert Job from API response
|
* Convert Job from API response, parsing date fields
|
||||||
* Date fields: createdAt, updatedAt
|
* Date fields: createdAt, updatedAt
|
||||||
* Nested models: owner (BaseUser)
|
|
||||||
*/
|
*/
|
||||||
export function convertJobFromApi(data: any): Job {
|
export function convertJobFromApi(data: any): Job {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1617,17 +1506,14 @@ export function convertJobFromApi(data: any): Job {
|
|||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
// Convert createdAt from ISO string to Date
|
// Convert createdAt from ISO string to Date
|
||||||
createdAt: data.createdAt ? new Date(data.createdAt) : undefined,
|
createdAt: new Date(data.createdAt),
|
||||||
// Convert updatedAt from ISO string to Date
|
// Convert updatedAt from ISO string to Date
|
||||||
updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,
|
updatedAt: new Date(data.updatedAt),
|
||||||
// Convert nested BaseUser model
|
|
||||||
owner: data.owner ? convertBaseUserFromApi(data.owner) : undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert JobApplication from API response
|
* Convert JobApplication from API response, parsing date fields
|
||||||
* Date fields: appliedDate, updatedDate
|
* Date fields: appliedDate, updatedDate
|
||||||
* Nested models: interviewSchedules (InterviewSchedule), decision (ApplicationDecision)
|
|
||||||
*/
|
*/
|
||||||
export function convertJobApplicationFromApi(data: any): JobApplication {
|
export function convertJobApplicationFromApi(data: any): JobApplication {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1638,16 +1524,11 @@ export function convertJobApplicationFromApi(data: any): JobApplication {
|
|||||||
appliedDate: new Date(data.appliedDate),
|
appliedDate: new Date(data.appliedDate),
|
||||||
// Convert updatedDate from ISO string to Date
|
// Convert updatedDate from ISO string to Date
|
||||||
updatedDate: new Date(data.updatedDate),
|
updatedDate: new Date(data.updatedDate),
|
||||||
// Convert nested InterviewSchedule model
|
|
||||||
interviewSchedules: data.interviewSchedules ? convertInterviewScheduleFromApi(data.interviewSchedules) : undefined,
|
|
||||||
// Convert nested ApplicationDecision model
|
|
||||||
decision: data.decision ? convertApplicationDecisionFromApi(data.decision) : undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert JobFull from API response
|
* Convert JobFull from API response, parsing date fields
|
||||||
* Date fields: createdAt, updatedAt, datePosted, applicationDeadline, featuredUntil
|
* Date fields: createdAt, updatedAt, datePosted, applicationDeadline, featuredUntil
|
||||||
* Nested models: owner (BaseUser), applicants (JobApplication)
|
|
||||||
*/
|
*/
|
||||||
export function convertJobFullFromApi(data: any): JobFull {
|
export function convertJobFullFromApi(data: any): JobFull {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1655,38 +1536,20 @@ export function convertJobFullFromApi(data: any): JobFull {
|
|||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
// Convert createdAt from ISO string to Date
|
// Convert createdAt from ISO string to Date
|
||||||
createdAt: data.createdAt ? new Date(data.createdAt) : undefined,
|
createdAt: new Date(data.createdAt),
|
||||||
// Convert updatedAt from ISO string to Date
|
// Convert updatedAt from ISO string to Date
|
||||||
updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,
|
updatedAt: new Date(data.updatedAt),
|
||||||
// Convert datePosted from ISO string to Date
|
// Convert datePosted from ISO string to Date
|
||||||
datePosted: data.datePosted ? new Date(data.datePosted) : undefined,
|
datePosted: new Date(data.datePosted),
|
||||||
// Convert applicationDeadline from ISO string to Date
|
// Convert applicationDeadline from ISO string to Date
|
||||||
applicationDeadline: data.applicationDeadline ? new Date(data.applicationDeadline) : undefined,
|
applicationDeadline: data.applicationDeadline ? new Date(data.applicationDeadline) : undefined,
|
||||||
// Convert featuredUntil from ISO string to Date
|
// Convert featuredUntil from ISO string to Date
|
||||||
featuredUntil: data.featuredUntil ? new Date(data.featuredUntil) : undefined,
|
featuredUntil: data.featuredUntil ? new Date(data.featuredUntil) : undefined,
|
||||||
// Convert nested BaseUser model
|
|
||||||
owner: data.owner ? convertBaseUserFromApi(data.owner) : undefined,
|
|
||||||
// Convert nested JobApplication model
|
|
||||||
applicants: data.applicants ? convertJobApplicationFromApi(data.applicants) : undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert JobListResponse from API response
|
* Convert JobRequirementsMessage from API response, parsing date fields
|
||||||
* Nested models: data (Job)
|
|
||||||
*/
|
|
||||||
export function convertJobListResponseFromApi(data: any): JobListResponse {
|
|
||||||
if (!data) return data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
// Convert nested Job model
|
|
||||||
data: data.data ? convertJobFromApi(data.data) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert JobRequirementsMessage from API response
|
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
* Nested models: job (Job)
|
|
||||||
*/
|
*/
|
||||||
export function convertJobRequirementsMessageFromApi(data: any): JobRequirementsMessage {
|
export function convertJobRequirementsMessageFromApi(data: any): JobRequirementsMessage {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1695,25 +1558,10 @@ export function convertJobRequirementsMessageFromApi(data: any): JobRequirements
|
|||||||
...data,
|
...data,
|
||||||
// Convert timestamp from ISO string to Date
|
// Convert timestamp from ISO string to Date
|
||||||
timestamp: data.timestamp ? new Date(data.timestamp) : undefined,
|
timestamp: data.timestamp ? new Date(data.timestamp) : undefined,
|
||||||
// Convert nested Job model
|
|
||||||
job: convertJobFromApi(data.job),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert JobResponse from API response
|
* Convert MessageReaction from API response, parsing date fields
|
||||||
* Nested models: data (Job)
|
|
||||||
*/
|
|
||||||
export function convertJobResponseFromApi(data: any): JobResponse {
|
|
||||||
if (!data) return data;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
// Convert nested Job model
|
|
||||||
data: data.data ? convertJobFromApi(data.data) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Convert MessageReaction from API response
|
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertMessageReactionFromApi(data: any): MessageReaction {
|
export function convertMessageReactionFromApi(data: any): MessageReaction {
|
||||||
@ -1726,9 +1574,8 @@ export function convertMessageReactionFromApi(data: any): MessageReaction {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert RAGConfiguration from API response
|
* Convert RAGConfiguration from API response, parsing date fields
|
||||||
* Date fields: createdAt, updatedAt
|
* Date fields: createdAt, updatedAt
|
||||||
* Nested models: dataSourceConfigurations (DataSourceConfiguration)
|
|
||||||
*/
|
*/
|
||||||
export function convertRAGConfigurationFromApi(data: any): RAGConfiguration {
|
export function convertRAGConfigurationFromApi(data: any): RAGConfiguration {
|
||||||
if (!data) return data;
|
if (!data) return data;
|
||||||
@ -1736,15 +1583,13 @@ export function convertRAGConfigurationFromApi(data: any): RAGConfiguration {
|
|||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
// Convert createdAt from ISO string to Date
|
// Convert createdAt from ISO string to Date
|
||||||
createdAt: data.createdAt ? new Date(data.createdAt) : undefined,
|
createdAt: new Date(data.createdAt),
|
||||||
// Convert updatedAt from ISO string to Date
|
// Convert updatedAt from ISO string to Date
|
||||||
updatedAt: data.updatedAt ? new Date(data.updatedAt) : undefined,
|
updatedAt: new Date(data.updatedAt),
|
||||||
// Convert nested DataSourceConfiguration model
|
|
||||||
dataSourceConfigurations: data.dataSourceConfigurations.map((item: any) => convertDataSourceConfigurationFromApi(item)),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert RateLimitResult from API response
|
* Convert RateLimitResult from API response, parsing date fields
|
||||||
* Date fields: resetTimes
|
* Date fields: resetTimes
|
||||||
*/
|
*/
|
||||||
export function convertRateLimitResultFromApi(data: any): RateLimitResult {
|
export function convertRateLimitResultFromApi(data: any): RateLimitResult {
|
||||||
@ -1757,7 +1602,7 @@ export function convertRateLimitResultFromApi(data: any): RateLimitResult {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert RateLimitStatus from API response
|
* Convert RateLimitStatus from API response, parsing date fields
|
||||||
* Date fields: resetTimes
|
* Date fields: resetTimes
|
||||||
*/
|
*/
|
||||||
export function convertRateLimitStatusFromApi(data: any): RateLimitStatus {
|
export function convertRateLimitStatusFromApi(data: any): RateLimitStatus {
|
||||||
@ -1770,7 +1615,7 @@ export function convertRateLimitStatusFromApi(data: any): RateLimitStatus {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert RefreshToken from API response
|
* Convert RefreshToken from API response, parsing date fields
|
||||||
* Date fields: expiresAt
|
* Date fields: expiresAt
|
||||||
*/
|
*/
|
||||||
export function convertRefreshTokenFromApi(data: any): RefreshToken {
|
export function convertRefreshTokenFromApi(data: any): RefreshToken {
|
||||||
@ -1783,7 +1628,7 @@ export function convertRefreshTokenFromApi(data: any): RefreshToken {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert SkillAssessment from API response
|
* Convert SkillAssessment from API response, parsing date fields
|
||||||
* Date fields: createdAt, updatedAt
|
* Date fields: createdAt, updatedAt
|
||||||
*/
|
*/
|
||||||
export function convertSkillAssessmentFromApi(data: any): SkillAssessment {
|
export function convertSkillAssessmentFromApi(data: any): SkillAssessment {
|
||||||
@ -1798,7 +1643,7 @@ export function convertSkillAssessmentFromApi(data: any): SkillAssessment {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert UserActivity from API response
|
* Convert UserActivity from API response, parsing date fields
|
||||||
* Date fields: timestamp
|
* Date fields: timestamp
|
||||||
*/
|
*/
|
||||||
export function convertUserActivityFromApi(data: any): UserActivity {
|
export function convertUserActivityFromApi(data: any): UserActivity {
|
||||||
@ -1811,7 +1656,7 @@ export function convertUserActivityFromApi(data: any): UserActivity {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Convert WorkExperience from API response
|
* Convert WorkExperience from API response, parsing date fields
|
||||||
* Date fields: startDate, endDate
|
* Date fields: startDate, endDate
|
||||||
*/
|
*/
|
||||||
export function convertWorkExperienceFromApi(data: any): WorkExperience {
|
export function convertWorkExperienceFromApi(data: any): WorkExperience {
|
||||||
@ -1842,8 +1687,6 @@ export function convertFromApi<T>(data: any, modelType: string): T {
|
|||||||
return convertApplicationDecisionFromApi(data) as T;
|
return convertApplicationDecisionFromApi(data) as T;
|
||||||
case 'Attachment':
|
case 'Attachment':
|
||||||
return convertAttachmentFromApi(data) as T;
|
return convertAttachmentFromApi(data) as T;
|
||||||
case 'AuthResponse':
|
|
||||||
return convertAuthResponseFromApi(data) as T;
|
|
||||||
case 'Authentication':
|
case 'Authentication':
|
||||||
return convertAuthenticationFromApi(data) as T;
|
return convertAuthenticationFromApi(data) as T;
|
||||||
case 'BaseUser':
|
case 'BaseUser':
|
||||||
@ -1854,10 +1697,6 @@ export function convertFromApi<T>(data: any, modelType: string): T {
|
|||||||
return convertCandidateFromApi(data) as T;
|
return convertCandidateFromApi(data) as T;
|
||||||
case 'CandidateAI':
|
case 'CandidateAI':
|
||||||
return convertCandidateAIFromApi(data) as T;
|
return convertCandidateAIFromApi(data) as T;
|
||||||
case 'CandidateListResponse':
|
|
||||||
return convertCandidateListResponseFromApi(data) as T;
|
|
||||||
case 'CandidateResponse':
|
|
||||||
return convertCandidateResponseFromApi(data) as T;
|
|
||||||
case 'Certification':
|
case 'Certification':
|
||||||
return convertCertificationFromApi(data) as T;
|
return convertCertificationFromApi(data) as T;
|
||||||
case 'ChatMessage':
|
case 'ChatMessage':
|
||||||
@ -1882,8 +1721,6 @@ export function convertFromApi<T>(data: any, modelType: string): T {
|
|||||||
return convertDataSourceConfigurationFromApi(data) as T;
|
return convertDataSourceConfigurationFromApi(data) as T;
|
||||||
case 'Document':
|
case 'Document':
|
||||||
return convertDocumentFromApi(data) as T;
|
return convertDocumentFromApi(data) as T;
|
||||||
case 'DocumentListResponse':
|
|
||||||
return convertDocumentListResponseFromApi(data) as T;
|
|
||||||
case 'DocumentMessage':
|
case 'DocumentMessage':
|
||||||
return convertDocumentMessageFromApi(data) as T;
|
return convertDocumentMessageFromApi(data) as T;
|
||||||
case 'EditHistory':
|
case 'EditHistory':
|
||||||
@ -1892,12 +1729,8 @@ export function convertFromApi<T>(data: any, modelType: string): T {
|
|||||||
return convertEducationFromApi(data) as T;
|
return convertEducationFromApi(data) as T;
|
||||||
case 'Employer':
|
case 'Employer':
|
||||||
return convertEmployerFromApi(data) as T;
|
return convertEmployerFromApi(data) as T;
|
||||||
case 'EmployerResponse':
|
|
||||||
return convertEmployerResponseFromApi(data) as T;
|
|
||||||
case 'Guest':
|
case 'Guest':
|
||||||
return convertGuestFromApi(data) as T;
|
return convertGuestFromApi(data) as T;
|
||||||
case 'GuestSessionResponse':
|
|
||||||
return convertGuestSessionResponseFromApi(data) as T;
|
|
||||||
case 'InterviewFeedback':
|
case 'InterviewFeedback':
|
||||||
return convertInterviewFeedbackFromApi(data) as T;
|
return convertInterviewFeedbackFromApi(data) as T;
|
||||||
case 'InterviewSchedule':
|
case 'InterviewSchedule':
|
||||||
@ -1908,12 +1741,8 @@ export function convertFromApi<T>(data: any, modelType: string): T {
|
|||||||
return convertJobApplicationFromApi(data) as T;
|
return convertJobApplicationFromApi(data) as T;
|
||||||
case 'JobFull':
|
case 'JobFull':
|
||||||
return convertJobFullFromApi(data) as T;
|
return convertJobFullFromApi(data) as T;
|
||||||
case 'JobListResponse':
|
|
||||||
return convertJobListResponseFromApi(data) as T;
|
|
||||||
case 'JobRequirementsMessage':
|
case 'JobRequirementsMessage':
|
||||||
return convertJobRequirementsMessageFromApi(data) as T;
|
return convertJobRequirementsMessageFromApi(data) as T;
|
||||||
case 'JobResponse':
|
|
||||||
return convertJobResponseFromApi(data) as T;
|
|
||||||
case 'MessageReaction':
|
case 'MessageReaction':
|
||||||
return convertMessageReactionFromApi(data) as T;
|
return convertMessageReactionFromApi(data) as T;
|
||||||
case 'RAGConfiguration':
|
case 'RAGConfiguration':
|
||||||
|
@ -823,16 +823,5 @@ Content: {content}
|
|||||||
|
|
||||||
raise ValueError("No JSON found in the response")
|
raise ValueError("No JSON found in the response")
|
||||||
|
|
||||||
def extract_markdown_from_text(self, text: str) -> str:
|
|
||||||
"""Extract Markdown string from text that may contain other content."""
|
|
||||||
markdown_pattern = r"```(md|markdown)\s*([\s\S]*?)\s*```"
|
|
||||||
match = re.search(markdown_pattern, text)
|
|
||||||
if match:
|
|
||||||
return match.group(2).strip()
|
|
||||||
|
|
||||||
raise ValueError("No Markdown found in the response")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Register the base agent
|
# Register the base agent
|
||||||
agent_registry.register(Agent._agent_type, Agent)
|
agent_registry.register(Agent._agent_type, Agent)
|
||||||
|
@ -511,5 +511,14 @@ Make sure at least one of the candidate's job descriptions take into account the
|
|||||||
|
|
||||||
raise ValueError("No JSON found in the response")
|
raise ValueError("No JSON found in the response")
|
||||||
|
|
||||||
|
def extract_markdown_from_text(self, text: str) -> str:
|
||||||
|
"""Extract Markdown string from text that may contain other content."""
|
||||||
|
markdown_pattern = r"```(md|markdown)\s*([\s\S]*?)\s*```"
|
||||||
|
match = re.search(markdown_pattern, text)
|
||||||
|
if match:
|
||||||
|
return match.group(2).strip()
|
||||||
|
|
||||||
|
raise ValueError("No Markdown found in the response")
|
||||||
|
|
||||||
# Register the base agent
|
# Register the base agent
|
||||||
agent_registry.register(GeneratePersona._agent_type, GeneratePersona)
|
agent_registry.register(GeneratePersona._agent_type, GeneratePersona)
|
||||||
|
@ -19,7 +19,7 @@ import asyncio
|
|||||||
import numpy as np # type: ignore
|
import numpy as np # type: ignore
|
||||||
|
|
||||||
from .base import Agent, agent_registry, LLMMessage
|
from .base import Agent, agent_registry, LLMMessage
|
||||||
from models import ApiActivityType, Candidate, ChatMessage, ChatMessageError, ChatMessageMetaData, ApiMessageType, ChatMessageStatus, ChatMessageUser, ChatOptions, ChatSenderType, ApiStatusType, Job, JobRequirements, JobRequirementsMessage, Tunables
|
from models import ApiActivityType, Candidate, ChatMessage, ChatMessageError, ChatMessageMetaData, ApiMessageType, ChatMessageStatus, ChatMessageUser, ChatOptions, ChatSenderType, ApiStatusType, JobRequirements, JobRequirementsMessage, Tunables
|
||||||
import model_cast
|
import model_cast
|
||||||
from logger import logger
|
from logger import logger
|
||||||
import defines
|
import defines
|
||||||
@ -107,15 +107,6 @@ class JobRequirementsAgent(Agent):
|
|||||||
async def generate(
|
async def generate(
|
||||||
self, llm: Any, model: str, session_id: str, prompt: str, tunables: Optional[Tunables] = None, temperature=0.7
|
self, llm: Any, model: str, session_id: str, prompt: str, tunables: Optional[Tunables] = None, temperature=0.7
|
||||||
) -> AsyncGenerator[ChatMessage, None]:
|
) -> AsyncGenerator[ChatMessage, None]:
|
||||||
if not self.user:
|
|
||||||
error_message = ChatMessageError(
|
|
||||||
session_id=session_id,
|
|
||||||
content="User is not set for this agent."
|
|
||||||
)
|
|
||||||
logger.error(f"⚠️ {error_message.content}")
|
|
||||||
yield error_message
|
|
||||||
return
|
|
||||||
|
|
||||||
# Stage 1A: Analyze job requirements
|
# Stage 1A: Analyze job requirements
|
||||||
status_message = ChatMessageStatus(
|
status_message = ChatMessageStatus(
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
@ -175,20 +166,14 @@ class JobRequirementsAgent(Agent):
|
|||||||
logger.error(f"⚠️ {status_message.content}")
|
logger.error(f"⚠️ {status_message.content}")
|
||||||
yield status_message
|
yield status_message
|
||||||
return
|
return
|
||||||
job = Job(
|
|
||||||
owner_id=self.user.id,
|
|
||||||
owner_type=self.user.user_type,
|
|
||||||
company=company,
|
|
||||||
title=title,
|
|
||||||
summary=summary,
|
|
||||||
requirements=requirements,
|
|
||||||
session_id=session_id,
|
|
||||||
description=prompt,
|
|
||||||
)
|
|
||||||
job_requirements_message = JobRequirementsMessage(
|
job_requirements_message = JobRequirementsMessage(
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
status=ApiStatusType.DONE,
|
status=ApiStatusType.DONE,
|
||||||
job=job,
|
requirements=requirements,
|
||||||
|
company=company,
|
||||||
|
title=title,
|
||||||
|
summary=summary,
|
||||||
|
description=prompt,
|
||||||
)
|
)
|
||||||
yield job_requirements_message
|
yield job_requirements_message
|
||||||
logger.info(f"✅ Job requirements analysis completed successfully.")
|
logger.info(f"✅ Job requirements analysis completed successfully.")
|
||||||
|
@ -2,15 +2,14 @@
|
|||||||
"""
|
"""
|
||||||
Enhanced Type Generator - Generate TypeScript types from Pydantic models
|
Enhanced Type Generator - Generate TypeScript types from Pydantic models
|
||||||
Now with command line parameters, pre-test validation, TypeScript compilation,
|
Now with command line parameters, pre-test validation, TypeScript compilation,
|
||||||
automatic date field conversion functions, proper enum default handling,
|
automatic date field conversion functions, and proper enum default handling
|
||||||
and NESTED MODEL CONVERSION SUPPORT
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Any, Dict, List, Optional, Union, get_origin, get_args, Set
|
from typing import Any, Dict, List, Optional, Union, get_origin, get_args
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -65,7 +64,7 @@ current_dir = os.path.dirname(os.path.abspath(__file__))
|
|||||||
sys.path.insert(0, current_dir)
|
sys.path.insert(0, current_dir)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from pydantic import BaseModel # type: ignore
|
from pydantic import BaseModel
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
print(f"Error importing pydantic: {e}")
|
print(f"Error importing pydantic: {e}")
|
||||||
print("Make sure pydantic is installed: pip install pydantic")
|
print("Make sure pydantic is installed: pip install pydantic")
|
||||||
@ -139,61 +138,6 @@ def is_date_type(python_type: Any) -> bool:
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_pydantic_model_type(python_type: Any) -> bool:
|
|
||||||
"""Check if a Python type is a Pydantic model"""
|
|
||||||
# Unwrap any annotations first
|
|
||||||
python_type = unwrap_annotated_type(python_type)
|
|
||||||
|
|
||||||
# Handle Union types (like Optional[SomeModel])
|
|
||||||
origin = get_origin(python_type)
|
|
||||||
if origin is Union:
|
|
||||||
args = get_args(python_type)
|
|
||||||
# Check if any of the union args is a Pydantic model (excluding None)
|
|
||||||
return any(is_pydantic_model_type(arg) for arg in args if arg is not type(None))
|
|
||||||
|
|
||||||
# Handle List types (like List[SomeModel])
|
|
||||||
if origin is list or origin is List:
|
|
||||||
args = get_args(python_type)
|
|
||||||
if args:
|
|
||||||
return is_pydantic_model_type(args[0])
|
|
||||||
|
|
||||||
# Check if it's a Pydantic model
|
|
||||||
try:
|
|
||||||
if isinstance(python_type, type) and issubclass(python_type, BaseModel):
|
|
||||||
return python_type != BaseModel
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_model_name_from_type(python_type: Any) -> Optional[str]:
|
|
||||||
"""Extract the model name from a type"""
|
|
||||||
# Unwrap any annotations first
|
|
||||||
python_type = unwrap_annotated_type(python_type)
|
|
||||||
|
|
||||||
# Handle Union types
|
|
||||||
origin = get_origin(python_type)
|
|
||||||
if origin is Union:
|
|
||||||
args = get_args(python_type)
|
|
||||||
# Find the first Pydantic model in the union
|
|
||||||
for arg in args:
|
|
||||||
if arg is not type(None):
|
|
||||||
model_name = get_model_name_from_type(arg)
|
|
||||||
if model_name:
|
|
||||||
return model_name
|
|
||||||
|
|
||||||
# Handle List types
|
|
||||||
if origin is list or origin is List:
|
|
||||||
args = get_args(python_type)
|
|
||||||
if args:
|
|
||||||
return get_model_name_from_type(args[0])
|
|
||||||
|
|
||||||
# Direct model check
|
|
||||||
if isinstance(python_type, type) and issubclass(python_type, BaseModel):
|
|
||||||
return python_type.__name__
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_default_enum_value(field_info: Any, debug: bool = False) -> Optional[Any]:
|
def get_default_enum_value(field_info: Any, debug: bool = False) -> Optional[Any]:
|
||||||
"""Extract the specific enum value from a field's default, if it exists"""
|
"""Extract the specific enum value from a field's default, if it exists"""
|
||||||
if not hasattr(field_info, 'default'):
|
if not hasattr(field_info, 'default'):
|
||||||
@ -472,12 +416,11 @@ def is_field_optional(field_info: Any, field_type: Any, debug: bool = False) ->
|
|||||||
print(f" └─ RESULT: Required (fallback - no Optional type, no default)")
|
print(f" └─ RESULT: Required (fallback - no Optional type, no default)")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def process_pydantic_model(model_class, all_models: Set[str], debug: bool = False) -> Dict[str, Any]:
|
def process_pydantic_model(model_class, debug: bool = False) -> Dict[str, Any]:
|
||||||
"""Process a Pydantic model and return TypeScript interface definition"""
|
"""Process a Pydantic model and return TypeScript interface definition"""
|
||||||
interface_name = model_class.__name__
|
interface_name = model_class.__name__
|
||||||
properties = []
|
properties = []
|
||||||
date_fields = [] # Track date fields for conversion functions
|
date_fields = [] # Track date fields for conversion functions
|
||||||
model_fields = [] # Track fields that are Pydantic models
|
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
print(f" 🔍 Processing model: {interface_name}")
|
print(f" 🔍 Processing model: {interface_name}")
|
||||||
@ -519,21 +462,6 @@ def process_pydantic_model(model_class, all_models: Set[str], debug: bool = Fals
|
|||||||
elif debug and ('date' in str(field_type).lower() or 'time' in str(field_type).lower()):
|
elif debug and ('date' in str(field_type).lower() or 'time' in str(field_type).lower()):
|
||||||
print(f" ⚠️ Field {ts_name} contains 'date'/'time' but not detected as date type: {field_type}")
|
print(f" ⚠️ Field {ts_name} contains 'date'/'time' but not detected as date type: {field_type}")
|
||||||
|
|
||||||
# Check if this is a Pydantic model field
|
|
||||||
if is_pydantic_model_type(field_type):
|
|
||||||
model_name = get_model_name_from_type(field_type)
|
|
||||||
if model_name and model_name in all_models:
|
|
||||||
is_optional = is_field_optional(field_info, field_type, debug)
|
|
||||||
is_list = get_origin(unwrap_annotated_type(field_type)) in (list, List)
|
|
||||||
model_fields.append({
|
|
||||||
'name': ts_name,
|
|
||||||
'model': model_name,
|
|
||||||
'optional': is_optional,
|
|
||||||
'is_list': is_list
|
|
||||||
})
|
|
||||||
if debug:
|
|
||||||
print(f" 🔗 Model field detected: {ts_name} -> {model_name} (optional: {is_optional}, list: {is_list})")
|
|
||||||
|
|
||||||
# Pass field_info to the type converter for default enum handling
|
# Pass field_info to the type converter for default enum handling
|
||||||
ts_type = python_type_to_typescript(field_type, field_info, debug)
|
ts_type = python_type_to_typescript(field_type, field_info, debug)
|
||||||
|
|
||||||
@ -586,21 +514,6 @@ def process_pydantic_model(model_class, all_models: Set[str], debug: bool = Fals
|
|||||||
elif debug and ('date' in str(field_type).lower() or 'time' in str(field_type).lower()):
|
elif debug and ('date' in str(field_type).lower() or 'time' in str(field_type).lower()):
|
||||||
print(f" ⚠️ Field {ts_name} contains 'date'/'time' but not detected as date type: {field_type}")
|
print(f" ⚠️ Field {ts_name} contains 'date'/'time' but not detected as date type: {field_type}")
|
||||||
|
|
||||||
# Check if this is a Pydantic model field
|
|
||||||
if is_pydantic_model_type(field_type):
|
|
||||||
model_name = get_model_name_from_type(field_type)
|
|
||||||
if model_name and model_name in all_models:
|
|
||||||
is_optional = is_field_optional(field_info, field_type)
|
|
||||||
is_list = get_origin(unwrap_annotated_type(field_type)) in (list, List)
|
|
||||||
model_fields.append({
|
|
||||||
'name': ts_name,
|
|
||||||
'model': model_name,
|
|
||||||
'optional': is_optional,
|
|
||||||
'is_list': is_list
|
|
||||||
})
|
|
||||||
if debug:
|
|
||||||
print(f" 🔗 Model field detected: {ts_name} -> {model_name} (optional: {is_optional}, list: {is_list})")
|
|
||||||
|
|
||||||
# Pass field_info to the type converter for default enum handling
|
# Pass field_info to the type converter for default enum handling
|
||||||
ts_type = python_type_to_typescript(field_type, field_info, debug)
|
ts_type = python_type_to_typescript(field_type, field_info, debug)
|
||||||
|
|
||||||
@ -622,8 +535,7 @@ def process_pydantic_model(model_class, all_models: Set[str], debug: bool = Fals
|
|||||||
return {
|
return {
|
||||||
'name': interface_name,
|
'name': interface_name,
|
||||||
'properties': properties,
|
'properties': properties,
|
||||||
'date_fields': date_fields,
|
'date_fields': date_fields
|
||||||
'model_fields': model_fields
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def process_enum(enum_class) -> Dict[str, Any]:
|
def process_enum(enum_class) -> Dict[str, Any]:
|
||||||
@ -637,87 +549,38 @@ def process_enum(enum_class) -> Dict[str, Any]:
|
|||||||
'values': " | ".join(values)
|
'values': " | ".join(values)
|
||||||
}
|
}
|
||||||
|
|
||||||
def build_conversion_dependency_graph(interfaces: List[Dict[str, Any]]) -> Dict[str, Set[str]]:
|
|
||||||
"""Build a graph of which models depend on which other models for conversion"""
|
|
||||||
dependencies = {}
|
|
||||||
|
|
||||||
# First pass: identify which models have conversions
|
|
||||||
models_with_conversions = set()
|
|
||||||
for interface in interfaces:
|
|
||||||
if interface.get('date_fields') or interface.get('model_fields'):
|
|
||||||
models_with_conversions.add(interface['name'])
|
|
||||||
|
|
||||||
# Second pass: build dependency graph
|
|
||||||
for interface in interfaces:
|
|
||||||
interface_name = interface['name']
|
|
||||||
deps = set()
|
|
||||||
|
|
||||||
# Add dependencies for nested models
|
|
||||||
for model_field in interface.get('model_fields', []):
|
|
||||||
model_name = model_field['model']
|
|
||||||
if model_name in models_with_conversions:
|
|
||||||
deps.add(model_name)
|
|
||||||
|
|
||||||
if deps or interface.get('date_fields'):
|
|
||||||
dependencies[interface_name] = deps
|
|
||||||
|
|
||||||
return dependencies
|
|
||||||
|
|
||||||
def generate_conversion_functions(interfaces: List[Dict[str, Any]]) -> str:
|
def generate_conversion_functions(interfaces: List[Dict[str, Any]]) -> str:
|
||||||
"""Generate TypeScript conversion functions for models with date fields or nested models"""
|
"""Generate TypeScript conversion functions for models with date fields"""
|
||||||
# Build dependency graph
|
|
||||||
dependencies = build_conversion_dependency_graph(interfaces)
|
|
||||||
|
|
||||||
if not dependencies:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
conversion_functions = []
|
conversion_functions = []
|
||||||
|
|
||||||
for interface in interfaces:
|
for interface in interfaces:
|
||||||
interface_name = interface['name']
|
interface_name = interface['name']
|
||||||
date_fields = interface.get('date_fields', [])
|
date_fields = interface.get('date_fields', [])
|
||||||
model_fields = interface.get('model_fields', [])
|
|
||||||
|
|
||||||
# Skip if no conversion needed
|
if not date_fields:
|
||||||
if not date_fields and not model_fields:
|
continue # Skip interfaces without date fields
|
||||||
continue
|
|
||||||
|
|
||||||
# Check if any model fields need conversion
|
|
||||||
model_fields_needing_conversion = [
|
|
||||||
mf for mf in model_fields
|
|
||||||
if mf['model'] in dependencies
|
|
||||||
]
|
|
||||||
|
|
||||||
if not date_fields and not model_fields_needing_conversion:
|
|
||||||
continue
|
|
||||||
|
|
||||||
function_name = f"convert{interface_name}FromApi"
|
function_name = f"convert{interface_name}FromApi"
|
||||||
|
|
||||||
# Generate function
|
# Generate function
|
||||||
func_lines = [
|
func_lines = [
|
||||||
f"/**",
|
f"/**",
|
||||||
f" * Convert {interface_name} from API response",
|
f" * Convert {interface_name} from API response, parsing date fields",
|
||||||
]
|
f" * Date fields: {', '.join([f['name'] for f in date_fields])}",
|
||||||
|
|
||||||
if date_fields:
|
|
||||||
func_lines.append(f" * Date fields: {', '.join([f['name'] for f in date_fields])}")
|
|
||||||
if model_fields_needing_conversion:
|
|
||||||
func_lines.append(f" * Nested models: {', '.join([f'{mf['name']} ({mf['model']})' for mf in model_fields_needing_conversion])}")
|
|
||||||
|
|
||||||
func_lines.extend([
|
|
||||||
f" */",
|
f" */",
|
||||||
f"export function {function_name}(data: any): {interface_name} {{",
|
f"export function {function_name}(data: any): {interface_name} {{",
|
||||||
f" if (!data) return data;",
|
f" if (!data) return data;",
|
||||||
f" ",
|
f" ",
|
||||||
f" return {{",
|
f" return {{",
|
||||||
f" ...data,"
|
f" ...data,"
|
||||||
])
|
]
|
||||||
|
|
||||||
# Add date field conversions
|
# Add date field conversions with validation
|
||||||
for date_field in date_fields:
|
for date_field in date_fields:
|
||||||
field_name = date_field['name']
|
field_name = date_field['name']
|
||||||
is_optional = date_field['optional']
|
is_optional = date_field['optional']
|
||||||
|
|
||||||
|
# Add a comment for clarity
|
||||||
func_lines.append(f" // Convert {field_name} from ISO string to Date")
|
func_lines.append(f" // Convert {field_name} from ISO string to Date")
|
||||||
|
|
||||||
if is_optional:
|
if is_optional:
|
||||||
@ -725,26 +588,6 @@ def generate_conversion_functions(interfaces: List[Dict[str, Any]]) -> str:
|
|||||||
else:
|
else:
|
||||||
func_lines.append(f" {field_name}: new Date(data.{field_name}),")
|
func_lines.append(f" {field_name}: new Date(data.{field_name}),")
|
||||||
|
|
||||||
# Add nested model conversions
|
|
||||||
for model_field in model_fields_needing_conversion:
|
|
||||||
field_name = model_field['name']
|
|
||||||
model_name = model_field['model']
|
|
||||||
is_optional = model_field['optional']
|
|
||||||
is_list = model_field['is_list']
|
|
||||||
|
|
||||||
func_lines.append(f" // Convert nested {model_name} model")
|
|
||||||
|
|
||||||
if is_list:
|
|
||||||
if is_optional:
|
|
||||||
func_lines.append(f" {field_name}: data.{field_name} ? data.{field_name}.map((item: any) => convert{model_name}FromApi(item)) : undefined,")
|
|
||||||
else:
|
|
||||||
func_lines.append(f" {field_name}: data.{field_name}.map((item: any) => convert{model_name}FromApi(item)),")
|
|
||||||
else:
|
|
||||||
if is_optional:
|
|
||||||
func_lines.append(f" {field_name}: data.{field_name} ? convert{model_name}FromApi(data.{field_name}) : undefined,")
|
|
||||||
else:
|
|
||||||
func_lines.append(f" {field_name}: convert{model_name}FromApi(data.{field_name}),")
|
|
||||||
|
|
||||||
func_lines.extend([
|
func_lines.extend([
|
||||||
f" }};",
|
f" }};",
|
||||||
f"}}"
|
f"}}"
|
||||||
@ -758,11 +601,11 @@ def generate_conversion_functions(interfaces: List[Dict[str, Any]]) -> str:
|
|||||||
# Generate the conversion functions section
|
# Generate the conversion functions section
|
||||||
result = [
|
result = [
|
||||||
"// ============================",
|
"// ============================",
|
||||||
"// Date and Nested Model Conversion Functions",
|
"// Date Conversion Functions",
|
||||||
"// ============================",
|
"// ============================",
|
||||||
"",
|
"",
|
||||||
"// These functions convert API responses to properly typed objects",
|
"// These functions convert API responses to properly typed objects",
|
||||||
"// with Date objects instead of ISO date strings and nested model conversions",
|
"// with Date objects instead of ISO date strings",
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -770,9 +613,9 @@ def generate_conversion_functions(interfaces: List[Dict[str, Any]]) -> str:
|
|||||||
result.append("")
|
result.append("")
|
||||||
|
|
||||||
# Generate a generic converter function
|
# Generate a generic converter function
|
||||||
models_with_conversions = list(dependencies.keys())
|
models_with_dates = [interface['name'] for interface in interfaces if interface.get('date_fields')]
|
||||||
|
|
||||||
if models_with_conversions:
|
if models_with_dates:
|
||||||
result.extend([
|
result.extend([
|
||||||
"/**",
|
"/**",
|
||||||
" * Generic converter that automatically selects the right conversion function",
|
" * Generic converter that automatically selects the right conversion function",
|
||||||
@ -784,7 +627,7 @@ def generate_conversion_functions(interfaces: List[Dict[str, Any]]) -> str:
|
|||||||
" switch (modelType) {"
|
" switch (modelType) {"
|
||||||
])
|
])
|
||||||
|
|
||||||
for model_name in sorted(models_with_conversions):
|
for model_name in models_with_dates:
|
||||||
result.append(f" case '{model_name}':")
|
result.append(f" case '{model_name}':")
|
||||||
result.append(f" return convert{model_name}FromApi(data) as T;")
|
result.append(f" return convert{model_name}FromApi(data) as T;")
|
||||||
|
|
||||||
@ -828,17 +671,8 @@ def generate_typescript_interfaces(source_file: str, debug: bool = False):
|
|||||||
|
|
||||||
interfaces = []
|
interfaces = []
|
||||||
enums = []
|
enums = []
|
||||||
all_models = set()
|
|
||||||
|
|
||||||
# First pass: collect all model names
|
# Scan the models module
|
||||||
for name in dir(models_module):
|
|
||||||
obj = getattr(models_module, name)
|
|
||||||
if (isinstance(obj, type) and
|
|
||||||
issubclass(obj, BaseModel) and
|
|
||||||
obj != BaseModel):
|
|
||||||
all_models.add(name)
|
|
||||||
|
|
||||||
# Second pass: process models with knowledge of all models
|
|
||||||
for name in dir(models_module):
|
for name in dir(models_module):
|
||||||
obj = getattr(models_module, name)
|
obj = getattr(models_module, name)
|
||||||
|
|
||||||
@ -852,17 +686,10 @@ def generate_typescript_interfaces(source_file: str, debug: bool = False):
|
|||||||
issubclass(obj, BaseModel) and
|
issubclass(obj, BaseModel) and
|
||||||
obj != BaseModel):
|
obj != BaseModel):
|
||||||
|
|
||||||
interface = process_pydantic_model(obj, all_models, debug)
|
interface = process_pydantic_model(obj, debug)
|
||||||
interfaces.append(interface)
|
interfaces.append(interface)
|
||||||
date_count = len(interface.get('date_fields', []))
|
date_count = len(interface.get('date_fields', []))
|
||||||
nested_count = len(interface.get('model_fields', []))
|
print(f" ✅ Found Pydantic model: {name}" + (f" ({date_count} date fields)" if date_count > 0 else ""))
|
||||||
status_parts = []
|
|
||||||
if date_count > 0:
|
|
||||||
status_parts.append(f"{date_count} date fields")
|
|
||||||
if nested_count > 0:
|
|
||||||
status_parts.append(f"{nested_count} nested models")
|
|
||||||
status = f" ({', '.join(status_parts)})" if status_parts else ""
|
|
||||||
print(f" ✅ Found Pydantic model: {name}{status}")
|
|
||||||
|
|
||||||
# Check if it's an Enum
|
# Check if it's an Enum
|
||||||
elif (isinstance(obj, type) and
|
elif (isinstance(obj, type) and
|
||||||
@ -880,10 +707,8 @@ def generate_typescript_interfaces(source_file: str, debug: bool = False):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
total_date_fields = sum(len(interface.get('date_fields', [])) for interface in interfaces)
|
total_date_fields = sum(len(interface.get('date_fields', [])) for interface in interfaces)
|
||||||
total_nested_models = sum(len(interface.get('model_fields', [])) for interface in interfaces)
|
|
||||||
print(f"\n📊 Found {len(interfaces)} interfaces and {len(enums)} enums")
|
print(f"\n📊 Found {len(interfaces)} interfaces and {len(enums)} enums")
|
||||||
print(f"🗓️ Found {total_date_fields} date fields across all models")
|
print(f"🗓️ Found {total_date_fields} date fields across all models")
|
||||||
print(f"🔗 Found {total_nested_models} nested model fields requiring conversion")
|
|
||||||
|
|
||||||
# Generate TypeScript content
|
# Generate TypeScript content
|
||||||
ts_content = f"""// Generated TypeScript types from Pydantic models
|
ts_content = f"""// Generated TypeScript types from Pydantic models
|
||||||
@ -956,7 +781,7 @@ def compile_typescript(ts_file: str) -> bool:
|
|||||||
def main():
|
def main():
|
||||||
"""Main function with command line argument parsing"""
|
"""Main function with command line argument parsing"""
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='Generate TypeScript types from Pydantic models with nested model conversion support',
|
description='Generate TypeScript types from Pydantic models with date conversion functions and proper enum handling',
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
epilog="""
|
epilog="""
|
||||||
Examples:
|
Examples:
|
||||||
@ -967,19 +792,12 @@ Examples:
|
|||||||
python generate_types.py --debug # Enable debug output
|
python generate_types.py --debug # Enable debug output
|
||||||
python generate_types.py --source models.py --output types.ts --skip-test --skip-compile --debug
|
python generate_types.py --source models.py --output types.ts --skip-test --skip-compile --debug
|
||||||
|
|
||||||
Generated conversion functions now support nested models:
|
Generated conversion functions can be used like:
|
||||||
// If JobRequirementsMessage has a 'job' field of type Job
|
const candidate = convertCandidateFromApi(apiResponse);
|
||||||
const message = convertJobRequirementsMessageFromApi(apiResponse);
|
const jobs = convertArrayFromApi<Job>(apiResponse, 'Job');
|
||||||
// The nested job field will also be converted automatically
|
|
||||||
|
|
||||||
// Arrays of models are also supported
|
Enum types are now properly handled:
|
||||||
const messages = convertArrayFromApi<JobRequirementsMessage>(apiResponse, 'JobRequirementsMessage');
|
status: ApiStatusType = ApiStatusType.DONE -> status: ApiStatusType (not locked to "done")
|
||||||
|
|
||||||
The conversion functions handle:
|
|
||||||
- Date field conversion (ISO strings to Date objects)
|
|
||||||
- Nested model conversion (recursive conversion of Pydantic model fields)
|
|
||||||
- Arrays of models
|
|
||||||
- Optional fields
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1016,12 +834,12 @@ The conversion functions handle:
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--version', '-v',
|
'--version', '-v',
|
||||||
action='version',
|
action='version',
|
||||||
version='TypeScript Generator 4.0 (With Nested Model Conversion Support)'
|
version='TypeScript Generator 3.2 (Fixed Enum Default Handling)'
|
||||||
)
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
print("🚀 Enhanced TypeScript Type Generator with Nested Model Conversion")
|
print("🚀 Enhanced TypeScript Type Generator with Fixed Enum Handling")
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
print(f"📁 Source file: {args.source}")
|
print(f"📁 Source file: {args.source}")
|
||||||
print(f"📁 Output file: {args.output}")
|
print(f"📁 Output file: {args.output}")
|
||||||
@ -1067,24 +885,29 @@ The conversion functions handle:
|
|||||||
# Count conversion functions and provide detailed feedback
|
# Count conversion functions and provide detailed feedback
|
||||||
conversion_count = ts_content.count('export function convert') - ts_content.count('convertFromApi') - ts_content.count('convertArrayFromApi')
|
conversion_count = ts_content.count('export function convert') - ts_content.count('convertFromApi') - ts_content.count('convertArrayFromApi')
|
||||||
enum_type_count = ts_content.count('export type')
|
enum_type_count = ts_content.count('export type')
|
||||||
nested_conversion_count = ts_content.count('// Convert nested')
|
|
||||||
|
|
||||||
if conversion_count > 0:
|
if conversion_count > 0:
|
||||||
print(f"🗓️ Generated {conversion_count} conversion functions")
|
print(f"🗓️ Generated {conversion_count} date conversion functions")
|
||||||
if nested_conversion_count > 0:
|
|
||||||
print(f"🔗 Including {nested_conversion_count} nested model conversions")
|
|
||||||
if enum_type_count > 0:
|
if enum_type_count > 0:
|
||||||
print(f"🎯 Generated {enum_type_count} enum types")
|
print(f"🎯 Generated {enum_type_count} enum types (properly allowing all values)")
|
||||||
|
|
||||||
if args.debug:
|
if args.debug:
|
||||||
# Show which models have conversions
|
# Show which models have date conversion
|
||||||
models_with_conversions = []
|
models_with_dates = []
|
||||||
for line in ts_content.split('\n'):
|
for line in ts_content.split('\n'):
|
||||||
if line.startswith('export function convert') and 'FromApi' in line and 'convertFromApi' not in line:
|
if line.startswith('export function convert') and 'FromApi' in line and 'convertFromApi' not in line:
|
||||||
model_name = line.split('convert')[1].split('FromApi')[0]
|
model_name = line.split('convert')[1].split('FromApi')[0]
|
||||||
models_with_conversions.append(model_name)
|
models_with_dates.append(model_name)
|
||||||
if models_with_conversions:
|
if models_with_dates:
|
||||||
print(f" Models with conversions: {', '.join(models_with_conversions)}")
|
print(f" Models with date conversion: {', '.join(models_with_dates)}")
|
||||||
|
|
||||||
|
# Provide troubleshooting info if debug mode
|
||||||
|
if args.debug:
|
||||||
|
print(f"\n🐛 Debug mode was enabled. If you see incorrect type conversions:")
|
||||||
|
print(f" 1. Check the debug output above for enum default handling")
|
||||||
|
print(f" 2. Look for '📅 Date type check' lines for date handling")
|
||||||
|
print(f" 3. Look for '⚠️' warnings about fallback types")
|
||||||
|
print(f" 4. Verify your Pydantic model field types and defaults are correct")
|
||||||
|
|
||||||
# Step 5: Compile TypeScript (unless skipped)
|
# Step 5: Compile TypeScript (unless skipped)
|
||||||
if not args.skip_compile:
|
if not args.skip_compile:
|
||||||
@ -1101,24 +924,19 @@ The conversion functions handle:
|
|||||||
print(f"✅ Generated {args.output} from {args.source}")
|
print(f"✅ Generated {args.output} from {args.source}")
|
||||||
print(f"✅ File size: {file_size} characters")
|
print(f"✅ File size: {file_size} characters")
|
||||||
if conversion_count > 0:
|
if conversion_count > 0:
|
||||||
print(f"✅ Conversion functions: {conversion_count}")
|
print(f"✅ Date conversion functions: {conversion_count}")
|
||||||
if nested_conversion_count > 0:
|
|
||||||
print(f"✅ Nested model conversions: {nested_conversion_count}")
|
|
||||||
if enum_type_count > 0:
|
if enum_type_count > 0:
|
||||||
print(f"✅ Enum types: {enum_type_count}")
|
print(f"✅ Enum types (with full value range): {enum_type_count}")
|
||||||
if not args.skip_test:
|
if not args.skip_test:
|
||||||
print("✅ Model validation passed")
|
print("✅ Model validation passed")
|
||||||
if not args.skip_compile:
|
if not args.skip_compile:
|
||||||
print("✅ TypeScript syntax validated")
|
print("✅ TypeScript syntax validated")
|
||||||
|
|
||||||
print(f"\n💡 Usage in your TypeScript project:")
|
print(f"\n💡 Usage in your TypeScript project:")
|
||||||
print(f" import {{ Candidate, Job, convertJobRequirementsMessageFromApi }} from './{Path(args.output).stem}';")
|
print(f" import {{ Candidate, Employer, Job, convertCandidateFromApi }} from './{Path(args.output).stem}';")
|
||||||
if conversion_count > 0:
|
if conversion_count > 0:
|
||||||
print(f"\n // Example with nested model conversion:")
|
print(f" const candidate = convertCandidateFromApi(apiResponse);")
|
||||||
print(f" const message = convertJobRequirementsMessageFromApi(apiResponse);")
|
print(f" const jobs = convertArrayFromApi<Job>(apiResponse, 'Job');")
|
||||||
print(f" // The nested 'job' field is automatically converted too!")
|
|
||||||
print(f"\n // For arrays:")
|
|
||||||
print(f" const messages = convertArrayFromApi<JobRequirementsMessage>(apiResponse, 'JobRequirementsMessage');")
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -2357,6 +2357,7 @@ async def create_job_from_content(database: RedisDatabase, current_user: Candida
|
|||||||
activity=ApiActivityType.SEARCHING
|
activity=ApiActivityType.SEARCHING
|
||||||
)
|
)
|
||||||
yield status_message
|
yield status_message
|
||||||
|
await asyncio.sleep(0)
|
||||||
|
|
||||||
async for message in chat_agent.generate(
|
async for message in chat_agent.generate(
|
||||||
llm=llm_manager.get_llm(),
|
llm=llm_manager.get_llm(),
|
||||||
@ -2365,52 +2366,16 @@ async def create_job_from_content(database: RedisDatabase, current_user: Candida
|
|||||||
prompt=content
|
prompt=content
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if not message or not isinstance(message, JobRequirementsMessage):
|
if not message or not isinstance(message, JobRequirementsMessage):
|
||||||
error_message = ChatMessageError(
|
error_message = ChatMessageError(
|
||||||
sessionId=MOCK_UUID, # No session ID for document uploads
|
sessionId=MOCK_UUID, # No session ID for document uploads
|
||||||
content="Job extraction did not convert successfully"
|
content="Failed to process job description file"
|
||||||
)
|
)
|
||||||
yield error_message
|
yield error_message
|
||||||
return
|
return
|
||||||
|
|
||||||
status_message = ChatMessageStatus(
|
logger.info(f"✅ Successfully saved job requirements job {message.id}")
|
||||||
sessionId=MOCK_UUID, # No session ID for document uploads
|
yield message
|
||||||
content=f"Reformatting job description as markdown...",
|
|
||||||
activity=ApiActivityType.CONVERTING
|
|
||||||
)
|
|
||||||
yield status_message
|
|
||||||
|
|
||||||
job_requirements : JobRequirementsMessage = message
|
|
||||||
async for message in chat_agent.llm_one_shot(
|
|
||||||
llm=llm_manager.get_llm(),
|
|
||||||
model=defines.model,
|
|
||||||
session_id=MOCK_UUID,
|
|
||||||
prompt=content,
|
|
||||||
system_prompt="""
|
|
||||||
You are a document editor. Take the provided job description and reformat as legible markdown.
|
|
||||||
Return only the markdown content, no other text. Make sure all content is included.
|
|
||||||
"""
|
|
||||||
):
|
|
||||||
pass
|
|
||||||
|
|
||||||
if not message or not isinstance(message, ChatMessage):
|
|
||||||
logger.error("❌ Failed to reformat job description to markdown")
|
|
||||||
error_message = ChatMessageError(
|
|
||||||
sessionId=MOCK_UUID, # No session ID for document uploads
|
|
||||||
content="Failed to reformat job description"
|
|
||||||
)
|
|
||||||
yield error_message
|
|
||||||
return
|
|
||||||
chat_message : ChatMessage = message
|
|
||||||
markdown = chat_message.content
|
|
||||||
try:
|
|
||||||
markdown = chat_agent.extract_markdown_from_text(chat_message.content)
|
|
||||||
except Exception as e:
|
|
||||||
pass
|
|
||||||
job_requirements.job.description = markdown
|
|
||||||
logger.info(f"✅ Successfully saved job requirements job {job_requirements.id}")
|
|
||||||
yield job_requirements
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@api_router.post("/candidates/profile/upload")
|
@api_router.post("/candidates/profile/upload")
|
||||||
@ -3307,7 +3272,6 @@ async def create_job_from_description(
|
|||||||
logger.info(f"📁 Received file content: size='{len(content)} bytes'")
|
logger.info(f"📁 Received file content: size='{len(content)} bytes'")
|
||||||
|
|
||||||
async for message in create_job_from_content(database=database, current_user=current_user, content=content):
|
async for message in create_job_from_content(database=database, current_user=current_user, content=content):
|
||||||
logger.info(f"📄 Yielding job creation message status: {message.status}")
|
|
||||||
yield message
|
yield message
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -3439,10 +3403,9 @@ async def create_job_from_file(
|
|||||||
yield error_message
|
yield error_message
|
||||||
logger.error(f"❌ Error converting {file.filename} to Markdown: {e}")
|
logger.error(f"❌ Error converting {file.filename} to Markdown: {e}")
|
||||||
return
|
return
|
||||||
|
async for message in create_job_from_content(database=database, current_user=current_user, content=file_content):
|
||||||
async for message in create_job_from_content(database=database, current_user=current_user, content=file_content):
|
yield message
|
||||||
yield message
|
return
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async def to_json(method):
|
async def to_json(method):
|
||||||
|
@ -480,8 +480,8 @@ class BaseUser(BaseUserWithType):
|
|||||||
full_name: str = Field(..., alias="fullName")
|
full_name: str = Field(..., alias="fullName")
|
||||||
phone: Optional[str] = None
|
phone: Optional[str] = None
|
||||||
location: Optional[Location] = None
|
location: Optional[Location] = None
|
||||||
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="createdAt")
|
created_at: datetime = Field(..., alias="createdAt")
|
||||||
updated_at: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="updatedAt")
|
updated_at: datetime = Field(..., alias="updatedAt")
|
||||||
last_login: Optional[datetime] = Field(None, alias="lastLogin")
|
last_login: Optional[datetime] = Field(None, alias="lastLogin")
|
||||||
profile_image: Optional[str] = Field(None, alias="profileImage")
|
profile_image: Optional[str] = Field(None, alias="profileImage")
|
||||||
status: UserStatus
|
status: UserStatus
|
||||||
@ -613,7 +613,7 @@ class Guest(BaseUser):
|
|||||||
username: str # Add username for consistency with other user types
|
username: str # Add username for consistency with other user types
|
||||||
converted_to_user_id: Optional[str] = Field(None, alias="convertedToUserId")
|
converted_to_user_id: Optional[str] = Field(None, alias="convertedToUserId")
|
||||||
ip_address: Optional[str] = Field(None, alias="ipAddress")
|
ip_address: Optional[str] = Field(None, alias="ipAddress")
|
||||||
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="createdAt")
|
created_at: datetime = Field(..., alias="createdAt")
|
||||||
user_agent: Optional[str] = Field(None, alias="userAgent")
|
user_agent: Optional[str] = Field(None, alias="userAgent")
|
||||||
rag_content_size: int = 0
|
rag_content_size: int = 0
|
||||||
model_config = {
|
model_config = {
|
||||||
@ -690,8 +690,8 @@ class Job(BaseModel):
|
|||||||
company: Optional[str]
|
company: Optional[str]
|
||||||
description: str
|
description: str
|
||||||
requirements: Optional[JobRequirements]
|
requirements: Optional[JobRequirements]
|
||||||
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="createdAt")
|
created_at: datetime = Field(..., alias="createdAt")
|
||||||
updated_at: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="updatedAt")
|
updated_at: datetime = Field(..., alias="updatedAt")
|
||||||
model_config = {
|
model_config = {
|
||||||
"populate_by_name": True # Allow both field names and aliases
|
"populate_by_name": True # Allow both field names and aliases
|
||||||
}
|
}
|
||||||
@ -700,7 +700,7 @@ class JobFull(Job):
|
|||||||
location: Location
|
location: Location
|
||||||
salary_range: Optional[SalaryRange] = Field(None, alias="salaryRange")
|
salary_range: Optional[SalaryRange] = Field(None, alias="salaryRange")
|
||||||
employment_type: EmploymentType = Field(..., alias="employmentType")
|
employment_type: EmploymentType = Field(..., alias="employmentType")
|
||||||
date_posted: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="datePosted")
|
date_posted: datetime = Field(..., alias="datePosted")
|
||||||
application_deadline: Optional[datetime] = Field(None, alias="applicationDeadline")
|
application_deadline: Optional[datetime] = Field(None, alias="applicationDeadline")
|
||||||
is_active: bool = Field(..., alias="isActive")
|
is_active: bool = Field(..., alias="isActive")
|
||||||
applicants: Optional[List["JobApplication"]] = None
|
applicants: Optional[List["JobApplication"]] = None
|
||||||
@ -723,8 +723,8 @@ class InterviewFeedback(BaseModel):
|
|||||||
weaknesses: List[str]
|
weaknesses: List[str]
|
||||||
recommendation: InterviewRecommendation
|
recommendation: InterviewRecommendation
|
||||||
comments: str
|
comments: str
|
||||||
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="createdAt")
|
created_at: datetime = Field(..., alias="createdAt")
|
||||||
updated_at: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="updatedAt")
|
updated_at: datetime = Field(..., alias="updatedAt")
|
||||||
is_visible: bool = Field(..., alias="isVisible")
|
is_visible: bool = Field(..., alias="isVisible")
|
||||||
skill_assessments: Optional[List[SkillAssessment]] = Field(None, alias="skillAssessments")
|
skill_assessments: Optional[List[SkillAssessment]] = Field(None, alias="skillAssessments")
|
||||||
model_config = {
|
model_config = {
|
||||||
@ -954,7 +954,11 @@ class ChatMessageRagSearch(ApiMessage):
|
|||||||
|
|
||||||
class JobRequirementsMessage(ApiMessage):
|
class JobRequirementsMessage(ApiMessage):
|
||||||
type: ApiMessageType = ApiMessageType.JSON
|
type: ApiMessageType = ApiMessageType.JSON
|
||||||
job: Job = Field(..., alias="job")
|
title: Optional[str]
|
||||||
|
summary: Optional[str]
|
||||||
|
company: Optional[str]
|
||||||
|
description: str
|
||||||
|
requirements: Optional[JobRequirements]
|
||||||
|
|
||||||
class DocumentMessage(ApiMessage):
|
class DocumentMessage(ApiMessage):
|
||||||
type: ApiMessageType = ApiMessageType.JSON
|
type: ApiMessageType = ApiMessageType.JSON
|
||||||
@ -1075,8 +1079,8 @@ class RAGConfiguration(BaseModel):
|
|||||||
embedding_model: str = Field(..., alias="embeddingModel")
|
embedding_model: str = Field(..., alias="embeddingModel")
|
||||||
vector_store_type: VectorStoreType = Field(..., alias="vectorStoreType")
|
vector_store_type: VectorStoreType = Field(..., alias="vectorStoreType")
|
||||||
retrieval_parameters: RetrievalParameters = Field(..., alias="retrievalParameters")
|
retrieval_parameters: RetrievalParameters = Field(..., alias="retrievalParameters")
|
||||||
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="createdAt")
|
created_at: datetime = Field(..., alias="createdAt")
|
||||||
updated_at: datetime = Field(default_factory=lambda: datetime.now(UTC), alias="updatedAt")
|
updated_at: datetime = Field(..., alias="updatedAt")
|
||||||
version: int
|
version: int
|
||||||
is_active: bool = Field(..., alias="isActive")
|
is_active: bool = Field(..., alias="isActive")
|
||||||
model_config = {
|
model_config = {
|
||||||
@ -1247,7 +1251,7 @@ class EmployerResponse(BaseModel):
|
|||||||
|
|
||||||
class JobResponse(BaseModel):
|
class JobResponse(BaseModel):
|
||||||
success: bool
|
success: bool
|
||||||
data: Optional[Job] = None
|
data: Optional["Job"] = None
|
||||||
error: Optional[ErrorDetail] = None
|
error: Optional[ErrorDetail] = None
|
||||||
meta: Optional[Dict[str, Any]] = None
|
meta: Optional[Dict[str, Any]] = None
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user