# Emergency Fix: Telegram ID References Removed **Date:** 2025-11-09 **Status:** ✅ FIXED **Severity:** CRITICAL (Production login broken) --- ## Problem After migrating database to remove `telegram_id` column, login was completely broken: - SQL queries still referenced `telegram_id` column - Column physically dropped but code not updated - Users unable to login/register **Error:** `column "telegram_id" does not exist` --- ## Root Cause Database migration script (`migrate_steam_support.py`) successfully: - ✅ Added new columns (steam_id, email, premium_expires_at, account_type) - ✅ Dropped telegram_id column But code was not updated: - ❌ `database.py` still defined telegram_id in schema - ❌ Functions still queried telegram_id - ❌ API endpoints still returned telegram_id --- ## Files Changed ### 1. `/api/database.py` **Removed:** - Line 41: `Column("telegram_id", Integer, unique=True, nullable=True)` from table definition - Lines 315-320: `get_player_by_telegram_id()` function (deleted entirely) - Line 338: `telegram_id` parameter from `create_player()` function **Before:** ```python players = Table( "players", metadata, Column("id", Integer, primary_key=True, autoincrement=True), Column("telegram_id", Integer, unique=True, nullable=True), # ❌ REMOVED Column("username", String(50), unique=True, nullable=True), ... ) async def get_player_by_telegram_id(telegram_id: int): # ❌ REMOVED async with DatabaseSession() as session: result = await session.execute( select(players).where(players.c.telegram_id == telegram_id) ) ... async def create_player( username: Optional[str] = None, password_hash: Optional[str] = None, telegram_id: Optional[int] = None, # ❌ REMOVED name: str = "Survivor" ): ... ``` **After:** ```python players = Table( "players", metadata, Column("id", Integer, primary_key=True, autoincrement=True), Column("username", String(50), unique=True, nullable=True), # ✅ Clean ... ) # get_player_by_telegram_id() deleted ✅ async def create_player( username: Optional[str] = None, password_hash: Optional[str] = None, name: str = "Survivor" # ✅ No telegram_id ): ... ``` ### 2. `/api/main.py` **Removed:** - Line 426: `telegram_id` from `get_me()` response - Lines 4123-4127: `/api/internal/player/{telegram_id}` endpoint (deleted) - Lines 4188-4192: `create_telegram_player()` function (deleted) **Before:** ```python @app.get("/api/auth/me") async def get_me(current_user: dict = Depends(get_current_user)): return { "id": current_user["id"], "username": current_user.get("username"), "telegram_id": current_user.get("telegram_id"), # ❌ REMOVED ... } @app.get("/api/internal/player/{telegram_id}") # ❌ REMOVED async def get_player_by_telegram(telegram_id: int): player = await db.get_player_by_telegram_id(telegram_id) ... @app.post("/api/internal/player") # ❌ REMOVED async def create_telegram_player(telegram_id: int, name: str = "Survivor"): player = await db.create_player(telegram_id=telegram_id, name=name) ... ``` **After:** ```python @app.get("/api/auth/me") async def get_me(current_user: dict = Depends(get_current_user)): return { "id": current_user["id"], "username": current_user.get("username"), # ✅ No telegram_id ... } # Telegram endpoints deleted ✅ ``` --- ## Deployment Steps 1. **Code Changes:** ```bash # Edited api/database.py # Edited api/main.py ``` 2. **Container Rebuild:** ```bash docker compose up -d --build echoes_of_the_ashes_api ``` 3. **Verification:** ```bash docker logs echoes_of_the_ashes_api --tail 30 ``` Result: ✅ Login working ``` 192.168.32.2 - "POST /api/auth/login HTTP/1.1" 200 192.168.32.2 - "GET /api/auth/me HTTP/1.1" 200 ``` --- ## Testing Checklist - [x] Login with existing user works - [x] Register new user works - [x] `/api/auth/me` returns user data (without telegram_id) - [x] Game loads after login - [x] WebSocket connection established - [x] No SQL errors in logs --- ## Impact Analysis ### ✅ Fixed - Login functionality restored - User registration working - User profile endpoint clean - No more SQL column errors ### ⚠️ Breaking Changes - **Removed endpoints** (no longer needed): - `GET /api/internal/player/{telegram_id}` - `POST /api/internal/player` (create_telegram_player) - **Removed function:** - `get_player_by_telegram_id()` in database.py ### 🔄 Still TODO (Future Work) - Complete account/player separation (see ACCOUNT_PLAYER_SEPARATION_PLAN.md) - Multi-character support - Email-based authentication - Steam integration - Tauri desktop build --- ## Prevention Measures **Lesson Learned:** When dropping database columns, must also: 1. Update SQLAlchemy table definitions 2. Remove/update all functions that query the column 3. Remove/update all API endpoints that return the column 4. Remove parameters from functions that accept the column 5. Test thoroughly before deployment **Better Process:** 1. Create migration script 2. Search codebase for all references: `grep -r "column_name"` 3. Update all code references 4. Run migration 5. Rebuild containers 6. Test --- ## Related Documents - `STEAM_AND_PREMIUM_PLAN.md` - Full Steam/premium implementation plan - `ACCOUNT_PLAYER_SEPARATION_PLAN.md` - Major refactor plan (accounts + characters) - `migrate_steam_support.py` - Original migration that dropped telegram_id - `CHANGELOG_STEAM_ICONS_2025-11-09.md` - Previous session changes --- ## Next Steps **IMMEDIATE (This is done ✅):** - [x] Remove telegram_id references - [x] Test login - [x] Deploy fix **SHORT TERM (Next sprint):** - [ ] Implement email field usage in registration - [ ] Add email validation - [ ] Start account/player separation **LONG TERM:** - [ ] Multi-character system - [ ] Steam authentication - [ ] Tauri desktop app - [ ] Avatar creator --- **Status:** Production is stable. Login working. Emergency resolved. ✅