KIEDIS Platform

AI-Powered Talent Matching Documentation

Explore the comprehensive documentation for KIEDIS - an intelligent platform that connects clients with freelancers through semantic search and LLM-powered job description analysis.

0
API Endpoints
0
Core Models
0
User Flows

Platform Features

AI-Powered Matching

Semantic search using pgvector embeddings and LLM technology for intelligent talent matching.

Document Processing

Automated extraction from job descriptions and resumes using AIDP technology.

Interactive Chat

LLM-powered conversational interface for refining requirements and search criteria.

Semantic Search

Vector-based similarity search with HNSW indexing for fast, accurate results.

User Flows

Client Job Description Creation Flow

flowchart TD Start([Client Lands on Platform]) --> Welcome[Welcome Page
/client/job-description] Welcome --> PathChoice{Choose Entry Path} PathChoice -->|Upload JD| Upload[Upload Job Description
Document] PathChoice -->|Describe| Describe[Describe Project
Requirements] PathChoice -->|Title| Title[Enter Position
Title] PathChoice -->|Free Text| FreeText[Free Text
Input] Upload --> CreateSession[Create Search Session
SearchSession.objects.create] Describe --> CreateSession Title --> CreateSession FreeText --> CreateSession CreateSession --> ChatInterface[JD Agentic Chat
Interface] ChatInterface -->|Upload Path| UploadDoc[Upload Document
JobDescriptionDocument] UploadDoc --> ExtractTask[AIDP Extraction
Task Queue] ExtractTask --> ProcessAIDP[Process with AIDP
extract_jd_doc_with_aidp_task] ProcessAIDP --> UpdateJD[Update Job Description
Content] ChatInterface --> ChatLoop{Chat Interaction} UpdateJD --> ChatLoop ChatLoop -->|Refine| RefineJD[Refine Requirements] ChatLoop -->|Add Details| AddDetails[Add Missing Details] ChatLoop -->|Search| SearchFreelancers[Search Freelancers] RefineJD --> UpdateSession[Update Search Session
filters, llm_ctx, state] AddDetails --> UpdateSession UpdateSession --> ChatLoop SearchFreelancers --> SemanticSearch[Semantic Search
pgvector] SemanticSearch --> DisplayResults[Display Freelancer
Results] DisplayResults --> Actions{User Actions} Actions -->|Bookmark| BookmarkFL[Bookmark Freelancer] Actions -->|Add Note| AddNote[Add Note to
Freelancer] Actions -->|Refine Search| ChatLoop ChatInterface -->|Anonymous User| SaveByEmail[Save JD by Email
SavedJobDescription] Actions -->|Complete| Complete([Session Complete]) classDef startEnd fill:#e1f5fe,stroke:#01579b,stroke-width:2px classDef process fill:#fff3e0,stroke:#ef6c00,stroke-width:2px classDef decision fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px classDef extraction fill:#fce4ec,stroke:#c2185b,stroke-width:2px classDef search fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px class Start,Complete startEnd class Welcome,CreateSession,ChatInterface,UpdateSession,DisplayResults process class PathChoice,ChatLoop,Actions decision class ExtractTask,ProcessAIDP,UpdateJD extraction class SemanticSearch,SearchFreelancers search

Freelancer Resume Upload Flow

