yoursdvniel commited on
Commit
383eb71
·
verified ·
1 Parent(s): f1ac8ee

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +40 -18
main.py CHANGED
@@ -558,38 +558,58 @@ def _extract_sme_doc_text(filename: str, file_bytes: bytes) -> str:
558
 
559
  return ""
560
 
561
-
562
- def _fetch_active_programs(company_code: str) -> List[Dict[str, Any]]:
563
  try:
564
- docs = (
565
- db.collection("programs")
566
- .where("companyCode", "==", company_code)
567
- .stream()
568
- )
 
569
 
570
  programs = []
 
571
  for doc_snap in docs:
572
  data = doc_snap.to_dict() or {}
573
  status = _norm(data.get("status") or data.get("programStatus"))
 
574
  if status and status not in ["active", "open", "running"]:
575
  continue
576
 
 
 
577
  programs.append({
578
  "id": doc_snap.id,
579
- "name": data.get("name") or data.get("programName") or data.get("title") or "",
 
580
  "description": data.get("description") or "",
581
- "sector": data.get("sector") or data.get("targetSector") or "",
582
- "stage": data.get("stage") or data.get("targetStage") or "",
583
- "branch": data.get("assignedBranch") or data.get("branch") or "",
584
- "requirements": data.get("requirements") or [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  })
586
 
587
- return programs[:30]
 
588
  except Exception as e:
589
  print("fetch_active_programs_failed:", e)
590
  return []
591
 
592
-
593
  def _fetch_intervention_catalog(company_code: str) -> List[Dict[str, Any]]:
594
  try:
595
  docs = (
@@ -717,7 +737,10 @@ Rules:
717
  - urgent/high urgency should be used where compliance, tax, funding, payroll, legal, safety, or survival risks are clear.
718
  - Recommend interventions only from the intervention catalog where possible.
719
  - Recommend one program from availablePrograms where possible.
720
- - If no program fits, leave recommendedProgramId blank and explain in summary.
 
 
 
721
  - benefitsOfProgram must explain why structured incubation helps.
722
  - benefitsOfAgents must explain why direct agent support helps without programme onboarding.
723
  - Keep text professional and concise.
@@ -1339,15 +1362,14 @@ def analyze_sme_application_intake():
1339
  """
1340
  try:
1341
  mode = request.form.get("mode") or "initial_review"
1342
- company_code = request.form.get("companyCode")
1343
  user_id = request.form.get("userId") or ""
1344
  contact_name = request.form.get("contactName") or ""
1345
  contact_email = request.form.get("email") or request.form.get("contactEmail") or ""
1346
  contact_phone = request.form.get("contactPhone") or ""
1347
  raw_story = (request.form.get("rawStory") or "").strip()
1348
 
1349
- if not company_code:
1350
- return jsonify({"error": "Missing companyCode"}), 400
1351
 
1352
  if not raw_story:
1353
  return jsonify({"error": "Missing rawStory"}), 400
 
558
 
559
  return ""
560
 
561
+ def _fetch_active_programs(company_code: Optional[str] = None) -> List[Dict[str, Any]]:
 
562
  try:
563
+ ref = db.collection("programs")
564
+
565
+ if company_code:
566
+ docs = ref.where("companyCode", "==", company_code).stream()
567
+ else:
568
+ docs = ref.stream()
569
 
570
  programs = []
571
+
572
  for doc_snap in docs:
573
  data = doc_snap.to_dict() or {}
574
  status = _norm(data.get("status") or data.get("programStatus"))
575
+
576
  if status and status not in ["active", "open", "running"]:
577
  continue
578
 
579
+ eligibility = data.get("eligibilityCriteria") or {}
580
+
581
  programs.append({
582
  "id": doc_snap.id,
583
+ "companyCode": data.get("companyCode") or "",
584
+ "name": data.get("name") or "",
585
  "description": data.get("description") or "",
586
+ "type": data.get("type") or "",
587
+ "cohortYear": data.get("cohortYear") or "",
588
+ "startDate": to_jsonable(data.get("startDate")),
589
+ "endDate": to_jsonable(data.get("endDate")),
590
+ "maxCapacity": data.get("maxCapacity"),
591
+ "registrationLink": data.get("registrationLink") or "",
592
+ "eligibilityCriteria": eligibility,
593
+ "eligibilitySummary": {
594
+ "minimumAge": eligibility.get("minimumAge"),
595
+ "maximumAge": eligibility.get("maximumAge"),
596
+ "gender": eligibility.get("gender"),
597
+ "sector": eligibility.get("sector"),
598
+ "province": eligibility.get("province"),
599
+ "minYearsOfTrading": eligibility.get("minYearsOfTrading"),
600
+ "bbbeeLevel": eligibility.get("bbbeeLevel"),
601
+ "minYouthOwnershipPercent": eligibility.get("minYouthOwnershipPercent"),
602
+ "minBlackOwnershipPercent": eligibility.get("minBlackOwnershipPercent"),
603
+ "minFemaleOwnershipPercent": eligibility.get("minFemaleOwnershipPercent"),
604
+ },
605
  })
606
 
607
+ return programs[:50]
608
+
609
  except Exception as e:
610
  print("fetch_active_programs_failed:", e)
611
  return []
612
 
 
613
  def _fetch_intervention_catalog(company_code: str) -> List[Dict[str, Any]]:
614
  try:
615
  docs = (
 
737
  - urgent/high urgency should be used where compliance, tax, funding, payroll, legal, safety, or survival risks are clear.
738
  - Recommend interventions only from the intervention catalog where possible.
739
  - Recommend one program from availablePrograms where possible.
740
+ - Match programmes using eligibilityCriteria first, especially province, sector, gender, age, years of trading, B-BBEE level, youth ownership, black ownership, and female ownership.
741
+ - If the SME does not clearly meet a programme's eligibility criteria, do not force that programme.
742
+ - If required eligibility data is missing from the SME story, add friendly questions to missingFields.
743
+ - If no programme fits, leave recommendedProgramId blank and explain why in summary.
744
  - benefitsOfProgram must explain why structured incubation helps.
745
  - benefitsOfAgents must explain why direct agent support helps without programme onboarding.
746
  - Keep text professional and concise.
 
1362
  """
1363
  try:
1364
  mode = request.form.get("mode") or "initial_review"
1365
+ company_code = (request.form.get("companyCode") or "").strip()
1366
  user_id = request.form.get("userId") or ""
1367
  contact_name = request.form.get("contactName") or ""
1368
  contact_email = request.form.get("email") or request.form.get("contactEmail") or ""
1369
  contact_phone = request.form.get("contactPhone") or ""
1370
  raw_story = (request.form.get("rawStory") or "").strip()
1371
 
1372
+ # companyCode is optional for public/unregistered SME intake
 
1373
 
1374
  if not raw_story:
1375
  return jsonify({"error": "Missing rawStory"}), 400