From 9198e1819f4b8c4318ea172ee1226dcee4d6088f Mon Sep 17 00:00:00 2001 From: Dharshin1 Date: Mon, 18 May 2026 09:58:30 +0530 Subject: [PATCH 1/6] Add Go language detection to explanation engine --- backend/app/services/code_assistant.py | 4 ++++ backend/tests/test_endpoints.py | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/backend/app/services/code_assistant.py b/backend/app/services/code_assistant.py index 81023339..9d33a0d6 100644 --- a/backend/app/services/code_assistant.py +++ b/backend/app/services/code_assistant.py @@ -33,6 +33,10 @@ r"#include\s*<", r"\bstd::\w+", r"\bcout\s*<<", r"\bint\s+main\s*\(", r"::\w+", ], + "Go": [ + r"\bfunc\s+\w+\s*\(", r"\bpackage\s+\w+", r"\bimport\s+\"", + r"fmt\.Print", r"\bgo\s+func\b", r":=", + ], } diff --git a/backend/tests/test_endpoints.py b/backend/tests/test_endpoints.py index 70cc2cc5..378ed366 100644 --- a/backend/tests/test_endpoints.py +++ b/backend/tests/test_endpoints.py @@ -116,6 +116,27 @@ def test_explanation_too_long(): r = client.post("/explanation/", json={"code": "x" * 60000}) assert r.status_code == 422 +def test_explanation_go_language(): + code = """ + package main + + import "fmt" + + func main() { + fmt.Println("Hello Go") + x := 10 + go func() { + fmt.Println(x) + }() + } + """ + + r = client.post("/explanation/", json={"code": code, "language": "go"}) + assert r.status_code == 200 + d = r.json() + assert d["language"] == "Go" + assert "summary" in d + assert isinstance(d["key_points"], list) # ── Debugging ───────────────────────────────────────────────────────────────── def test_debug_detects_zero_division(): From eecde9eb3249a94140a09a3dc12c4d450c4f0659 Mon Sep 17 00:00:00 2001 From: Dharshin1 Date: Mon, 18 May 2026 10:16:29 +0530 Subject: [PATCH 2/6] Fixed lint error in code --- backend/app/services/code_assistant.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/services/code_assistant.py b/backend/app/services/code_assistant.py index 9d33a0d6..b3681a0e 100644 --- a/backend/app/services/code_assistant.py +++ b/backend/app/services/code_assistant.py @@ -35,7 +35,7 @@ ], "Go": [ r"\bfunc\s+\w+\s*\(", r"\bpackage\s+\w+", r"\bimport\s+\"", - r"fmt\.Print", r"\bgo\s+func\b", r":=", + r"fmt\.Print", r"\bgo\s+func\b", r":=", ], } From 2e0e1a25b2487bf195660532f66871e68812b6c0 Mon Sep 17 00:00:00 2001 From: Dharshin1 Date: Thu, 21 May 2026 11:41:44 +0530 Subject: [PATCH 3/6] Fix remaining Ruff lint issues --- backend/tests/test_endpoints.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/tests/test_endpoints.py b/backend/tests/test_endpoints.py index 378ed366..11ce85c1 100644 --- a/backend/tests/test_endpoints.py +++ b/backend/tests/test_endpoints.py @@ -2,10 +2,10 @@ QyverixAI — Test Suite Run: cd backend && pytest -v """ -import pytest from fastapi.testclient import TestClient -import sys, os +import sys +import os sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from app.main import app From 567aa568b964ddde1c8dc4eb0a5c80ebfab691dc Mon Sep 17 00:00:00 2001 From: Dharshin1 Date: Thu, 21 May 2026 11:51:54 +0530 Subject: [PATCH 4/6] Resolve merge conflicts in code_assistant --- backend/app/services/code_assistant.py | 55 ++++++++++++++++---------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/backend/app/services/code_assistant.py b/backend/app/services/code_assistant.py index b3681a0e..cbb93db9 100644 --- a/backend/app/services/code_assistant.py +++ b/backend/app/services/code_assistant.py @@ -12,30 +12,45 @@ # ── Language Detection ───────────────────────────────────────────────────────── LANG_SIGNATURES: dict[str, list[str]] = { - "Python": [ - r"\bdef\s+\w+\s*\(", r"\bimport\s+\w+", r"\bprint\s*\(", - r":\s*$", r"\belif\b", r"\bself\b", r"#.*", r"\bNone\b", - ], - "JavaScript": [ - r"\bconst\b|\blet\b|\bvar\b", r"function\s+\w+\s*\(", - r"=>\s*[{(]", r"console\.log\(", r"require\(", r"export\s+(default|const)", + "C++": [ + r"#include\s*<", r"\bstd::\w+", r"\bcout\s*<<", + r"\bint\s+main\s*\(", r"::\w+", ], - "TypeScript": [ - r":\s*(string|number|boolean|any|void|never)\b", - r"\binterface\s+\w+", r"\btype\s+\w+\s*=", - r"<\w+>", r"as\s+\w+", r"readonly\s+\w+", + + "Go": [ + r"\bfunc\s+\w+\s*\(", + r"\bpackage\s+\w+", + r"\bimport\s+\"", + r"fmt\.Print", + r"\bgo\s+func\b", + r":=", ], - "Java": [ - r"\bpublic\s+(class|void|static)\b", r"\bSystem\.out\.print", - r"\bimport\s+java\.", r"@Override", r"\bnew\s+\w+\s*\(", + + "PHP": [ + r"<\?php", + r"\$\w+\s*=", + r"\becho\s+", + r"\bfunction\s+\w+\s*\(", + r"\barray\s*\(", + r"->\w+", ], - "C++": [ - r"#include\s*<", r"\bstd::\w+", r"\bcout\s*<<", - r"\bint\s+main\s*\(", r"::\w+", + + "Rust": [ + r"\bfn\s+\w+\s*\(", + r"\blet\s+mut\b", + r"\buse\s+std::", + r"println!\(", + r"\bimpl\b", + r"\bOption<\w+>", ], - "Go": [ - r"\bfunc\s+\w+\s*\(", r"\bpackage\s+\w+", r"\bimport\s+\"", - r"fmt\.Print", r"\bgo\s+func\b", r":=", + + "Kotlin": [ + r"\bfun\s+\w+\s*\(", + r"\bval\s+\w+", + r"\bvar\s+\w+", + r"println\s*\(", + r"data\s+class\s+\w+", + r":\s*\w+\s*\?", ], } From 0a03dd39ff28752362c5f9b6af8311581af81707 Mon Sep 17 00:00:00 2001 From: Dharshin1 Date: Mon, 25 May 2026 16:53:41 +0530 Subject: [PATCH 5/6] fix: resolve lint and rebase issues --- backend/app/routers/analyze.py | 1 + backend/app/routers/share.py | 50 +++++++++++++++++++++------ backend/app/services/email_service.py | 16 ++++----- backend/tests/test_digest.py | 3 +- backend/tests/test_endpoints.py | 5 ++- backend/tests/test_share.py | 2 +- 6 files changed, 54 insertions(+), 23 deletions(-) diff --git a/backend/app/routers/analyze.py b/backend/app/routers/analyze.py index 495ec5df..022c583a 100644 --- a/backend/app/routers/analyze.py +++ b/backend/app/routers/analyze.py @@ -1,4 +1,5 @@ """Full analysis router - POST /analyze/ and POST /analyze/zip/.""" + from __future__ import annotations import time diff --git a/backend/app/routers/share.py b/backend/app/routers/share.py index da1a100f..46978153 100644 --- a/backend/app/routers/share.py +++ b/backend/app/routers/share.py @@ -23,13 +23,18 @@ def create_share(payload: ShareCreateRequest, db: Session = Depends(get_db)): token = "" for _ in range(5): candidate = secrets.token_urlsafe(8) - exists = db.execute(select(SharedSnippet).where(SharedSnippet.token == candidate)).scalar_one_or_none() + exists = db.execute( + select(SharedSnippet).where(SharedSnippet.token == candidate) + ).scalar_one_or_none() if exists is None: token = candidate break if not token: - raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Could not create share token") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Could not create share token", + ) record = SharedSnippet( token=token, @@ -56,13 +61,24 @@ def get_share(token: str, db: Session = Depends(get_db)): _Base.metadata.create_all(bind=db.get_bind()) - record = db.execute(select(SharedSnippet).where(SharedSnippet.token == token)).scalar_one_or_none() + record = db.execute( + select(SharedSnippet).where(SharedSnippet.token == token) + ).scalar_one_or_none() if record is None: # fallback: try raw SQL in case ORM mapping/env differences hide the record from sqlalchemy import text - raw = db.execute(text("SELECT token, code, result_json, created_at FROM shares WHERE token = :t"), {"t": token}).first() + + raw = db.execute( + text( + "SELECT token, code, result_json, created_at FROM shares WHERE token = :t" + ), + {"t": token}, + ).first() if raw is None: - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Shared result not found or expired") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Shared result not found or expired", + ) # parse created_at which may be string or datetime token_val, code_val, result_json_val, created_at_val = raw @@ -74,20 +90,32 @@ def get_share(token: str, db: Session = Depends(get_db)): created_at = _dt.datetime.fromisoformat(created_at) except Exception: try: - created_at = _dt.datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S.%f") + created_at = _dt.datetime.strptime( + created_at, "%Y-%m-%d %H:%M:%S.%f" + ) except Exception: created_at = None if created_at is None: - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Shared result not found or expired") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Shared result not found or expired", + ) if created_at.tzinfo is None: created_at = created_at.replace(tzinfo=_dt.timezone.utc) if created_at < _dt.datetime.now(_dt.timezone.utc) - _dt.timedelta(days=7): - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Shared result expired") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Shared result expired" + ) - return ShareRecord(id=token_val, code=code_val, result=json.loads(result_json_val), created_at=created_at.isoformat()) + return ShareRecord( + id=token_val, + code=code_val, + result=json.loads(result_json_val), + created_at=created_at.isoformat(), + ) # expire shares older than 7 days — normalize tzinfo if necessary from datetime import datetime, timezone, timedelta @@ -97,7 +125,9 @@ def get_share(token: str, db: Session = Depends(get_db)): created_at = created_at.replace(tzinfo=timezone.utc) if created_at < datetime.now(timezone.utc) - timedelta(days=7): - raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Shared result expired") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="Shared result expired" + ) return ShareRecord( id=record.token, diff --git a/backend/app/services/email_service.py b/backend/app/services/email_service.py index 42716064..3c977fb1 100644 --- a/backend/app/services/email_service.py +++ b/backend/app/services/email_service.py @@ -156,7 +156,7 @@ def _build_html(stats: dict, unsubscribe_url: str) -> str: score_line = f""" Average Score - {stats['avg_score']}/100 {emoji}{change} + {stats["avg_score"]}/100 {emoji}{change} """ bug_line = "" @@ -164,7 +164,7 @@ def _build_html(stats: dict, unsubscribe_url: str) -> str: bug_line = f""" Most Common Bug - {stats['top_bug']} + {stats["top_bug"]} """ return f""" @@ -176,32 +176,32 @@ def _build_html(stats: dict, unsubscribe_url: str) -> str:

