Initial release v1.1.0

- Complete MVP for tracking Fidelity brokerage account performance
- Transaction import from CSV with deduplication
- Automatic FIFO position tracking with options support
- Real-time P&L calculations with market data caching
- Dashboard with timeframe filtering (30/90/180 days, 1 year, YTD, all time)
- Docker-based deployment with PostgreSQL backend
- React/TypeScript frontend with TailwindCSS
- FastAPI backend with SQLAlchemy ORM

Features:
- Multi-account support
- Import via CSV upload or filesystem
- Open and closed position tracking
- Balance history charting
- Performance analytics and metrics
- Top trades analysis
- Responsive UI design

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Chris
2026-01-22 14:27:43 -05:00
commit eea4469095
90 changed files with 14513 additions and 0 deletions

200
ROOT_CAUSE_FOUND.md Normal file
View File

@@ -0,0 +1,200 @@
# ROOT CAUSE FOUND! 🎯
## The Diagnostic Revealed Everything
Your diagnostic output showed the **exact problem**:
### What We Saw
**Registered Routes (from diagnostic):**
```
POST /api/accounts/
GET /api/accounts/
```
Notice the **trailing slash**? (`/api/accounts/`)
**HTTP Response (from diagnostic):**
```
HTTP/1.1 307 Temporary Redirect
location: http://localhost:8000/api/accounts/
```
The backend was redirecting FROM `/api/accounts` TO `/api/accounts/`
## Why This Was Happening
### The Route Definition
In `accounts.py`, the routes were defined as:
```python
@router.get("/", response_model=List[AccountResponse])
def list_accounts(...):
...
```
### How FastAPI Combines Paths
When you register the router in `main.py`:
```python
app.include_router(
accounts.router,
prefix="/api/accounts", # <-- prefix
tags=["accounts"]
)
```
FastAPI combines them:
```
prefix: "/api/accounts" + route: "/" = "/api/accounts/"
↑ trailing slash!
```
### What the Frontend Was Doing
Your React frontend was calling:
```javascript
fetch('http://starship2:8000/api/accounts') // No trailing slash
```
### The Result
1. Frontend: `GET /api/accounts` (no slash)
2. Backend: "I only have `/api/accounts/` (with slash)"
3. Backend: "Let me redirect you there: HTTP 307"
4. Frontend: "I don't follow redirects automatically, request fails"
5. UI: Spinning loading indicator forever
## The Fix
Changed all route decorators from:
```python
@router.get("/", ...) # Creates /api/accounts/
```
To:
```python
@router.get("", ...) # Creates /api/accounts
```
Now when combined:
```
prefix: "/api/accounts" + route: "" = "/api/accounts"
↑ NO trailing slash!
```
Perfect match with what the frontend calls!
## Files Fixed
1. **backend/app/api/endpoints/accounts.py**
- Changed `@router.post("/")``@router.post("")`
- Changed `@router.get("/")``@router.get("")`
2. **backend/app/api/endpoints/positions.py**
- Changed `@router.get("/")``@router.get("")`
3. **backend/app/api/endpoints/transactions.py**
- Changed `@router.get("/")``@router.get("")`
## Why Previous Fixes Didn't Work
We spent time trying to fix:
- Docker cache (not the issue)
- Database connection (not the issue)
- redirect_slashes parameter (not the issue)
- Environment variables (not the issue)
**The real issue was simply the trailing slash in route paths!**
## How To Apply The Fix
### Option 1: Quick Transfer (Recommended)
On your Mac:
```bash
cd /Users/chris/Desktop/fidelity
./transfer-final-fix.sh
```
Then on your server:
```bash
cd ~/fidelity
./FINAL_FIX.sh
```
### Option 2: Manual Transfer
```bash
# On Mac
cd /Users/chris/Desktop/fidelity
scp backend/app/api/endpoints/accounts.py pi@starship2:~/fidelity/backend/app/api/endpoints/
scp backend/app/api/endpoints/positions.py pi@starship2:~/fidelity/backend/app/api/endpoints/
scp backend/app/api/endpoints/transactions.py pi@starship2:~/fidelity/backend/app/api/endpoints/
scp FINAL_FIX.sh pi@starship2:~/fidelity/
# On Server
ssh pi@starship2
cd ~/fidelity
chmod +x FINAL_FIX.sh
./FINAL_FIX.sh
```
## What Will Happen
The FINAL_FIX.sh script will:
1. Stop containers
2. Remove backend image
3. Rebuild backend with fixed code
4. Start services
5. Test automatically
6. Show **SUCCESS!** if it works
## Expected Result
After the fix:
-`GET /api/accounts` returns HTTP 200 (not 307!)
- ✅ Response: `[]` (empty array)
- ✅ Account creation works in UI
- ✅ No more spinning/loading forever
## Why The Diagnostic Was So Helpful
The diagnostic showed:
1. ✅ Backend had correct main.py (no redirect_slashes=False)
2. ✅ Database connection worked perfectly
3. ✅ Environment variables were correct
4. ✅ Image was freshly built (2 minutes ago)
5. ❌ But routes were registered WITH trailing slashes
6. ❌ And HTTP test returned 307 redirect
This pointed directly to the route path issue!
## Lesson Learned
FastAPI's route registration is simple but subtle:
```python
# These are DIFFERENT:
@router.get("/") # With trailing slash
@router.get("") # Without trailing slash
# When combined with prefix "/api/accounts":
"/api/accounts" + "/" = "/api/accounts/" # Not what we want
"/api/accounts" + "" = "/api/accounts" # Perfect!
```
## Final Note
This is a common FastAPI gotcha. The framework's `redirect_slashes=True` parameter is supposed to handle this, but when routes are registered with explicit trailing slashes, it creates the redirect behavior we saw.
By using empty string `""` for the root route of each router, we match exactly what the frontend expects, and everything works!
---
**Status:** ✅ Root cause identified and fixed!
**Next:** Transfer files and rebuild
**Expected:** Account creation should work perfectly!