API Reference ============= This guide is intended for developers who wish to build their own frontend applications or integrations on top of the Calyntro API. The API is built with **FastAPI** and follows RESTful principles. All responses are JSON-formatted. .. note:: The Base URL for all endpoints is ``/v1``. Common Concepts --------------- Request Format ~~~~~~~~~~~~~~ Most analysis endpoints accept ``POST`` requests to allow for complex filtering parameters in the body. Dates should be provided in ISO 8601 format (e.g., ``2023-01-01T00:00:00``). **Standard Filter Parameters:** Many endpoints use a common filter structure: * ``start_date``: The beginning of the analysis time window. * ``end_date``: The end of the analysis time window. * ``module_name``: Optional. Filter results to a specific architectural component/module. .. note:: Some older endpoints use ``from`` (aliased from ``from_``) and ``to`` instead of ``start_date`` and ``end_date``. These are noted in the respective sections. Response Format ~~~~~~~~~~~~~~~ Most list-based responses wrap the results in an ``items`` array: .. code-block:: json { "items": [ { ... }, { ... } ] } -------------------------------------------------------------------------------- Repository & Files ------------------ Get Repository Info ~~~~~~~~~~~~~~~~~~~ Retrieves metadata and statistics for the entire repository, including time span, last import, total commits, active committers, and file type distribution. * **URL:** ``/v1/repository/info`` * **Method:** ``GET`` **Response:** .. code-block:: json { "items": { "project_name": "mongodb", "time_span": { "start": "01.01.2024", "end": "17.04.2026", "days": 837 }, "last_import": "2026-04-17 14:30:00", "total_commits": 5676, "committers": 42, "file_types": [ { "name": "TypeScript", "value": 45.2, "color": "#3178c6", "extension": ".ts, .tsx" }, { "name": "Python", "value": 20.5, "color": "#3572A5", "extension": ".py" }, { "name": "Other", "value": 34.3, "color": "#cccccc", "extension": "" } ] } } .. list-table:: Response Fields (``items``) :header-rows: 1 :widths: 25 75 * - Field - Description * - ``project_name`` - Name of the analyzed project as configured in ``config.yaml`` (``project.name``). * - ``time_span`` - Object containing ``start``, ``end`` (formatted dates) and ``days`` (total span). * - ``last_import`` - Timestamp of the most recent data import. * - ``total_commits`` - Total number of commits in the analysis database. * - ``committers`` - Number of distinct active committers. * - ``file_types`` - Top-5 file type distribution by commit share. Each entry has ``name``, ``value`` (%), ``color`` (hex), ``extension``. Get File Details ~~~~~~~~~~~~~~~~ Returns comprehensive metrics, KPIs, and activity history for a specific file. * **URL:** ``/v1/files/details`` * **Method:** ``POST`` **Request Body (JSON):** * ``file_path`` (required): The full path of the file. * ``start_date`` (optional): Analysis start date. * ``end_date`` (optional): Analysis end date. **Response:** .. code-block:: json { "meta": { "file_path": "src/core/main.py", "module": "core", "last_modified": "2024-03-15T10:00:00", "contributor_count": 5, "contributor_names": ["Alice", "Bob"] }, "kpis": { "complexity": { "value": 42.0, "trend_pct": 5.0 }, "churn_rate": { "value": 12.5, "trend_pct": -2.1 }, "hotspot_score": { "value": 0.85, "trend_pct": 0.0 }, "silo_risk_pct": { "value": 0.0, "trend_pct": 0.0 } }, "metrics": { "loc": 450, "cyclomatic": 25, "cognitive": 18 }, "activity": { "commits": 124, "churn": 1540, "file_age_days": 450 } } -------------------------------------------------------------------------------- Lines of Code (LOC) ------------------- Endpoints for analyzing the size of the codebase. Get LOC per File ~~~~~~~~~~~~~~~~ Returns the Lines of Code count for each file, based on the latest commit within the selected timeframe. * **URL:** ``/v1/analysis/loc/files`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59", "module_name": "optional_module_name" } **Response:** .. code-block:: json { "items": [ { "name": "src/main.py", "loc": 150 } ] } Get LOC per Module ~~~~~~~~~~~~~~~~~~ Returns the aggregated Lines of Code for each defined module. * **URL:** ``/v1/analysis/loc/modules`` * **Method:** ``POST`` **Request Body:** Same as *Get LOC per File*. **Response:** .. code-block:: json { "items": [ { "name": "src/core/", "loc": 5240 } ] } Get Total LOC ~~~~~~~~~~~~~ Returns the grand total Lines of Code for the entire project (or filtered selection). * **URL:** ``/v1/analysis/loc/total`` * **Method:** ``POST`` * **Request Body:** Same as *Get LOC per File*. **Response:** .. code-block:: json { "items": [ { "name": "Total", "loc": 15420 } ] } -------------------------------------------------------------------------------- Evolution & Pulse ----------------- Endpoints for analyzing how the codebase changes over time. Change Frequency (Files) ~~~~~~~~~~~~~~~~~~~~~~~~ Retrieves commit activity for files, including commit counts, author metrics, and last modification details. * **URL:** ``/v1/analyze/commits`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59", "module_name": "optional_module_name" } **Response:** .. code-block:: json { "items": [ { "file_path": "src/core/analysis.py", "commit_count": 42, "last_modified": "2023-12-01T10:00:00", "main_contributor": "John Doe", "author_count": 3, "last_commit_message": "Refactor analysis engine" } ] } Change Frequency (Modules) ~~~~~~~~~~~~~~~~~~~~~~~~~~ Retrieves commit activity aggregated by module. * **URL:** ``/v1/analyze/modules/commits`` * **Method:** ``POST`` * **Request Body:** Same as *Change Frequency (Files)*. **Response:** .. code-block:: json { "items": [ { "module_name": "src/api/", "commit_count": 85, "last_modified": "2023-12-15T14:30:00", "main_contributor": "Jane Smith", "author_count": 5, "last_commit_message": "Fix API authentication" } ] } Change Recency (Files) ~~~~~~~~~~~~~~~~~~~~~~ Returns the age of files (time since first and last commit). * **URL:** ``/v1/analyze/age`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "from_": "2023-01-01T00:00:00", "to": "2023-12-31T23:59:59", "module": "optional_module_name", "nbr_items": 50 } **Response:** .. code-block:: json { "items": [ { "file_path": "src/utils.py", "first_commit": "2021-01-01T12:00:00", "last_commit": "2023-11-15T09:30:00", "age_days": 1048, "revisions": 15 } ] } Change Recency (Modules) ~~~~~~~~~~~~~~~~~~~~~~~~ Returns the age aggregated by module. * **URL:** ``/v1/analyze/modules/age`` * **Method:** ``POST`` * **Request Body:** Same as *Change Recency (Files)*. **Response:** .. code-block:: json { "items": [ { "module_name": "src/core/", "first_commit": "2020-05-10T08:00:00", "last_commit": "2023-12-01T16:45:00", "age_days": 1300, "revisions": 450 } ] } Absolute Churn ~~~~~~~~~~~~~~ Returns the absolute churn (added + deleted lines) per file. * **URL:** ``/v1/analyze/abs_churn/files`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "from": "2023-01-01T00:00:00", "to": "2023-12-31T23:59:59", "module": "optional_module_name", "nbr_items": 100 } **Response:** .. code-block:: json { "items": [ { "file_path": "src/db/connection.py", "abs_churn": 1250, "total_added": 800, "total_deleted": 450, "first_change": "2023-01-15T10:00:00", "last_change": "2023-11-20T15:30:00", "revisions": 12 } ] } Absolute Churn (Modules) ~~~~~~~~~~~~~~~~~~~~~~~~ Returns the absolute churn aggregated by module. * **URL:** ``/v1/analyze/abs_churn/modules`` * **Method:** ``POST`` * **Request Body:** Same as *Absolute Churn*. Development Trend ~~~~~~~~~~~~~~~~~ Analyzes the evolution of hotspots by comparing a baseline time window with a current time window. * **URL:** ``/v1/analyze/hotspot_trends`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "baseline": { "from": "2023-01-01T00:00:00", "to": "2023-06-30T23:59:59" }, "current": { "from": "2023-07-01T00:00:00", "to": "2023-12-31T23:59:59" }, "module": "optional_module_name", "nbr_items": 50 } **Response:** .. code-block:: json { "items": [ { "file_path": "src/core/analysis.py", "churn_baseline": 450, "churn_current": 820, "scores": { "structural": { "baseline": 0.45, "current": 0.82, "delta": 0.37, "delta_norm": 0.5, "norm": 0.6, "trend": "up" }, "activity": { "baseline": 15, "current": 25, "delta": 10, "delta_norm": 0.4, "norm": 0.5, "trend": "up" } } } ] } File Trend History ~~~~~~~~~~~~~~~~~~ Returns the historical development of metrics for a specific file. * **URL:** ``/v1/analyze/file_trend`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "file_path": "src/core/service.py", "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59", "bucket_days": 14, "metric": "churn" } **Response:** .. code-block:: json { "items": [ { "file_path": "src/core/service.py", "metric": "churn", "from_date": "2023-01-01T00:00:00", "to_date": "2023-12-31T23:59:59", "bucket_days": 14, "series": [ { "t": "2023-01-01T00:00:00", "value": 150 }, { "t": "2023-01-15T00:00:00", "value": 240 } ] } ] } Module Trend History ~~~~~~~~~~~~~~~~~~~~ Returns the historical development of a single churn-based metric for one module. * **URL:** ``/v1/analyze/module_trend`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "module_name": "src/api/", "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59", "bucket_days": 14, "metric": "churn" } **Response:** Same structure as *File Trend History*. Per-Module Trends (Visual View) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns bucketed time series for **four metrics simultaneously** across all modules (or a requested subset). This is the data source for the Trend Analysis visual view in the dashboard. All modules share an identical time axis so the frontend can render them on a common x-axis without further alignment. * **URL:** ``/v1/analysis/trends/modules`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2024-01-01T00:00:00", "end_date": "2024-12-31T23:59:59", "bucket_days": 30, "module_names": ["core", "api"] } .. list-table:: Request Parameters :header-rows: 1 :widths: 20 10 70 * - Parameter - Required - Description * - ``start_date`` - No - Start of the analysis window; defaults to 12 months before ``end_date``. * - ``end_date`` - No - End of the analysis window; defaults to now. * - ``bucket_days`` - No - Width of each time bucket in days. Default: ``30``. * - ``module_names`` - No - List of component names to include. ``null`` or omitted returns all modules. **Response:** .. code-block:: json { "items": { "bucket_days": 30, "buckets": [ "2024-01-01T00:00:00", "2024-02-01T00:00:00" ], "modules": [ { "module_name": "core", "complexity": [21.3, 22.1], "loc": [14200, 14850], "silo_ratio": [16.4, 17.1], "commits": [42, 38] } ] } } .. list-table:: Response Fields :header-rows: 1 :widths: 20 80 * - Field - Description * - ``bucket_days`` - The bucket width used (echoes the request value). * - ``buckets`` - Ordered list of bucket start timestamps. Shared across all modules. * - ``modules`` - One entry per module. Each metric is an array aligned to ``buckets``; ``null`` at a position means no data exists for that module in that bucket. * - ``complexity`` - Average cognitive complexity per bucket. * - ``loc`` - Total lines of code per bucket (latest snapshot per file within bucket). * - ``silo_ratio`` - Percentage of silo files per bucket (ownership ≥ 80 %). * - ``commits`` - Distinct commit count per bucket. -------------------------------------------------------------------------------- Quality & Risk -------------- Hotspot Analysis (Age & Churn) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Identifies "Hotspots" based on the intersection of high churn and file age. * **URL:** ``/v1/analyze/hotspots/churnage`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "from": "2023-01-01T00:00:00", "to": "2023-12-31T23:59:59", "module": "optional_module_name", "nbr_items": 50 } **Response:** .. code-block:: json { "items": [ { "file_path": "src/core/logic.py", "age_days": 450, "churn": 1200, "hotspot_score": 0.89 } ] } Hotspot Analysis (Complexity & Churn) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Identifies hotspots by combining cognitive complexity with churn metrics. * **URL:** ``/v1/analyze/hotspots/complexity`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59", "component_name": "optional_module_name" } **Response:** .. code-block:: json [ { "file_path": "src/complex_logic.py", "complexity": 150, "churn": 2500, "hotspot_score": 0.85 } ] -------------------------------------------------------------------------------- Structure & Logic ----------------- Combined Complexity (Files) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns complexity metrics (Cyclomatic, Cognitive, Efforts, LOC) combined with a trend indicator. * **URL:** ``/v1/analysis/complexity/combined`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59", "module_name": "optional_module_name" } **Response:** .. code-block:: json { "items": [ { "file_path": "src/main.py", "cognitive": 12, "cyclomatic": 8, "loc": 150, "efforts": 450.5, "trend_indicator": 2.0 } ] } Combined Complexity (Modules) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns aggregated complexity metrics for modules. * **URL:** ``/v1/analysis/complexity/modules`` * **Method:** ``POST`` * **Request Body:** Same as *Combined Complexity (Files)*. **Response:** .. code-block:: json { "items": [ { "file_path": "src/core/", "cognitive": 120, "cyclomatic": 85, "loc": 5240, "efforts": 12500.0, "trend_indicator": 1.5 } ] } Complexity Trend History ~~~~~~~~~~~~~~~~~~~~~~~~ Returns the historical complexity trend for a specific file. * **URL:** ``/v1/analyze/hotspots/complexity/trend`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "file_path": "src/core/service.py", "module_name": null, "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59" } **Response:** .. code-block:: json { "items": [ { "author_date": "2023-01-15T10:00:00", "complexity": 15, "cognitive": 12, "efforts": 450.0, "loc": 120, "commit_churn": 25 } ] } -------------------------------------------------------------------------------- Team & Knowledge ---------------- Engineering Eras ~~~~~~~~~~~~~~~~ Detects temporal development phases (eras) for a module or the full repository. Eras are derived deterministically from Git signals — no AI is involved. Each era spans a contiguous period with a stable, recognisable pattern. * **URL:** ``/v1/analysis/eras`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "module_name": "db", "start_date": "2022-01-01T00:00:00", "end_date": "2024-01-01T00:00:00", "min_duration_months": 2, "cp_threshold": 0.30 } All fields except ``start_date`` and ``end_date`` are optional. ``cp_threshold`` controls sensitivity: lower values detect more era boundaries. **Response:** .. code-block:: json { "module": "db", "eras": [ { "era_type": "knowledge_concentration", "label": "Ownership Concentration Era", "start": "2023-04-01T00:00:00", "end": "2024-01-01T00:00:00", "duration_months": 9, "signals": { "commits_norm": 0.45, "complexity_delta": 0.08, "contributor_norm": 0.12, "silo_ratio": 0.87 } } ] } **Era types:** ``rapid_growth``, ``stabilization``, ``knowledge_concentration``, ``refactoring``, ``neglect``, ``transition``, ``unknown``. **Signal semantics:** * ``commits_norm`` — relative commit activity (0 = lowest month in range, 1 = highest) * ``complexity_delta`` — signed complexity change per bucket (positive = growing) * ``contributor_norm`` — relative team size (0 = fewest contributors, 1 = most) * ``silo_ratio`` — fraction of files in this bucket where one author holds ≥ 80 % of commits (0–1) Code Ownership (Files) ~~~~~~~~~~~~~~~~~~~~~~ Returns the number of distinct authors per file and identifies the main contributor. * **URL:** ``/v1/analysis/contributors/files`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59", "module_name": "optional_module_name" } Code Ownership (Modules) ~~~~~~~~~~~~~~~~~~~~~~~~ Returns ownership statistics aggregated by module. * **URL:** ``/v1/analysis/contributors/modules`` * **Method:** ``POST`` * **Request Body:** Same as *Code Ownership (Files)*. **Response:** .. code-block:: json { "items": [ { "module_name": "src/api/", "author_count": 8, "main_contributor": "Jane Smith" } ] } Knowledge Silos (Files) ~~~~~~~~~~~~~~~~~~~~~~~ Returns all files classified as a knowledge silo — files where a single developer accounts for at least ``silo_threshold`` (default 80 %) of all commits. Results are ordered by ownership percentage descending. * **URL:** ``/v1/analysis/silos/files`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59", "module_name": "optional_module_name", "silo_threshold": 0.80, "min_commits": 5 } .. list-table:: Request Parameters :header-rows: 1 :widths: 20 10 70 * - Parameter - Required - Description * - ``start_date`` - No - ISO 8601 timestamp. Only commits on or after this date are considered. * - ``end_date`` - No - ISO 8601 timestamp. Only commits on or before this date are considered. * - ``module_name`` - No - Restrict analysis to a specific component name. * - ``silo_threshold`` - No - Fractional ownership threshold (0.5–1.0). A file is a silo when the top contributor meets or exceeds this value. Default: ``0.80``. * - ``min_commits`` - No - Minimum total commits a file must have to be included. Filters out rarely touched files. Default: ``5``. **Response:** .. code-block:: json { "items": [ { "file_path": "src/core/engine.py", "component_name": "core", "silo_developer": "alice", "ownership_pct": 94.3, "total_commits": 87, "risk": "high" } ] } .. list-table:: Response Fields :header-rows: 1 :widths: 25 75 * - Field - Description * - ``file_path`` - Path to the silo file. * - ``component_name`` - The architectural component this file belongs to (``null`` if unassigned). * - ``silo_developer`` - The developer who holds sole knowledge of this file. * - ``ownership_pct`` - Percentage of commits attributed to the silo developer (0–100). * - ``total_commits`` - Total number of commits to this file within the filtered time window. * - ``risk`` - Risk classification: ``low`` (80–89 %), ``medium`` (90–94 %), ``high`` (95–99 %), ``critical`` (100 %). Knowledge Silos (Modules) ~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns the silo density for each component — the fraction of files within the module that are knowledge silos — and identifies which developer is responsible for the most silos in that module. Results are ordered by silo ratio descending. * **URL:** ``/v1/analysis/silos/modules`` * **Method:** ``POST`` * **Request Body:** Same as *Knowledge Silos (Files)*. **Response:** .. code-block:: json { "items": [ { "component_name": "core", "total_files": 24, "silo_files": 9, "silo_ratio": 0.375, "dominant_silo_developer": "alice", "risk": "medium", "risk_score": 3.75 } ] } .. list-table:: Response Fields :header-rows: 1 :widths: 25 75 * - Field - Description * - ``component_name`` - Name of the architectural component. * - ``total_files`` - Total number of distinct files active in the module within the time window. * - ``silo_files`` - Number of files in the module that are classified as silos. * - ``silo_ratio`` - Fraction of files that are silos (``silo_files / total_files``). * - ``dominant_silo_developer`` - The developer responsible for the highest number of silos within this module. * - ``risk`` - Risk derived from ``silo_ratio``: ``low`` (< 25 %), ``medium`` (25–49 %), ``high`` (50–74 %), ``critical`` (≥ 75 %). * - ``risk_score`` - Numeric risk score on a 0–10 scale (``silo_ratio × 10``, rounded to 2 decimal places). Used by the Knowledge Risk screen to rank modules and size the risk bar. Knowledge Silos (Developers) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns the silo footprint of each developer — how many files and modules they are the sole knowledge holder of. Results are ordered by silo file count descending. * **URL:** ``/v1/analysis/silos/developers`` * **Method:** ``POST`` * **Request Body:** Same as *Knowledge Silos (Files)*. **Response:** .. code-block:: json { "items": [ { "developer": "alice", "silo_file_count": 14, "silo_module_count": 3, "avg_ownership_pct": 91.7, "risk": "high" } ] } .. list-table:: Response Fields :header-rows: 1 :widths: 25 75 * - Field - Description * - ``developer`` - Developer name. * - ``silo_file_count`` - Number of files for which this developer is the sole knowledge holder. * - ``silo_module_count`` - Number of distinct components containing at least one of their silo files. * - ``avg_ownership_pct`` - Average ownership percentage across all their silo files. * - ``risk`` - Risk derived from ``silo_file_count``: ``low`` (1–2), ``medium`` (3–9), ``high`` (10–19), ``critical`` (≥ 20). Module Ownership by Teams ~~~~~~~~~~~~~~~~~~~~~~~~~ Shows how much of each module is owned by different teams (Team-centric view). * **URL:** ``/v1/analysis/alignment/modules`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2023-01-01T00:00:00", "end_date": "2023-12-31T23:59:59", "component_name": "optional_module_name" } **Response:** .. code-block:: json { "items": [ { "team_name": "Frontend Team", "module_name_1": "UI Components", "ratio_1": 0.85, "module_name_2": "Icons", "ratio_2": 0.10, "module_name_3": "Tests", "ratio_3": 0.05, "health_status": "healthy" } ] } Top Team Contributors ~~~~~~~~~~~~~~~~~~~~~ Shows the top 3 contributing teams for each module (Module-centric view). * **URL:** ``/v1/analysis/alignment/teams`` * **Method:** ``POST`` * **Request Body:** Same as *Module Ownership by Teams*. **Response:** .. code-block:: json { "items": [ { "component_name": "src/core/", "team_name_1": "Core Team", "ratio_1": 0.75, "team_name_2": "DevOps", "ratio_2": 0.20, "team_name_3": "Unassigned/Others", "ratio_3": 0.05, "health_status": "monopoly" } ] } Team Ownership Drift Timeline ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Returns team ownership ratios per module per time bucket, enabling visualisation of how team responsibility shifted over time (Conway's Law drift). Only modules with a meaningful ownership change (≥10% shift in the leading team's ratio across buckets) are included. * **URL:** ``/v1/analysis/alignment/drift`` * **Method:** ``POST`` **Request Body:** .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Field - Type - Description * - ``start_date`` - datetime *(optional)* - Start of the analysis window. Defaults to two years ago. * - ``end_date`` - datetime *(optional)* - End of the analysis window. Defaults to today. * - ``bucket_months`` - integer *(default: 3)* - Bucket size in months. Use 3 for quarterly, 1 for monthly. * - ``module_name`` - string *(optional)* - Filter to a single module name. **Response Fields:** .. list-table:: :header-rows: 1 :widths: 25 75 * - Field - Description * - ``buckets`` - List of ISO date strings (``YYYY-MM-DD``) representing bucket start dates. * - ``modules`` - List of module objects with meaningful ownership drift (see below). * - ``modules[].module_name`` - Module name (component name). * - ``modules[].health_status`` - Latest bucket health status: ``monopoly`` (>90% one team), ``unassigned_heavy`` (Unassigned/Others >30%), ``fragmented`` (top-2 teams cover <50%), ``healthy``. * - ``modules[].series`` - One entry per bucket (aligned to ``buckets``). Each entry has a ``bucket`` (ISO date) and ``teams`` list of ``{ team, ratio }`` slices sorted by ratio desc. Empty ``teams`` list means no commits in that bucket. **Example Response:** .. code-block:: json { "buckets": ["2023-01-01", "2023-04-01", "2023-07-01", "2023-10-01"], "modules": [ { "module_name": "MMI_QML", "health_status": "fragmented", "series": [ { "bucket": "2023-01-01", "teams": [{"team": "Team C", "ratio": 0.72}, {"team": "Team F", "ratio": 0.21}] }, { "bucket": "2023-04-01", "teams": [{"team": "Team C", "ratio": 0.61}, {"team": "Team F", "ratio": 0.31}] }, { "bucket": "2023-07-01", "teams": [{"team": "Team F", "ratio": 0.55}, {"team": "Team C", "ratio": 0.38}] }, { "bucket": "2023-10-01", "teams": [{"team": "Team F", "ratio": 0.60}, {"team": "Team C", "ratio": 0.33}] } ] } ] } Hotspot Concentration ~~~~~~~~~~~~~~~~~~~~~ Returns the hotspot severity distribution for a module or the entire codebase as a single aggregated result — not a ranked list. Structural scores (``log1p(churn) × age_days``) are normalised within the result set so the metric is comparable across modules of any size and age. The normalisation mirrors the ``coupling_score`` approach: the file with the highest score receives 1.0, the lowest receives 0.0. Thresholds are consistent with the ``critical_hotspot`` warning type. * **URL:** ``/v1/analyze/hotspots/concentration`` * **Method:** ``POST`` .. note:: Returns zeros for all fields when no file activity exists in the requested window or the requested module does not exist. **Request Body:** .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Field - Type - Description * - ``module`` - string *(optional)* - Filter to a specific module name. Omit for codebase-wide concentration. * - ``start_date`` - datetime *(optional)* - Start of the analysis window. * - ``end_date`` - datetime *(optional)* - End of the analysis window. **Response Fields:** .. list-table:: :header-rows: 1 :widths: 25 75 * - Field - Description * - ``total_files`` - Total number of files with activity in the requested window. * - ``critical_count`` - Files whose normalised hotspot score is ≥ 0.9. * - ``high_count`` - Files whose normalised hotspot score is ≥ 0.7 and < 0.9. * - ``critical_ratio`` - ``critical_count / total_files × 100``. Returns 0.0 when ``total_files = 0``. * - ``high_ratio`` - ``high_count / total_files × 100``. Returns 0.0 when ``total_files = 0``. Contributors Trend ~~~~~~~~~~~~~~~~~~ Returns the number of distinct active contributors per time bucket. Each bucket spans ``bucket_days`` days (default 30). The ``t`` field marks the bucket start date, formatted identically to other trend endpoints (``/analysis/trends/overview``, ``/analyze/module_trend``), making it straightforward to overlay contributor activity with complexity or churn sparklines in custom dashboards. Without ``module_name``, the trend reflects the entire codebase. A declining trend signals growing knowledge concentration risk before silo metrics surface it at file level. * **URL:** ``/v1/analysis/contributors/trend`` * **Method:** ``POST`` **Request Body:** .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Field - Type - Description * - ``module_name`` - string *(optional)* - Filter to a specific module. Omit for codebase-wide trend. * - ``start_date`` - datetime *(optional)* - Start of the time window. Defaults to the repository's analysis start date. * - ``end_date`` - datetime *(optional)* - End of the time window. Defaults to today. * - ``bucket_days`` - integer *(optional, default 30)* - Bucket width in days. **Response Fields** (per item in ``items``): .. list-table:: :header-rows: 1 :widths: 25 75 * - Field - Description * - ``t`` - Bucket start date (ISO 8601 datetime). Buckets are non-overlapping and ordered ascending. * - ``contributor_count`` - Number of distinct authors who committed to the module (or codebase) within this bucket. Each author is counted once per bucket regardless of commit frequency. Change Coupling ~~~~~~~~~~~~~~~ Returns module pairs ranked by co-change frequency, enriched with team ownership context. Each pair represents two modules that were modified together in the same commits. Cross-team pairs indicate Conway's Law violations — coordination overhead caused by architectural boundaries that do not align with team boundaries. Results are pre-sorted: cross-team pairs first, then by ``total_co_changes`` descending within each boundary type. * **URL:** ``/v1/analysis/coupling/modules`` * **Method:** ``POST`` .. note:: Requires at least one completed analysis import. Returns an empty ``items`` list if coupling data has not been computed yet. **Request Body:** .. code-block:: json { "start_date": "2024-01-01T00:00:00", "end_date": "2024-12-31T23:59:59", "boundary_type": "cross_team" } .. list-table:: Request Parameters :header-rows: 1 :widths: 20 10 70 * - Parameter - Required - Description * - ``start_date`` - No - ISO 8601 timestamp. Restricts team ownership calculation to commits within this window. Omit to use all available history. * - ``end_date`` - No - ISO 8601 timestamp. Upper bound for the ownership window. * - ``boundary_type`` - No - Filter results by team boundary: ``cross_team``, ``same_team``, or ``unknown``. Omit to return all pairs. **Response:** .. code-block:: json { "items": [ { "module1": "src_mongo", "team1": "Storage Engine", "team1_ownership": 0.46, "module2": "src_third_party", "team2": "Test Infrastructure", "team2_ownership": 0.98, "coupled_file_pairs": 15, "total_co_changes": 21415, "boundary_type": "cross_team", "module1_commit_count": 204831, "module2_commit_count": 27112, "shared_commit_count": 27 } ] } .. list-table:: Response Fields (each item in ``items``) :header-rows: 1 :widths: 25 75 * - Field - Description * - ``module1`` - Name of the first module in the pair. The module with the lower lexicographic name is always placed in ``module1``. * - ``team1`` - Primary owning team of ``module1`` as resolved from the team configuration. ``null`` if no team assignment exists. * - ``team1_ownership`` - Fraction (0–1) of commits to ``module1`` attributed to ``team1`` in the configured time window. ``null`` if team is unknown. * - ``module2`` - Name of the second module in the pair. * - ``team2`` - Primary owning team of ``module2``. ``null`` if no team assignment exists. * - ``team2_ownership`` - Fraction (0–1) of commits to ``module2`` attributed to ``team2``. * - ``coupled_file_pairs`` - Number of distinct file pairs (one file from each module) that have co-changed at least once. Indicates the *breadth* of the coupling: a low value suggests an isolated connection; a high value indicates systemic coupling across many files. * - ``total_co_changes`` - Total file-pair co-change events: Σ (co_change_count per file pair). If a single commit touches *N* files in module1 and *M* files in module2, that counts as *N × M* events. Can be orders of magnitude larger than ``shared_commit_count``. * - ``boundary_type`` - Team boundary classification: ``cross_team`` (modules owned by different teams), ``same_team``, or ``unknown`` (team data unavailable for one or both modules). * - ``module1_commit_count`` - Total distinct commits that touched any file in ``module1`` across all history. Used as the denominator in coupling direction calculations: ``P(module2 | module1) = shared_commit_count / module1_commit_count``. * - ``module2_commit_count`` - Total distinct commits that touched any file in ``module2`` across all history. * - ``shared_commit_count`` - Commits that touched at least one file in ``module1`` **and** at least one file in ``module2`` simultaneously. This is the commit-level coordination count — directly comparable to ``module1_commit_count`` and ``module2_commit_count`` for direction analysis. .. note:: **``total_co_changes`` vs ``shared_commit_count``** — these measure different things. ``shared_commit_count`` counts commits at the module level (27 in the example above). ``total_co_changes`` counts file-pair co-change events, which multiplies with the number of files touched per commit (27 commits × ~790 file pairs per commit ≈ 21,415 events). Use ``shared_commit_count`` for direction analysis; use ``total_co_changes`` for ranking pairs. Coupling Partners ~~~~~~~~~~~~~~~~~ Returns all modules that co-change with a given module, ranked by co-change frequency. Provides an asymmetric, partner-centric view: instead of symmetric pairs, each result item describes one partner relative to the queried module. The ``coupling_score`` is normalised within the result set — the strongest partner always receives a score of 1.0, making relative comparisons meaningful regardless of absolute co-change volume. * **URL:** ``/v1/analysis/coupling/partners`` * **Method:** ``POST`` .. note:: Returns an empty ``items`` list if no coupling data exists or the given module has no known co-change partners. **Request Body:** .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Field - Type - Description * - ``module_name`` - string *(required)* - The module for which coupling partners are queried. * - ``start_date`` - datetime *(optional)* - Restrict team ownership calculation to commits on or after this date. * - ``end_date`` - datetime *(optional)* - Restrict team ownership calculation to commits on or before this date. * - ``boundary_type`` - string *(optional)* - Filter by ``cross_team``, ``same_team``, or ``unknown``. Omit to return all. **Response Fields** (per item in ``items``): .. list-table:: :header-rows: 1 :widths: 25 75 * - Field - Description * - ``partner_module`` - Name of the co-changing partner module. * - ``team`` - Primary owning team of the partner module. ``null`` if no team data is available. * - ``team_ownership`` - Fraction (0–1) of churn in the partner module attributed to ``team``. ``null`` if no team data. * - ``coupled_file_pairs`` - Number of distinct file pairs (one from each module) that have co-changed at least once. * - ``total_co_changes`` - Total co-change events between this module and the partner. Used for absolute ranking. * - ``coupling_score`` - Normalised coupling strength (0.0–1.0). The partner with the highest ``total_co_changes`` receives 1.0; all others are scaled relative to it. Enables meaningful comparison across modules with different activity levels. * - ``boundary_type`` - Team boundary classification relative to the queried module: ``cross_team``, ``same_team``, or ``unknown`` (team data unavailable for one or both modules). -------------------------------------------------------------------------------- Dashboard KPIs -------------- Lightweight aggregate endpoints that power the four KPI cards, the three sparkline panels, and the warnings list on the overview dashboard. All computation happens in the backend; the frontend receives pre-calculated values and renders them directly. Project Summary ~~~~~~~~~~~~~~~ Returns the four headline metrics for the current period together with their trend percentages compared to an explicit baseline period. Powers all four KPI cards. * **URL:** ``/v1/analysis/summary`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2024-01-01T00:00:00", "end_date": "2024-12-31T23:59:59", "baseline_start_date": "2023-01-01T00:00:00", "baseline_end_date": "2023-12-31T23:59:59", "module_name": null } .. list-table:: Request Parameters :header-rows: 1 :widths: 25 10 65 * - Parameter - Required - Description * - ``start_date`` - Yes - Start of the current analysis period. * - ``end_date`` - Yes - End of the current analysis period. * - ``baseline_start_date`` - Yes - Start of the baseline period used for trend calculation. * - ``baseline_end_date`` - Yes - End of the baseline period used for trend calculation. * - ``module_name`` - No - Restrict analysis to a specific component. **Response:** .. code-block:: json { "items": [ { "total_commits": 1808, "total_commits_trend_pct": 12.5, "avg_file_age_days": 47, "avg_file_age_trend_pct": -5.3, "avg_complexity": 23.4, "avg_complexity_trend_pct": 3.1, "silo_ratio_pct": 18.2, "silo_ratio_trend_pct": 1.4 } ] } .. list-table:: Response Fields :header-rows: 1 :widths: 30 70 * - Field - Description * - ``total_commits`` - Total commit count in the current period. * - ``total_commits_trend_pct`` - Signed percentage change vs. baseline (positive = more commits). * - ``avg_file_age_days`` - Average file age in days across all files in the current period. * - ``avg_file_age_trend_pct`` - Signed percentage change in average file age vs. baseline. * - ``avg_complexity`` - Average cognitive complexity across all files. * - ``avg_complexity_trend_pct`` - Signed percentage change in average complexity vs. baseline (positive = worse). * - ``silo_ratio_pct`` - Percentage of files where a single developer owns ≥ 80 % of commits. * - ``silo_ratio_trend_pct`` - Signed percentage change in silo ratio vs. baseline (positive = more silos). Trends Overview ~~~~~~~~~~~~~~~ Returns time-bucketed trend series for complexity, LOC, silo ratio, and commit activity. Powers the three sparkline panels on the overview dashboard. * **URL:** ``/v1/analysis/trends/overview`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2024-01-01T00:00:00", "end_date": "2024-12-31T23:59:59", "module_name": null, "bucket_days": 30 } .. list-table:: Request Parameters :header-rows: 1 :widths: 20 10 70 * - Parameter - Required - Description * - ``start_date`` - No - Start of the analysis window; defaults to 12 months before ``end_date``. * - ``end_date`` - No - End of the analysis window; defaults to now. * - ``module_name`` - No - Restrict all series to a specific component. * - ``bucket_days`` - No - Width of each time bucket in days. Default: ``30``. **Response:** .. code-block:: json { "bucket_days": 30, "complexity": [ { "t": "2024-01-01T00:00:00", "value": 21.3 }, { "t": "2024-02-01T00:00:00", "value": 22.1 } ], "loc": [ { "t": "2024-01-01T00:00:00", "value": 142300.0 }, { "t": "2024-02-01T00:00:00", "value": 148700.0 } ], "silo_ratio": [ { "t": "2024-01-01T00:00:00", "value": 16.4 }, { "t": "2024-02-01T00:00:00", "value": 17.1 } ], "commits": [ { "t": "2024-01-01T00:00:00", "value": 142.0 }, { "t": "2024-02-01T00:00:00", "value": 157.0 } ] } All four series share identical ``t`` timestamps so they can be aligned on the same x-axis in the frontend without further processing. .. list-table:: Response Fields :header-rows: 1 :widths: 20 80 * - Field - Description * - ``bucket_days`` - The bucket width used (echoes the request value). * - ``complexity`` - Average cognitive complexity per bucket. * - ``loc`` - Total lines of code per bucket (latest snapshot per file within bucket). * - ``silo_ratio`` - Percentage of silo files per bucket (ownership ≥ 80 %). * - ``commits`` - Total commit count per bucket. Warnings ~~~~~~~~ Returns the top-N warnings ranked by severity then normalised risk score. All warning types are derived exclusively from Git data — no external integrations required. Powers the warnings list on the overview dashboard. * **URL:** ``/v1/analysis/warnings`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2024-01-01T00:00:00", "end_date": "2024-12-31T23:59:59", "module_name": null, "limit": 10 } .. list-table:: Request Parameters :header-rows: 1 :widths: 20 10 70 * - Parameter - Required - Description * - ``start_date`` - Yes - Start of the analysis window. * - ``end_date`` - Yes - End of the analysis window. * - ``module_name`` - No - Restrict analysis to a specific component. * - ``limit`` - No - Maximum number of warnings to return. Default: ``10``. **Response:** .. code-block:: json { "items": [ { "module_name": "PaymentService", "reason": "critical_hotspot", "reason_label": "Critical Hotspot", "severity": "critical", "metric_value": 94.0, "metric_unit": "normalized_score" } ] } .. list-table:: Warning Reason Codes :header-rows: 1 :widths: 20 20 20 40 * - ``reason`` - ``reason_label`` - ``metric_unit`` - Description * - ``critical_hotspot`` - Critical Hotspot - ``normalized_score`` - Relative risk score 0–100 (``hotspot_score / max_hotspot_score × 100``). Critical ≥ 90, high ≥ 70. Score is relative to the worst module in the selected period, not an absolute threshold. * - ``silo_risk`` - Knowledge Silo - ``ownership_pct`` - File dominated by a single developer. Critical ≥ 95 %, high ≥ 80 %. * - ``complexity_spike`` - Complexity Spike - ``trend_indicator`` - Rapid complexity growth. Critical > 4.0×, high > 3.0×. * - ``churn_outlier`` - Churn Outlier - ``lines_changed`` - Absolute churn far above project average. Critical > 5× avg, high > 3× avg. * - ``legacy_reactivated`` - Legacy Reactivated - ``days`` - File dormant > 365 days that is now being heavily modified (churn > 2× avg). Always high. Results are ordered by severity (``critical`` before ``high``) then by normalised risk score descending. Commit Count KPI ~~~~~~~~~~~~~~~~ Returns the total commit count together with a growth percentage for use as a KPI indicator. * **URL:** ``/v1/analyze/commits/count`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2024-01-01T00:00:00", "end_date": "2024-12-31T23:59:59", "module_name": null, "trend_window_days": 30 } **Response:** .. code-block:: json { "items": { "total_commits": 1808, "growth_pct": 12.5 } } .. list-table:: Response Fields :header-rows: 1 :widths: 25 75 * - Field - Description * - ``total_commits`` - Total commit count within the requested period. * - ``growth_pct`` - Signed percentage change vs. the same window shifted back by ``trend_window_days`` (positive = more commits). Complexity Average KPI ~~~~~~~~~~~~~~~~~~~~~~ Returns the project-wide average cognitive complexity and its growth trend. Files with zero cognitive complexity (e.g. non-code assets) are excluded. * **URL:** ``/v1/analysis/complexity/avg`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2024-01-01T00:00:00", "end_date": "2024-12-31T23:59:59", "module_name": null, "trend_window_days": 30 } **Response:** .. code-block:: json { "items": { "avg_cognitive": 23.4, "growth_pct": 3.1 } } .. list-table:: Response Fields :header-rows: 1 :widths: 25 75 * - Field - Description * - ``avg_cognitive`` - Average cognitive complexity across all files (latest value per file as of ``end_date``). * - ``growth_pct`` - Signed percentage change vs. the window shifted back by ``trend_window_days`` (positive = complexity increased). Silo Count KPI ~~~~~~~~~~~~~~ Returns the total number of silo files and its growth trend. Consistent with the other silo endpoints — uses the same threshold and noise filters. * **URL:** ``/v1/analysis/silos/count`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2024-01-01T00:00:00", "end_date": "2024-12-31T23:59:59", "module_name": null, "silo_threshold": 0.80, "min_commits": 5, "trend_window_days": 30 } All parameters are optional. Defaults: ``silo_threshold`` = ``0.80``, ``min_commits`` = ``5``, ``trend_window_days`` = ``30``. **Response:** .. code-block:: json { "items": { "silo_count": 14, "growth_pct": 7.7 } } .. list-table:: Response Fields :header-rows: 1 :widths: 25 75 * - Field - Description * - ``silo_count`` - Number of silo files in the requested period. * - ``growth_pct`` - Signed percentage change vs. the window shifted back by ``trend_window_days`` (positive = more silos). -------------------------------------------------------------------------------- Configuration ------------- Get Modules ~~~~~~~~~~~ Returns a list of all configured architectural components/modules. * **URL:** ``/v1/config/modules`` * **Method:** ``GET`` **Response:** .. code-block:: json { "items": [ { "component_name": "src_core", "display_name": "Core" } ] } .. list-table:: Response Fields :header-rows: 1 :widths: 25 75 * - Field - Description * - ``component_name`` - Internal component identifier as defined in ``config.yaml``. * - ``display_name`` - Human-readable label shown in the UI. Runtime Context ~~~~~~~~~~~~~~~ Returns UI-facing runtime flags set by the server configuration. Clients fetch this once at startup to adapt their behaviour (e.g. hide author names in anonymised deployments, or enable demo-mode restrictions). .. note:: This endpoint does **not** carry the ``/v1`` prefix and is served outside the versioned API namespace. * **URL:** ``/api/context`` * **Method:** ``GET`` **Response:** .. code-block:: json { "anonymized": false, "demo_mode": false } .. list-table:: Response Fields :header-rows: 1 :widths: 25 75 * - Field - Description * - ``anonymized`` - When ``true``, author names are replaced with anonymised identifiers in all responses. Controlled by the ``context.anonymized`` flag in the server configuration. * - ``demo_mode`` - When ``true``, the instance is running in read-only demo mode. Write operations and certain configuration endpoints are disabled. Average File Age KPI ~~~~~~~~~~~~~~~~~~~~ Returns the project-wide average file age and its growth trend. * **URL:** ``/v1/analyze/age/avg`` * **Method:** ``POST`` **Request Body:** .. code-block:: json { "start_date": "2024-01-01T00:00:00", "end_date": "2024-12-31T23:59:59", "module_name": null, "trend_window_days": 30 } **Response:** .. code-block:: json { "items": { "avg_file_age_days": 47.5, "growth_pct": -5.3 } } .. list-table:: Response Fields :header-rows: 1 :widths: 25 75 * - Field - Description * - ``avg_file_age_days`` - Average file age in days across all files in the current period. * - ``growth_pct`` - Signed percentage change vs. the baseline window shifted back by ``trend_window_days``. -------------------------------------------------------------------------------- Get Analysis Start Date ~~~~~~~~~~~~~~~~~~~~~~~ Returns the configured start date for the current analysis session. * **URL:** ``/v1/config/analysis-since`` * **Method:** ``GET`` **Response:** .. code-block:: json { "items": { "analysis_since": "2020-01-01T00:00:00" } } API Info ~~~~~~~~ Returns metadata about the currently running analysis session, including database paths. * **URL:** ``/info`` * **Method:** ``GET`` .. note:: This endpoint does **not** carry the ``/v1`` prefix — it is served at the root path. **Response:** .. code-block:: json { "analysis_database": "/path/to/analysis.duckdb", "config_database": "/path/to/config.duckdb", "debug": false } Health Check ~~~~~~~~~~~~ Returns the current health status of the API and its database connection. Intended for use by container orchestration systems (Docker, Kubernetes). * **URL:** ``/api/health`` * **Method:** ``GET`` **Response (healthy):** .. code-block:: json { "status": "healthy", "database": "connected", "version": "1.0.0" } **Response (unhealthy, HTTP 503):** .. code-block:: json { "status": "unhealthy", "reason": "" }