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

8.3 KiB

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

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

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

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

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

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

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

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:

{
    "username": "daniel",
    "email": "daniel@example.com",
    "password": "mipass123"
}

Login Response:

{
    "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:

{
    "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

  • Usuario puede registrarse con username, email, password
  • Usuario puede hacer login y recibe JWT
  • Rutas protegidas requieren token válido
  • No permite registro con username/email duplicado

Posts

  • Usuario puede crear post con imagen y caption
  • Feed global muestra todos los posts ordenados por fecha
  • Feed personalizado solo muestra posts de usuarios seguidos
  • Usuario puede eliminar SUS propios posts

Likes / Dislikes

  • Usuario puede dar like a un post
  • Usuario puede dar dislike a un post
  • Like y dislike son mutuamente excluyentes
  • Contador de likes/dislikes se actualiza en tiempo real

Comentarios

  • Usuario puede comentar en un post
  • Usuario puede eliminar SUS comentarios
  • Lista de comentarios incluye username y timestamp

Follow

  • Usuario puede seguir a otro usuario
  • Usuario puede dejar de seguir
  • No puede followearse a sí mismo
  • Stats muestran followers y following count

8. Roadmap de Tasks (para Task Manager)

  1. Architecture: Crear SPEC.md y estructura del proyecto ✓
  2. Backlog:
    • Setup proyecto FastAPI con SQLite
    • Implementar auth (register, login, JWT)
    • CRUD posts con upload de imágenes
    • Sistema de likes/dislikes
    • Sistema de comentarios
    • Sistema de follow/unfollow
    • Feed global y personalizado
    • 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