Fabio Antonini Claude Sonnet 4.6 commited on
Commit
3d87cee
·
1 Parent(s): 977221f

fix: resolve local dev issues found during first test run

Browse files

- Replace passlib with bcrypt directly (passlib 1.7 incompatible with bcrypt 4.x)
- Fix SQLite engine config: disable pool_pre_ping, add check_same_thread=False
- Import all models in __init__.py so SQLAlchemy resolves relationships
- Change dev proxy port to 8001 (port 8000 occupied by Wacom service on dev machine)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

backend/auth/password.py CHANGED
@@ -1,15 +1,14 @@
1
  """
2
  GraphoLab Backend — Password hashing with bcrypt.
 
3
  """
4
 
5
- from passlib.context import CryptContext
6
-
7
- _ctx = CryptContext(schemes=["bcrypt"], deprecated="auto")
8
 
9
 
10
  def hash_password(plain: str) -> str:
11
- return _ctx.hash(plain)
12
 
13
 
14
  def verify_password(plain: str, hashed: str) -> bool:
15
- return _ctx.verify(plain, hashed)
 
1
  """
2
  GraphoLab Backend — Password hashing with bcrypt.
3
+ Uses bcrypt directly (passlib 1.7 is incompatible with bcrypt 4.x).
4
  """
5
 
6
+ import bcrypt
 
 
7
 
8
 
9
  def hash_password(plain: str) -> str:
10
+ return bcrypt.hashpw(plain.encode(), bcrypt.gensalt()).decode()
11
 
12
 
13
  def verify_password(plain: str, hashed: str) -> bool:
14
+ return bcrypt.checkpw(plain.encode(), hashed.encode())
backend/database.py CHANGED
@@ -9,11 +9,15 @@ from sqlalchemy.orm import DeclarativeBase
9
 
10
  from backend.config import settings
11
 
12
- engine = create_async_engine(
13
- settings.database_url,
14
- echo=settings.debug,
15
- pool_pre_ping=True,
16
- )
 
 
 
 
17
 
18
  AsyncSessionLocal = async_sessionmaker(
19
  bind=engine,
 
9
 
10
  from backend.config import settings
11
 
12
+ # SQLite needs check_same_thread=False; pool_pre_ping is not compatible with aiosqlite
13
+ _is_sqlite = settings.database_url.startswith("sqlite")
14
+ _engine_kwargs: dict = {"echo": settings.debug}
15
+ if _is_sqlite:
16
+ _engine_kwargs["connect_args"] = {"check_same_thread": False}
17
+ else:
18
+ _engine_kwargs["pool_pre_ping"] = True
19
+
20
+ engine = create_async_engine(settings.database_url, **_engine_kwargs)
21
 
22
  AsyncSessionLocal = async_sessionmaker(
23
  bind=engine,
backend/models/__init__.py CHANGED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Import all models so SQLAlchemy can resolve relationships regardless of import order.
2
+ from backend.models.user import User, Organization, Role # noqa: F401
3
+ from backend.models.project import Project, Document, Analysis, ProjectStatus, AnalysisType # noqa: F401
frontend/vite.config.ts CHANGED
@@ -14,7 +14,7 @@ export default defineConfig({
14
  port: 3000,
15
  proxy: {
16
  '/api': {
17
- target: 'http://localhost:8000',
18
  changeOrigin: true,
19
  rewrite: (p) => p.replace(/^\/api/, ''),
20
  },
 
14
  port: 3000,
15
  proxy: {
16
  '/api': {
17
+ target: 'http://localhost:8001',
18
  changeOrigin: true,
19
  rewrite: (p) => p.replace(/^\/api/, ''),
20
  },