Skip to content

LeonardoChapal/readit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Readit

Plataforma web colaborativa de reseñas literarias, estilo Reddit. Los usuarios descubren libros, publican reseñas, votan, comentan y reciben recomendaciones personalizadas según sus intereses.

  • Backend: Python 3.10+, FastAPI, SQLAlchemy 2.0, PostgreSQL (Neon)
  • Frontend: React 19, TypeScript, Vite 8, TailwindCSS v4
  • Despliegue: Render (backend) · Vercel (frontend)

Funcionalidades

Cuentas y onboarding

  • Registro e inicio de sesión con JWT
  • Onboarding de 2 pasos al registrarse: selección de géneros favoritos (máx. 3) y libros ya leídos (máx. 5)
  • Edición de perfil (usuario, email, contraseña, avatar)
  • Sección "Tus intereses" en el perfil — visualiza géneros y etiquetas con los que el sistema te recomienda

Descubrimiento y feed

  • Feed global con ordenamiento (más votadas, más recientes, mayor calificación ★)
  • Feed personalizado de usuarios seguidos
  • Sección Trending semanal en el home
  • Recomendaciones personalizadas ("Para ti") con motivos transparentes — cada libro muestra POR QUÉ fue recomendado (ej. "Por Ficción", "#realismo mágico")
  • Página de descubrimiento por etiqueta (/etiqueta/:id) — todos los libros con una etiqueta dada
  • Libros relacionados en la página de cada libro, basados en etiquetas y género compartidos
  • Búsqueda de libros, reseñas y usuarios con filtro por género

Libros

  • Página de detalle con portada, sinopsis (descripción), género, año, etiquetas y calificación promedio
  • Importación desde Open Library
  • Subida de portada
  • Lista de lectura por estado (Quiero leer / Leyendo / Ya leí)

Reseñas y comunidad

  • Publicar, editar, eliminar y compartir reseñas con calificación de estrellas (1–5)
  • Votos (+1 / -1) con sistema de puntos
  • Comentarios anidados (hasta 4 niveles de profundidad)
  • Seguir y dejar de seguir a otros usuarios
  • Notificaciones (comentarios, votos, nuevos seguidores)

Sistema de recomendaciones

  • Algoritmo basado en pesos de intereses: género × 0.7 + etiqueta × 0.3 + popularidad × 0.2
  • Caché de 24 h por usuario en recommendation_cache
  • Tracking de actividad (view_book, vote, comment, add_to_list, search, etc.) para alimentar el sistema
  • Intereses inferidos: al agregar un libro a tu lista o votar +1 una reseña, el peso del género en tu perfil sube automáticamente

Administración

  • Modo oscuro en todo el panel
  • Toasts de feedback (éxito/error) al ejecutar acciones
  • Gestión de libros, reseñas, comentarios, géneros, etiquetas y usuarios
  • Importación masiva desde Open Library con asignación de género al vuelo
  • Edición inline de etiquetas por libro
  • Dashboard con stats: usuarios/libros/reseñas/comentarios, top reseñas, top usuarios, géneros con más libros (gráfico de barras) y libros más guardados en listas de lectura

Requisitos previos

  • Python 3.10+
  • Node.js 18+
  • npm 9+

Instalación local

Backend

cd backend
python -m venv venv
.\venv\Scripts\activate
pip install -r requirements.txt

Crea el archivo .env en backend/ con las siguientes variables:

DATABASE_URL=postgresql://usuario:contraseña@host.neon.tech/dbname
JWT_SECRET_KEY=una-clave-larga-y-segura
JWT_ALGORITHM=HS256
JWT_EXPIRATION_MINUTES=60
CORS_ORIGINS=http://localhost:5173

Frontend

cd frontend
npm install

Crea el archivo .env en frontend/ con:

VITE_API_URL=http://localhost:8000

Ejecución

Abre dos terminales desde la raíz del proyecto.

Terminal 1 — Backend

cd backend
.\venv\Scripts\activate
uvicorn main:app --reload

Disponible en http://localhost:8000. Documentación interactiva en http://localhost:8000/docs.

Terminal 2 — Frontend

cd frontend
npm run dev

Disponible en http://localhost:5173.


Migraciones

Las migraciones son scripts manuales en backend/. Ejecutar en orden:

