33800 Docs

← Retour

Proposition : Setup NeedFinder Collector

Date : 20/12/2025 04:37 Status : En attente de validation Objectif : Mettre en place le collector NeedFinder avec workflow complet


Résumé

Setup du projet NeedFinder Collector avec :


Actions prévues

1. Création repo GitLab

# Sur gitlab.local
Nom: needfinder
Branches: main + develop
Visibilité: Private

2. Structure projet

needfinder/
├── package.json
├── tsconfig.json
├── Dockerfile
├── docker-compose.yml
├── conf.prod.gouroubleu.yml
├── conf.dev.gouroubleu.yml
├── src/
│   ├── index.ts              # Entry point API
│   ├── collectors/
│   │   ├── reddit.ts         # Collector Reddit
│   │   └── hackernews.ts     # Collector HN
│   ├── db/
│   │   └── schema.sql        # Tables Supabase
│   ├── services/
│   │   └── analyzer.ts       # Analyse IA (futur)
│   └── cron/
│       └── scheduler.ts      # Cron jobs
└── .env.example

3. Schéma Supabase dédié (sur DEV)

Principe : Chaque projet a son propre schéma PostgreSQL + son propre user avec accès limité.

-- ============================================
-- CRÉATION SCHÉMA DÉDIÉ
-- ============================================

-- Créer le schéma
CREATE SCHEMA IF NOT EXISTS needfinder;

-- Créer un rôle dédié pour ce projet
CREATE ROLE needfinder_service WITH LOGIN PASSWORD 'xxx';

-- Donner accès uniquement au schéma needfinder
GRANT USAGE ON SCHEMA needfinder TO needfinder_service;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA needfinder TO needfinder_service;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA needfinder TO needfinder_service;
ALTER DEFAULT PRIVILEGES IN SCHEMA needfinder GRANT ALL ON TABLES TO needfinder_service;
ALTER DEFAULT PRIVILEGES IN SCHEMA needfinder GRANT ALL ON SEQUENCES TO needfinder_service;

-- ============================================
-- TABLES DANS LE SCHÉMA NEEDFINDER
-- ============================================

-- Sources de données
CREATE TABLE needfinder.sources (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name VARCHAR(100) NOT NULL,
    is_active BOOLEAN DEFAULT true,
    last_collected_at TIMESTAMPTZ
);

-- Posts collectés
CREATE TABLE needfinder.posts (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    source_id UUID REFERENCES needfinder.sources(id),
    external_id VARCHAR(200) UNIQUE,
    external_url TEXT,
    title TEXT,
    content TEXT,
    author VARCHAR(200),
    subreddit VARCHAR(100),
    score INTEGER,
    comment_count INTEGER,
    posted_at TIMESTAMPTZ,
    collected_at TIMESTAMPTZ DEFAULT NOW(),
    is_processed BOOLEAN DEFAULT false
);

-- Besoins détectés
CREATE TABLE needfinder.needs (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    need_statement TEXT NOT NULL,
    category VARCHAR(100),
    mention_count INTEGER DEFAULT 1,
    first_seen_at TIMESTAMPTZ DEFAULT NOW(),
    last_seen_at TIMESTAMPTZ DEFAULT NOW(),
    opportunity_score INTEGER DEFAULT 0
);

-- Lien posts → needs
CREATE TABLE needfinder.mentions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    need_id UUID REFERENCES needfinder.needs(id),
    post_id UUID REFERENCES needfinder.posts(id),
    extracted_text TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(need_id, post_id)
);

-- Logs de collection
CREATE TABLE needfinder.collection_logs (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    source VARCHAR(50),
    status VARCHAR(20),
    posts_collected INTEGER DEFAULT 0,
    error_message TEXT,
    started_at TIMESTAMPTZ DEFAULT NOW(),
    completed_at TIMESTAMPTZ
);

-- Index
CREATE INDEX idx_posts_source ON needfinder.posts(source_id, posted_at DESC);
CREATE INDEX idx_posts_processed ON needfinder.posts(is_processed) WHERE is_processed = false;
CREATE INDEX idx_needs_score ON needfinder.needs(opportunity_score DESC);

3b. Credentials projet (à ajouter dans secrets/)

# Dans /mnt/stock_36to/data/33800-stack/docker/secrets/dev.env
# Section: NEEDFINDER
NEEDFINDER_DB_HOST=192.168.1.51
NEEDFINDER_DB_PORT=5432
NEEDFINDER_DB_NAME=postgres
NEEDFINDER_DB_SCHEMA=needfinder
NEEDFINDER_DB_USER=needfinder_service
NEEDFINDER_DB_PASSWORD=<généré>
NEEDFINDER_DB_URL=postgresql://needfinder_service:<password>@192.168.1.51:5432/postgres?schema=needfinder

4. Stack technique

Composant Techno
Runtime Bun
API Elysia
DB Supabase DEV
Cron Bun cron / node-cron
Container Docker

5. Déploiement dev-portainer

Propriété Valeur
Container needfinder-collector-dev
Port 5200
Image needfinder-collector:dev
Restart always
Cron Toutes les 6h

6. Config Nginx

# needfinder-api-dev.33800.nowhere84.com → dev-portainer:5200
server {
    listen 443 ssl http2;
    server_name needfinder-api-dev.33800.nowhere84.com;

    ssl_certificate /etc/letsencrypt/live/33800.nowhere84.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/33800.nowhere84.com/privkey.pem;

    location / {
        proxy_pass http://192.168.1.51:5200;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

7. Endpoints API (Phase 1)

GET  /health                 # Health check
GET  /api/stats              # Stats collection
POST /api/collect/reddit     # Trigger collecte Reddit
POST /api/collect/hn         # Trigger collecte HN
GET  /api/posts              # Liste posts collectés
GET  /api/needs              # Liste besoins détectés (futur)

8. Variables d'environnement

# .env.dev
SUPABASE_URL=https://supabase-api-dev.33800.nowhere84.com
SUPABASE_KEY=<service_role_key>
REDDIT_USER_AGENT=NeedFinder/1.0
CRON_INTERVAL=6h
PORT=5200

Étapes d'exécution

  1. [x] Créer repo GitLab needfinder
  2. [x] Créer structure projet sur vscode.local ✅
  3. [x] Créer tables Supabase DEV ✅
  4. [x] Développer collectors (Reddit + HN) ✅
  5. [x] Créer Dockerfile ✅
  6. [x] Déployer sur dev-portainer ✅
  7. [x] Configurer Nginx ✅
  8. [x] Tester collecte ✅ (77 posts)
  9. [x] Activer cron ✅ (toutes les 6h)

URLs finales

Service URL
API DEV https://needfinder-api-dev.33800.nowhere84.com
Health https://needfinder-api-dev.33800.nowhere84.com/health
Swagger https://needfinder-api-dev.33800.nowhere84.com/swagger
Stats https://needfinder-api-dev.33800.nowhere84.com/api/stats

Validation