factcircuit
FactCircuit: an auditable claim-and-evidence verification loop with immutable provenance, staged checks, bounded retrieval, and reproducible evaluation.
Hotel rate intelligence: competitor rate grid, pricing advice, demand signals.
Translation pending
DataTypeScript · JavaScriptGitHub @maandesai2006-techOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
A free, self-hosted hotel rate intelligence dashboard — a lightweight
Lighthouse/OTA-Insight-style tool. Track what competitor hotels charge night by
night, spot high-demand dates, see where your own rate sits against the market,
and watch how prices move over time.
Rate data comes from the free, keyless Xotelo API,
which serves TripAdvisor's public meta-search prices across OTAs (Booking.com,
Expedia, Agoda, …). Hosting fits entirely in Vercel + Supabase free tiers.
No paid services, no API keys for the data source.Read the full README ↗A free, self-hosted hotel rate intelligence dashboard — a lightweight Lighthouse/OTA-Insight-style tool. Track what competitor hotels charge night by night, spot high-demand dates, see where your own rate sits against the market, and watch how prices move over time.
Rate data comes from the free, keyless Xotelo API, which serves TripAdvisor's public meta-search prices across OTAs (Booking.com, Expedia, Agoda, …). Hosting fits entirely in Vercel + Supabase free tiers. No paid services, no API keys for the data source.
Originally built on the Amadeus Self-Service API, which was decommissioned on July 17, 2026 — Xotelo replaced it and is a better fit anyway: any hotel on TripAdvisor works, identified simply by its TripAdvisor page URL.
From any machine with Node 18+:
node scripts/test-xotelo.mjs "https://www.tripadvisor.com/Hotel_Review-g…-d…-Reviews-….html"
Paste your own hotel's TripAdvisor URL — it prints the live OTA offers for a night two weeks out.
supabase/migrations/ in numeric order, 001 first.
The last one (008_tenant_isolation.sql) is what stops one customer's
account from reading another's.Already done for this repo's owner: the project rate-beacon (
https://fcyghazlfnytejvdxkfk.supabase.co, us-east-1) exists with the schema applied — just grab the service_role key from its dashboard.
rate-beacon..env.example:
SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_ANON_KEY,
APP_SECRET (any long random string — it encrypts stored credentials and
derives each account's database identity), and CRON_SECRET (another long
random string — protects the daily job).vercel.json registers a daily cron at 06:00 UTC that snapshots
all rates; Vercel authenticates it automatically with CRON_SECRET.Open the site → Create a profile (paste the hotel's TripAdvisor link, add competitors) → hit Refresh rates once. From then on the daily job keeps the history building automatically. Profiles are per-baseline-hotel: each one bundles a hotel, its market, notes, and its own competitor set, switchable from the dashboard header.
cp .env.example .env.local # fill in your Supabase values
npm install
npm run dev # http://localhost:3000
Every competitor set is derived from public data by the same pipeline, so it works for any hotel anywhere — nothing is hand-authored:
/list).Run it from the dashboard (Find competitors), from the API
(POST /api/discover?profileId=1[&baselineId=g..-d..]), or standalone:
SUPABASE_URL=... SUPABASE_SERVICE_ROLE_KEY=... \
node scripts/discover.mjs 1 # all baselines in profile 1
node scripts/discover.mjs 1 g34550-d10637341 15 3 # one hotel, 15 comps, 3 extras each
Adding a new hotel and running discovery gives that hotel its own nearest competitors rather than inheriting another hotel's set. Map-context hotels are priced over a short 7-night window so the extra coverage stays cheap.
POST /api/refresh?maxDates=30 in chunks.src/lib/xotelo.ts and can be swapped
for another provider without touching the dashboard, database, or insights.Next.js 15 (App Router, TypeScript) · Tailwind CSS 4 · Supabase (Postgres) ·
Xotelo API (/api/rates, /api/list) · Vercel Cron.
Every secret this project uses has, at some point, been pasted into a chat window or a terminal. Before a second customer's data is in the system, rotate all of them. In order, because some depend on others:
APP_SECRET — generate a new 32+ character random string. This
invalidates every stored mailbox password and every encrypted report
text, and changes each account's derived Supabase credentials. After
deploying: reconnect any mailbox from the reports tab (the password is
re-encrypted under the new secret), and the app resets each account's
auth-user password automatically on its next request.CRON_SECRET — any long random string. The app rewrites it into
api_settings on the next run, so the in-database scheduler follows.INGEST_SECRET — set the same new value on Vercel and in the
Cloudflare Worker (npx wrangler secret put INGEST_SECRET).SUPABASE_SERVICE_ROLE_KEY on Vercel and redeploy.Then run /api/system-check. Every row should be green, and Tenant
isolation should still read "Enforced by the database".