Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions DOCS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# 🎬 MovieWebProject — Guía de instalación

Guía completa para levantar el proyecto frontend + backend, configurar las variables de entorno y preparar la base de datos.

## 📖 Índice

1. [🚀 Comandos principales](#-comandos-principales-post-instalación)
2. [⚙️ Instalación paso a paso](#%EF%B8%8F-instalación-paso-a-paso)
3. [🧠 Configuración del Backend](#-configuración-del-backend)
4. [🎨 Configuración del Frontend](#-configuración-de-frontend)
5. [🗄️ Base de Datos SQL (PostgreSQL)](#%EF%B8%8F-configuración-de-base-de-datos-sql-postgresql)
6. [☁️ Base de Datos NoSQL (MongoDB)](#configuración-de-base-de-datos-nosql-mongodb)
7. [🧩 Estructura del proyecto](#-estructura-del-proyecto)
8. [💡 Tips finales](#-tips-finales)
9. [🛠️ Stack Tecnológico](#%EF%B8%8F-stack-tecnológico)


## 🚀 Comandos principales (post instalación)

Ejecutar todo el proyecto (frontend + backend):
```bash
npm run dev:all
```

Migrar la base de datos (SQL):
```bash
npm run migrate
```

Ejecutar sólo el cliente (Astro):
```bash
npm run dev:client
```

Ejecutar sólo el servidor (Express):
```bash
npm run dev:server
```

## ⚙️ Instalación paso a paso

1️⃣ Clonar el repositorio
```bash
git clone https://github.com/lulibetelu/MovieWebProject.git
```

2️⃣ Instalar las dependencias
```bash
cd MovieWebProject
npm install # Dependencias del root
cd client && npm install # Dependencias del frontend
cd ../server && npm install # Dependencias del backend
cd ..
```
> 💡 Es importante instalar tanto las dependencias del root como las del cliente y servidor.

## 🧠 Configuración del Backend

📍 Ubicación: `/server`

Configurar las variables de entorno del __servidor__:
- Moverse a la carpeta `/server`.
- Copiar el archivo `.env.example` a `.env`.
- Configurar las variables:
- `PORT`: Puerto en el que se ejecutará el servidor (API).
- `DB_HOST`: Host de la base de datos.
- `DB_USER`: Usuario de la base de datos.
- `DB_PASSWORD`: Contraseña de la base de datos.
- `DB_PORT`: Puerto de la base de datos.
- `DEBUG`: Modo de depuración (true/false).
- `API_MODE`: Modo API o RENDER (true).
- `SECRET_KEY`: Clave secreta para la aplicación. (texto random)
- `TMDB_API_KEY`: 🔑 Clave de API para la API de The Movie Database. (Crearse una cuenta en [TMDB](https://www.themoviedb.org/) y poner la api key)

Mas información sobre `server` en [README](README.md).

## 🎨 Configuración de Frontend

📍 Ubicación: `/client`

Configurar las variables de entorno del __cliente__:
- Moverse a la carpeta `/client`.
- Copiar el archivo `.env.example` a `.env`.
- Configurar las variables:
- `PUBLIC_TMDB_API_KEY`: 🔑 Misma que en el `server`.
- `PUBLIC_API_URL`: ruta al servidor (`http://localhost:3500/api`)
- `NLPCLOUD_TOKEN`: 🔑 Crearse una cuenta en [NLPCloud](https://nlpcloud.com/) y poner el token

Mas información sobre `client` en [README](./client/README.md).

## 🗄️ Configuración de Base de Datos SQL (PostgreSQL)

📍 Ubicación: `/db`

Correr los scripts de la carpeta en orden para modificar la base de datos local.
### Primera vez

- Ejecutar los __12 scripts base__ del profesor.
- Ejecutar el script 13 `/db/13_migration_table.sql`

### Despues de cada __git pull__

Ejecutar el comando `npm run migrate` (desde root) para actualizar la base de datos.

Mas información sobre `db` en [instrucciones](./db/instrucciones.txt).

## Configuración de Base de Datos NoSQL (MongoDB)

🚧 Próximamente…
La integración con MongoDB se encuentra en desarrollo.

## 🧩 Estructura del proyecto
```sh
MovieWebProject/
├── client/ → Frontend (Astro)
│ ├── src/
│ ├── public/
│ └── .env
├── server/ → Backend (Express + PostgreSQL)
│ ├── src/
│ ├── db/
│ └── .env
├── db/ → Scripts SQL
├── package.json → Scripts globales
└── README.md
```

## 💡 Tips finales

- 📦 Antes de correr npm run dev:all, asegurate de que PostgreSQL esté levantado.
- 🧠 Si hay errores de conexión, revisá las rutas de las variables .env.
- 🔥 El resumen automático de reseñas usa la API /api/summarize (NLPCloud).

## 🛠️ Stack Tecnológico

- Frontend: Astro, Tailwind CSS
- Backend: Express, Node.js
- Base de datos SQL: PostgreSQL
- Base de datos NoSQL: MongoDB (próximamente)
- APIs externas: TMDB, NLPCloud
3 changes: 2 additions & 1 deletion client/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
PUBLIC_TMDB_API_KEY="your_api_key"
PUBLIC_TMDB_API_KEY=your_api_key
PUBLIC_API_URL="http://localhost:3500/api"
NLPCLOUD_TOKEN=your_api_key
5 changes: 3 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "megafront",
"name": "client",
"type": "module",
"version": "0.0.1",
"version": "0.1.0",
"scripts": {
"dev": "astro dev --no-check",
"build": "astro build",
Expand All @@ -20,6 +20,7 @@
"daisyui": "^5.3.7",
"gsap": "^3.13.0",
"motion": "^12.23.24",
"nlpcloud": "^2.0.8",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"tailwindcss": "^4.1.15",
Expand Down
69 changes: 69 additions & 0 deletions client/src/components/reusables/AiReview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { useEffect, useState } from "react";

const AiReview = ({ reviews = [] }) => {
const [summary, setSummary] = useState(null);

useEffect(() => {
let ignore = false;
const controller = new AbortController();

async function summarize() {
console.log(null);

if (!reviews || reviews.length === 0) {
setSummary("Sin reseñas.");
return;
}

try {
// Unimos las reseñas en un solo string
const text = reviews.join(". ");

const res = await fetch("http://localhost:4321/api/summarize", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text }),
signal: controller.signal,
});

if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}

const data = await res.json();

if (!ignore) {
setSummary(data?.summary ?? "error");
}
} catch (err) {
if (!ignore) {
console.error("Error al conectar con la API:", err);
setSummary("error");
}
}
}

summarize();

return () => {
ignore = true;
controller.abort();
};
}, [reviews]);

return summary === "error" ? (
<p></p>
) : summary ? (
<div className="flex flex-col gap-2">
<h4 className="text-base-content text-xl font-semibold leading-snug">
Resumen de las reseñas:
</h4>

<p className="text-base-content/90 text-lg">{summary || ""}</p>
</div>
) : (
<div class="skeleton h-16 w-full"></div>
);
};

export default AiReview;
55 changes: 0 additions & 55 deletions client/src/components/reusables/MoviesCarousel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,58 +78,3 @@ const MoviesCarousel = ({ movieGroup = [], title = "", idx = 0 }) => {
};

export default MoviesCarousel;

{
/* Carousel
<div className="mt-10 w-full py-5 flex justify-center">
<div className="w-[90%] bg-base-200 px-5 py-5 rounded-lg shadow-lg">
<div className="carousel w-full">
{hasOut ? (
out.map((movieGroup, index) => (
<div
className="carousel-item w-full flex justify-center gap-4"
id={`item-${index}`}
key={`group-${index}`}
>
{Array.isArray(movieGroup) &&
movieGroup.length > 0 ? (
movieGroup.map((img, idx) => (
<div
className="card bg-base-300 shadow-xl"
key={`${index}-${idx}`}
>
<MovieImages
data={{
title: img,
apiKey: tmdbApiKey,
}}
/>
<div className="card-body">
<h2 className="card-title">
{typeof img === "string"
? img.slice(0, 28)
: String(img)}
</h2>
</div>
</div>
))
) : (
<div className="text-center text-gray-500">
No movies in this group
</div>
)}
</div>
))
) : hasResult ? (
<h1>Loaded!</h1>
) : (
<div className="text-center text-gray-500">
No movies available
</div>
)}
</div>
</div>

</div>
*/
}
37 changes: 37 additions & 0 deletions client/src/pages/api/summarize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import NLPCloudClient from "nlpcloud";

export const prerender = false;

const client = new NLPCloudClient({
model: "bart-large-cnn",
token: import.meta.env.NLPCLOUD_TOKEN,
});

export async function POST({ request }) {
const requestData = await request.json();
const reviewsText = requestData.text;

try {
const summary = await client.summarization({
text: reviewsText,
});

return new Response(
JSON.stringify({
summary: summary.data.summary_text,
}),
{
headers: { "Content-Type": "application/json" },
},
);
} catch (err) {
console.error("Error al resumir:", err);
return new Response(
JSON.stringify({
error: true,
message: err.message,
}),
{ status: 500 },
);
}
}
Loading