flowchart TD Start([Freelancer Registration]) --> Auth{Authentication
Status} Auth -->|New User| Onboard[Onboarding Flow] Auth -->|Existing User| Dashboard[Freelancer Dashboard] Onboard --> UploadChoice{Upload Method} Dashboard --> UploadChoice UploadChoice -->|Single| SingleUpload[Single Resume
Upload Form] UploadChoice -->|Bulk| BulkUpload[Bulk Resume
Upload Form] SingleUpload --> CreateDoc[Create ResumeDocument
Object] BulkUpload --> CreateMultipleDocs[Create Multiple
ResumeDocument Objects] CreateDoc --> CalcChecksum[Calculate MD5
Checksum] CreateMultipleDocs --> CalcChecksum CalcChecksum --> CheckCache{Check Cache
for Existing Results} CheckCache -->|Cache Hit| LoadCached[Load Cached
AIDP Results] CheckCache -->|Cache Miss| QueueTask[Queue AIDP
Extraction Task] QueueTask --> CeleryTask[Celery Task:
extract_resume_with_aidp] CeleryTask --> AIDPProcess[AIDP Processing
run_checklist] AIDPProcess --> ExtractData[Extract Structured Data:
- Name & Contact
- Education
- Work Experience
- Skills
- Languages
- Certifications] LoadCached --> SaveProfile ExtractData --> CacheResults[Cache Results
24 hours] CacheResults --> SaveProfile[Save to Database] SaveProfile --> CreateFreelancer{Freelancer
Exists?} CreateFreelancer -->|No| NewFreelancer[Create Freelancer
Profile] CreateFreelancer -->|Yes| UpdateFreelancer[Update Existing
Freelancer] NewFreelancer --> SaveComponents[Save Components:
- ContactInformation
- Education entries
- WorkExperience entries
- Skills & Languages
- Certifications] UpdateFreelancer --> SaveComponents SaveComponents --> GenerateEmbed[Generate Embeddings
for Semantic Search] GenerateEmbed --> WorkExpEmbed[Work Experience
Embeddings] GenerateEmbed --> SkillEmbed[Skill Type
Embeddings] WorkExpEmbed --> IndexPgVector[Index in pgvector
HNSW Index] SkillEmbed --> IndexPgVector CeleryTask --> StatusUpdate[Update Task Status:
PENDING → STARTED → SUCCESS/FAILURE] StatusUpdate --> NotifyUser[Notify User
of Completion] Onboard --> GenQuestions[Generate Onboarding
Questions via LLM] GenQuestions --> AnswerQuestions[User Answers
Questions] AnswerQuestions --> UpdateProfile[Update Profile
with Answers] UpdateProfile --> SaveComponents IndexPgVector --> Complete([Profile Ready
for Matching]) classDef startEnd fill:#e1f5fe,stroke:#01579b,stroke-width:2px classDef process fill:#fff3e0,stroke:#ef6c00,stroke-width:2px classDef decision fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px classDef cache fill:#ffecb3,stroke:#f57f17,stroke-width:2px classDef extraction fill:#fce4ec,stroke:#c2185b,stroke-width:2px classDef embedding fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px class Start,Complete startEnd class Dashboard,CreateDoc,SaveProfile,NewFreelancer,UpdateFreelancer,SaveComponents process class Auth,UploadChoice,CheckCache,CreateFreelancer decision class LoadCached,CacheResults cache class QueueTask,CeleryTask,AIDPProcess,ExtractData extraction class GenerateEmbed,WorkExpEmbed,SkillEmbed,IndexPgVector embedding

SearchSession State Machine

stateDiagram-v2 [*] --> Created: User initiates JD creation Created --> Active: User starts interaction Active --> Processing: Document uploaded Processing --> Active: Extraction complete Active --> Searching: Search triggered Searching --> Results: Search complete Results --> Active: Refine search Active --> Saved: Anonymous user saves Active --> Completed: User satisfied Processing --> Failed: Extraction error Searching --> Failed: Search error Failed --> Active: Retry action Completed --> [*] Saved --> [*] note right of Created pristine = true filters = {} llm_ctx = {} end note note right of Active pristine = false Chat history accumulating Filters being refined end note note right of Processing JobDescriptionDocument task_status = STARTED AIDP extraction running end note note right of Results Freelancers displayed Bookmarks available Notes can be added end note

System Architecture

Backend Architecture Overview

graph TB subgraph "Client Layer" Web[Web Browser] Mobile[Mobile App] end subgraph "Frontend Layer" React[React 19 + TypeScript] Vite[Vite Build System] TanStack[TanStack Query] end subgraph "API Layer" Django[Django 5.2] DRF[Django REST Framework] OpenAPI[OpenAPI Schema] end subgraph "Business Logic" SearchEngine[Semantic Search Engine] LLMChat[LLM Chat System] AIDPExtractor[AIDP Extractor] end subgraph "Data Layer" PostgreSQL[(PostgreSQL
+ pgvector)] Redis[(Redis Cache)] FileStorage[File Storage] end subgraph "Background Tasks" Celery[Celery Workers] Flower[Flower Monitor] end subgraph "AI Services" OpenRouter[OpenRouter API] Embeddings[Embedding Service] Phoenix[Phoenix Observability] end Web --> React Mobile --> React React --> TanStack TanStack --> OpenAPI OpenAPI --> DRF DRF --> Django Django --> SearchEngine Django --> LLMChat Django --> AIDPExtractor SearchEngine --> PostgreSQL SearchEngine --> Embeddings LLMChat --> OpenRouter LLMChat --> Redis AIDPExtractor --> Celery Celery --> Redis Celery --> PostgreSQL Django --> FileStorage Celery -.-> Flower LLMChat -.-> Phoenix classDef frontend fill:#61dafb,color:#000 classDef backend fill:#092e20,color:#fff classDef database fill:#336791,color:#fff classDef cache fill:#dc382d,color:#fff classDef worker fill:#37814a,color:#fff classDef ai fill:#ff6b35,color:#fff class React,Vite,TanStack frontend class Django,DRF,SearchEngine,LLMChat,AIDPExtractor backend class PostgreSQL,FileStorage database class Redis cache class Celery,Flower worker class OpenRouter,Embeddings,Phoenix ai