cd backend
.\venv\Scripts\activate
python migrate_<nombre>.py

Scripts disponibles:

  • migrate_add_rating.py — calificación en reseñas
  • migrate_add_reading_list.py — lista de lectura por usuario
  • migrate_add_follow.py — sistema de seguidores
  • migrate_add_notification.py — notificaciones
  • migrate_recommendation_system.py — tablas de recomendaciones, etiquetas, intereses, actividad y grupos
  • migrate_add_book_description.py — columna description en book

Datos de ejemplo (seed)

seed_db.py puebla la base con:

  • 10 géneros
  • 16 etiquetas
  • 35 libros clásicos con descripciones
  • 8 usuarios de prueba (contraseña: lectura123)
  • 36 reseñas
  • 51 entradas de lista de lectura
  • Intereses preasignados (user_interest) por usuario para que las recomendaciones funcionen al primer login
cd backend
.\venv\Scripts\activate
python seed_db.py

El script es idempotente — se puede ejecutar varias veces sin duplicar nada y actualiza descripciones vacías en libros existentes.

Usuarios de prueba (contraseña: lectura123):

Usuario Gustos principales
ana_lectora Ficción, fantasía, terror
carlos_books Ficción, fantasía, ciencia ficción
sofia_lee Ciencia ficción, romance, no ficción
lucia_mendez Romance, clásicos
david_reads Ciencia ficción, fantasía, ciberpunk
marta_lit Thriller, terror, misterio
pablo_books Ficción, historia, no ficción
elena_pages No ficción, ensayo

Los emails siguen el patrón {usuario}@readit.com.


