prod: UI Optimisée mise en production

- Documentation archivée et réorganisée
- Backend: Ajout tests, migrations, library service, rate limiting
- Frontend: Suppression Flutter, focus sur interface web HTML/JS
- Tailwind CSS ajouté pour le style
- Améliorations UX et corrections bugs

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
root
2026-01-20 09:56:39 +00:00
parent bc03225e47
commit 801e6a050b
263 changed files with 33100 additions and 23058 deletions
+90
View File
@@ -0,0 +1,90 @@
"""Liked Track model."""
import uuid
from datetime import datetime
from typing import TYPE_CHECKING
from sqlalchemy import String, ForeignKey, Index
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.core.database import Base
if TYPE_CHECKING:
from app.models.user import User
from app.models.track import Track
class LikedTrack(Base):
"""Liked Track model representing user's liked/favorited tracks."""
__tablename__ = "liked_tracks"
# Primary key
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
index=True,
)
# Foreign keys
user_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
track_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("tracks.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
# Additional metadata
notes: Mapped[str | None] = mapped_column(
String(1000),
nullable=True,
comment="User notes about the track",
)
# Timestamps
created_at: Mapped[datetime] = mapped_column(
default=datetime.utcnow,
nullable=False,
)
updated_at: Mapped[datetime] = mapped_column(
default=datetime.utcnow,
onupdate=datetime.utcnow,
nullable=False,
)
# Relationships
user: Mapped["User"] = relationship(
"User",
back_populates="liked_tracks",
lazy="selectin",
)
track: Mapped["Track"] = relationship(
"Track",
lazy="selectin",
)
# Table indices for optimal queries and uniqueness constraint
__table_args__ = (
Index("ix_liked_tracks_user_track", "user_id", "track_id", unique=True),
)
def __repr__(self) -> str:
return f"<LikedTrack user={self.user_id} track={self.track_id}>"
def to_dict(self) -> dict:
"""Convert liked track model to dictionary."""
return {
"id": str(self.id),
"user_id": str(self.user_id),
"track_id": str(self.track_id),
"notes": self.notes,
"created_at": self.created_at.isoformat(),
"updated_at": self.updated_at.isoformat(),
}