Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions docs/personalization_design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
\# AI-Driven Personalized Learning Path — Design Doc



\## Overview

This feature dynamically generates a personalized learning path for each user by detecting topic-wise weaknesses based on their performance and activity history.



\## Goals

\- Detect weak areas using performance analytics.

\- Recommend weekly personalized goals.

\- Increase engagement and retention.

\- Deliver smarter preparation paths via AI.



\## Scope (MVP)

\- Weakness detection using rule-based scoring.

\- Weekly roadmap with:

  - 2–3 weak topics to focus on.

  - Practice problems \& concept resources.

  - Progress tracking.



\## Data Schema

\*\*Events\*\*

```json

{

  "user\_id": "string",

  "activity\_type": "quiz|coding|mock",

  "topic": "arrays|dp|graphs|system-design",

  "subtopic": "two-pointer",

  "timestamp": "ISO8601",

  "accuracy": 0.85,

  "time\_taken\_seconds": 120,

  "attempts": 1,

  "difficulty": "easy|medium|hard",

  "exercise\_id": "string"

}
Comment on lines +37 to +65
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Event schema: add constraints and a few operational fields

To make downstream validation and analytics simpler, specify constraints and add a few commonly used fields.

Recommended refinements:

  • Constraints:
    • accuracy: float in [0.0, 1.0]
    • time_taken_seconds: non-negative int
    • attempts: int ≥ 1
    • difficulty: enum {easy, medium, hard}
    • activity_type: enum {quiz, coding, mock}
  • Additional fields:
    • event_id (string UUID)
    • session_id (string)
    • source (e.g., web/app)
    • platform (e.g., ios/android/web)
    • language (e.g., python/java)
    • version (client build/app version)

If you want, I can update the sample JSON here and mirror the same constraints in the FastAPI/Pydantic models.

🤖 Prompt for AI Agents
In docs/personalization_design.md around lines 37 to 65, the event schema lacks
explicit constraints and some useful operational fields. Update the JSON schema
to specify constraints such as accuracy being a float between 0.0 and 1.0,
time_taken_seconds as a non-negative integer, attempts as an integer greater or
equal to 1, and enums for difficulty and activity_type. Also, add additional
fields like event_id (UUID string), session_id, source, platform, language, and
version to improve validation and analytics clarity.

Comment on lines +41 to +65
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix: Close the JSON code fence to avoid broken Markdown rendering

The JSON example block is opened (Line 41) but not closed, which will break rendering for everything that follows.

Apply this diff to close the code fence:

   "exercise_id": "string"
 }
 
-
+```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```json
{
  "user\_id": "string",
  "activity\_type": "quiz|coding|mock",
  "topic": "arrays|dp|graphs|system-design",
  "subtopic": "two-pointer",
  "timestamp": "ISO8601",
  "accuracy": 0.85,
  "time\_taken\_seconds": 120,
  "attempts": 1,
  "difficulty": "easy|medium|hard",
  "exercise\_id": "string"
}
🤖 Prompt for AI Agents
In docs/personalization_design.md between lines 41 and 65, the JSON code block
is opened but not closed, causing broken Markdown rendering. Fix this by adding
a closing triple backtick (```) after the JSON example to properly close the
code fence.




69 changes: 69 additions & 0 deletions services/personalization/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---

## **2. Backend Starter (FastAPI)** — `services/personalization/app.py`
```python
Comment on lines +1 to +4
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: File contains Markdown wrappers (front-matter and code fences) and won’t import

There’s ---, a Markdown header, and a ```python fence inside a .py file, which causes SyntaxError (matches the static analysis hints).

Apply this diff to strip Markdown from the Python file:

---- 
-
-## **2. Backend Starter (FastAPI)** — `services/personalization/app.py`
-```python
+"""
+Personalization Service (FastAPI)
+"""
@@
-    return mock_roadmaps[user_id]
-```
+    return mock_roadmaps[user_id]

Also applies to: 69-69

🧰 Tools
🪛 Ruff (0.12.2)

1-2: SyntaxError: Expected an expression


4-4: SyntaxError: Got unexpected token `


4-4: SyntaxError: Got unexpected token `


