Update plan for 3-photo / 2-ride session flow

Photo 2 serves as both end of ride 1 and start of ride 2.
Server holds in-memory session state across the 3 uploads
and writes both Excel rows after the final photo.

https://claude.ai/code/session_015myTTMs6yDsAGarATe5ePZ
This commit is contained in:
Claude 2026-03-18 18:24:22 +00:00
parent 235fbd226b
commit cede60cfa9
No known key found for this signature in database

90
PLAN.md
View file

@ -3,9 +3,12 @@
## How it works ## How it works
1. Open the web app on your phone 1. Open the web app on your phone
2. Take a photo of the odometer 2. Take **3 photos** in sequence:
3. Claude Vision API reads the number automatically - **Photo 1** — odometer at the start of ride 1
4. The km driven is calculated and saved to an Excel sheet - **Photo 2** — odometer at the end of ride 1 / start of ride 2
- **Photo 3** — odometer at the end of ride 2
3. Claude Vision API reads each number automatically
4. Two trip rows are calculated and saved to the Excel sheet
5. Download the sheet anytime 5. Download the sheet anytime
--- ---
@ -23,9 +26,10 @@
## Excel sheet columns ## Excel sheet columns
| Date | Time | Odometer (km) | Trip (km) | Notes | | Date | Time | Odometer start (km) | Odometer end (km) | Trip (km) | Notes |
|------------|-------|---------------|-----------|-------| |------------|-------|---------------------|-------------------|-----------|-------|
| 2026-03-18 | 08:14 | 84 320 | 47 | Work | | 2026-03-18 | 08:14 | 84 273 | 84 320 | 47 | Ride 1 |
| 2026-03-18 | 09:05 | 84 320 | 84 391 | 71 | Ride 2 |
--- ---
@ -34,38 +38,76 @@
``` ```
Driverthing/ Driverthing/
├── src/ ├── src/
│ ├── main.rs # Axum server + routes │ ├── main.rs # Axum server + routes + session state
│ ├── claude.rs # Claude API vision call │ ├── claude.rs # Claude API vision call
│ └── excel.rs # Excel read/write logic │ └── excel.rs # Excel read/write logic
├── templates/ ├── templates/
│ └── index.html # Mobile camera upload page │ └── index.html # Mobile step-by-step camera upload UI
├── Cargo.toml ├── Cargo.toml
└── mileage_log.xlsx # Generated, gitignored └── mileage_log.xlsx # Generated, gitignored
``` ```
--- ---
## Flow ## Session state (in-memory)
Between the 3 uploads the server holds a simple session with:
``` ```
Phone camera → upload photo session {
→ Axum receives multipart/form-data reading_1: Option<u32> # start of ride 1
→ Claude Vision: "What is the odometer reading?" reading_2: Option<u32> # end of ride 1 / start of ride 2
→ Extract number reading_3: Option<u32> # end of ride 2
→ Calculate delta from last reading }
→ Append row to Excel ```
→ Show confirmation on screen
When all three readings are present, two rows are written to Excel and the
session is cleared.
---
## UI flow (single page, steps replace each other)
```
Step 1: "Take photo of odometer — START of ride 1"
[Camera button] → upload
↓ server reads: 84 273 ✓
Step 2: "Take photo of odometer — END of ride 1 / START of ride 2"
[Camera button] → upload
↓ server reads: 84 320 ✓
↓ Ride 1: 47 km (shown on screen)
Step 3: "Take photo of odometer — END of ride 2"
[Camera button] → upload
↓ server reads: 84 391 ✓
↓ Ride 2: 71 km (shown on screen)
↓ Both rows saved ✓
Done screen: summary + [Download Excel] + [Start new session]
```
---
## Flow (technical)
```
POST /upload?step=1 → read photo → store reading_1 in session
POST /upload?step=2 → read photo → store reading_2 → calc ride1 delta → show
POST /upload?step=3 → read photo → store reading_3 → calc ride2 delta
→ write 2 rows to Excel → return summary
GET /download → serve mileage_log.xlsx
``` ```
--- ---
## Implementation steps ## Implementation steps
1. Set up Axum server with a multipart file upload endpoint 1. Set up Axum server with in-memory session state (DashMap or Mutex<HashMap>)
2. Send uploaded image (base64) to Claude API with a vision prompt 2. Create a single `/upload` endpoint that accepts `step=1|2|3` + multipart image
3. Parse the odometer number from the response 3. Send each uploaded image (base64) to Claude Vision API: "What is the odometer reading in km? Reply with only the number."
4. Read the last recorded odometer value from the Excel file 4. Parse the integer from the response and store it in the session
5. Calculate the difference (km driven) 5. After step 2: calculate ride 1 km, return intermediate confirmation
6. Append a new row (date, time, odometer, trip km, notes) to the sheet 6. After step 3: calculate ride 2 km, append both rows to the Excel file, clear session
7. Return confirmation to the browser 7. Mobile-friendly step-by-step HTML UI (progress indicator, camera capture)
8. Add a download endpoint for the Excel file 8. `GET /download` endpoint to serve the Excel file