husseinelsaadi Claude Opus 4.8 commited on
Commit
981366b
Β·
1 Parent(s): c3ec385

Pre-seed demo candidate interviews so HR dashboard is always populated

Browse files

The SQLite DB on the Space is ephemeral, so live interviews are wiped on
restart, leaving the HR dashboard empty. Seed two completed interviews
for the demo candidate (candidate@codingo.ai) on the Data Scientist and
Data Engineer jobs (both owned by hr@codingo.ai), with realistic Q&A,
evaluations and matching skills. Idempotent per (candidate, job).

Now logging into the HR account always shows candidates with working
Download Report (PDF) buttons, regardless of restarts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files changed (1) hide show
  1. backend/models/database.py +92 -0
backend/models/database.py CHANGED
@@ -249,6 +249,98 @@ def seed_demo_data():
249
  num_questions=4,
250
  ))
251
  db.session.commit()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  except Exception as exc:
253
  # Never let seeding break startup.
254
  db.session.rollback()
 
249
  num_questions=4,
250
  ))
251
  db.session.commit()
252
+
253
+ # --- Pre-seed completed demo interviews for the demo candidate so the
254
+ # HR dashboard is always populated even after a restart (the SQLite
255
+ # DB is ephemeral on Hugging Face). Idempotent per (candidate, job):
256
+ # a row is only created when one does not already exist. ---
257
+ demo_interviews = [
258
+ {
259
+ 'role': 'Data Scientist',
260
+ 'skills': ['Python', 'SQL', 'Pandas', 'scikit-learn',
261
+ 'Machine Learning', 'Data Visualization'],
262
+ 'experience': [
263
+ 'Data Analyst at BrightData (2 years) β€” built dashboards and predictive models',
264
+ 'Machine Learning Intern at NorthBridge Analytics β€” customer churn prediction',
265
+ ],
266
+ 'education': ['BSc in Computer Science, USAL'],
267
+ 'qa_log': [
268
+ {
269
+ 'question': "Hi, I'm LUNA, your AI recruiter. Can you tell me about your background and what drew you to data science?",
270
+ 'answer': "I have around three years working with data. I started as a data analyst building dashboards, then moved into machine learning where I built churn and forecasting models in Python with scikit-learn. I love data science because it turns messy data into decisions that actually move the business.",
271
+ 'evaluation': {'score': 'Excellent', 'feedback': 'Clear, specific background with concrete tools and real impact on the business.'},
272
+ },
273
+ {
274
+ 'question': "How do you prevent a model from overfitting?",
275
+ 'answer': "I use cross-validation to get an honest estimate of performance, keep the model as simple as the data allows, and apply regularization like L1 or L2. I also use more training data when possible, early stopping for neural nets, and I always compare training versus validation error to catch overfitting early.",
276
+ 'evaluation': {'score': 'Excellent', 'feedback': 'Covers cross-validation, regularization, and monitoring train/validation gap accurately.'},
277
+ },
278
+ {
279
+ 'question': "Walk me through a data science project you are proud of and the impact it had.",
280
+ 'answer': "At NorthBridge I built a customer churn model. I engineered features from usage logs, trained a gradient boosting model, and reached about 0.86 ROC-AUC. The retention team used the risk scores to target outreach and we reduced monthly churn by roughly 12 percent.",
281
+ 'evaluation': {'score': 'Good', 'feedback': 'Solid end-to-end project with a measurable result; could add more on validation and deployment.'},
282
+ },
283
+ {
284
+ 'question': "What are your salary expectations? Are you looking for a full-time or part-time role, and do you prefer remote or on-site work?",
285
+ 'answer': "I'm looking for a full-time role and I'm flexible on salary within the market range for a mid-level data scientist. I'm happy with hybrid or on-site, and comfortable fully remote as well.",
286
+ 'evaluation': {'score': 'Excellent', 'feedback': 'Clear, reasonable and flexible answer on logistics.'},
287
+ },
288
+ ],
289
+ },
290
+ {
291
+ 'role': 'Data Engineer',
292
+ 'skills': ['Python', 'SQL', 'Apache Spark', 'Airflow', 'ETL', 'AWS'],
293
+ 'experience': [
294
+ 'Data Engineer at Cloudbyte Systems (3 years) β€” built batch and streaming pipelines',
295
+ 'Backend Developer β€” automated ETL jobs and data quality checks',
296
+ ],
297
+ 'education': ['BSc in Software Engineering, USAL'],
298
+ 'qa_log': [
299
+ {
300
+ 'question': "Hi, I'm LUNA, your AI recruiter. Tell me about your experience and why data engineering?",
301
+ 'answer': "I've spent three years as a data engineer building pipelines in Python and Spark, orchestrated with Airflow on AWS. I enjoy data engineering because reliable, well-modeled data is what makes everything else β€” analytics and machine learning β€” actually work.",
302
+ 'evaluation': {'score': 'Excellent', 'feedback': 'Strong, specific experience with the exact stack the role needs.'},
303
+ },
304
+ {
305
+ 'question': "How do you design a reliable ETL pipeline?",
306
+ 'answer': "I make each step idempotent so re-runs are safe, add schema validation and data quality checks early, and design for incremental loads instead of full reloads. I orchestrate with Airflow, add retries and alerting on failures, and keep raw data so I can reprocess if logic changes.",
307
+ 'evaluation': {'score': 'Excellent', 'feedback': 'Idempotency, validation, incremental loads and observability β€” a complete, senior answer.'},
308
+ },
309
+ {
310
+ 'question': "Describe a time you optimized a slow data pipeline.",
311
+ 'answer': "A nightly Spark job was taking over four hours. I found it was shuffling too much data, so I repartitioned on the join key, cached a reused dataframe, and switched some wide transformations to broadcast joins. It dropped to about forty minutes.",
312
+ 'evaluation': {'score': 'Good', 'feedback': 'Concrete optimization with a real result; could mention profiling and cost trade-offs.'},
313
+ },
314
+ {
315
+ 'question': "What are your salary expectations? Are you looking for a full-time or part-time role, and do you prefer remote or on-site work?",
316
+ 'answer': "Full-time, and I'm open on compensation within the senior data engineer range. I prefer hybrid but I'm fully comfortable working remotely.",
317
+ 'evaluation': {'score': 'Excellent', 'feedback': 'Direct and flexible on role type, pay and location.'},
318
+ },
319
+ ],
320
+ },
321
+ ]
322
+
323
+ for spec in demo_interviews:
324
+ job = Job.query.filter_by(role=spec['role'], recruiter_id=recruiter.id).first()
325
+ if job is None:
326
+ continue
327
+ existing = Application.query.filter_by(user_id=applicant.id, job_id=job.id).first()
328
+ if existing is not None:
329
+ continue
330
+ db.session.add(Application(
331
+ job_id=job.id,
332
+ user_id=applicant.id,
333
+ name=applicant.username,
334
+ email=applicant.email,
335
+ status='interviewed',
336
+ extracted_features=json.dumps({
337
+ 'skills': spec['skills'],
338
+ 'experience': spec['experience'],
339
+ 'education': spec['education'],
340
+ }),
341
+ interview_log=json.dumps(spec['qa_log'], ensure_ascii=False),
342
+ ))
343
+ db.session.commit()
344
  except Exception as exc:
345
  # Never let seeding break startup.
346
  db.session.rollback()