4-4: SyntaxError: Got unexpected token `

🤖 Prompt for AI Agents
In services/personalization/app.py at the very beginning (lines 1 to 4) and at
line 69, remove all Markdown-specific syntax including the front-matter '---'
and the triple backticks ```python and ``` that are wrapping the Python code.
These Markdown wrappers cause syntax errors in the Python file. Ensure the file
contains only valid Python code without any Markdown formatting.

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List
from datetime import datetime

Comment on lines +6 to +9
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Strengthen imports for validation and enums

Use Pydantic Field for constraints and Enum for typed fields.

-from pydantic import BaseModel
-from typing import List
-from datetime import datetime
+from pydantic import BaseModel, Field
+from typing import List
+from datetime import datetime
+from enum import Enum
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from pydantic import BaseModel
from typing import List
from datetime import datetime
from pydantic import BaseModel, Field
from typing import List
from datetime import datetime
from enum import Enum
🤖 Prompt for AI Agents
In services/personalization/app.py around lines 6 to 9, the imports should be
enhanced by adding Pydantic's Field to enable validation constraints on model
fields and importing Enum from the enum module to define typed enumerations.
Update the import statements to include these for stronger data validation and
clearer type definitions.

app = FastAPI(title="Personalization Service")

# ---- Schemas ----
class Event(BaseModel):
user_id: str
activity_type: str
topic: str
subtopic: str
timestamp: datetime
accuracy: float
time_taken_seconds: int
attempts: int
difficulty: str
exercise_id: str

Comment on lines +13 to +24
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Schema hardening: enums and field constraints for Event

Constrain inputs to reduce bad data. Also future-proof for Pydantic v2 semantics.

-class Event(BaseModel):
-    user_id: str
-    activity_type: str
-    topic: str
-    subtopic: str
-    timestamp: datetime
-    accuracy: float
-    time_taken_seconds: int
-    attempts: int
-    difficulty: str
-    exercise_id: str
+class ActivityType(str, Enum):
+    quiz = "quiz"
+    coding = "coding"
+    mock = "mock"
+
+
+class Difficulty(str, Enum):
+    easy = "easy"
+    medium = "medium"
+    hard = "hard"
+
+
+class Event(BaseModel):
+    user_id: str
+    activity_type: ActivityType
+    topic: str
+    subtopic: str
+    timestamp: datetime
+    accuracy: float = Field(ge=0.0, le=1.0)
+    time_taken_seconds: int = Field(ge=0)
+    attempts: int = Field(ge=1)
+    difficulty: Difficulty
+    exercise_id: str
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class Event(BaseModel):
user_id: str
activity_type: str
topic: str
subtopic: str
timestamp: datetime
accuracy: float
time_taken_seconds: int
attempts: int
difficulty: str
exercise_id: str
class ActivityType(str, Enum):
quiz = "quiz"
coding = "coding"
mock = "mock"
class Difficulty(str, Enum):
easy = "easy"
medium = "medium"
hard = "hard"
class Event(BaseModel):
user_id: str
activity_type: ActivityType
topic: str
subtopic: str
timestamp: datetime
accuracy: float = Field(ge=0.0, le=1.0)
time_taken_seconds: int = Field(ge=0)
attempts: int = Field(ge=1)
difficulty: Difficulty
exercise_id: str
🤖 Prompt for AI Agents
In services/personalization/app.py around lines 13 to 24, the Event model fields
lack constraints and enums, which can lead to invalid data. Define enums for
fields like activity_type, difficulty, and possibly topic/subtopic if values are
known. Add field constraints such as min/max lengths for strings, positive
values for numeric fields, and use Pydantic's Field with appropriate validators.
This will harden the schema and prepare it for Pydantic v2 compatibility.

class Task(BaseModel):
description: str
completed: bool = False

class WeekPlan(BaseModel):
week_no: int
topics: List[str]
tasks: List[Task]
goal: str

class Roadmap(BaseModel):
user_id: str
weeks: List[WeekPlan]

# ---- Mock Database ----
mock_events = []
mock_roadmaps = {
"u1": Roadmap(
user_id="u1",
weeks=[
WeekPlan(
week_no=1,
topics=["arrays", "two-pointer"],
tasks=[
Task(description="Solve 3 practice problems"),
Task(description="Watch 2 concept videos"),
Task(description="Take revision quiz")
],
goal="Reach avg_accuracy ≥ 0.75"
)
]
)
}

# ---- Endpoints ----
@app.post("/events")
def add_event(event: Event):
mock_events.append(event.dict())
return {"message": "Event recorded", "total_events": len(mock_events)}
Comment on lines +60 to +63
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

POST /events: return 201 and prefer model_dump() in Pydantic v2

Status 201 is more accurate for creation; model_dump avoids v2 deprecation warnings.

If you chose “store models” (Option A above):

-@app.post("/events")
-def add_event(event: Event):
-    mock_events.append(event.dict())
-    return {"message": "Event recorded", "total_events": len(mock_events)}
+@app.post("/events", status_code=201)
+def add_event(event: Event):
+    mock_events.append(event)
+    return {"message": "Event recorded", "total_events": len(mock_events)}

If you prefer storing dicts:

-@app.post("/events")
-def add_event(event: Event):
-    mock_events.append(event.dict())
+@app.post("/events", status_code=201)
+def add_event(event: Event):
+    mock_events.append(event.model_dump())
     return {"message": "Event recorded", "total_events": len(mock_events)}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@app.post("/events")
def add_event(event: Event):
mock_events.append(event.dict())
return {"message": "Event recorded", "total_events": len(mock_events)}
@app.post("/events", status_code=201)
def add_event(event: Event):
mock_events.append(event)
return {"message": "Event recorded", "total_events": len(mock_events)}
Suggested change
@app.post("/events")
def add_event(event: Event):
mock_events.append(event.dict())
return {"message": "Event recorded", "total_events": len(mock_events)}
@app.post("/events", status_code=201)
def add_event(event: Event):
mock_events.append(event.model_dump())
return {"message": "Event recorded", "total_events": len(mock_events)}
🤖 Prompt for AI Agents
In services/personalization/app.py around lines 60 to 63, the POST /events
endpoint should return HTTP status 201 to indicate resource creation, and use
event.model_dump() instead of event.dict() to comply with Pydantic v2 standards
and avoid deprecation warnings. Update the return statement to include status
code 201 and replace event.dict() with event.model_dump() when appending to
mock_events.


@app.get("/user/{user_id}/path", response_model=Roadmap)
def get_roadmap(user_id: str):
if user_id not in mock_roadmaps:
raise HTTPException(status_code=404, detail="No roadmap found for this user")
return mock_roadmaps[user_id]
Comment on lines +1 to +69
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify and fix syntax errors flagged by static analysis

Confirm that the file no longer contains markdown fences/backticks and parses as Python.

Run:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Detecting markdown fences in services/personalization/app.py"
rg -n '^(---|```)' services/personalization/app.py || echo "No markdown fences detected."