QyverixAI Weekly Digest

-

{stats['week_start']} – {stats['week_end']}

+

{stats["week_start"]} – {stats["week_end"]}

Here's your weekly code analysis summary.

- + - + {score_line} - + {bug_line}
Analyses Run{stats['total_analyses']}{stats["total_analyses"]}
Languages{', '.join(stats['languages'])}{", ".join(stats["languages"])}
Issues Found{stats['total_issues']}{stats["total_issues"]}
- Open QyverixAI + Open QyverixAI
-

This email was sent to {stats['email']} because you subscribed to the QyverixAI weekly digest.

+

This email was sent to {stats["email"]} because you subscribed to the QyverixAI weekly digest.

Unsubscribe

diff --git a/backend/tests/test_digest.py b/backend/tests/test_digest.py index 698acdd7..1e3231f1 100644 --- a/backend/tests/test_digest.py +++ b/backend/tests/test_digest.py @@ -8,7 +8,8 @@ from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -import sys, os +import sys +import os sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) diff --git a/backend/tests/test_endpoints.py b/backend/tests/test_endpoints.py index d0574303..7b75f6c2 100644 --- a/backend/tests/test_endpoints.py +++ b/backend/tests/test_endpoints.py @@ -2,12 +2,11 @@ QyverixAI — Test Suite Run: cd backend && pytest -v """ -import io -import zipfile import pytest from fastapi.testclient import TestClient -import sys, os +import sys +import os sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from app import main as app_main diff --git a/backend/tests/test_share.py b/backend/tests/test_share.py index 22826e0b..b3bcbe16 100644 --- a/backend/tests/test_share.py +++ b/backend/tests/test_share.py @@ -25,7 +25,7 @@ def _configure_test_db(monkeypatch, tmp_path): def test_create_and_fetch_share(monkeypatch, tmp_path): - session_local = _configure_test_db(monkeypatch, tmp_path) + _configure_test_db(monkeypatch, tmp_path) from fastapi.testclient import TestClient From 3496e8b9a085479a33366dfd4278cc1b9008e01f Mon Sep 17 00:00:00 2001 From: Dharshin1 Date: Tue, 26 May 2026 21:51:39 +0530 Subject: [PATCH 6/6] Fix Swift language detection --- backend/app/services/code_assistant.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/backend/app/services/code_assistant.py b/backend/app/services/code_assistant.py index 58b5561b..9828e714 100644 --- a/backend/app/services/code_assistant.py +++ b/backend/app/services/code_assistant.py @@ -11,6 +11,17 @@ # ── Language Detection ───────────────────────────────────────────────────────── LANG_SIGNATURES: dict[str, list[str]] = { + "Swift": [ + r"\bimport\s+Foundation\b", + r"\bfunc\s+\w+\s*\(", + r"\b(let|var)\s+\w+\s*:\s*\w+", + r"\bclass\s+\w+", + r"\bstruct\s+\w+", + r"\bprotocol\s+\w+", + r"\bextension\s+\w+", + r"\bguard\s+let\b", + r"\bprint\s*\(", + ], "Python": [ r"\bdef\s+\w+\s*\(", r"\bimport\s+\w+", @@ -214,6 +225,7 @@ class BugPattern: "C++", "PHP", "Rust", + "Swift", ] )