Fix dev stack startup: seed path, missing migration, passlib/bcrypt incompatibility

- python -m scripts.seed (module mode) fixes ModuleNotFoundError
- Add scripts/__init__.py to make scripts/ a proper package
- Generate initial Alembic migration for users table
- Replace passlib with direct bcrypt>=4.0 (passlib unmaintained, broken with bcrypt 4.x)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
curo1305
2026-04-12 16:03:03 +02:00
parent 61cef2eacd
commit e6d7888513
6 changed files with 79 additions and 7 deletions
@@ -0,0 +1,39 @@
"""create users table
Revision ID: 38efeff7c45a
Revises:
Create Date: 2026-04-12 14:00:30.503479
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
revision: str = '38efeff7c45a'
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('users',
sa.Column('id', sa.String(), nullable=False),
sa.Column('email', sa.String(), nullable=False),
sa.Column('hashed_password', sa.String(), nullable=False),
sa.Column('full_name', sa.String(), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('is_superuser', sa.Boolean(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_users_email'), table_name='users')
op.drop_table('users')
# ### end Alembic commands ###
+3 -5
View File
@@ -1,19 +1,17 @@
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
import bcrypt
from jose import jwt from jose import jwt
from passlib.context import CryptContext
from app.core.config import settings from app.core.config import settings
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def hash_password(password: str) -> str: def hash_password(password: str) -> str:
return pwd_context.hash(password) return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
def verify_password(plain: str, hashed: str) -> bool: def verify_password(plain: str, hashed: str) -> bool:
return pwd_context.verify(plain, hashed) return bcrypt.checkpw(plain.encode(), hashed.encode())
def create_access_token(subject: str) -> str: def create_access_token(subject: str) -> str:
+1 -1
View File
@@ -15,7 +15,7 @@ dependencies = [
"pydantic[email]>=2.7", "pydantic[email]>=2.7",
"pydantic-settings>=2.2", "pydantic-settings>=2.2",
"python-jose[cryptography]>=3.3", "python-jose[cryptography]>=3.3",
"passlib[bcrypt]>=1.7", "bcrypt>=4.0",
"python-multipart>=0.0.9", "python-multipart>=0.0.9",
] ]
View File
+1 -1
View File
@@ -5,7 +5,7 @@ echo "[start] running migrations..."
alembic upgrade head alembic upgrade head
echo "[start] seeding dev data..." echo "[start] seeding dev data..."
python scripts/seed.py python -m scripts.seed
echo "[start] starting uvicorn..." echo "[start] starting uvicorn..."
exec uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload exec uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
+35
View File
@@ -0,0 +1,35 @@
# 2026-04-12 — Troubleshoot dev stack startup
**Timestamp:** 2026-04-12T15:30:00
## Summary
Fixed three startup failures discovered when running the dev stack for the first time.
## Issues Fixed
1. **`ModuleNotFoundError: No module named 'app'`** — `python scripts/seed.py` does not add the working directory to `sys.path`. Changed to `python -m scripts.seed` which uses module mode and adds `/app` to the path. Added `backend/scripts/__init__.py` to make the directory a package.
2. **`relation "users" does not exist`** — No Alembic migration files existed, so `alembic upgrade head` was a no-op. Generated the initial migration (`38efeff7c45a_create_users_table.py`) by running `alembic revision --autogenerate` inside the backend container against the live database.
3. **`ValueError: password cannot be longer than 72 bytes` (passlib + bcrypt 4.x incompatibility)** — `passlib` is unmaintained and its bcrypt wrap-bug detection raises an exception against bcrypt 4.x. Replaced `passlib[bcrypt]` with direct `bcrypt>=4.0` usage in both `pyproject.toml` and `app/core/security.py`.
## Smoke Test Results (all passing)
- `GET /api/health``{"status":"ok"}`
- `POST /api/auth/login` → JWT token issued for `test@example.com`
- `GET /api/users/me` → returns user profile with valid token
- `POST /api/auth/register` → new user created successfully
- Weak password (`"password"`) → rejected with detailed validation errors
- Frontend `http://localhost:5173` → HTTP 200
## Files Added
- `backend/scripts/__init__.py` — makes scripts/ a Python package
- `backend/alembic/versions/38efeff7c45a_create_users_table.py` — initial migration
## Files Modified
- `backend/scripts/start_dev.sh``python scripts/seed.py``python -m scripts.seed`
- `backend/pyproject.toml``passlib[bcrypt]>=1.7``bcrypt>=4.0`
- `backend/app/core/security.py` — replaced passlib with direct bcrypt calls