Cómo probar el sistema de recomendaciones

  1. Inicia sesión con cualquier usuario del seed (ej. david_reads / lectura123).
  2. En la página de inicio, la sección "Para ti" muestra hasta 6 libros recomendados, cada uno con un chip naranja que explica el motivo del match (Por Ciencia ficción, #ciberpunk, Popular, etc.).
  3. Visita el perfil del usuario para ver la sección "Tus intereses" con géneros y etiquetas en chips naranja (onboarding) o gris con etiqueta "inferido" (los que el sistema dedujo de la actividad).
  4. En la página de cualquier libro, al final hay "Si te gustó esto, también te puede gustar": libros relacionados ordenados por etiquetas compartidas (+2 puntos por etiqueta) y género igual (+1 punto).
  5. Haz clic en cualquier etiqueta (#realismo mágico, #ciberpunk, etc.) y aterrizarás en una página de descubrimiento con todos los libros de esa etiqueta.
  6. Agrega un libro a tu lista de lectura o vota +1 una reseña — el peso del género correspondiente en user_interest sube automáticamente (con source='inferred').

El caché de recomendaciones (recommendation_cache) dura 24 horas por usuario. Para invalidarlo manualmente, basta con borrar las filas de ese usuario en la tabla.


Notas técnicas

  • Constraint chk_ui_weight: el peso en user_interest está limitado por base de datos. Todos los routers limitan incrementos a 1.0 (min(weight + delta, 1.0)).
  • Eliminar libros desde admin elimina manualmente sus dependencias en cascada (notificaciones de sus reseñas, votos, comentarios, reseñas y entradas de lista de lectura) porque las FKs originales no tienen ON DELETE CASCADE.
  • Onboarding step 2 ordena los libros por relevancia según los géneros elegidos en step 1 (los libros del género seleccionado aparecen primero).
  • Toasts en admin: feedback visual (éxito/error) en todas las acciones de BooksPage con auto-dismiss en 3.5 s.
  • Schemas Pydantic: BookDetail se construye manualmente en get_book para evitar que from_attributes=True intente validar la relación book.tags (que devuelve BookTag, no TagSimple).

Estructura del proyecto

readit/
├── backend/
│   ├── main.py                          # Entry point FastAPI
│   ├── database.py
│   ├── auth.py                          # JWT, bcrypt, get_current_user
│   ├── seed_db.py                       # Datos de ejemplo
│   ├── requirements.txt
│   ├── migrate_*.py                     # Migraciones manuales
│   ├── models/
│   │   ├── user.py
│   │   ├── book.py                      # incluye campo description
│   │   ├── review.py
│   │   ├── comment.py                   # con parent_comment_id (anidados)
│   │   ├── vote.py
│   │   ├── genre.py
│   │   ├── reading_list.py
│   │   ├── follow.py
│   │   ├── notification.py
│   │   ├── tag.py                       # Tag + BookTag
│   │   ├── user_interest.py
│   │   ├── user_activity.py
│   │   ├── user_group.py                # UserGroup + Membership + Affinity
│   │   └── recommendation_cache.py
│   ├── schemas/
│   │   ├── user.py
│   │   ├── book.py
│   │   ├── review.py
│   │   ├── comment.py
│   │   ├── genre.py
│   │   ├── reading_list.py
│   │   ├── tag.py
│   │   └── recommendation.py
│   └── routers/
│       ├── auth.py
│       ├── books.py                     # incluye /related para libros similares
│       ├── reviews.py                   # incluye edición de reseña
│       ├── comments.py                  # crea, edita, borra comentarios anidados
│       ├── genres.py
│       ├── users.py                     # incluye /me/interests
│       ├── admin.py                     # stats + CRUD de admin
│       ├── search.py
│       ├── reading_list.py              # actualiza intereses inferidos
│       ├── feed.py
│       ├── notifications.py
│       ├── tags.py                      # incluye /tags/{id}/books
│       ├── onboarding.py                # /options y /complete
│       ├── activity.py                  # log de actividad
│       └── recommendations.py           # con caché de 24 h
└── frontend/
    └── src/
        ├── App.tsx
        ├── pages/
        │   ├── HomePage.tsx             # con "Para ti", trending, feed
        │   ├── BookPage.tsx             # con sinopsis y libros relacionados
        │   ├── TagPage.tsx              # descubrimiento por etiqueta
        │   ├── ReviewDetailPage.tsx     # con edición y comentarios anidados
        │   ├── CreateReviewPage.tsx
        │   ├── ExplorePage.tsx
        │   ├── ProfilePage.tsx          # con sección "Tus intereses"
        │   ├── SearchPage.tsx
        │   ├── OnboardingPage.tsx       # 2 pasos: géneros + libros leídos
        │   ├── LoginPage.tsx
        │   ├── RegisterPage.tsx
        │   ├── NotFoundPage.tsx
        │   └── admin/
        │       ├── DashboardPage.tsx    # con gráfico de géneros y top libros
        │       ├── BooksPage.tsx        # con edición de descripción y toasts
        │       ├── UsersPage.tsx
        │       ├── ReviewsPage.tsx
        │       ├── CommentsPage.tsx
        │       ├── GenresPage.tsx
        │       └── TagsPage.tsx
        ├── components/
        │   ├── Navbar.tsx
        │   ├── ReviewCard.tsx
        │   ├── CommentThread.tsx        # comentarios anidados con tracking
        │   ├── BookCover.tsx
        │   ├── SearchBar.tsx
        │   ├── StarRating.tsx
        │   ├── StarPicker.tsx
        │   ├── UserAvatar.tsx
        │   ├── Highlight.tsx
        │   ├── AdminLayout.tsx          # sidebar + dark mode toggle
        │   └── AdminRoute.tsx
        ├── hooks/
        │   ├── useAuth.tsx
        │   ├── useActivity.ts           # registro de actividad fire-and-forget
        │   └── useTheme.ts              # dark mode
        ├── lib/
        │   └── api.ts
        └── types/
            ├── auth.ts
            ├── book.ts
            ├── review.ts
            ├── reading_list.ts
            ├── recommendation.ts
            ├── comment.ts
            └── user.ts

Despliegue

Backend — Render

  • Root directory: backend
  • Build command: pip install -r requirements.txt
  • Start command: uvicorn main:app --host 0.0.0.0 --port $PORT
  • Variables de entorno: DATABASE_URL, JWT_SECRET_KEY, JWT_ALGORITHM, JWT_EXPIRATION_MINUTES, CORS_ORIGINS

Frontend — Vercel

  • Root directory: frontend
  • Variable de entorno: VITE_API_URL=https://tu-backend.onrender.com

Autor

Leonardo Chapal Díaz — ParqueSoftTI, Cohorte 37

About

Plataforma web de reseñas literarias tipo Reddit — FastAPI + React

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors