File size: 7,827 Bytes
6464253
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# Mini-ATS Implementation Summary

## What Was Built

A complete single-file Streamlit application (`streamlit_app.py`) that transforms the original JD2GH candidate finder into a full-featured mini Applicant Tracking System (ATS).

## File Structure

```
/Users/amirsh/Documents/Repo/hack/
β”œβ”€β”€ streamlit_app.py          # Main application (~1800 lines, single file)
β”œβ”€β”€ requirements.txt           # Python dependencies
β”œβ”€β”€ .env                       # API keys (gitignored)
β”œβ”€β”€ .env.example              # Environment template
β”œβ”€β”€ README.md                 # Complete documentation
β”œβ”€β”€ run_streamlit.sh          # Startup script
β”œβ”€β”€ ats.db                    # SQLite database (auto-created)
└── venv/                     # Python virtual environment
```

## Key Features Implemented

### 1. Database Layer (SQLModel)

**7 Models with Timestamps:**
- `JobPosting` - Job details, parsed requirements, weights, stats
- `Candidate` - GitHub profiles, portfolios
- `JobCandidateMatch` - Per-job scoring, evidence, status
- `Invitation` - Tokenized invite links with expiry
- `AssessmentTemplate` - Test questions (Soft/Tech)
- `AssessmentAttempt` - Results, duration, anti-cheat metrics

**Database Functions:**
- `init_db()` - Auto-creates tables on startup
- `recalc_job_stats()` - Updates candidate counts
- Automatic timestamps (created_at, updated_at)

### 2. Utilities

**File Upload Support:**
- `extract_text_from_upload()` - Supports PDF, DOCX, MD, TXT
- Uses pypdf for PDF extraction
- Uses python-docx for Word documents

**Token Management:**
- `make_token()` - URL-safe invitation tokens
- `parse_token()` - Token validation and parsing

**JSON Helpers:**
- `json_dumps()` - Safe serialization
- `json_loads()` - Safe deserialization with defaults

### 3. AI & GitHub Integration

**Gemini Wrapper:**
- `gemini_extract_spec()` - Extracts structured JD data
- Returns: role, languages, topics, must_have, nice_to_have
- Lowercase normalization for matching

**GitHub Discovery:**
- `run_discovery_for_job()` - Reuses existing search_github_users()
- Scores candidates using existing score_user()
- Returns: login, name, location, followers, stars, portfolio, scores, evidence

**Assessment Templates:**
- `seed_assessment_templates()` - Creates default tests
- Soft Skills: 5 MCQs (7 minutes)
- Technical: 8 MCQs (20 minutes)

### 4. Multi-Page Navigation

**5 Pages:**

#### Dashboard
- Job posts, candidates, applied, tested metrics
- Active job listings table
- Click-through to other pages

#### Job Postings
- **New Job Tab:**
  - Form: title, city, synonyms, min repos
  - JD input: text area OR file upload
  - AI extraction with Gemini
  - Editable multiselect chips (languages, topics, must_have, nice_to_have)
  - Weight sliders (skills, activity, quality, completeness)
  - Save to database
  
- **Manage Tab:**
  - Card grid of existing jobs
  - Stats per job
  - Edit and delete buttons
  - "Open Dataset" β†’ navigates to Candidates

#### Candidates
- Job selector dropdown
- Config display (city, synonyms, min repos, skills)
- **Run/Refresh Discovery** button
  - Searches GitHub
  - Scores candidates
  - Upserts to database
- **Filters:**
  - "Has all must-haves" checkbox
  - "Active in last 90 days" checkbox
- **Top N Display:**
  - Slider to select top candidates
  - Profile cards with scores and evidence
  - **Invite button** β†’ generates token link
- **Full Dataset Table**
- **Export:** CSV and JSON download buttons

#### Tests (HR)
- Job selector
- Table of all assessment attempts
- Columns: login, name, kind, scores, duration, anti-cheat metrics, status
- Real-time view of candidate test results

#### Candidate Portal
- **Token-based access** via URL parameter
- **Profile Form:**
  - Name, email, LinkedIn, years experience
  - Save β†’ updates candidate record
  - Marks invitation as used
  - Updates match status to "APPLIED"
- **Assessment Buttons:**
  - Start Soft Skills Test (7 min)
  - Start Technical Test (20 min)
  - Shows completion status and scores
- **Active Assessment:**
  - Timer display (MM:SS countdown)
  - Auto-submit on timeout
  - Anti-cheat tracking display
  - MCQ questions with radio buttons
  - Submit button
  - Scoring with penalties
  - Updates match status to "TESTED"

### 5. Assessment System

**Features:**
- Timer with countdown display
- Auto-submit on timeout
- MCQ questions rendered from templates
- Lightweight anti-cheat JavaScript:
  - Tab switch detection (visibilitychange event)
  - Copy/paste blocking
- Scoring:
  - Soft: 2 points per question, max 10
  - Tech: Scaled to 10 points
  - Penalties: -1 for >2 tab switches, -1 for copy/paste
- Results stored in AssessmentAttempt table
- Job stats auto-updated

### 6. Reused Code

**From Original App:**
- `extract_jd_spec()` - Gemini extraction (kept as fallback)
- `search_github_users()` - GitHub GraphQL search (async)
- `score_user()` - Scoring algorithm with subscores
- All existing GitHub query logic
- All existing scoring formulas

**New Wrappers:**
- `gemini_extract_spec()` - Calls original, adds normalization
- `run_discovery_for_job()` - Orchestrates search + scoring

## Technical Constraints Met

βœ… **Single file** - Everything in streamlit_app.py  
βœ… **Reuse existing code** - All GitHub/Gemini functions preserved  
βœ… **SQLite + SQLModel** - Local persistence with ORM  
βœ… **Minimal dependencies** - Only added pypdf, python-docx  
βœ… **No email** - Copyable invitation links  
βœ… **Lightweight anti-cheat** - JavaScript event listeners  
βœ… **Simple UI** - Clean Streamlit components, no custom CSS  

## Dependencies Added

```
pypdf          # PDF text extraction
python-docx    # DOCX text extraction
```

(All others were already in requirements.txt)

## Testing Checklist

- [x] Database initialization on startup
- [x] Job creation with JD extraction
- [x] File upload (PDF, DOCX, MD, TXT)
- [x] Editable requirement chips
- [x] Weight sliders
- [x] GitHub discovery and scoring
- [x] Candidate filtering
- [x] Invitation generation
- [x] Token-based portal access
- [x] Profile form save
- [x] Assessment timer
- [x] MCQ rendering
- [x] Anti-cheat tracking
- [x] Assessment submission and scoring
- [x] Dashboard metrics
- [x] CSV/JSON export

## Usage Flow

1. **Start:** `./run_streamlit.sh` or `streamlit run streamlit_app.py`
2. **Create Job:** Job Postings β†’ New Job β†’ upload/paste JD β†’ extract β†’ edit β†’ save
3. **Find Candidates:** Candidates β†’ select job β†’ Run Discovery
4. **Invite:** Top N β†’ click Invite β†’ copy link
5. **Candidate Flow:** Opens link β†’ fills profile β†’ takes tests
6. **Review:** Tests (HR) β†’ view scores and anti-cheat data
7. **Track:** Dashboard β†’ see overall metrics

## Code Statistics

- **Total Lines:** ~1800
- **Models:** 7 SQLModel classes
- **Pages:** 5 Streamlit pages
- **Functions:** ~15 utility/wrapper functions
- **Reused:** 3 original functions (extract_jd_spec, search_github_users, score_user)
- **Database Tables:** 6 tables with auto-timestamps
- **Assessment Questions:** 13 total (5 soft + 8 tech)

## What Makes This a "Mini-ATS"

1. **Complete Lifecycle:** Discovery β†’ Invitation β†’ Application β†’ Assessment β†’ Review
2. **Database Persistence:** All data stored locally with relationships
3. **Multi-User Support:** Separate candidate portal vs HR views
4. **Assessment Platform:** Timed tests with scoring and anti-cheat
5. **Analytics:** Dashboard with KPIs and job stats
6. **Export:** CSV/JSON for external analysis

## Future Enhancements (Not Implemented)

- Email integration (SendGrid, AWS SES)
- PostgreSQL for multi-user/production
- Enterprise proctoring APIs
- Advanced analytics dashboard
- Video interviews
- ATS integrations (Greenhouse, Lever)
- Candidate pipeline stages
- Automated email campaigns