echo "AST-parse the file to catch syntax errors"
python - << 'PY'
import ast, sys, pathlib
p = pathlib.Path("services/personalization/app.py")
try:
    ast.parse(p.read_text(encoding="utf-8"))
    print("AST parse OK: services/personalization/app.py")
except SyntaxError as e:
    print("SyntaxError:", e)
    sys.exit(1)
PY

Length of output: 373


Remove Markdown Fences Causing Syntax Errors

The file services/personalization/app.py still contains Markdown fences that break Python parsing. Please remove these lines (and any closing ``` fence) so the file is valid Python:

• services/personalization/app.py:1
­– Remove the leading ---
• services/personalization/app.py:4
­– Remove the opening ````python```

After stripping out all backticks/markdown fences, re-run your static analysis or ast.parse check to confirm there are no remaining syntax errors.

🧰 Tools
🪛 Ruff (0.12.2)

1-2: SyntaxError: Expected an expression


4-4: SyntaxError: Got unexpected token `


4-4: SyntaxError: Got unexpected token `


4-4: SyntaxError: Got unexpected token `

🤖 Prompt for AI Agents
In services/personalization/app.py at the beginning of the file (lines 1 to 4),
remove the leading markdown fences including the line with "---" and the opening
"```python" fence. Also ensure to remove any closing "```" fence if present
later in the file. This will make the file valid Python code and prevent syntax
errors during parsing or static analysis.