metalfrom.eu/apps/api/migrations/008_band_locations.sql
Nicolas Fryder f145188d1f fix(geocoder): band_locations.ma_id en BIGINT — débloque 62k bands
bands.ma_id est BIGINT (crawler génère jusqu'à ~3.5e9) mais band_locations.ma_id
avait été créé en INTEGER (max 2.1e9). Tout INSERT pour un band à ma_id élevé
échouait en "integer out of range", erreur avalée silencieusement par l'enqueue.
62 239 bands (sur 96 143 localisables) n'entraient donc jamais dans le pipeline,
d'où 0 llm_needed / 0 erreur trompeurs.

- migration 008: ma_id BIGINT (installs neuves)
- migration 009: ALTER COLUMN ma_id TYPE BIGINT (DB existante)
- enqueue.py: compte les inserts échoués (failed=) au lieu de les avaler
- worker.py: sync_bands_primary prend le lieu d'ORIGINE (step 0) et non la
  dernière localisation — garde les groupes européens en Europe
- admin app.js: coût LLM robuste au NaN (NUMERIC accepte la valeur spéciale NaN)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 19:47:30 +02:00

54 lines
2 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 008_band_locations.sql
-- Table relationnelle N steps × M villes par band pour le géocodage multi-périodes.
-- Remplace la logique mono-entrée de geocode_queue pour les nouveaux traitements.
CREATE TABLE IF NOT EXISTS band_locations (
id BIGSERIAL PRIMARY KEY,
ma_id BIGINT NOT NULL REFERENCES bands(ma_id) ON DELETE CASCADE,
step_order SMALLINT NOT NULL DEFAULT 0,
step_label TEXT,
location_raw TEXT NOT NULL,
is_country_only BOOLEAN NOT NULL DEFAULT FALSE,
lat DOUBLE PRECISION,
lon DOUBLE PRECISION,
geocode_status TEXT NOT NULL DEFAULT 'queued',
geocode_query TEXT,
geocode_provider TEXT,
geocode_confidence REAL,
geocode_error TEXT,
geocode_tries_geo SMALLINT NOT NULL DEFAULT 0,
geocode_tries_llm SMALLINT NOT NULL DEFAULT 0,
geocode_next_at TIMESTAMPTZ NOT NULL DEFAULT now(),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (ma_id, step_order, location_raw)
);
-- Index pour la boucle de travail du geocoder
CREATE INDEX IF NOT EXISTS idx_bl_geo_work
ON band_locations (geocode_next_at ASC, id ASC)
WHERE geocode_status = 'queued';
-- Index pour la boucle du groq-worker
CREATE INDEX IF NOT EXISTS idx_bl_llm_work
ON band_locations (geocode_tries_llm ASC, id ASC)
WHERE geocode_status = 'llm_needed';
-- Index de navigation par band
CREATE INDEX IF NOT EXISTS idx_bl_ma_id ON band_locations (ma_id);
-- Cache pour éviter de rappeler le LLM pour la même entrée
CREATE TABLE IF NOT EXISTS llm_cache (
id BIGSERIAL PRIMARY KEY,
input_hash TEXT NOT NULL UNIQUE,
model TEXT NOT NULL,
prompt TEXT NOT NULL,
response TEXT NOT NULL,
parsed_city TEXT,
parsed_country TEXT,
is_null BOOLEAN NOT NULL DEFAULT FALSE,
tokens_in INTEGER,
tokens_out INTEGER,
cost_usd NUMERIC(10, 8),
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);