尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Veille immobilière : recherches, connecteurs, import, carte, détection de similaires.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
PWA de veille immobilière responsable : surveillez plusieurs sources d'annonces sur une zone géographique, historisez les annonces, détectez les doublons / annonces recyclées, suivez l'évolution des prix, qualifiez manuellement et recevez des notifications pertinentes.檢視完整 README ↗
PWA de veille immobilière : surveillez plusieurs sources d'annonces sur une zone géographique, historisez les annonces, détectez les doublons / annonces recyclées, suivez l'évolution des prix, qualifiez manuellement et recevez des notifications pertinentes.
D'où viennent les annonces. Trois voies :
- l'import manuel (URL ou JSON collé) ;
- la capture initiée par l'utilisateur : un bookmarklet copie les champs de la page qu'il consulte ;
- une collecte serveur automatique : les Edge Functions
ingest-runetingest-nowlisent les plans de site et les pages d'annonces publiques de 14 sites d'agences et de réseaux immobiliers (liste dansscripts/seed-agences.mjs), et en extraient prix, surface, pièces et ville (balises de la page, JSON-LD, API REST publique de WordPress pour l'un d'eux).Le collecteur s'annonce (
miss-lookhouse-collector/1.0), lit le HTML tel qu'il est servi, espace ses requêtes d'au moins 300 ms et s'arrête à 50 ou 60 annonces par site et par passage. Il ne lit pas lerobots.txtdes sites, et le dépôt ne consigne aucune autorisation de leur part. leboncoin, SeLoger, Bien'ici et PAP ne sont pas collectés.
Membre de la famille de PWA mister-guiiug (React 19 + Vite 8 + Tailwind v4 +
Zustand + Zod, config partagée @mister-guiiug/dev-pwa-config).
authorized_api + dry-run, et connecteurs de site : plans de site, HTML,
JSON-LD, WordPress REST), prix de référence DVF, partage de recherches (lecture),
statut de livraison des notifications, canal e-mail (opt-in),
similarité par embeddings (option) et politique d'inscription (hook,
sur invitation par défaut). Reste : éprouver le push réel (navigateur
installé), et les gestes d'exploitation qui activent ces trois derniers
— voir Ce qui reste.src/domain) : similarité explicable (texte,
prix, surface, pièces, géo, hash perceptuel d'images (comparaison
d'empreintes fournies : rien ne les calcule depuis les photos), contact), scoring de
pertinence/fraîcheur, détection de baisse de prix et de republication,
historisation (deltas + série de prix), clustering de doublons.src/ingestion) : connecteurs (import
manuel, URL de recherche, capture navigateur via bookmarklet, API
autorisée, et connecteurs de site dans src/ingestion/sites : plans de site,
HTML, JSON-LD, WordPress REST), validation Zod, plan d'actions idempotent.supabase/migrations 0001→0020), Edge Functions
ingest-run (réveillée toutes les heures par pg_cron ; collecte chaque
recherche due, hourly après 55 min, daily après 23 h ; cœur partagé),
ingest-now (collecte immédiate du catalogue partagé, lancée par tout
utilisateur connecté depuis « Traitements », au plus une fois par 10 minutes),
connectors-admin (gestion collaborative : tout utilisateur connecté active ou
coupe les connecteurs du catalogue partagé et fixe leurs départements ; sans
département, le périmètre est national), embed (embeddings
gte-small, appelée en fin d'ingestion), notify (dispatch-once : webhook +
Web Push VAPID + e-mail + statut de livraison), dvf (prix au
m²), connector-test (dry-run) et notify-test (notification de test).notify : câblé (opt-in dans les Réglages, adresse du
compte confirmée, API compatible Resend), mais inerte tant que ses secrets
ne sont pas posés (le canal est alors skipped). Et notify n'est
appelée par aucun cron : aujourd'hui, seule la « Notification test » la
déclenche — e-mail, webhook et push compris. La planifier est une décision à
part, qui demande d'abord d'estampiller l'arriéré de notifications jamais
dispatchées (voir supabase/README.md §5).invite par défaut, liste d'adresses),
mais sans effet tant que le hook n'est pas branché — c'est ce geste qui
choisit la politique. L'ouverture publique demande aussi un SMTP
personnalisé : le service d'e-mail intégré de Supabase n'écrit qu'aux
membres de l'équipe du projet, 2 messages par heure — le lien de connexion
n'atteindrait personne d'autre.gte-small est
entraîné surtout sur l'anglais : bon pour les doublons et les republications
(textes quasi identiques), pas pour la similarité de sens fine entre
annonces françaises. Le poids (0,2) et le plancher de cosinus (0,85) sont
posés a priori, non calibrés sur un corpus. L'index HNSW est approximatif, et
la RLS filtre ses candidats après lui. Le signal s'affiche sur la fiche
d'une annonce ; l'écran « Doublons » reste celui de l'heuristique.authorized_api alors
qu'ils lisent des pages publiques. Reste à faire : lire le robots.txt de
chaque site et consigner son autorisation ou ses conditions d'utilisation.
leboncoin, SeLoger, Bien'ici et PAP restent non branchés, faute d'API ou de
flux autorisé (voir hypothèses).database.types.ts), tests des helpers Edge (DVF).Le dépôt ne déploie aucune Edge Function et ne pose aucun secret. Les
migrations 0016→0020, elles, partent en production à la fusion (CI).
embed et notify (après la fusion et le passage des
migrations) : supabase functions deploy embed --no-verify-jwt et
supabase functions deploy notify --no-verify-jwt ; redéployer aussi
ingest-run (qui appelle désormais embed). Rappeler embed à la main
pour résorber l'arriéré — supabase/README.md §5.notify : EMAIL_API_KEY, EMAIL_FROM
(et, au besoin, EMAIL_API_URL, APP_URL), par
supabase secrets set --env-file depuis un fichier hors du dépôt —
supabase/README.md §5.public.lh_before_user_created ; invite est déjà en place
(sinon update public.app_settings set signup_mode = 'open') ; remplir
public.signup_allowlist — supabase/README.md §4.1.supabase/README.md
§4.2.api-adresse.data.gouv.fr (officiel,
gratuit, sans clé) — vérifié comme service public.robots.txt ni CGU. Les connecteurs de site sont enregistrés
en mode authorized_api, pas server_fetch, et le drapeau
sources.server_fetch_allowed (posé à true pour les 14 sites par
seed-agences.mjs) n'est lu par aucune fonction : il ne bloque rien.┌──────────────────────── PWA (GitHub Pages / installable) ────────────────────────┐
│ React 19 + Vite 8 + Tailwind v4 + Zustand + react-router (HashRouter) │
│ src/domain ── cœur PUR (similarité, scoring, historisation, clustering) │
│ src/ingestion── connecteurs + pipeline (plan idempotent) │
│ Mode LOCAL : tout en navigateur (localStorage) │ Mode SUPABASE : ↓ │
└────────────────────────────────────────────────────┼──────────────────────────────┘
│ supabase-js (clé anon, RLS)
┌─────────────────────────── Supabase ────────────────▼──────────────────────────┐
│ PostgreSQL : schéma normalisé + RLS deny-by-default + audit (triggers) │
│ pg_cron (horaire) → pg_net → Edge Function `ingest-run` (service_role) │
│ « Actualiser le catalogue » → Edge `ingest-now` · Edge `connectors-admin` │
│ Edge `notify` (webhook + Web Push VAPID + e-mail + statut) · `dvf` · `*-test` │
│ Edge `embed` (gte-small, en fin d'ingestion) → pgvector, index HNSW, RLS │
│ Hook Auth « Before User Created » → inscription open / invite (si branché) │
│ Storage privé `listing-media` (prévu, inutilisé par le code) │
└──────────────────────────────────────────────────────────────────────────────────┘
# 1) Auth GitHub Packages (config famille @mister-guiiug)
export NODE_AUTH_TOKEN="$(gh auth token)" # nécessite le scope read:packages
# 2) Installer + lancer (port 5173, celui de Vite par défaut)
npm install
npm run dev
Ouvrez http://localhost:5173/ : l'app démarre en mode démo local avec un jeu de données fictif. Essayez Importer (charger l'exemple) pour voir le moteur dédupliquer/scorer/notifier en direct.
| Script | Rôle |
|---|---|
npm run dev | Serveur de dev (port 5173) |
npm test | Tests unitaires (Vitest) |
npm run type-check | Typage strict (TS tsc -b) |
npm run lint | ESLint |
npm run format | Prettier (la CI vérifie format:check) |
npm run build | Build de production |
npm run supabase:push | Applique les migrations (CLI Supabase) |
npm run seed:agences | Amorce les 14 connecteurs de site et le catalogue partagé « Agences 63 » |
Le backend est provisionné, validé en live (isolation RLS par compte prouvée)
et le site déployé tourne en mode Supabase (authentification requise). Détails
techniques (migrations, RLS, planification, Edge Functions, secrets) :
supabase/README.md.
.env.example → .env.local et
renseigner VITE_BACKEND=supabase + URL + clé anon publiques..env.production (versionné, valeurs publiques
uniquement ; la RLS arbitre tous les accès) et reçoit du workflow Deploy
deux variables du dépôt. VITE_SENTRY_DSN : Sentry (hébergement en
Allemagne) démarre dès le chargement, sans demande de consentement ; il
signale chaque ouverture (session) et reçoit un rapport à chaque erreur.
VITE_POSTHOG_KEY : la mesure d'audience PostHog (nuage européen) n'est
chargée qu'après accord dans le bandeau de consentement.Les secrets (
service_role,INGEST_TOKEN, clé VAPID privée, clé d'API e-mail) ne vivent jamais dans le dépôt : ils sont dans les secrets Supabase / Edge Functions, et dans le Vault pour l'URL et le jeton du cron. Le mot de passe de la base et un jeton d'accès Supabase sont, eux, des secrets GitHub Actions (SUPABASE_DB_PASSWORD,SUPABASE_ACCESS_TOKEN), lus par le workflowSupabase migrations.
⚠️ Les migrations partent en production à la fusion. Le workflow
Supabase migrationsappliquesupabase/migrations/**au projet hébergé à chaque fusion surmain: ses secrets sont posés depuis le 14/09/2026, et il passe depuis (après dix échecs de juin au 13/09, dont l'historique est dansCONFIG.md). Une migration doit donc être additive, rejouable et couverte parsupabase/tests/avant d'être fusionnée. Les Edge Functions, elles, ne sont déployées par aucun workflow.
CI/CD délégués aux workflows réutilisables famille, en @v6 (pwa-ci.yml,
pwa-deploy.yml, pwa-lighthouse.yml, pwa-supabase-test.yml,
pwa-supabase-keepalive.yml). base = /miss-lookhouse/, HashRouter. Le site atterrit sur
https://mister-guiiug.github.io/miss-lookhouse/ (mode Supabase — écran de
connexion). Lancer npx prettier --write . avant tout commit (la CI vérifie
prettier --check).
npm run seed:agences ;
connecteurs authorized_api JSON + dry-run ; leboncoin / SeLoger /
Bien'ici / PAP non branchésrobots.txt et trace de l'autorisation de chaque site collecté_shared/core, généré)dvf, prix au m²)ZonePolygonEditor)gte-small) en option, après
l'heuristique — sur la fiche d'une annonce ; fonction embed à déployerinvite par défaut, liste d'adresses, hook
« Before User Created ») — livrée, à activer par l'exploitantsupabase/README.md §4.2), reste à
configurer au tableau de bord — préalable à l'ouverture publiquenpm test
Couvrent : normalisation FR, similarité textuelle/géo/image, scoring, deltas de
prix, clustering, mélange des embeddings (poids, plancher, idempotence),
plan d'ingestion (nouveau vs maj, baisse de prix, recyclage, exclusion hors
zone), composition et statuts de l'e-mail de notify, mappers Supabase
(dont statut de livraison), géocodeur BAN, file de synchro,
pagination du dépôt et les écrans (réglages, refus d'inscription sur
invitation, suppression de compte…).
Les tests pgTAP (supabase/tests/) ne tournent qu'en CI (workflow
Supabase tests) : le poste n'a pas de Docker.
src/
domain/ cœur PUR (similarité, embeddings, scoring, géo, images, historisation) + tests
ingestion/ connecteurs (dont sites/ : plans de site, HTML, JSON-LD, WordPress)
+ schema (zod) + pipeline + bookmarklet + tests
notify/ partie PURE du dispatch (e-mail, statuts par canal), copiée côté Edge + tests
push/ abonnement Web Push
store/ Zustand (mode local) + persistance
demo/ jeu de données de la démo locale
backend/ sélection backend, client, mappers, dépôt, file de synchro
auth/ adaptateur d'auth, AuthGate, inscription (l'AuthProvider vient du socle)
components/ layout, nav, menu d'en-tête, UI (badges, sparkline)
features/ écrans (dashboard, searches, listings, similar, map,
notifications, processing, settings, import, connectors, auth)
lib/ formatage, géocodeur (BAN), DVF, statistiques des passages, appui long
scripts/ build-edge-core, generate-maskable, seed-agences
supabase/
migrations/ 0001_schema … 0020_audit_partage_fermes_a_anon (RLS, planif,
partage, livraison, embeddings, e-mail, inscription, droits de la
vue des recherches dues, audit et partage fermés à anon)
functions/ ingest-run · ingest-now · connectors-admin · embed · notify · dvf ·
connector-test · notify-test · _shared (core généré)
tests/ pgTAP (joués en CI)
MIT, © 2026 GuiiuG (famille mister-guiiug). Soutien : Buy Me a Coffee (mister.guiiug).
open / invite (défaut) et liste d'adresses,
tranchées par un hook « Before User Created » — inactif tant que
l'exploitant ne l'a pas branché.supabase/functions/_shared/core est
généré depuis src/ (npm run build:edge-core) → la même normalisation et
le même plan d'ingestion côté serveur, avec garde anti-dérive en CI.authorized_api (mode Supabase) : CRUD + dry-run (« Tester »)
qui récupère/mappe/normalise un échantillon sans rien écrire, derrière une
garde anti-SSRF. Partage de recherches en lecture (e-mail, RLS additive).AuthGate) + adaptateur de
dépôt offline-first : file de synchro persistante (rejeu / dead-letter),
pull → hydrate / push, bascule local ↔ supabase par variable d'env.security definer,
suppression de compte, droits d'ingestion et de la vue des recherches dues,
embeddings, opt-in e-mail, hook d'inscription).