Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Herramienta de prospección comercial en Flask: encuentra, investiga y organiza empresas candidatas a servicios de cargue y descargue en Bogotá y municipios cercanos.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
Herramienta de prospección comercial para encontrar, investigar y gestionar empresas ubicadas en Bogotá y municipios cercanos (Funza, Mosquera, Chía, Cajicá, Cota y Madrid) que puedan necesitar servicios de cargue y descargue de mercancías: bodegas, centros de distribución, empresas logísticas, distribuidoras, mayoristas, importadoras, comercializadoras, empresas de alimentos/bebidas, industriales, etc.檢視完整 README ↗
Herramienta de prospección comercial para encontrar, investigar y gestionar empresas ubicadas en Bogotá y municipios cercanos (Funza, Mosquera, Chía, Cajicá, Cota y Madrid) que puedan necesitar servicios de cargue y descargue de mercancías: bodegas, centros de distribución, empresas logísticas, distribuidoras, mayoristas, importadoras, comercializadoras, empresas de alimentos/bebidas, industriales, etc.
La aplicación no contacta empresas automáticamente ni hace spam. Encuentra empresas en varias fuentes públicas, investiga y completa sus datos de contacto, elimina duplicados/cadenas, y da una herramienta ordenada para hacerles seguimiento comercial manual. El envío final de cualquier mensaje siempre lo hace la persona, desde su propio correo o WhatsApp.
La primera versión solo usaba OpenStreetMap (Overpass API): encontraba muchas empresas, pero casi ninguna tenía teléfono, email o sitio web, y cadenas grandes (Carulla, UNO, etc.) aparecían decenas de veces como si cada sucursal fuera una empresa distinta — cantidad sin calidad. Esta versión convierte el sistema de "buscador de empresas" a "buscador + investigador de empresas": combina varias fuentes, elimina duplicados/cadenas, y completa los datos de contacto que faltan antes de mostrar el resultado.
git clone https://github.com/Mundanesleet/Protector.git
cd Protector
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Linux/macOS
pip install -r requirements.txt
copy .env.example .env # Windows
# cp .env.example .env # Linux/macOS
python app.py
La aplicación queda disponible en http://127.0.0.1:5000/. La base de datos SQLite se crea automáticamente (instance/prospector.db) en el primer arranque; si ya existía de una versión anterior, las columnas nuevas se agregan solas sin perder datos (ver "Migraciones" más abajo).
Sin configurar ninguna key, la aplicación funciona igual usando solo OpenStreetMap — Google Places y Brave Search son mejoras opcionales.
.env)| Variable | Descripción | Obligatoria |
|---|---|---|
SECRET_KEY | Clave de Flask | No (tiene default de desarrollo) |
DATABASE_URL | URI de SQLAlchemy | No |
OVERPASS_API_URL / OVERPASS_TIMEOUT | Overpass API | No |
GOOGLE_MAPS_API_KEY | Habilita Google Places como fuente de búsqueda | No — sin ella, solo se usa Overpass |
BRAVE_SEARCH_API_KEY | Habilita la investigación con Brave Search | No — sin ella, el botón "Investigar" avisa que falta configurar |
Cómo obtener GOOGLE_MAPS_API_KEY: consola de Google Cloud → crear proyecto → activar facturación (obligatorio aunque el uso quede en $0 dentro del nivel gratis) → habilitar "Places API (New)" → Credentials → Create API Key.
Cómo obtener BRAVE_SEARCH_API_KEY: api-dashboard.search.brave.com → crear cuenta → nueva API key (no requiere tarjeta para el nivel gratis).
protector/
├── app.py # Application factory de Flask + migraciones ligeras
├── config.py # Configuracion via variables de entorno
├── database/__init__.py # Instancia SQLAlchemy (db) + ensure_schema_migrations()
├── models/ # Company, Prospect, Note, Location, Source
├── routes/ # Blueprints: controladores delgados
│ ├── main_routes.py # Vista del dashboard
│ ├── company_routes.py # /api/search, /api/companies*
│ ├── prospect_routes.py # /api/prospects*
│ └── api_routes.py # /api/stats, /api/meta
├── services/
│ ├── data_sources/
│ │ ├── overpass_service.py # Busqueda por tags de OpenStreetMap (gratis)
│ │ ├── google_places_service.py # Busqueda por intencion comercial (Google Places)
│ │ └── brave_search_service.py # Investigacion web (sitio oficial, Facebook, LinkedIn)
│ ├── company_service.py # Dedup/cadenas, filtros, normalizacion, export a Excel
│ ├── company_enrichment_service.py # Orquesta Brave + contact_finder por empresa
│ ├── contact_finder_service.py # Extrae email/WhatsApp de la web propia de una empresa
│ └── message_template_service.py # Mensaje sugerido y editable por categoria
├── templates/ # Jinja2 + Bootstrap 5
└── static/
├── css/style.css
└── js/{app,dashboard,map}.js
Por qué esta separación:
services/data_sources/ aísla cada fuente de búsqueda externa. Las tres exponen la misma forma de resultado (dict con name, address, phone, website, source, source_id, etc.), así que company_service.save_companies() no necesita saber de dónde vino cada empresa.company_enrichment_service.py está separado de company_service.py porque orquesta otro servicio (brave_search_service) más el ya existente contact_finder_service — es lógica de composición, no de persistencia.models/: Company son los datos de la empresa; Location son sucursales legítimas de una empresa con varias sedes reales (no cadenas grandes, esas se excluyen); Source guarda de dónde vino cada dato individual (campo + tipo de fuente + URL + fecha); Prospect/Note son la gestión comercial, separada a propósito de los datos de la empresa.SQLite/db.create_all() crea tablas nuevas pero no agrega columnas a una tabla que ya existe con datos. database/ensure_schema_migrations() corre ALTER TABLE para las columnas nuevas la primera vez que hacen falta, y se llama automáticamente al arrancar la app — no hay que hacer nada manual, y los datos existentes nunca se borran.
Company tiene una restricción única (source, source_id); sin eso, se identifica por nombre + dirección + coordenadas.+57 XXXXXXXXXX) para que "+57 601 1234567", "(601) 1234567" y "6011234567" no se traten como datos distintos.POST /api/search acepta sources: ["overpass", "google_places"]. Si se piden varias, se corren todas y se combinan los resultados; si una falla (incluido "no configurada"), se reporta como advertencia sin tumbar la búsqueda completa mientras al menos una fuente funcione.
website está en "Pro" (5.000 gratis/mes). El teléfono se consigue igual, gratis, desde la propia web de la empresa.Desde la ficha de cada empresa:
Source con su procedencia. No sobreescribe datos ya confirmados, y no vuelve a gastar cuota de Brave si la misma empresa ya se investigó en las últimas 24 horas.Se eligió bajo demanda por empresa (no un proceso automático en lote) para que el usuario controle exactamente cuánta cuota gratuita de Brave Search se gasta, y porque enviar mensajes o investigar cientos de empresas automáticamente sin supervisión iba en contra del alcance original del proyecto (no spam).
Un borrador editable por categoría, con botones Abrir en correo/Abrir en WhatsApp que abren tu propio cliente con el destinatario y mensaje ya cargados — el clic final de enviar siempre lo das tú.
SQLite ya es gratis (es un archivo local, igual que sería un Excel) y evita los problemas reales de usar una hoja de cálculo como almacenamiento de una app web: bloqueo del archivo si lo tienes abierto mientras la app escribe, y tener que reimplementar a mano la deduplicación y las relaciones que aquí ya resuelve el ORM. El botón Exportar a Excel genera un .xlsx bajo demanda como respaldo portable, sin ese riesgo.
| Método | Ruta | Descripción |
|---|---|---|
POST | /api/search | Busca empresas (zones, categories, sources: overpass/google_places) y las guarda sin duplicar |
GET | /api/companies | Lista empresas (filtros: city, category, status, q, has_phone, has_website) |
GET | /api/companies/export | Descarga en .xlsx las empresas (mismos filtros que arriba) |
GET | /api/companies/<id> | Detalle de una empresa (incluye prospecto, notas, fuentes por dato y mensaje sugerido) |
POST | /api/companies/<id>/find-contact | Busca email/WhatsApp en la web ya conocida de la empresa |
POST | /api/companies/<id>/enrich | Investiga con Brave Search + web propia (force: true para saltar el enfriamiento de 24h) |
POST | /api/companies/cleanup-chains | Limpia retroactivamente cadenas/franquicias ya guardadas |
PUT | /api/companies/<id> | Edición manual de una empresa |
POST | /api/companies/<id>/save | Guarda una empresa como prospecto (idempotente) |
PUT | /api/prospects/<id> | Cambia el estado comercial de un prospecto |
POST | /api/prospects/<id>/notes | Agrega una nota comercial |
GET | /api/stats | Estadísticas para las tarjetas del dashboard |
GET | /api/meta | Zonas, categorías y estados disponibles (usado por el frontend) |
Todas las respuestas son JSON. Los errores nunca exponen detalles técnicos al usuario ({"error": "mensaje amigable"}); el detalle técnico queda en el log del servidor. Ninguna API key llega nunca al frontend — todas las llamadas externas se hacen desde el backend.
| Fuente | Nivel gratis | Costo después |
|---|---|---|
| Overpass API (OpenStreetMap) | Ilimitado, pero es un recurso público compartido: puede responder lento o con error en horas de alta demanda | Gratis siempre |
| Google Places Text Search (campos usados: nombre, dirección, ubicación, website — nivel "Pro") | 5.000 solicitudes/mes | US$32 por cada 1.000 adicionales |
| Brave Search API | US$5 en crédito automático/mes (≈1.000 búsquedas) | US$5 por cada 1.000 adicionales |
Recomendaciones para no superar la cuota:
google_places_service.py ya evita relanzar la misma consulta dentro de 6 horas.No implementado todavía (a propósito): login/registro, pagos, envío automático de WhatsApp/email, scraping agresivo de redes sociales, IA generativa, Docker.