Technology Stack

Frontend

React 19
TypeScript
Vite

Backend

Django 5.2
Django REST
Celery

Data

PostgreSQL
pgvector
Redis

Data Models

Entity Relationship Diagram

erDiagram User ||--o| Freelancer : has User ||--o{ SearchSession : creates Freelancer ||--o{ ResumeDocument : uploads Freelancer ||--o| ContactInformation : has Freelancer ||--o{ Education : has Freelancer ||--o{ WorkExperienceEntry : has Freelancer ||--o{ FreelancerSkill : has Freelancer ||--o{ FreelancerLanguageSkill : has Freelancer ||--o{ FreelancerCertification : has SearchSession ||--|| JobDescription : contains SearchSession ||--o{ SearchSessionBookmark : has SearchSession ||--o{ SearchSessionNote : has SearchSession ||--o{ SavedJobDescription : saved_by JobDescription ||--o{ JobDescriptionDocument : has WorkExperienceEntry ||--o{ ResponsibilityActivity : contains FreelancerSkill }o--|| SkillType : references FreelancerLanguageSkill }o--|| Language : references FreelancerCertification }o--|| CertificationType : references User { uuid id PK string email string name boolean is_freelancer boolean is_client datetime created_at datetime updated_at } Freelancer { uuid id PK uuid user_id FK string name string nationality string academic_title vector embedding datetime created_at datetime updated_at } SearchSession { uuid id PK uuid user_id FK string name json filters json state json llm_ctx boolean pristine datetime created_at datetime updated_at } JobDescription { uuid id PK uuid search_session_id FK string title text description json requirements datetime created_at datetime updated_at } ResumeDocument { uuid id PK uuid freelancer_id FK file document string file_checksum string task_status json task_details text resume_content datetime created_at datetime updated_at } ContactInformation { uuid id PK uuid freelancer_id FK string phone text address string website string linkedin datetime created_at datetime updated_at } Education { uuid id PK uuid freelancer_id FK string degree string institution string field_of_study date start_date date end_date datetime created_at datetime updated_at } WorkExperienceEntry { uuid id PK uuid freelancer_id FK string company string position text description date start_date date end_date vector embedding datetime created_at datetime updated_at }

Key Model Relationships

User & Authentication

Custom user model extending AbstractUser with support for both client and freelancer roles. OAuth integration with LinkedIn for streamlined registration.

class User(AbstractUser):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    email = models.EmailField(unique=True)
    is_freelancer = models.BooleanField(default=False)
    is_client = models.BooleanField(default=False)

Search & Matching

SearchSession tracks search state and chat history with 1:1 relationship to JobDescription. Supports both authenticated and anonymous users.

class SearchSession(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    user = models.ForeignKey(User, null=True, blank=True)
    filters = models.JSONField(default=dict)
    state = models.JSONField(default=dict)
    llm_ctx = models.JSONField(default=dict)
    pristine = models.BooleanField(default=True)

Freelancer Profile

Comprehensive freelancer profile with embeddings for semantic search. Related models for education, experience, skills, and certifications.

class Freelancer(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    user = models.OneToOneField(User)
    name = models.CharField(max_length=255)
    nationality = models.CharField(max_length=100)
    academic_title = models.CharField(max_length=255)
    embedding = VectorField(dimensions=1536)

API Documentation

Client APIs

Freelancer APIs

Chat APIs

POST /api/v1/freelancers/search-sessions/ Create new search session

Request Body

{
  "name": "Senior Backend Developer Search",
  "filters": {
    "skills": ["Python", "Django", "PostgreSQL"],
    "experience_years": 5,
    "location": "Remote"
  }
}

Response

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Senior Backend Developer Search",
  "filters": {},
  "state": {},
  "pristine": true,
  "created_at": "2024-01-15T10:30:00Z"
}
GET /api/v1/freelancers/search-sessions/{id}/ Get search session details

Response

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Senior Backend Developer Search",
  "filters": {
    "skills": ["Python", "Django"],
    "experience_years": 5
  },
  "state": {
    "search_performed": true,
    "results_count": 24
  },
  "job_description": {
    "title": "Senior Backend Developer",
    "description": "Looking for experienced developer..."
  }
}
POST /api/v1/freelancers/search-sessions/{id}/results/ Execute semantic search

Request Body

{
  "query": "Experienced Python developer with Django expertise",
  "filters": {
    "skills": ["Python", "Django", "REST API"],
    "min_experience": 3,
    "max_experience": 10,
    "availability": "full-time"
  },
  "page": 1,
  "limit": 20
}

Response

{
  "results": [
    {
      "freelancer_id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "John Doe",
      "title": "Senior Python Developer",
      "skills": ["Python", "Django", "PostgreSQL"],
      "experience_years": 7,
      "similarity_score": 0.95,
      "profile_summary": "Experienced backend developer..."
    }
  ],
  "total": 45,
  "page": 1,
  "limit": 20,
  "has_next": true
}
POST /resume/upload/ Upload single resume

Request (multipart/form-data)

curl -X POST \
  -F "document=@resume.pdf" \
  -F "freelancer_id=550e8400-e29b-41d4-a716-446655440000" \
  /resume/upload/

Response

{
  "resume_id": "789e0123-e45b-67c8-d901-234567890123",
  "status": "processing",
  "message": "Resume uploaded successfully. Processing started.",
  "task_id": "celery-task-456",
  "redirect_url": "/resume/check-status/?id=789e0123-e45b-67c8-d901-234567890123"
}
GET /resume/check-status/?id={id} Check processing status

Response (Processing)

{
  "status": "STARTED",
  "progress": 45,
  "message": "Extracting work experience...",
  "estimated_completion": "2024-01-15T10:33:00Z"
}

Response (Completed)

{
  "status": "SUCCESS",
  "progress": 100,
  "message": "Resume processed successfully",
  "freelancer": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Jane Smith",
    "skills_extracted": 15,
    "experience_entries": 4,
    "education_entries": 2
  }
}
POST /api/v1/llm-chat/chat/ Send chat message

Request Body

{
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "message": "I need a Python developer with 5+ years experience",
  "mode": "edit_job_description",
  "context": {
    "current_filters": {},
    "previous_messages": []
  }
}

Response

{
  "response": "I'll help you find Python developers with 5+ years of experience. Let me refine your job description...",
  "suggestions": [
    "Would you like to specify particular Python frameworks?",
    "What type of projects will they work on?",
    "Any preference for industry experience?"
  ],
  "updated_filters": {
    "skills": ["Python"],
    "min_experience": 5
  },
  "message_id": "msg_789"
}
WebSocket /ws/llm-chat/{mode}/ Real-time chat stream

WebSocket Message

{
  "type": "chat_message",
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "message": "Show me freelancers who match these requirements",
  "timestamp": "2024-01-15T10:30:00Z"
}

Streaming Response

{
  "type": "token",
  "content": "I found 12 freelancers who match your requirements. Here are the top candidates:",
  "message_id": "msg_790"
}

{
  "type": "freelancer_results",
  "results": [...]
}

{
  "type": "message_complete",
  "message_id": "msg_790"
}

Team Collaboration

Development Team Workspace

A
B
C
D

Recent Activity

A
Alice Johnson commented on Client Flow Diagram
2 minutes ago
B
Bob Wilson added annotation to API Documentation
5 minutes ago
C
Charlie Davis updated Architecture Diagram
12 minutes ago

Comments & Discussions

A
Alice Johnson 10 minutes ago
The client flow looks good, but should we add error handling for upload failures?
B
Bob Wilson 8 minutes ago
@Alice Good point! I'll add that to the edge cases section. We should also consider rate limiting scenarios.
U

Team Members

A
Alice Johnson
Lead Backend Developer
Online - Working on API design
B
Bob Wilson
Frontend Architect
Online - Reviewing user flows
C
Charlie Davis
DevOps Engineer
Away - In meeting until 3:00 PM
D
Diana Chen
Data Scientist
Offline - Last seen 2 hours ago