Files
instagram-clone/SPEC.md
OpenClaw Agent a3eca3b7da feat: implement Instagram clone SocialPhoto API
- FastAPI backend with SQLite database
- JWT authentication (register, login)
- User profiles with follow/unfollow
- Posts with image upload and likes/dislikes
- Comments with likes
- Global and personalized feed
- Comprehensive pytest test suite (37 tests)

TASK-ID: 758f4029-702
2026-04-16 03:20:48 +00:00

338 lines
8.3 KiB
Markdown

# SPEC.md — Instagram Clone (SocialPhoto)
> Sistema de red social para compartir imágenes con likes, comentarios y seguimiento de usuarios
## 1. Concepto & Visión
**SocialPhoto** es un clon minimalista de Instagram que prioriza la simplicidad y velocidad. Permite a usuarios registrarse, subir imágenes, interactuar con publicaciones (likes/no me gusta), comentar y seguir a otros usuarios. El enfoque es en ser rápido, portable (todo en un archivo SQLite) y fácil de desplegar.
**Principios:**
- Simple de instalar y operar
- Base de datos portable (SQLite)
- API RESTful clara y documentada
- Ideal para testing de agentes de IA
---
## 2. Stack Tecnológico
| Componente | Tecnología |
|------------|------------|
| **Backend** | Python 3.11+ con FastAPI |
| **Base de datos** | SQLite3 |
| **Auth** | JWT (python-jose) |
| **Upload imágenes** | Almacenamiento local en `/uploads` |
| **Password hashing** | bcrypt |
| **Testing** | pytest + pytest-asyncio |
| **CLI (testing)** | curl o httpie |
---
## 3. Modelo de Datos (SQLite)
### Tabla: `users`
```sql
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
avatar_url TEXT DEFAULT '/static/default-avatar.png',
bio TEXT DEFAULT '',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
### Tabla: `posts`
```sql
CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id),
image_path TEXT NOT NULL,
caption TEXT DEFAULT '',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
### Tabla: `comments`
```sql
CREATE TABLE comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id INTEGER NOT NULL REFERENCES posts(id),
user_id INTEGER NOT NULL REFERENCES users(id),
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
### Tabla: `likes`
```sql
CREATE TABLE likes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id INTEGER NOT NULL REFERENCES posts(id),
user_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(post_id, user_id)
);
```
### Tabla: `dislikes`
```sql
CREATE TABLE dislikes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id INTEGER NOT NULL REFERENCES posts(id),
user_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(post_id, user_id)
);
```
### Tabla: `follows`
```sql
CREATE TABLE follows (
id INTEGER PRIMARY KEY AUTOINCREMENT,
follower_id INTEGER NOT NULL REFERENCES users(id),
following_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(follower_id, following_id)
);
```
### Tabla: `comment_likes`
```sql
CREATE TABLE comment_likes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
comment_id INTEGER NOT NULL REFERENCES comments(id),
user_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(comment_id, user_id)
);
```
---
## 4. API Endpoints
### Autenticación
| Método | Endpoint | Descripción |
|--------|----------|-------------|
| POST | `/auth/register` | Registrar usuario |
| POST | `/auth/login` | Login, retorna JWT |
**Register Request:**
```json
{
"username": "daniel",
"email": "daniel@example.com",
"password": "mipass123"
}
```
**Login Response:**
```json
{
"access_token": "eyJ...",
"token_type": "bearer"
}
```
---
### Usuarios
| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET | `/users/{id}` | Obtener perfil de usuario |
| GET | `/users/{id}/posts` | Posts de un usuario |
| GET | `/users/{id}/stats` | Stats (posts, followers, following) |
| POST | `/users/{id}/follow` | Seguir usuario |
| DELETE | `/users/{id}/follow` | Dejar de seguir |
---
### Posts
| Método | Endpoint | Descripción |
|--------|----------|-------------|
| POST | `/posts` | Crear post (con imagen) |
| GET | `/posts` | Feed global |
| GET | `/posts/{id}` | Detalle de post |
| DELETE | `/posts/{id}` | Eliminar post |
| POST | `/posts/{id}/like` | Dar like |
| DELETE | `/posts/{id}/like` | Quitar like |
| POST | `/posts/{id}/dislike` | Dar no me gusta |
| DELETE | `/posts/{id}/dislike` | Quitar no me gusta |
**Crear Post:**
```
POST /posts
Content-Type: multipart/form-data
caption: "Mi primera foto"
image: <archivo>
```
**Response:**
```json
{
"id": 1,
"user_id": 1,
"username": "daniel",
"image_url": "/uploads/abc123.jpg",
"caption": "Mi primera foto",
"likes_count": 0,
"dislikes_count": 0,
"comments_count": 0,
"created_at": "2026-04-15T22:00:00Z"
}
```
---
### Comentarios
| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET | `/posts/{post_id}/comments` | Listar comentarios |
| POST | `/posts/{post_id}/comments` | Agregar comentario |
| DELETE | `/comments/{id}` | Eliminar comentario |
| POST | `/comments/{id}/like` | Dar like a comentario |
---
### Feed
| Método | Endpoint | Descripción |
|--------|----------|-------------|
| GET | `/feed` | Feed de usuarios que sigues |
| GET | `/feed/global` | Feed global (todos) |
**Query params:** `?limit=20&offset=0`
---
## 5. Detalles de Implementación
### Upload de Imágenes
- Directorio: `./uploads/`
- Nombres: `{uuid}_{original_filename}`
- Formatos: jpg, jpeg, png, gif, webp
- Tamaño máximo: 10MB
### Auth JWT
- Algorithm: HS256
- Expiración: 24 horas
- Header: `Authorization: Bearer <token>`
### Likes/Dislikes
- Un usuario solo puede dar UN like O un dislike por post (no ambos)
- Dar dislike si ya hay like lo reemplaza
- Dar like si ya hay dislike lo reemplaza
### Follow
- No puedes seguirte a ti mismo
- Mensaje de error si intentas seguir alguien que ya sigues
### Timestamps
- Todos en UTC
- Formato ISO 8601 en responses
---
## 6. Estructura del Proyecto
```
socialphoto/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI app
│ ├── database.py # SQLite connection + setup
│ ├── models.py # Pydantic models
│ ├── auth.py # JWT auth helpers
│ ├── routes/
│ │ ├── __init__.py
│ │ ├── auth.py
│ │ ├── users.py
│ │ ├── posts.py
│ │ ├── comments.py
│ │ └── feed.py
│ └── services/
│ └── __init__.py
├── uploads/ # Imágenes
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_auth.py
│ ├── test_posts.py
│ └── test_social.py
├── requirements.txt
├── SPEC.md
└── README.md
```
---
## 7. Criterios de Aceptación
### Auth
- [x] Usuario puede registrarse con username, email, password
- [x] Usuario puede hacer login y recibe JWT
- [x] Rutas protegidas requieren token válido
- [x] No permite registro con username/email duplicado
### Posts
- [x] Usuario puede crear post con imagen y caption
- [x] Feed global muestra todos los posts ordenados por fecha
- [x] Feed personalizado solo muestra posts de usuarios seguidos
- [x] Usuario puede eliminar SUS propios posts
### Likes / Dislikes
- [x] Usuario puede dar like a un post
- [x] Usuario puede dar dislike a un post
- [x] Like y dislike son mutuamente excluyentes
- [x] Contador de likes/dislikes se actualiza en tiempo real
### Comentarios
- [x] Usuario puede comentar en un post
- [x] Usuario puede eliminar SUS comentarios
- [x] Lista de comentarios incluye username y timestamp
### Follow
- [x] Usuario puede seguir a otro usuario
- [x] Usuario puede dejar de seguir
- [x] No puede followearse a sí mismo
- [x] Stats muestran followers y following count
---
## 8. Roadmap de Tasks (para Task Manager)
1. **Architecture**: Crear SPEC.md y estructura del proyecto ✓
2. **Backlog**:
- [x] Setup proyecto FastAPI con SQLite
- [x] Implementar auth (register, login, JWT)
- [x] CRUD posts con upload de imágenes
- [x] Sistema de likes/dislikes
- [x] Sistema de comentarios
- [x] Sistema de follow/unfollow
- [x] Feed global y personalizado
- [x] Tests unitarios
- [ ] README y documentación
---
## 9. Notas
- Usar SQLite para simplicidad y portabilidad
- No requiere Docker ni servicios externos
- Ideal para testing de SDMAS Orchestrator
- En producción real se migraría a PostgreSQL