feat(backend): FastAPI + libSQL + auth register/login/me + tests (TDD)

- FastAPI app with lifespan, CORS, health endpoint
- SQLAlchemy 2.0 async with aiosqlite, Base/UUIDMixin/TenantMixin/TimestampMixin
- Tenant and User models with multi-tenant isolation
- Auth: register (creates tenant+user), login, /me endpoint
- JWT HS256 tokens, bcrypt password hashing
- Alembic async setup with initial migration
- 6 passing tests (register, login, wrong password, me, no token, health)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 17:26:31 +02:00
parent c3482bba8d
commit 907b7be0fd
24 changed files with 623 additions and 0 deletions

32
backend/app/db/base.py Normal file
View File

@@ -0,0 +1,32 @@
import uuid
from datetime import datetime, UTC
from sqlalchemy import String, Text
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
def uuid7() -> str:
return str(uuid.uuid4())
class Base(DeclarativeBase):
pass
class UUIDMixin:
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=uuid7)
class TenantMixin:
tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
class TimestampMixin:
created_at: Mapped[str] = mapped_column(
Text, default=lambda: datetime.now(UTC).isoformat()
)
updated_at: Mapped[str] = mapped_column(
Text,
default=lambda: datetime.now(UTC).isoformat(),
onupdate=lambda: datetime.now(UTC).isoformat(),
)