Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ time, and the number of assistants the route needs — in under a second.
> Hosted on Render's free tier, which spins services down when idle. The first
> request after a quiet period can take up to 60 seconds to wake the instance.

**Demo login:** not yet provisioned — see "Creating a demo login" below.
**Demo access:** available on request. Sign-in goes through a shared identity
service that also backs my other portfolio apps; the first sign-in after a quiet
period can be slow while that service wakes up.

---

Expand Down Expand Up @@ -133,7 +135,7 @@ fail if the fix is reverted:
|---|---|
| Backend | Flask, SQLAlchemy, Flask-Migrate (Alembic) |
| Database | PostgreSQL (production and local dev) |
| Auth | Flask-Login, Flask-Bcrypt, role-based access (Manager / SSR) |
| Auth | Shared identity-service (RS256 JWT, verified against its JWKS) for credentials; Flask-Login for the browser session; role-based access (Manager / SSR) |
| Geocoding & routing | OpenRouteService, behind a swappable `DistanceProvider` |
| Maps | Leaflet.js + OpenStreetMap |
| CI | GitHub Actions (pytest on Python 3.12 and 3.13) |
Expand Down Expand Up @@ -189,29 +191,35 @@ python seed_demo.py # optional: a five-stop demo route
flask --app run.py run
```

Then open http://127.0.0.1:5000 and register a Manager account.
Sign-in needs a running identity-service. The app looks for it at
`http://localhost:8081` by default; set `IDENTITY_URL` to point elsewhere.
Then open http://127.0.0.1:5000 and register an account.

`seed_demo.py` seeds stops **without** coordinates, since geocoding needs an API
key. With `ORS_API_KEY` set it geocodes them for you; otherwise use the
"Re-geocode from address" button on each stop. Rural and industrial addresses
are exactly where public geocoders go wrong, so every stop also accepts a manual
latitude and longitude — the plant's own address resolves about three miles off.

### Creating a demo login
### Accounts and roles

Credentials are never committed. Pass them through the environment:
Credentials live in the shared identity service, never in this repo. The first
time someone signs in, RouteOptimizer creates their account with the
least-privileged **SSR** role. An administrator promotes people to Manager
afterwards.

```bash
DEMO_USERNAME=demo DEMO_PASSWORD='choose-something' python seed_demo.py
```
An account created here before the identity service existed is linked on its
first sign-in, and only if the person also supplies the old local password.
Identity-service emails are unverified, so an email match alone is never enough
to claim an existing account.

---

## Project Status

**Working:** full CRUD for stops, routes, holidays and plant settings;
geocoding with manual override; distance-matrix caching; the VRPTW optimizer;
the results dashboard; per-stop schedule editing; 84 tests in CI.
the results dashboard; per-stop schedule editing; 114 tests.

**Known limitations, by priority rather than oversight:**

Expand Down
Loading