From 772554cce9a3e7bfc9646d1fd128d09595fec44d Mon Sep 17 00:00:00 2001 From: santusht06 <115890693+santusht06@users.noreply.github.com> Date: Mon, 24 Aug 2026 13:14:00 +0530 Subject: [PATCH 1/2] docs: modernize architecture, add REST API reference, and sync test suite counts --- PULL_REQUEST_TEMPLATE.md | 12 +- README.md | 6 +- docs/README.md | 45 +++++ docs/api_reference.md | 243 ++++++++++++++++++++++++ docs/architecture.md | 401 ++++++++++++++++++--------------------- 5 files changed, 484 insertions(+), 223 deletions(-) create mode 100644 docs/README.md create mode 100644 docs/api_reference.md diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index f0080c1e..84f769f6 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -49,18 +49,18 @@ Closes # 1. Clone this branch: `git checkout your-branch-name` 2. Install dependencies: `pip install -r requirements.txt` -3. Run the app: `python app.py` -4. Open http://127.0.0.1:5000 and... -5. Run the tests: `python tests/test_basic.py` +3. Run the app: `PORT=5001 python src/app.py` +4. Open http://localhost:5001 and verify functionality +5. Run the tests: `pytest tests/` Expected test output: ``` -27 passed, 0 failed out of 27 tests +660+ passed in tests/ ``` ## Test Results [required] - + ``` paste output here @@ -82,7 +82,7 @@ paste output here - [ ] I have read [CONTRIBUTING.md](../CONTRIBUTING.md) and followed all guidelines - [ ] My branch name follows the convention: `feat/`, `fix/`, `docs/`, `data/`, `style/`, `test/` -- [ ] I have run `python tests/test_basic.py` and all 27 tests pass +- [ ] I have run `pytest tests/` and all test suites pass - [ ] I have run `flake8 .` locally and there are no errors - [ ] I have not introduced any `print()` or `console.log()` debug statements - [ ] Every new function I wrote has a docstring diff --git a/README.md b/README.md index 5824d604..f3359da4 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ [![Python](https://img.shields.io/badge/Python-3.8%2B-2335c2?style=for-the-badge&logo=python&logoColor=white)](https://www.python.org/) [![Flask](https://img.shields.io/badge/Flask-3.0-0f172a?style=for-the-badge&logo=flask&logoColor=white)](https://flask.palletsprojects.com/) [![MIT License](https://img.shields.io/badge/License-MIT-fbbf24?style=for-the-badge)](LICENSE) -[![Tests](https://img.shields.io/badge/Tests-27_Passing-22c55e?style=for-the-badge&logo=checkmarx&logoColor=white)](#quick-start) +[![Tests](https://img.shields.io/badge/Tests-660%2B_Passing-22c55e?style=for-the-badge&logo=checkmarx&logoColor=white)](#quick-start) [![PRs Welcome](https://img.shields.io/badge/PRs-Welcome-7c3aed?style=for-the-badge&logo=git&logoColor=white)](CONTRIBUTING.md) [![GSSoC](https://img.shields.io/badge/GSSoC-2026-fbbf24?style=for-the-badge&logo=opensourceinitiative&logoColor=0f1560)](https://gssoc.girlscript.tech/) @@ -178,13 +178,13 @@ python src/app.py Run the test suite: ```bash -python tests/test_basic.py +pytest tests/ ``` Expected output: ```bash -All tests passed +================= 660+ passed in tests/ ================= ``` --- diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..ed4c2f35 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,45 @@ +# DevPath Documentation Portal + +Welcome to the DevPath technical documentation suite. Whether you are an open-source contributor, architect, or developer exploring the API, you will find detailed guides and specifications below. + +--- + +## 📚 Documentation Index + +| Guide | Description | Target Audience | +|---|---|---| +| **[System Architecture](architecture.md)** | Detailed system components, Blueprint design, security model, and request lifecycles. | Contributors & Maintainers | +| **[REST API Reference](api_reference.md)** | Complete endpoint specifications, request payloads, schemas, and responses. | Integrators & Frontend Developers | +| **[Contribution Guide](contribution_guide.md)** | Step-by-step development setup, branch naming, testing, and PR guidelines. | GSSoC & Open Source Contributors | +| **[Project Overview](project_overview.md)** | Mission, problem statement, and algorithm scoring design. | All Developers | +| **[Security Policy](security.md)** | Security architecture, vulnerability reporting, and best practices. | Security Researchers & Deployers | +| **[Frequently Asked Questions](faq.md)** | Common troubleshooting tips and implementation questions. | General | + +--- + +## 🚀 Quick Technical Summary + +- **Backend**: Python 3.8+ & Flask 3.1 +- **Database**: SQLite with SQLAlchemy ORM (auto-seeded from `data/projects.json`) +- **Authentication**: Authlib (OAuth 2.0 with GitHub integration) +- **Frontend**: Vanilla JavaScript (ES6+), Semantic HTML5, Glassmorphism CSS design system +- **Security**: Strict CSP, Flask-WTF CSRF tokens, secure session cookie policies +- **Testing**: Automated `pytest` suite with **660+ passing test cases** + +--- + +## 🛠️ Running Locally + +```bash +# 1. Create and activate virtual environment +python3 -m venv venv +source venv/bin/activate + +# 2. Install dependencies +pip install -r requirements.txt + +# 3. Start development server +PORT=5001 python src/app.py +``` + +Then visit **http://localhost:5001** in your browser. diff --git a/docs/api_reference.md b/docs/api_reference.md new file mode 100644 index 00000000..14f9d051 --- /dev/null +++ b/docs/api_reference.md @@ -0,0 +1,243 @@ +# DevPath REST API Reference + +This document provides complete documentation for the DevPath HTTP APIs. + +All JSON endpoints accept and return `application/json; charset=utf-8` unless specified otherwise. + +--- + +## Table of Contents + +- [1. Recommendation & Discovery API](#1-recommendation--discovery-api) + - [POST /api/recommend](#post-apirecommend) + - [GET /api/search](#get-apisearch) +- [2. Roadmap & Comparison API](#2-roadmap--comparison-api) + - [GET /api/roadmaps](#get-apiroadmaps) + - [GET /api/compare](#get-apicompare) +- [3. Starter Code & Project API](#3-starter-code--project-api) + - [GET /project/{id}/code](#get-projectidcode) + - [GET /project/{id}/download](#get-projectiddownload) +- [4. Portfolio & Progress API](#4-portfolio--progress-api) + - [POST /api/portfolio-analysis](#post-apiportfolio-analysis) + - [POST /api/progress/project](#post-apiprogressproject) +- [5. GitHub Integration API](#5-github-integration-api) + - [POST /api/github/export](#post-apigithubexport) +- [6. System & Utility Endpoints](#6-system--utility-endpoints) + - [GET /healthz](#get-healthz) + - [GET /sitemap.xml](#get-sitemapxml) + - [GET /robots.txt](#get-robotstxt) + +--- + +## 1. Recommendation & Discovery API + +### `POST /api/recommend` + +Generates personalized project recommendations based on submitted developer profile. + +- **Authentication**: None +- **Content-Type**: `application/json` + +#### Request Body +```json +{ + "skills": ["Python", "Flask"], + "level": "Beginner", + "interest": "Web Development", + "time": "Low" +} +``` + +| Field | Type | Required | Description | +|---|---|---|---| +| `skills` | `Array` or `string` | Yes | List of user skills or comma-separated string | +| `level` | `string` | Yes | Experience level: `"Beginner"`, `"Intermediate"`, or `"Advanced"` | +| `interest` | `string` or `Array` | Yes | Domain of interest (e.g. `"Web Development"`, `"Data Science"`, `"AI"`) | +| `time` | `string` | Yes | Time commitment: `"Low"` (<5 hrs), `"Medium"` (5-15 hrs), `"High"` (>15 hrs) | + +#### Response `200 OK` +```json +{ + "projects": [ + { + "id": 1, + "title": "Weather Dashboard", + "level": "Beginner", + "interest": "Web Development", + "time": "Low", + "description": "Build a clean weather forecasting web app using OpenWeather API.", + "skills": ["HTML", "CSS", "JavaScript", "Fetch API"], + "features": ["Live city search", "5-day forecast cards"], + "tech_stack": ["HTML5", "CSS3", "JavaScript"], + "roadmap": ["1. Set up basic HTML structure", "2. Fetch weather data"], + "resources": [{"title": "MDN Fetch API", "url": "https://developer.mozilla.org"}], + "starter_code": "weather_app.html", + "score": 12.0 + } + ] +} +``` + +#### Error Responses +- `400 Bad Request`: Missing or invalid fields. + +--- + +### `GET /api/search` + +Real-time search across all catalog projects. + +- **Query Parameters**: + - `q` (string, required): Search query string matching title, description, skills, or tech stack. + +#### Example Request +```http +GET /api/search?q=flask HTTP/1.1 +``` + +#### Response `200 OK` +```json +{ + "results": [ + { + "id": 4, + "title": "REST API with Flask", + "level": "Intermediate", + "interest": "Backend", + "description": "Build a structured CRUD REST API using Flask and SQLite." + } + ] +} +``` + +--- + +## 2. Roadmap & Comparison API + +### `GET /api/roadmaps` + +Returns available structured career tracks and roadmap titles. + +#### Response `200 OK` +```json +{ + "roadmaps": [ + {"id": "frontend", "title": "Frontend Developer"}, + {"id": "backend", "title": "Backend Developer"}, + {"id": "fullstack", "title": "Full Stack Developer"}, + {"id": "ai-ml", "title": "AI & Machine Learning Engineer"} + ] +} +``` + +--- + +### `GET /api/compare` + +Compares two roadmap paths and computes overlapping skills and milestone differences. + +- **Query Parameters**: + - `role1` (string, required): First roadmap identifier. + - `role2` (string, required): Second roadmap identifier. + +#### Response `200 OK` +```json +{ + "role1": "frontend", + "role2": "backend", + "shared_skills": ["Git", "HTTP/REST", "Command Line"], + "unique_to_role1": ["CSS/SCSS", "DOM Manipulation", "React"], + "unique_to_role2": ["SQL", "Databases", "Server Architecture"], + "overlap_percentage": 35 +} +``` + +--- + +## 3. Starter Code & Project API + +### `GET /project/{id}/code` + +Fetches starter code file contents for rendering in the code preview modal. + +#### Response `200 OK` +```json +{ + "filename": "weather_app.html", + "code": "\n\n...", + "language": "html" +} +``` + +#### Error Responses +- `404 Not Found`: Project or starter code template not found. + +--- + +### `GET /project/{id}/download` + +Downloads the project starter boilerplate as a file attachment. + +- **Response Header**: `Content-Disposition: attachment; filename="starter_code.zip"` + +--- + +## 4. Portfolio & Progress API + +### `POST /api/portfolio-analysis` + +Analyzes user-completed projects and provides a skill diversity score and suggestions. + +#### Request Body +```json +{ + "completed_projects": [1, 3, 7] +} +``` + +#### Response `200 OK` +```json +{ + "score": 78, + "level": "Good progress, room to grow", + "covered_domains": ["Web Development", "Backend"], + "recommendations": ["Explore a Data or Cloud project to round out your skills."] +} +``` + +--- + +## 5. GitHub Integration API + +### `POST /api/github/export` + +Exports a project roadmap and starter code directly into a new GitHub repository on the authenticated user's account. + +- **Authentication**: Required (User session with GitHub OAuth token) +- **Request Body**: +```json +{ + "project_id": 1, + "repo_name": "my-weather-dashboard", + "is_private": true +} +``` + +#### Response `200 OK` +```json +{ + "success": true, + "repo_url": "https://github.com/username/my-weather-dashboard", + "message": "Repository created successfully!" +} +``` + +--- + +## 6. System & Utility Endpoints + +| Method | Endpoint | Description | Status Code | +|---|---|---|---| +| `GET` | `/healthz` | System health and database connectivity check | `200 OK` | +| `GET` | `/sitemap.xml` | Dynamic XML sitemap for SEO crawlers | `200 OK` (`application/xml`) | +| `GET` | `/robots.txt` | Crawler policy and sitemap pointer | `200 OK` (`text/plain`) | diff --git a/docs/architecture.md b/docs/architecture.md index e60f30d7..95b29e8e 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,239 +1,212 @@ -# Architecture — DevPath +# System Architecture — DevPath -This document explains how DevPath is structured, how data flows through the -system, and why each module exists. +This document provides a comprehensive, production-grade overview of DevPath's architecture, directory structure, data layer, security mechanisms, and request lifecycle. --- -## High-Level Architecture - -``` -Browser - | - | HTTP request (GET / or POST /api/recommend) - v -Flask Application (app.py) - | - |-- Blueprint registration - v -routes/main_routes.py <-- receives requests, validates, delegates - | - |-- calls utils/recommender.py (scoring + filtering logic) - |-- calls utils/data_loader.py (reads projects.json) - |-- calls utils/file_server.py (resolves + serves starter code) - | - v -templates/ + static/ <-- rendered HTML + JS + CSS served to browser +## 1. System Architecture Overview + +DevPath is built on a modular **Flask application factory and Blueprint architecture** with a hybrid persistence layer (SQLAlchemy ORM + JSON dataset seeding), Authlib OAuth2 authentication, Flask-WTF CSRF protection, and strict HTTP security headers. + +```mermaid +flowchart TD + subgraph Client["Client Tier"] + Browser["Modern Web Browser"] + end + + subgraph Security["Security & Middleware"] + CSP["Security Headers & CSP"] + CSRF["CSRF Protection (Flask-WTF)"] + Auth["OAuth2 & Session Guard"] + end + + subgraph App["Flask Application (src/app.py)"] + MainBP["Main Blueprint (routes/main_routes.py)"] + AuthBP["Auth Blueprint (routes/auth_routes.py)"] + AdminBP["Admin Blueprint (routes/admin_routes.py)"] + GithubBP["GitHub Blueprint (routes/github_routes.py)"] + Errors["Error Boundary (errors/handlers.py)"] + end + + subgraph Services["Core Engine & Utilities (src/utils/)"] + Recommender["Recommendation Engine (recommender.py)"] + DataLoader["Data Loader & Cache (data_loader.py)"] + FileServer["Secure Starter Code Server (file_server.py)"] + Analyzer["Portfolio Analyzer (portfolio_analyzer.py)"] + Roadmaps["Roadmap Comparator (roadmap_comparator.py)"] + end + + subgraph Persistence["Persistence Tier"] + SQLite[(SQLite Database - SQLAlchemy ORM)] + ProjectsJSON[("data/projects.json - Seed & Fallback")] + StarterFiles[("starter_code/ - Code Templates")] + end + + Browser -->|HTTP Requests| CSP + CSP --> CSRF + CSRF --> Auth + Auth --> App + + MainBP --> Recommender + MainBP --> DataLoader + MainBP --> FileServer + MainBP --> Analyzer + MainBP --> Roadmaps + AuthBP --> SQLite + AdminBP --> SQLite + GithubBP --> FileServer + + DataLoader --> ProjectsJSON + DataLoader --> SQLite + FileServer --> StarterFiles ``` --- -## Module Responsibilities - -### app.py - -The entry point. Its only jobs are: - -- Create the Flask app instance -- Register the `main` Blueprint from `routes/` -- Register the 404 and 500 error handlers -- Start the dev server when run directly - -No business logic, no data access, no file handling. - ---- - -### routes/main_routes.py - -Contains all URL route handlers, registered as a Flask Blueprint named `main`. - -Each route handler follows the same pattern: - -1. Read and strip input from the request -2. Call one or more utility functions -3. Return a rendered template or a JSON response - -Routes defined: - -| Method | Path | Description | -|--------|-------------------------------|-----------------------------------| -| GET | `/` | Render homepage | -| POST | `/api/recommend` | Return matching project JSON | -| GET | `/project/` | Render project detail page | -| GET | `/project//code` | Return starter code content JSON | -| GET | `/project//download` | Serve starter code as download | - ---- - -### utils/data_loader.py - -Handles all reading and lookup of project data. - -Functions: - -- `load_all_projects()` — reads and returns the full JSON array -- `find_project_by_id(project_id)` — returns a single project dict or None - -The data file path is resolved relative to the module file itself, so the app -works correctly regardless of the working directory it is started from. - ---- - -### utils/recommender.py - -Contains all recommendation logic. Nothing in this module knows about HTTP, -Flask, or file paths. - -Functions: - -- `parse_skills(skills_string)` — converts `"Python, HTML"` to `["python", "html"]` -- `score_single_project(project, user_skills, level, interest, time)` — returns an integer score -- `get_recommendations(skills, level, interest, time)` — returns the top N projects -- `validate_recommendation_inputs(...)` — returns a list of error strings - -Scoring weights are named module-level constants: - -```python -WEIGHT_SKILL = 3 # Points per matching skill (scaled by coverage ratio) -WEIGHT_LEVEL = 2 # Points for matching experience level -WEIGHT_INTEREST = 2 # Points for matching interest area -WEIGHT_TIME = 1 # Points for matching time availability +## 2. Directory Structure + +```text +devpath/ +├── data/ # Data datasets and persistent storage +│ ├── projects.json # Canonical project catalog and metadata +│ ├── roadmaps.json # Career roadmap paths +│ └── devpath.db # SQLite development database (auto-seeded) +├── docs/ # Comprehensive documentation +│ ├── README.md # Documentation portal & index +│ ├── architecture.md # System design and data flow (this file) +│ ├── api_reference.md # Complete REST API reference +│ ├── contribution_guide.md # Step-by-step developer contribution guide +│ ├── project_overview.md # Purpose and core value proposition +│ ├── security.md # Security policy and disclosure +│ └── faq.md # Frequently asked questions +├── src/ # Primary application source code +│ ├── app.py # Application entry point, config, and startup +│ ├── config.py # Centralized configuration class +│ ├── models.py # SQLAlchemy ORM models +│ ├── errors/ # Global error handling and logging +│ │ ├── handlers.py # HTTP and unhandled exception error boundaries +│ │ └── error_logger.py # Structured error formatting & correlation IDs +│ ├── routes/ # Modular Flask Blueprints +│ │ ├── main_routes.py # Core views, recommend, search, explore, compare +│ │ ├── auth_routes.py # User authentication and session management +│ │ ├── admin_routes.py # Protected admin management CRUD routes +│ │ └── github_routes.py # GitHub OAuth and repository export workflows +│ ├── static/ # Stylesheets, client scripts, assets, icons +│ │ ├── css/ & style.css # Responsive theme styling & CSS variables +│ │ └── js/ & script.js # Interactivity, recommendation UI, theme toggles +│ ├── templates/ # Jinja2 HTML templates +│ │ ├── partials/ # Reusable UI partials (navbar, footer, modals, buttons) +│ │ ├── admin/ # Admin dashboard and form templates +│ │ └── errors/ # Custom error pages (400, 403, 404, 429, 500) +│ └── utils/ # Core algorithms and business logic services +│ ├── recommender.py # Rule-based recommendation engine +│ ├── data_loader.py # Dataset loading and caching +│ ├── file_server.py # Path-traversal-safe starter code reader +│ ├── portfolio_analyzer.py # Portfolio diversity scoring engine +│ └── roadmap_comparator.py # Career roadmap diff and overlap utility +├── starter_code/ # Downloadable starter project templates +├── tests/ # Automated test suite (660+ pytest tests) +├── tools/ # Repository integrity and validation utilities +│ └── sentinel/ # DevPath Sentinel dataset & code validator +├── .env.example # Template environment variables +├── Dockerfile # Container definition +├── Makefile # Developer shortcut commands +└── requirements.txt # Production Python dependencies ``` -Changing a weight number changes the relative influence of each criterion -across all recommendations. - --- -### utils/file_server.py - -Handles safe resolution and serving of starter code files. - -Functions: - -- `resolve_starter_file(project)` — returns the absolute path to the file, or None -- `read_starter_code(project)` — returns `{"filename": ..., "code": ...}` or None -- `get_starter_code_dir()` — returns the directory path for `send_from_directory` - -The `os.path.basename()` call in `resolve_starter_file` ensures that a -malicious `starter_code` value in the JSON (such as `../../etc/passwd`) cannot -cause a path traversal vulnerability. +## 3. Core Modules & Responsibilities + +### `src/app.py` +The primary application bootstrapper: +- Initializes Flask and loads settings from `Config`. +- Configures CSRF protection (`CSRFProtect`) with exemptions for stateless JSON API routes. +- Initializes SQLAlchemy ORM (`db.init_app`) and auto-seeds initial project data from `data/projects.json` if the database is empty. +- Configures GitHub OAuth provider integration via Authlib. +- Registers Blueprints (`main`, `auth_bp`, `admin_bp`, `github_bp`). +- Attaches the global error boundary via `register_error_handlers`. +- Adds strict security headers on every response (`X-Frame-Options`, `Content-Security-Policy`, `X-Content-Type-Options`, `Referrer-Policy`). + +### `src/models.py` +Defines SQLAlchemy models: +- **`User`**: Account identity (GitHub OAuth ID, username, avatar, admin role). +- **`Project`**: Catalog project details, skills, required experience level, roadmap steps, estimated hours, and starter code pointers. +- **`UserProgress`**: Per-user project completion status, active steps, and notes. +- **`UserGameProgress`**: Quiz / coding challenge scores and badges. + +### `src/utils/recommender.py` +Houses the recommendation engine without any HTTP or database dependencies: +- **`parse_skills(skills_input)`**: Normalizes skill strings or JSON arrays into a standardized lowercased skill set, resolving synonyms via `SKILL_SYNONYMS`. +- **`score_single_project(...)`**: Computes weighted scores: + - Skill Coverage: Matched skills weighted by $( \text{matched} / \text{total\_skills} )$. + - Experience Level Match (+2 pts). + - Domain / Interest Match (+2 pts). + - Time Commitment Match (+1 pt). +- **`get_recommendations(...)`**: Filters and sorts candidates deterministically, returning the top matches. + +### `src/utils/file_server.py` +Safely exposes starter code templates: +- Uses strict basename resolution and canonical path validation to prevent **Path Traversal Attacks** (`../`). +- Returns raw source code for the in-browser modal and streams files as attachments for downloads. --- -## Data Flow: Recommendation Request - -``` -1. User submits form - | -2. script.js sends POST /api/recommend - {skills: "Python", level: "Beginner", interest: "Data", time: "Low"} - | -3. main_routes.recommend() reads and strips each field - | -4. validate_recommendation_inputs() checks for empty fields - - Returns 400 JSON error if any field missing - | -5. get_recommendations() is called - | - 5a. parse_skills("Python") -> ["python"] - | - 5b. load_all_projects() reads data/projects.json (7 projects) - | - 5c. For each project, score_single_project() computes: - - Skill coverage score: matched * 3 * (matched / total_project_skills) - A user covering 1 of 2 required skills scores less than one covering both. - - Level match +2 points - - Interest match +2 points - - Time match +1 point - | - 5d. Projects with score > 0 are collected - | - 5e. Sorted descending by score - | - 5f. Top 3 returned - | -6. main_routes.recommend() returns 200 JSON {projects: [...]} - | -7. script.js receives response and calls renderResults() - | -8. buildProjectCard() creates DOM elements for each project - | -9. Cards inserted into #results-grid and section scrolled into view +## 4. Request Lifecycle & Recommendation Flow + +```mermaid +sequenceDiagram + autonumber + actor User + participant Browser + participant Flask as Flask Router (src/app.py) + participant MainBP as Main Blueprint + participant Engine as Recommender Engine + participant DB as SQLite / projects.json + + User->>Browser: Selects skills, level, interest, time & submits + Browser->>Flask: POST /api/recommend (JSON payload) + Flask->>Flask: Validate Security & CSRF Exemption + Flask->>MainBP: Route to recommend() handler + MainBP->>MainBP: validate_recommendation_inputs() + alt Inputs Invalid + MainBP-->>Browser: 400 Bad Request {error: "..."} + else Inputs Valid + MainBP->>Engine: get_recommendations(skills, level, interest, time) + Engine->>DB: Fetch active projects + Engine->>Engine: Parse skills, apply synonyms & compute weighted scores + Engine-->>MainBP: Top 3 sorted project matches + MainBP-->>Browser: 200 OK {projects: [...]} + Browser->>Browser: Render project cards dynamically + end ``` --- -## Data Flow: Project Detail Page +## 5. Security & Protection Model -``` -1. User clicks "View Full Project" link -> GET /project/1 - | -2. main_routes.project_detail(1) calls find_project_by_id(1) - | -3. project dict passed to render_template("project.html", project=project) - | -4. Jinja2 renders the template, iterating roadmap steps with loop.index - | -5. Browser receives complete HTML - | -6. User clicks "View Code" button - | -7. script.js calls GET /project/1/code - | -8. main_routes.view_code(1): - - find_project_by_id(1) -> project dict - - read_starter_code(project) -> {filename, code} - - Returns 200 JSON - | -9. script.js injects filename + code into the slide-up code panel -``` +1. **Content Security Policy (CSP)**: + - Restricts script and stylesheet execution. + - Permits trusted GitHub avatar domains for user profiles (`https://avatars.githubusercontent.com`). + - Disallows framing (`frame-ancestors 'none'`) to eliminate Clickjacking. +2. **CSRF Protection**: + - Web forms require valid CSRF tokens via Flask-WTF. + - JSON-only API routes are explicitly exempt since cross-origin JSON requests require CORS preflight and `Content-Type: application/json`. +3. **Session Hardening**: + - Session cookies utilize `HttpOnly=True`, `SameSite='Lax'`, and `Secure=True` in production. +4. **Path Traversal Guards**: + - Starter code file requests are sanitized using `os.path.basename()` and verified against `STARTER_CODE_DIR`. --- -## Template Rendering +## 6. Testing & Quality Assurance -DevPath uses Flask's built-in Jinja2 templating. Templates receive data through -`render_template()` keyword arguments. The project detail template uses -`{{ project.title }}`, `{% for step in project.roadmap %}`, and similar -expressions to render dynamic content server-side. - -No client-side template engine is used. The frontend JavaScript only handles -interactivity (form submission, chip management, code panel) and rendering of -the recommendation cards (which come back from the API as JSON). - ---- +The test suite covers over **660+ automated tests** using `pytest`: +- **Unit Tests**: Skill parsing, synonym resolution, scoring math, tiebreakers, portfolio diversity metrics. +- **Integration Tests**: Blueprint routes, OAuth callbacks, CSRF enforcement, error boundaries. +- **Dataset & Starter Code Sentinel**: `tools/sentinel/cli.py` validates that all JSON entries contain required fields and resolve to valid starter files. -## Static Files - -CSS and JavaScript are served from the `static/` directory by Flask's built-in -static file handler. In production, these would ideally be served directly by -a web server like Nginx rather than through Flask. - ---- - -## Testing Strategy - -Tests live in `tests/test_basic.py` and are grouped into four categories: - -1. **Data loader tests** — verify the JSON file loads and has correct structure -2. **Recommender unit tests** — test scoring, parsing, and validation in isolation -3. **HTTP route tests** — use Flask's test client to verify status codes and response shapes -4. **Edge case tests** — empty inputs, missing IDs, no-match scenarios - -Run with: `python tests/test_basic.py` or `pytest tests/` - ---- - -## Extending the Project - -The most common extension points are: - -| What to change | Where to change it | -|-------------------------|---------------------------------------------| -| Add a new project | `data/projects.json` | -| Change scoring weights | `utils/recommender.py` (top constants) | -| Add a new route | `routes/main_routes.py` | -| Change recommendation count | `utils/recommender.py` (MAX_RESULTS) | -| Add a new interest area | `data/projects.json` + `templates/index.html` dropdown | -| Change UI styling | `static/style.css` CSS variables block | +To execute the test suite: +```bash +pytest tests/ +``` From 66a79f9d79ddeeda63f146ddaf19cffb6e7a504e Mon Sep 17 00:00:00 2001 From: santusht06 <115890693+santusht06@users.noreply.github.com> Date: Sat, 5 Sep 2026 12:40:50 +0530 Subject: [PATCH 2/2] docs(api): sync API reference with backend routes, schemas, and parameters --- docs/api_reference.md | 660 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 583 insertions(+), 77 deletions(-) diff --git a/docs/api_reference.md b/docs/api_reference.md index 14f9d051..2a6674ab 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.md @@ -1,6 +1,6 @@ # DevPath REST API Reference -This document provides complete documentation for the DevPath HTTP APIs. +This document provides verified, complete technical documentation for the DevPath HTTP APIs. All JSON endpoints accept and return `application/json; charset=utf-8` unless specified otherwise. @@ -8,32 +8,57 @@ All JSON endpoints accept and return `application/json; charset=utf-8` unless sp ## Table of Contents -- [1. Recommendation & Discovery API](#1-recommendation--discovery-api) +- [1. Recommendation & Project Discovery API](#1-recommendation--project-discovery-api) - [POST /api/recommend](#post-apirecommend) - [GET /api/search](#get-apisearch) -- [2. Roadmap & Comparison API](#2-roadmap--comparison-api) - - [GET /api/roadmaps](#get-apiroadmaps) - - [GET /api/compare](#get-apicompare) -- [3. Starter Code & Project API](#3-starter-code--project-api) + - [GET /api/project/{id}/resources](#get-apiprojectidresources) - [GET /project/{id}/code](#get-projectidcode) - [GET /project/{id}/download](#get-projectiddownload) -- [4. Portfolio & Progress API](#4-portfolio--progress-api) +- [2. Career Roadmaps & Comparison API](#2-career-roadmaps--comparison-api) + - [GET /api/roadmaps](#get-apiroadmaps) + - [GET /api/compare](#get-apicompare) +- [3. User Progress & Portfolio Analytics API](#3-user-progress--portfolio-analytics-api) + - [GET /api/project/{id}/progress](#get-apiprojectidprogress) + - [POST /api/project/{id}/progress](#post-apiprojectidprogress) + - [GET /api/user-progress](#get-apiuser-progress) + - [POST /api/user-progress](#post-apiuser-progress) - [POST /api/portfolio-analysis](#post-apiportfolio-analysis) - - [POST /api/progress/project](#post-apiprogressproject) -- [5. GitHub Integration API](#5-github-integration-api) - - [POST /api/github/export](#post-apigithubexport) -- [6. System & Utility Endpoints](#6-system--utility-endpoints) - - [GET /healthz](#get-healthz) + - [GET /api/leaderboard](#get-apileaderboard) +- [4. Skill Progression Engine API](#4-skill-progression-engine-api) + - [POST /api/skill-progression/validate](#post-apiskill-progressionvalidate) + - [POST /api/skill-progression/record](#post-apiskill-progressionrecord) + - [GET /api/skill-progression/user/{user_id}](#get-apiskill-progressionuseruser_id) + - [GET /api/skill-progression/next/{user_id}/{skill}](#get-apiskill-progressionnextuser_idskill) +- [5. Code Review & Mentorship API](#5-code-review--mentorship-api) + - [POST /api/code-review/submit](#post-apicode-reviewsubmit) + - [GET /api/code-review/submission/{submission_id}](#get-apicode-reviewsubmissionsubmission_id) + - [GET /api/code-review/user/{user_id}/submissions](#get-apicode-reviewuseruser_idsubmissions) + - [GET /api/code-review/project/{project_id}/submissions](#get-apicode-reviewprojectproject_idsubmissions) + - [POST /api/code-review/start](#post-apicode-reviewstart) + - [POST /api/code-review/{review_id}/comment](#post-apicode-reviewreview_idcomment) + - [POST /api/code-review/{review_id}/score](#post-apicode-reviewreview_idscore) + - [POST /api/code-review/{review_id}/complete](#post-apicode-reviewreview_idcomplete) +- [6. Personalized Learning Path API](#6-personalized-learning-path-api) + - [POST /api/learning-path/{path_id}](#post-apilearning-pathpath_id) + - [GET /api/learning-path/{path_id}](#get-apilearning-pathpath_id) + - [PUT /api/learning-path/{path_id}](#put-apilearning-pathpath_id) + - [GET /api/learning-path/{path_id}/analytics](#get-apilearning-pathpath_idanalytics) +- [7. GitHub Integration & Repository Export](#7-github-integration--repository-export) + - [POST /project/{id}/export_github](#post-projectidexport_github) + - [GET /api/github/login](#get-apigithublogin) + - [GET /api/github/callback](#get-apigithubcallback) +- [8. System Health & SEO Endpoints](#8-system-health--seo-endpoints) + - [GET /health](#get-health) - [GET /sitemap.xml](#get-sitemapxml) - [GET /robots.txt](#get-robotstxt) --- -## 1. Recommendation & Discovery API +## 1. Recommendation & Project Discovery API ### `POST /api/recommend` -Generates personalized project recommendations based on submitted developer profile. +Generates weighted, personalized project recommendations based on the user's skill set, experience level, domain interests, and time availability. - **Authentication**: None - **Content-Type**: `application/json` @@ -50,7 +75,7 @@ Generates personalized project recommendations based on submitted developer prof | Field | Type | Required | Description | |---|---|---|---| -| `skills` | `Array` or `string` | Yes | List of user skills or comma-separated string | +| `skills` | `Array` or `string` | Yes | List of user skills or comma-separated string (e.g. `"Python, Flask"`) | | `level` | `string` | Yes | Experience level: `"Beginner"`, `"Intermediate"`, or `"Advanced"` | | `interest` | `string` or `Array` | Yes | Domain of interest (e.g. `"Web Development"`, `"Data Science"`, `"AI"`) | | `time` | `string` | Yes | Time commitment: `"Low"` (<5 hrs), `"Medium"` (5-15 hrs), `"High"` (>15 hrs) | @@ -70,7 +95,9 @@ Generates personalized project recommendations based on submitted developer prof "features": ["Live city search", "5-day forecast cards"], "tech_stack": ["HTML5", "CSS3", "JavaScript"], "roadmap": ["1. Set up basic HTML structure", "2. Fetch weather data"], - "resources": [{"title": "MDN Fetch API", "url": "https://developer.mozilla.org"}], + "resources": [ + {"title": "MDN Fetch API", "url": "https://developer.mozilla.org"} + ], "starter_code": "weather_app.html", "score": 12.0 } @@ -79,32 +106,46 @@ Generates personalized project recommendations based on submitted developer prof ``` #### Error Responses -- `400 Bad Request`: Missing or invalid fields. +- `400 Bad Request`: `{ "error": "All fields (skills, level, interest, time) are required." }` --- ### `GET /api/search` -Real-time search across all catalog projects. +Performs instant case-insensitive search across projects by title, description, skills, and tech stack. - **Query Parameters**: - - `q` (string, required): Search query string matching title, description, skills, or tech stack. + - `q` (string, required): Search query string (e.g. `flask`). -#### Example Request -```http -GET /api/search?q=flask HTTP/1.1 +#### Response `200 OK` +```json +[ + { + "id": 4, + "title": "REST API with Flask", + "description": "Build a structured CRUD REST API using Flask and SQLite.", + "skills": ["Python", "Flask", "SQLite"], + "level": "Intermediate", + "interest": "Backend", + "time": "Medium" + } +] ``` +--- + +### `GET /api/project/{id}/resources` + +Returns curated learning resources and external reference tutorials for a project. + #### Response `200 OK` ```json { - "results": [ + "project_id": 1, + "resources": [ { - "id": 4, - "title": "REST API with Flask", - "level": "Intermediate", - "interest": "Backend", - "description": "Build a structured CRUD REST API using Flask and SQLite." + "title": "MDN Fetch API Guide", + "url": "https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API" } ] } @@ -112,132 +153,597 @@ GET /api/search?q=flask HTTP/1.1 --- -## 2. Roadmap & Comparison API - -### `GET /api/roadmaps` +### `GET /project/{id}/code` -Returns available structured career tracks and roadmap titles. +Fetches starter code file contents for rendering in the client-side code preview modal. #### Response `200 OK` ```json { - "roadmaps": [ - {"id": "frontend", "title": "Frontend Developer"}, - {"id": "backend", "title": "Backend Developer"}, - {"id": "fullstack", "title": "Full Stack Developer"}, - {"id": "ai-ml", "title": "AI & Machine Learning Engineer"} - ] + "filename": "weather_app.html", + "code": "\n\n...\n" } ``` +#### Error Responses +- `404 Not Found`: `{ "error": "Project or starter code not found" }` + +--- + +### `GET /project/{id}/download` + +Downloads the project starter boilerplate as a file attachment. + +- **Response Header**: `Content-Disposition: attachment; filename=""` +- **Response Content**: Raw file stream. + +--- + +## 2. Career Roadmaps & Comparison API + +### `GET /api/roadmaps` + +Returns all structured career roadmaps as a direct JSON array. + +#### Response `200 OK` +```json +[ + { + "id": "frontend", + "title": "Frontend Developer", + "description": "Master building responsive, accessible web interfaces.", + "duration_weeks": 12, + "difficulty_score": 3, + "skills": ["HTML", "CSS", "JavaScript", "Git", "React"], + "topics": ["Responsive Design", "DOM Manipulation", "State Management"], + "career_opportunities": ["Junior Frontend Developer", "UI Engineer"] + }, + { + "id": "backend", + "title": "Backend Developer", + "description": "Design secure APIs, business logic, and databases.", + "duration_weeks": 14, + "difficulty_score": 4, + "skills": ["Python", "SQL", "Git", "REST APIs", "Docker"], + "topics": ["Database Design", "Authentication", "Server Architecture"], + "career_opportunities": ["Backend Engineer", "API Developer"] + } +] +``` + --- ### `GET /api/compare` -Compares two roadmap paths and computes overlapping skills and milestone differences. +Compares two career roadmaps side-by-side and computes overlapping vs. unique skills, topics, and duration metrics. - **Query Parameters**: - - `role1` (string, required): First roadmap identifier. - - `role2` (string, required): Second roadmap identifier. + - `a` (string, required): First roadmap ID (e.g. `frontend`). + - `b` (string, required): Second roadmap ID (e.g. `backend`). #### Response `200 OK` ```json { - "role1": "frontend", - "role2": "backend", - "shared_skills": ["Git", "HTTP/REST", "Command Line"], - "unique_to_role1": ["CSS/SCSS", "DOM Manipulation", "React"], - "unique_to_role2": ["SQL", "Databases", "Server Architecture"], - "overlap_percentage": 35 + "roadmap_a": { + "id": "frontend", + "title": "Frontend Developer", + "duration_weeks": 12, + "difficulty_score": 3, + "skills": ["HTML", "CSS", "JavaScript", "Git"], + "topics": ["Responsive Design", "DOM Manipulation"] + }, + "roadmap_b": { + "id": "backend", + "title": "Backend Developer", + "duration_weeks": 14, + "difficulty_score": 4, + "skills": ["Python", "SQL", "Git"], + "topics": ["Database Design", "Authentication"] + }, + "overlapping_skills": ["Git"], + "unique_skills_a": ["HTML", "CSS", "JavaScript"], + "unique_skills_b": ["Python", "SQL"], + "overlapping_topics": [], + "unique_topics_a": ["Responsive Design", "DOM Manipulation"], + "unique_topics_b": ["Database Design", "Authentication"], + "overlapping_careers": [], + "unique_careers_a": ["Junior Frontend Developer"], + "unique_careers_b": ["Backend Engineer"], + "summary": { + "shared_skills_count": 1, + "shared_topics_count": 0, + "total_unique_skills": 5 + }, + "metrics": { + "duration_weeks": { "a": 12, "b": 14, "max": 14 }, + "difficulty_score": { "a": 3, "b": 4, "max": 5 }, + "topics_count": { "a": 2, "b": 2 }, + "skills_count": { "a": 4, "b": 3 }, + "career_count": { "a": 1, "b": 1 } + } } ``` +#### Error Responses +- `400 Bad Request`: `{ "error": "Both 'a' and 'b' query parameters are required." }` +- `404 Not Found`: `{ "error": "One or both roadmap IDs were not found." }` + --- -## 3. Starter Code & Project API +## 3. User Progress & Portfolio Analytics API -### `GET /project/{id}/code` +### `GET /api/project/{id}/progress` + +Returns the authenticated user's completed roadmap step indexes for a project. -Fetches starter code file contents for rendering in the code preview modal. +- **Authentication**: Required (`session['user_id']`) #### Response `200 OK` ```json { - "filename": "weather_app.html", - "code": "\n\n...", - "language": "html" + "completed_steps": [0, 1, 2] } ``` #### Error Responses -- `404 Not Found`: Project or starter code template not found. +- `401 Unauthorized`: `{ "error": "Unauthorized" }` --- -### `GET /project/{id}/download` +### `POST /api/project/{id}/progress` -Downloads the project starter boilerplate as a file attachment. +Saves or updates completed roadmap steps for a project. + +- **Authentication**: Required (`session['user_id']`) +- **Content-Type**: `application/json` + +#### Request Body +```json +{ + "completed_steps": [0, 1, 2, 3] +} +``` + +#### Response `200 OK` +```json +{ + "message": "Progress saved successfully" +} +``` + +--- + +### `GET /api/user-progress` -- **Response Header**: `Content-Disposition: attachment; filename="starter_code.zip"` +Fetches user gamification progress, challenge badges, and quiz scores. + +- **Authentication**: Required (`session['user_id']`) + +#### Response `200 OK` +```json +{ + "data": { + "quiz_scores": { "python": 90 }, + "completed_challenges": ["challenge-1"] + } +} +``` --- -## 4. Portfolio & Progress API +### `POST /api/user-progress` + +Saves user gamification progress payload. + +- **Authentication**: Required (`session['user_id']`) +- **Request Body**: +```json +{ + "data": { + "quiz_scores": { "python": 90 }, + "completed_challenges": ["challenge-1", "challenge-2"] + } +} +``` + +#### Response `200 OK` +```json +{ + "message": "Progress updated successfully" +} +``` + +--- ### `POST /api/portfolio-analysis` -Analyzes user-completed projects and provides a skill diversity score and suggestions. +Evaluates completed project diversity and provides portfolio health scoring. + +- **Content-Type**: `application/json` #### Request Body ```json { - "completed_projects": [1, 3, 7] + "completed_projects": [1, 3] +} +``` + +#### Response `200 OK` +```json +{ + "score": 75, + "tier": "good", + "label": "Good progress, room to grow", + "categories": [ + { "name": "Frontend", "percentage": 50 }, + { "name": "Backend", "percentage": 50 } + ], + "recommendations": [ + "Consider building a project using databases or data visualization to round out your skills." + ] } ``` +--- + +### `GET /api/leaderboard` + +Retrieves public leaderboard ranking of active community contributors. + #### Response `200 OK` ```json { - "score": 78, - "level": "Good progress, room to grow", - "covered_domains": ["Web Development", "Backend"], - "recommendations": ["Explore a Data or Cloud project to round out your skills."] + "leaderboard": [ + { "username": "developer1", "projects_completed": 8, "badge": "Master" } + ] } ``` --- -## 5. GitHub Integration API +## 4. Skill Progression Engine API + +### `POST /api/skill-progression/validate` + +Validates whether a user satisfies prerequisites before attempting a higher skill tier. + +- **Authentication**: Required +- **Request Body**: +```json +{ + "skill": "Python", + "difficulty": "intermediate" +} +``` + +#### Response `200 OK` +```json +{ + "allowed": true, + "skill": "Python", + "target_difficulty": "INTERMEDIATE", + "reason": "Prerequisites satisfied." +} +``` + +--- -### `POST /api/github/export` +### `POST /api/skill-progression/record` -Exports a project roadmap and starter code directly into a new GitHub repository on the authenticated user's account. +Records successful completion of a skill difficulty level with optional score. -- **Authentication**: Required (User session with GitHub OAuth token) +- **Authentication**: Required - **Request Body**: ```json { + "skill": "Python", + "difficulty": "beginner", + "assessment_score": 85.0 +} +``` + +#### Response `201 Created` +```json +{ + "success": true, + "user_id": 1, + "skill": "Python", + "difficulty": "beginner", + "skill_data": { + "level": "BEGINNER", + "score": 85.0, + "completed_at": "2026-09-05T12:00:00" + } +} +``` + +--- + +### `GET /api/skill-progression/user/{user_id}` + +Fetches overall skill progression profile and proficiency score for a user. + +- **Authentication**: Required (Matches `{user_id}`) + +#### Response `200 OK` +```json +{ + "user_id": "1", + "skills": { + "Python": { "level": "BEGINNER", "score": 85.0 } + }, + "proficiency": 65.0 +} +``` + +--- + +### `GET /api/skill-progression/next/{user_id}/{skill}` + +Returns the recommended next difficulty level to pursue for a given skill. + +- **Authentication**: Required (Matches `{user_id}`) + +#### Response `200 OK` +```json +{ + "user_id": "1", + "skill": "Python", + "next_skill": { + "skill": "Python", + "difficulty": "INTERMEDIATE" + } +} +``` + +--- + +## 5. Code Review & Mentorship API + +### `POST /api/code-review/submit` + +Submits project code for structured peer and automated review. + +- **Authentication**: Required +- **Request Body**: +```json +{ + "submission_id": "sub_101", "project_id": 1, - "repo_name": "my-weather-dashboard", - "is_private": true + "code": "def fetch_weather(): pass", + "language": "python", + "description": "Initial working prototype" +} +``` + +#### Response `201 Created` +```json +{ + "success": true, + "submission": { + "submission_id": "sub_101", + "user_id": 1, + "project_id": 1, + "language": "python", + "status": "pending_review" + } +} +``` + +--- + +### `GET /api/code-review/submission/{submission_id}` + +Fetches code submission status and review comments. + +- **Authentication**: Required + +#### Response `200 OK` +```json +{ + "success": true, + "submission": { + "submission_id": "sub_101", + "status": "in_review", + "code": "def fetch_weather(): pass" + } +} +``` + +--- + +### `GET /api/code-review/user/{user_id}/submissions` + +Returns all code submissions submitted by a specific user. + +- **Authentication**: Required (Matches `{user_id}`) + +#### Response `200 OK` +```json +{ + "user_id": "1", + "submissions": [ ... ], + "count": 1 } ``` +--- + +### `GET /api/code-review/project/{project_id}/submissions` + +Retrieves all code review submissions tied to a specific catalog project. + +- **Authentication**: Required + #### Response `200 OK` ```json +{ + "project_id": 1, + "submissions": [ ... ], + "count": 2 +} +``` + +--- + +### `POST /api/code-review/start` + +Initiates an active review session for a pending submission. + +- **Authentication**: Required +- **Request Body**: +```json +{ + "submission_id": "sub_101", + "reviewer_id": "reviewer_5" +} +``` + +#### Response `200 OK` / `201 Created` +```json { "success": true, - "repo_url": "https://github.com/username/my-weather-dashboard", - "message": "Repository created successfully!" + "review": { + "review_id": "rev_201", + "submission_id": "sub_101", + "status": "in_progress" + } +} +``` + +--- + +### `POST /api/code-review/{review_id}/comment` + +Adds line-level or general feedback to a review session. + +- **Request Body**: +```json +{ + "comment": "Consider handling network timeout errors gracefully.", + "line_number": 14 } ``` --- -## 6. System & Utility Endpoints +### `POST /api/code-review/{review_id}/score` + +Submits numerical evaluation metrics for code quality, readability, and performance. -| Method | Endpoint | Description | Status Code | +- **Request Body**: +```json +{ + "quality_score": 88, + "readability_score": 92 +} +``` + +--- + +### `POST /api/code-review/{review_id}/complete` + +Marks a code review as finalized. + +#### Response `200 OK` +```json +{ + "success": true, + "message": "Review marked as complete." +} +``` + +--- + +## 6. Personalized Learning Path API + +| Endpoint | Method | Description | Auth Required | +|---|---|---|---| +| `/api/learning-path/{path_id}` | `POST` | Create a new custom adaptive learning path | Yes | +| `/api/learning-path/{path_id}` | `GET` | Fetch details, milestones, and status of a learning path | No | +| `/api/learning-path/{path_id}` | `PUT` | Update active milestone progress | Yes | +| `/api/learning-path/{path_id}/analytics` | `GET` | Retrieve completion rates and velocity metrics | No | + +--- + +## 7. GitHub Integration & Repository Export + +### `POST /project/{id}/export_github` + +Exports project starter code directly into a new GitHub repository on the authenticated user's GitHub profile. + +- **Authentication**: Required (`session['github_token']` from OAuth login) +- **Content-Type**: `application/json` + +#### Request Body +```json +{ + "repo_name": "my-weather-dashboard", + "description": "Starter code project built with DevPath", + "private": false +} +``` + +| Field | Type | Required | Description | |---|---|---|---| -| `GET` | `/healthz` | System health and database connectivity check | `200 OK` | -| `GET` | `/sitemap.xml` | Dynamic XML sitemap for SEO crawlers | `200 OK` (`application/xml`) | -| `GET` | `/robots.txt` | Crawler policy and sitemap pointer | `200 OK` (`text/plain`) | +| `repo_name` | `string` | Yes | Target repository name | +| `description` | `string` | No | Optional repository description | +| `private` | `boolean` | No | Visibility flag (defaults to `false` for public repo) | + +#### Response `200 OK` +```json +{ + "success": true, + "repo_url": "https://github.com/octocat/my-weather-dashboard", + "message": "Repository created and starter code exported successfully!" +} +``` + +#### Error Responses +- `401 Unauthorized`: GitHub OAuth authorization missing or expired. +- `404 Not Found`: Project template not found. +- `500 Internal Server Error`: GitHub API failure during repository creation. + +--- + +### `GET /api/github/login` + +Initiates GitHub OAuth 2.0 web application authorization flow. Redirects user to GitHub with `public_repo` scope and CSRF `state` parameter. + +--- + +### `GET /api/github/callback` + +Handles the OAuth 2.0 authorization code exchange with GitHub and persists access token in user session. + +--- + +## 8. System Health & SEO Endpoints + +### `GET /health` + +Checks system status and uptime. + +#### Response `200 OK` +```json +{ + "status": "healthy", + "timestamp": "2026-09-05T12:35:00.000000" +} +``` + +--- + +### `GET /sitemap.xml` + +Generates dynamic XML sitemap indexing all active projects, comparison routes, and static landing pages. + +- **Response Header**: `Content-Type: application/xml` + +--- + +### `GET /robots.txt` + +Serves standard crawler permissions and sitemap pointer. + +- **Response Header**: `Content-Type: text/plain`