Skip to content

Commit be9f683

Browse files
committed
Add DELETE endpoint and update frontend to support topic deletion
1 parent 979c08d commit be9f683

File tree

5 files changed

+375
-231
lines changed

5 files changed

+375
-231
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# Topics Manager - Backend API
2+
3+
## 📡 Endpoints Implementados
4+
5+
### 1. GET `/api/topics`
6+
Obtiene la lista de todos los topics.
7+
8+
**Respuesta exitosa (200):**
9+
```json
10+
[
11+
{
12+
"id": "507f1f77bcf86cd799439011",
13+
"name": "React Basics"
14+
},
15+
{
16+
"id": "507f1f77bcf86cd799439012",
17+
"name": "TypeScript Advanced"
18+
}
19+
]
20+
```
21+
22+
**Uso:**
23+
```typescript
24+
fetch("http://localhost:8080/api/topics")
25+
.then(res => res.json())
26+
.then(topics => console.log(topics))
27+
```
28+
29+
---
30+
31+
### 2. POST `/api/topics`
32+
Crea un nuevo topic.
33+
34+
**Parámetros (JSON):**
35+
```json
36+
{
37+
"name": "New Topic Name"
38+
}
39+
```
40+
41+
**Respuesta exitosa (200):**
42+
```json
43+
{
44+
"_id": "507f1f77bcf86cd799439013",
45+
"name": "New Topic Name",
46+
"__v": 0
47+
}
48+
```
49+
50+
**Uso:**
51+
```typescript
52+
fetch("http://localhost:8080/api/topics", {
53+
method: "POST",
54+
headers: {
55+
"Content-Type": "application/json"
56+
},
57+
body: JSON.stringify({ name: "New Topic" })
58+
})
59+
.then(res => res.json())
60+
.then(result => console.log(result))
61+
```
62+
63+
---
64+
65+
### 3. DELETE `/api/topics/:id` ✅ NUEVA
66+
Elimina un topic específico por su ID.
67+
68+
**Parámetros:**
69+
- `id` (URL parameter): ID de MongoDB del topic
70+
71+
**Respuesta exitosa (200):**
72+
```json
73+
{
74+
"message": "Topic deleted successfully",
75+
"id": "507f1f77bcf86cd799439011"
76+
}
77+
```
78+
79+
**Respuesta error - no encontrado (404):**
80+
```json
81+
{
82+
"error": "Topic not found"
83+
}
84+
```
85+
86+
**Respuesta error - validación (400):**
87+
```json
88+
{
89+
"error": "Invalid topic ID"
90+
}
91+
```
92+
93+
**Uso:**
94+
```typescript
95+
fetch("http://localhost:8080/api/topics/507f1f77bcf86cd799439011", {
96+
method: "DELETE"
97+
})
98+
.then(res => res.json())
99+
.then(result => console.log(result))
100+
```
101+
102+
---
103+
104+
## 🔧 Características de Seguridad
105+
106+
**Validación de ID**: Usa `findByIdAndDelete` que valida automáticamente IDs de MongoDB
107+
**Manejo de errores**: Retorna errores apropiadios (404 si no existe, 400 para validación)
108+
**Logging**: Logs en consola para debugging
109+
**CORS**: Habilitado para todas las rutas
110+
111+
---
112+
113+
## 📊 Código Implementado
114+
115+
### Backend (`index.js`)
116+
```javascript
117+
router.delete("/topics/:id", async (req, res) => {
118+
console.log("[DELETE] Topic by ID:", req.params.id);
119+
120+
try {
121+
const result = await Topic.findByIdAndDelete(req.params.id);
122+
if (!result) {
123+
return res.status(404).send({ error: "Topic not found" });
124+
}
125+
console.log("Deleted topic:", result);
126+
res.send({ message: "Topic deleted successfully", id: req.params.id });
127+
} catch (error) {
128+
console.error(error);
129+
res.status(400).send({ error: error.message });
130+
}
131+
});
132+
```
133+
134+
### Frontend (`topic-table.tsx`)
135+
```typescript
136+
const handleDeleteTopic = async (id: string) => {
137+
if (!window.confirm("Are you sure you want to delete this topic?")) {
138+
return;
139+
}
140+
141+
try {
142+
const response = await fetch(`http://localhost:8080/api/topics/${id}`, {
143+
method: "DELETE",
144+
});
145+
146+
if (!response.ok) {
147+
throw new Error("Failed to delete topic");
148+
}
149+
150+
await fetchTopics();
151+
} catch (error) {
152+
console.error("Error deleting topic:", error);
153+
setError("Failed to delete topic. Please try again.");
154+
}
155+
};
156+
```
157+
158+
---
159+
160+
## 🎯 Flujo de Uso
161+
162+
1. **Usuario hace click en "Delete"** en el botón de la tarjeta de topic
163+
2. **Se muestra confirmación** con `window.confirm()`
164+
3. **Se envía DELETE request** a `/api/topics/:id`
165+
4. **Backend elimina el topic** de la base de datos
166+
5. **Frontend recarga la lista** y muestra el resultado
167+
168+
---
169+
170+
## ✨ Mejoras Futuras
171+
172+
- [ ] Soft delete (marcar como eliminado sin borrar)
173+
- [ ] Historial de eliminaciones
174+
- [ ] Recuperación de topics eliminados
175+
- [ ] Batch delete (eliminar múltiples)
176+
- [ ] Confirmación adicional con email

01-contenedores/contenedores-vi/my-app/backend/index.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,22 @@ router.get("/topics", async (_, res) => {
6767
}
6868
});
6969

70+
router.delete("/topics/:id", async (req, res) => {
71+
console.log("[DELETE] Topic by ID:", req.params.id);
72+
73+
try {
74+
const result = await Topic.findByIdAndDelete(req.params.id);
75+
if (!result) {
76+
return res.status(404).send({ error: "Topic not found" });
77+
}
78+
console.log("Deleted topic:", result);
79+
res.send({ message: "Topic deleted successfully", id: req.params.id });
80+
} catch (error) {
81+
console.error(error);
82+
res.status(400).send({ error: error.message });
83+
}
84+
});
85+
7086
//all routes will be prefixed with /api
7187
app.use("/api", router);
7288

01-contenedores/contenedores-vi/my-app/compose.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ services:
1717
build:
1818
context: ./backend
1919

20+
develop:
21+
watch:
22+
- action: rebuild
23+
path: ./backend
24+
2025
ports:
2126
- 8080:8080
2227
depends_on:

0 commit comments

Comments
 (0)