# wrenstuff/surfcaster architecture

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

- Interactive diagram: https://gitdiagram.com/wrenstuff/surfcaster
- Repository: https://github.com/wrenstuff/surfcaster

## Overview

SurfCaster is a Flask web application for detecting potentially phishing URLs, with role-based user, reviewer, and administrator workflows. A signed-in user submits a URL; the role route extracts URL features, runs the Baelin model, records scan history, and presents the result. Users can flag scans for review, and reviewers or administrators can approve or reject queued scans. Authentication also supports account management and password recovery. The route and model excerpts support the scan and review wiring; the implementation of persistence helpers and recovery email is not sampled.

Main entry points: [`SurfCaster/reviewer/routes.py`](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/reviewer/routes.py) (Reviewer routes), [`SurfCaster/admin/routes.py`](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/admin/routes.py) (Admin routes), [`SurfCaster/authorisedUser/routes.py`](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/authorisedUser/routes.py) (User routes), [`SurfCaster/app.py`](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/app.py) (Flask app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web application"]
  node_app["Flask app<br/>[app.py]"]
  node_users["User routes<br/>[routes.py]"]
  node_guest["Guest routes<br/>[routes.py]"]
  node_templates["Page templates"]
end

subgraph group_identity["Identity and roles"]
  node_auth["Authentication routes<br/>[routes.py]"]
  node_models["Account and scan models<br/>[db_models.py]"]
  node_database[("SQLite database")]
  node_recover["Recovery helpers"]
end

subgraph group_scanning["URL detection"]
  node_extractor["URL feature extraction<br/>[url_extractor.py]"]
  node_baelin["Baelin classifier<br/>[Baelin.py]"]
  node_checkpoint["Model checkpoint"]
  node_scaler["Feature scaler<br/>[Baelin_scaler.pkl]"]
  node_shorteners["Shortener list<br/>[url-shortners.txt]"]
end

subgraph group_review["Review and history"]
  node_reviewer["Reviewer routes<br/>[routes.py]"]
  node_admin["Admin routes<br/>[routes.py]"]
  node_extensions["Scan history helpers<br/>[extensions.py]"]
end

node_actor(("Browser user"))
node_email["Email service"]

node_actor -->|"opens"| node_app
node_app -->|"registers routes"| node_auth
node_app -->|"registers routes"| node_users
node_app -->|"registers routes"| node_reviewer
node_app -->|"registers routes"| node_admin
node_app -->|"registers routes"| node_guest
node_auth -->|"renders pages"| node_templates
node_users -->|"renders pages"| node_templates
node_reviewer -->|"renders pages"| node_templates
node_admin -->|"renders pages"| node_templates
node_guest -->|"renders pages"| node_templates
node_auth -->|"queries and updates"| node_models
node_models -->|"persists records"| node_database
node_auth -->|"calls recovery"| node_recover
node_recover -.->|"sends recovery code"| node_email
node_users -->|"extracts features"| node_extractor
node_reviewer -->|"extracts features"| node_extractor
node_admin -->|"extracts features"| node_extractor
node_extractor -->|"reads list"| node_shorteners
node_users -->|"predicts URL"| node_baelin
node_reviewer -->|"predicts URL"| node_baelin
node_admin -->|"predicts URL"| node_baelin
node_users -->|"loads weights"| node_checkpoint
node_reviewer -->|"loads weights"| node_checkpoint
node_admin -->|"loads weights"| node_checkpoint
node_users -->|"loads scaler"| node_scaler
node_reviewer -->|"loads scaler"| node_scaler
node_admin -->|"loads scaler"| node_scaler
node_users -->|"records scan"| node_extensions
node_reviewer -->|"records scan"| node_extensions
node_admin -->|"records scan"| node_extensions
node_users -->|"writes flagged scans"| node_models
node_reviewer -->|"reviews scans"| node_models
node_admin -->|"manages users and scans"| node_models
node_reviewer -->|"gets review history"| node_extensions
node_admin -->|"gets review history"| node_extensions

click node_app "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/app.py"
click node_auth "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/auth/routes.py"
click node_users "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/authorisedUser/routes.py"
click node_reviewer "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/reviewer/routes.py"
click node_admin "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/admin/routes.py"
click node_guest "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/unauthorisedUser/routes.py"
click node_templates "https://github.com/wrenstuff/surfcaster/tree/main/SurfCaster/templates"
click node_models "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/db_models.py"
click node_extensions "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/extensions.py"
click node_extractor "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/url_extractor.py"
click node_baelin "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/models/Baelin.py"
click node_checkpoint "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/models/Baelin_checkpoint.pth"
click node_scaler "https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/models/Baelin_scaler.pkl"
click node_shorteners "https://github.com/wrenstuff/surfcaster/blob/main/url-shortners.txt"

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_app,node_users,node_guest,node_templates,node_actor toneBlue
class node_auth,node_models,node_database,node_recover toneAmber
class node_extractor,node_baelin,node_checkpoint,node_scaler,node_shorteners toneMint
class node_reviewer,node_admin,node_extensions toneRose
class node_email toneIndigo
```

## Components

### Web application

- [Flask app](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/app.py): `SurfCaster/app.py`
- [User routes](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/authorisedUser/routes.py): `SurfCaster/authorisedUser/routes.py`
- [Guest routes](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/unauthorisedUser/routes.py): `SurfCaster/unauthorisedUser/routes.py`
- [Page templates](https://github.com/wrenstuff/surfcaster/tree/main/SurfCaster/templates): `SurfCaster/templates`

### Identity and roles

- [Authentication routes](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/auth/routes.py): `SurfCaster/auth/routes.py`
- [Account and scan models](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/db_models.py): `SurfCaster/db_models.py`
- **SQLite database**
- **Recovery helpers**

### URL detection

- [URL feature extraction](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/url_extractor.py): `SurfCaster/url_extractor.py`
- [Baelin classifier](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/models/Baelin.py): `SurfCaster/models/Baelin.py`
- [Model checkpoint](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/models/Baelin_checkpoint.pth): `SurfCaster/models/Baelin_checkpoint.pth`
- [Feature scaler](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/models/Baelin_scaler.pkl): `SurfCaster/models/Baelin_scaler.pkl`
- [Shortener list](https://github.com/wrenstuff/surfcaster/blob/main/url-shortners.txt): `url-shortners.txt`

### Review and history

- [Reviewer routes](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/reviewer/routes.py): `SurfCaster/reviewer/routes.py`
- [Admin routes](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/admin/routes.py): `SurfCaster/admin/routes.py`
- [Scan history helpers](https://github.com/wrenstuff/surfcaster/blob/main/SurfCaster/extensions.py): `SurfCaster/extensions.py`

### Other components

- **Browser user**
- **Email service**

## Connections

- Browser user → Flask app: opens
- Flask app → Authentication routes: registers routes
- Flask app → User routes: registers routes
- Flask app → Reviewer routes: registers routes
- Flask app → Admin routes: registers routes
- Flask app → Guest routes: registers routes
- Authentication routes → Page templates: renders pages
- User routes → Page templates: renders pages
- Reviewer routes → Page templates: renders pages
- Admin routes → Page templates: renders pages
- Guest routes → Page templates: renders pages
- Authentication routes → Account and scan models: queries and updates
- Account and scan models → SQLite database: persists records
- Authentication routes → Recovery helpers: calls recovery
- Recovery helpers → Email service: sends recovery code
- User routes → URL feature extraction: extracts features
- Reviewer routes → URL feature extraction: extracts features
- Admin routes → URL feature extraction: extracts features
- URL feature extraction → Shortener list: reads list
- User routes → Baelin classifier: predicts URL
- Reviewer routes → Baelin classifier: predicts URL
- Admin routes → Baelin classifier: predicts URL
- User routes → Model checkpoint: loads weights
- Reviewer routes → Model checkpoint: loads weights
- Admin routes → Model checkpoint: loads weights
- User routes → Feature scaler: loads scaler
- Reviewer routes → Feature scaler: loads scaler
- Admin routes → Feature scaler: loads scaler
- User routes → Scan history helpers: records scan
- Reviewer routes → Scan history helpers: records scan
- Admin routes → Scan history helpers: records scan
- User routes → Account and scan models: writes flagged scans
- Reviewer routes → Account and scan models: reviews scans
- Admin routes → Account and scan models: manages users and scans
- Reviewer routes → Scan history helpers: gets review history
- Admin routes → Scan history helpers: gets review history
