# agnare/staffsenseml architecture

> Architecture diagram of the GitHub repository agnare/staffsenseml, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/agnare/staffsenseml
- Repository: https://github.com/agnare/staffsenseml

## Overview

StaffSenseML is a FastAPI microservice that accepts employee features from StaffSense, predicts attrition risk, and returns a score, risk factors, and retention actions. Its prediction path runs through request validation and the predictor; the service can use a trained scikit-learn model or a weights-based fallback. A separate documented retraining path generates synthetic data and saves model artifacts. The tree and excerpts support these main responsibilities, but omitted portions of services.py leave some internal sequencing uncertain.

Main entry points: [`services.py`](https://github.com/agnare/staffsenseml/blob/main/services.py) (Prediction service), [`train.py`](https://github.com/agnare/staffsenseml/blob/main/train.py) (Training workflow), [`main.py`](https://github.com/agnare/staffsenseml/blob/main/main.py) (FastAPI endpoints), [`model/weights.json`](https://github.com/agnare/staffsenseml/blob/main/model/weights.json) (Fallback weights)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["API boundary"]
  node_api["FastAPI endpoints<br/>[main.py]"]
  node_schemas["Request and response schemas<br/>[schemas.py]"]
  node_response["Prediction response<br/>[schemas.py]"]
end

subgraph group_prediction["Risk prediction"]
  node_predictor["Prediction service<br/>[services.py]"]
  node_featureprep["Feature preparation<br/>[services.py]"]
  node_modelscore["Model scoring<br/>[services.py]"]
  node_riskresult["Risk score and level<br/>[services.py]"]
  node_modelartifact["Trained model and scaler"]
  node_weights["Fallback weights<br/>[weights.json]"]
end

subgraph group_explanations["Decision support"]
  node_factoranalysis["Risk factor analysis<br/>[services.py]"]
  node_actionplan["Retention action plan<br/>[services.py]"]
end

subgraph group_training["Model training"]
  node_trainer["Training workflow<br/>[train.py]"]
  node_syntheticdata["Synthetic employee data<br/>[train.py]"]
  node_trainingdata["Training dataset<br/>[train.py]"]
  node_trainedartifacts["Saved model artifacts"]
end

node_staffsense(("StaffSense client"))

node_staffsense -->|"POST prediction"| node_api
node_api -->|"validates request"| node_schemas
node_api -->|"calls predict"| node_predictor
node_predictor -->|"prepares features"| node_featureprep
node_predictor -->|"scores features"| node_modelscore
node_predictor -->|"loads model and scaler"| node_modelartifact
node_predictor -.->|"loads fallback"| node_weights
node_predictor -->|"computes risk"| node_riskresult
node_predictor -->|"analyzes factors"| node_factoranalysis
node_predictor -->|"generates actions"| node_actionplan
node_predictor -->|"builds response"| node_response
node_api -->|"returns prediction"| node_staffsense
node_trainer -->|"generates records"| node_syntheticdata
node_syntheticdata -->|"writes dataset"| node_trainingdata
node_trainer -->|"loads for training"| node_trainingdata
node_trainer -->|"saves model and scaler"| node_trainedartifacts
node_trainer -->|"writes weights"| node_weights

click node_api "https://github.com/agnare/staffsenseml/blob/main/main.py"
click node_schemas "https://github.com/agnare/staffsenseml/blob/main/schemas.py"
click node_predictor "https://github.com/agnare/staffsenseml/blob/main/services.py"
click node_featureprep "https://github.com/agnare/staffsenseml/blob/main/services.py"
click node_modelscore "https://github.com/agnare/staffsenseml/blob/main/services.py"
click node_riskresult "https://github.com/agnare/staffsenseml/blob/main/services.py"
click node_modelartifact "https://github.com/agnare/staffsenseml/tree/main/model"
click node_weights "https://github.com/agnare/staffsenseml/blob/main/model/weights.json"
click node_factoranalysis "https://github.com/agnare/staffsenseml/blob/main/services.py"
click node_actionplan "https://github.com/agnare/staffsenseml/blob/main/services.py"
click node_response "https://github.com/agnare/staffsenseml/blob/main/schemas.py"
click node_trainer "https://github.com/agnare/staffsenseml/blob/main/train.py"
click node_syntheticdata "https://github.com/agnare/staffsenseml/blob/main/train.py"
click node_trainingdata "https://github.com/agnare/staffsenseml/blob/main/train.py"
click node_trainedartifacts "https://github.com/agnare/staffsenseml/tree/main/model"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_api,node_schemas,node_response,node_staffsense toneBlue
class node_predictor,node_featureprep,node_modelscore,node_riskresult,node_modelartifact,node_weights toneAmber
class node_factoranalysis,node_actionplan toneMint
class node_trainer,node_syntheticdata,node_trainingdata,node_trainedartifacts toneRose
```

## Components

### API boundary

- [FastAPI endpoints](https://github.com/agnare/staffsenseml/blob/main/main.py): `main.py`
- [Request and response schemas](https://github.com/agnare/staffsenseml/blob/main/schemas.py): `schemas.py`
- [Prediction response](https://github.com/agnare/staffsenseml/blob/main/schemas.py): `schemas.py`

### Risk prediction

- [Prediction service](https://github.com/agnare/staffsenseml/blob/main/services.py): `services.py`
- [Feature preparation](https://github.com/agnare/staffsenseml/blob/main/services.py): `services.py`
- [Model scoring](https://github.com/agnare/staffsenseml/blob/main/services.py): `services.py`
- [Risk score and level](https://github.com/agnare/staffsenseml/blob/main/services.py): `services.py`
- [Trained model and scaler](https://github.com/agnare/staffsenseml/tree/main/model): `model`
- [Fallback weights](https://github.com/agnare/staffsenseml/blob/main/model/weights.json): `model/weights.json`

### Decision support

- [Risk factor analysis](https://github.com/agnare/staffsenseml/blob/main/services.py): `services.py`
- [Retention action plan](https://github.com/agnare/staffsenseml/blob/main/services.py): `services.py`

### Model training

- [Training workflow](https://github.com/agnare/staffsenseml/blob/main/train.py): `train.py`
- [Synthetic employee data](https://github.com/agnare/staffsenseml/blob/main/train.py): `train.py`
- [Training dataset](https://github.com/agnare/staffsenseml/blob/main/train.py): `train.py`
- [Saved model artifacts](https://github.com/agnare/staffsenseml/tree/main/model): `model`

### Other components

- **StaffSense client**

## Connections

- StaffSense client → FastAPI endpoints: POST prediction
- FastAPI endpoints → Request and response schemas: validates request
- FastAPI endpoints → Prediction service: calls predict
- Prediction service → Feature preparation: prepares features
- Prediction service → Model scoring: scores features
- Prediction service → Trained model and scaler: loads model and scaler
- Prediction service → Fallback weights: loads fallback
- Prediction service → Risk score and level: computes risk
- Prediction service → Risk factor analysis: analyzes factors
- Prediction service → Retention action plan: generates actions
- Prediction service → Prediction response: builds response
- FastAPI endpoints → StaffSense client: returns prediction
- Training workflow → Synthetic employee data: generates records
- Synthetic employee data → Training dataset: writes dataset
- Training workflow → Training dataset: loads for training
- Training workflow → Saved model artifacts: saves model and scaler
- Training workflow → Fallback weights: writes weights
