Synaplan
Open-source AI platform for companies: self-hosted AI agents, GDPR-compliant chatbot widget, RAG knowledge base, WhatsApp and Outlook AI, MCP, multi-model routing. Docker, Kubernetes or hosted in Germ
Track job offers, match them to your search profiles, and review AI fit scores.
BusinessTypeScript · VueGitHub @ValentinOsvaldoLatest connection check failedOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗¿Nuevo en el proyecto? Empieza por docs/ONBOARDING.md.
cp .env.example .env # pon tu GEMINI_API_KEY
docker compose up --build
localhost:5432 (postgres/postgres)127.0.0.1.postgres_data (docker compose down -v los borra).Nota: el resto de este documento es la especificación original (multi-usuario con JWT); ya no refleja la autenticación actual.
Sistema personal de seguimiento de ofertas de trabajo con scraping automatizado y análisis de compatibilidad con IA. Diseñado para dos usuarios (Osvaldo y Guillermo) que comparten el sistema pero tienen perfiles de búsqueda independientes por rol (frontend, backend, fullstack, mobile). La IA evalúa cada oferta contra el perfil específico activo, extrae salario y prestaciones del texto, y presenta un top 5 de las mejores oportunidades por perfil.
| Capa | Tecnología | Justificación |
|---|---|---|
| Scraper | Python + FastAPI + Jobspy + APScheduler | Jobspy es la librería más madura para esto; se expone como microservicio mínimo |
| Backend | NestJS + TypeORM + PostgreSQL | Stack conocido, tipado, estructurado por módulos |
| IA | Groq API (llama-3.3-70b) | Gratuita, 14,400 req/día, compatible con SDK de OpenAI, latencia muy baja |
| Frontend | Nuxt 3 + Vue 3 + TanStack Query + Pinia | Stack conocido, SSR opcional, excelente DX |
| PDF parsing | pdf-parse (Node) | Extrae texto de CVs al momento de subir; texto se guarda en DB |
┌─────────────────────┐ ┌──────────────────────────────────────┐
│ Microservicio │ │ NestJS Backend │
│ Python (FastAPI) │──────▶ │ │
│ │ HTTP │ ┌──────────┐ ┌──────────────────┐ │
│ - Jobspy scraping │ │ │ /jobs │ │ /users │ │
│ - APScheduler cron │◀────── │ │ ingest │ │ CV upload │ │
│ - POST /scrape │ trigger│ └──────────┘ └──────────────────┘ │
└─────────────────────┘ │ │
│ ┌──────────────────────────────┐ │
│ │ Groq Service │ │
│ │ analiza oferta × usuario │ │
│ └──────────────────────────────┘ │
│ │ │
│ ┌───────────▼──────────────────┐ │
│ │ PostgreSQL │ │
│ │ users · jobs · analyses │ │
│ └──────────────────────────────┘ │
└──────────────┬───────────────────────┘
│ REST API
▼
┌──────────────────────────┐
│ Nuxt Frontend │
│ dashboard · detalle │
│ trigger manual scraper │
└──────────────────────────┘
usersid UUID PRIMARY KEY DEFAULT gen_random_uuid()
name VARCHAR(100) NOT NULL
email VARCHAR(150) UNIQUE NOT NULL
password_hash VARCHAR(255) NOT NULL -- bcrypt hash
cv_text TEXT -- texto extraído del PDF
cv_filename VARCHAR(255) -- nombre del archivo original
cv_uploaded_at TIMESTAMPTZ
created_at TIMESTAMPTZ DEFAULT NOW()
jobsid UUID PRIMARY KEY DEFAULT gen_random_uuid()
title VARCHAR(255) NOT NULL
company VARCHAR(255)
location VARCHAR(255)
description TEXT
url VARCHAR(500) UNIQUE -- evita duplicados
source VARCHAR(50) -- 'linkedin' | 'indeed'
date_posted DATE
scraped_at TIMESTAMPTZ DEFAULT NOW()
search_profilesid UUID PRIMARY KEY DEFAULT gen_random_uuid()
user_id UUID REFERENCES users(id) ON DELETE CASCADE
name VARCHAR(100) NOT NULL -- "Frontend", "Backend", "Mobile"
role VARCHAR(50) NOT NULL -- 'frontend' | 'backend' | 'fullstack' | 'mobile'
keywords TEXT[] -- ["vue", "react", "typescript"]
locations TEXT[] -- ["Mexico", "Remote"]
is_active BOOLEAN DEFAULT true
created_at TIMESTAMPTZ DEFAULT NOW()
This is the beginning of the README. Read the rest at the original. Read the full README ↗