🔗 InnovaLinks

Spec v1.0 · .NET (ASP.NET Core) + SQLite + JWT · API → Dokploy · Front → Cloudflare Pages


📖 ¿Qué es?

Acortador de URLs como Bitly. El usuario registra una URL larga, elige un slug personalizado y recibe un enlace corto. Cada visita redirige automáticamente y suma un clic al contador.


🧠 Modelo de datos

Tabla users

CampoTipoNotas
idUUIDPK, auto-generado
emailTEXTUNIQUE, NOT NULL
password_hashTEXTNOT NULL. Almacenar hash (bcrypt/argon2)
created_atDATETIMEDEFAULT NOW

Tabla links

CampoTipoNotas
idUUIDPK, auto-generado
user_idUUIDFK → users.id, NOT NULL
slugTEXTUNIQUE, NOT NULL
original_urlTEXTNOT NULL
enabledBOOLDEFAULT true
clicksINTDEFAULT 0
created_atDATETIMEDEFAULT NOW
updated_atDATETIMEDEFAULT NOW

📡 Endpoints

Auth

POST /api/auth/register público
{ // Request
  "email": "user@example.com",
  "password": "mipass"
}
// Response 201
{ "id": "uuid", "email": "user@example.com" }
// Error 409 — email ya registrado
POST /api/auth/login público
{ // Request
  "email": "user@example.com",
  "password": "mipass"
}
// Response 200
{ "token": "jwt...", "user": { "id": "uuid", "email": "user@example.com" } }
// Error 401 — credenciales inválidas

Links

Todos requieren Authorization: Bearer <token>

POST /api/links auth
{ // Request
  "url": "https://ejemplo.com/articulo/muy/largo",
  "slug": "mislug"
}
// Response 201
{
  "id": "uuid",
  "slug": "mislug",
  "short_url": "https://go.innovaisoft.com/mislug",
  "original_url": "https://ejemplo.com/articulo/muy/largo",
  "clicks": 0
}
// Error 409 — slug ya existe
GET /api/links auth
// Response 200 — lista de links del usuario autenticado
[
  {
    "id": "uuid",
    "slug": "mislug",
    "original_url": "https://ejemplo.com/articulo/muy/largo",
    "enabled": true,
    "clicks": 42,
    "created_at": "2025-10-06T..."
  }
]
PUT /api/links/{id} auth
{ // Request (ambos campos opcionales)
  "url": "https://nueva-url.com",
  "slug": "nuevo-slug"
}
// Response 200 — link actualizado
// Error 409 — slug ya ocupado
DELETE /api/links/{id} auth
// Response 204 — sin contenido
PATCH /api/links/{id}/toggle auth
// Response 200
{ "id": "uuid", "enabled": false }

🔄 Redirect público

Cualquier visita a GET /{slug} (sin auth) se resuelve así:

SituaciónCódigoRespuesta
✅ Slug existe + enabled: true302Redirige a la URL original. Contador +1.
🔧 Slug existe + enabled: false200Página HTML "Enlace en mantenimiento"
❌ Slug no existe404Página HTML 404 personalizada

🌐 Dominio


📦 Deploy

ComponenteDestino
API (.NET + SQLite)Dokploy (contenedor Docker)
Web ClientCloudflare Pages (estático)
Spec HTMLCloudflare Pages (vista previa)

🧭 Próximos pasos

  1. Aprobar spec ✅
  2. Definir subdominio exacto
  3. Crear repo en GitHub
  4. Crear proyecto .NET ASP.NET Core con endpoints
  5. Desplegar API en Dokploy
  6. Crear Web Client (frontend)

Innova IA Soft — Spec v1.0 — Octubre 2025