尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Developer marketing site for the FlightPowers travel-data APIs (Next.js 15, static-first).
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗The apex marketing site for the FlightPowers travel-data APIs (live Google Flights +
Booking.com pricing). Built to the blueprint in the ops workspace's
state/gtm/SITE_SPEC.md (2026-08-26). Currently deployed on the Vercel project
flightpowers-developers (serving developers.flightpowers.com and the project's
*.vercel.app URL); it becomes flightpowers.com via the apex-swap runbook below.
| Layer | Choice |
|---|---|
| Framework | Next.js 15 (App Router), TypeScript, React 19 |
| Rendering | Static-first — every marketing page is prerendered HTML (force-static); only /api/* is dynamic |
| Styling | Tailwind CSS v4, CSS-first tokens in src/app/globals.css. Dark-only by design. No component library |
| Fonts | Inter (body), Space Grotesk (display), JetBrains Mono — via next/font, self-hosted at build |
| Content | TSX pages + MDX (guides, changelog) |
| Sitemap | src/app/sitemap.ts walks the route tree; dynamic segments enumerated from their datasets |
| Hosting | Vercel, deployed by CLI (npx vercel@latest --prod). No git auto-deploy |
src/lib/
site.ts SINGLE source of truth: counts, links (verified 2026-08-26), UTM builder
pricing.ts plan tables read from the live listings (READ_ON stamp); perThousand math
diff.ts the six verified differentiators — the only feature claims allowed weight
fixtures.ts + fixtures/*.json — REAL captured API responses (dated); all canned UI
renders from these and is labelled "captured run"
matrix.ts the {agent}×{task} dataset behind /integrations/<agent>/<task> (~42 pages)
snippets.ts cURL/Python/Node builders for the ApiUpsellCard (key always $RAPIDAPI_KEY)
demo/
budget.ts spend controls (see below)
upstream.ts the ONLY module that reads FP_DEMO_KEY ('server-only')
shapes.ts the fixed set of query shapes a visitor can trigger
intent.ts hero chat: free text → one of the fixed shapes (rule-based, no LLM)
src/app/api/
demo/ THE one spend route (agent chat + tools share it → shared counters)
verify-key/ relays a visitor's own key to GET /v1/verify; never logs it
e/ first-party event beacon → structured lines in the function log
Order of checks in /api/demo: same-origin → response cache (repeats are free) →
per-IP daily cap → global daily budget. Costs are priced per shape before anything is
spent (a sampled month-scan = ~10 upstream calls and is charged as such). Live results are
cached by (shape, params); cached hits are labelled and free.
Honest limitation: counters are in-memory per serverless instance. All spend goes through
the single /api/demo function precisely so its instances share fate, but N warm
instances still mean up to N× the nominal caps. The numbers are conservative and the demo
key's own plan quota is the final backstop. If the demo ever needs exact accounting, move
the counters to a durable store (Vercel KV/Redis) — the budget.ts interface is already
shaped for it.
DEMO_PER_IP_DAILY (default 12) — backend calls per visitor per dayDAILY_BACKEND_CALL_BUDGET (default 400) — global daily ceiling per instance| Name | Purpose |
|---|---|
FP_DEMO_KEY | RapidAPI key the demo/tools spend server-side. NEVER in the repo, client bundles, logs, or error messages. Only src/lib/demo/upstream.ts reads it |
DAILY_BACKEND_CALL_BUDGET | global daily demo budget (mrabi's dial) |
DEMO_PER_IP_DAILY | per-visitor daily cap |
NEXT_PUBLIC_SITE_URL | canonical origin override (defaults to https://flightpowers.com) |
lib/ config; npm run check-pricing re-parses the live
RapidAPI listings, filters visibility === "PUBLIC", fails on drift, and fails FATALLY
if a non-public plan name ever appears in the committed table.llms.txt is generated from the same config as the pages.llms.txt (src/app/llms.txt/route.ts)The pricing, counts, and link tables render from src/lib/, so they can never drift. The
Guides and Comparisons sections are a hand-maintained list of - [title](url): description
lines, not a scan of src/app/guides/(article)/* or src/app/compare/* — a new guide or
comparison page does not appear here on its own. When you ship one:
route.ts, same one-line-description style as its
neighbours.LLMS_LAST_UPDATED in src/lib/llms.ts to today's date.curl -s <deployed-url>/llms.txt after deploy and check the new page is listed.llms-full.txt needs no update for a new guide — it renders only the OpenAPI reference, not
the guides/compare index.
npm run dev # local dev
npm run build # must pass clean before any deploy
npm run check-pricing # live-listing drift check (run before deploying)
npm run predeploy # check-pricing + build
npx vercel@latest --prod # deploy (from the repo root; project is linked)
lib/pricing.ts (last-good values) and scripts/check-pricing.mjs is the drift/leak
gate run before deploys. Same guarantees, deterministic builds./blog does not 301 to demo.: the spec's redirect map sends /blog to the
consumer blog on demo., but §2 also defines the new apex blog at /blog. Both can't
hold; the 6 old consumer POST slugs 301 to demo. (in next.config.mjs) and /blog
itself is the new developer blog./api/agent merged into /api/demo: separate route files are separate Vercel
functions with separate in-memory budget counters; one spend route keeps one counter set./api/e) that writes structured [fp-event] lines to the function log (drain later).
The api_upsell_click vocabulary matches the spec so a real sink can be swapped in.GET /v1/verify debits one
request from the key's hotels plan. The spec's pre-launch gate assumed it might be
free; it isn't, so the box says so instead of hiding it.Demo-path latency measured 2026-08-26 over the capture calls (n≈44 against
api.flightpowers.com): oneway p50 ≈ 3.9s, p95 ≈ 13s, max 15.5s; roundtrip 5–17s (retries
dominate); hotels by-name 7–27s. Conclusion: synchronous UX with honest progress copy +
generous timeouts (30s oneway / 45s roundtrip+hotels, maxDuration: 60), degrade to
captured runs on timeout. /v1/verify: debits 1 hotels-plan request per call (measured).
State at hand-off: this project serves developers.flightpowers.com + its *.vercel.app
domain. The OLD apex (flightpowers.com) serves the consumer engine from a different
Vercel project. demo.flightpowers.com does not resolve yet.
demo.flightpowers.com to the consumer-engine project (Vercel → that project →
Domains → add). Wait for cert issuance; verify the engine answers identically on demo.
while the apex still serves it. Zero downtime possible in this step.flightpowers.com (+ www if present) from the
consumer-engine project and add flightpowers.com to flightpowers-developers.
Same-account domain move: DNS unchanged, cutover is seconds. The engine is already live
on demo., so it never goes dark.curl -s https://flightpowers.com/ | grep "<h1" → the new herocurl -sI https://flightpowers.com/blog/flex-dates-cheaper-flights → 301 to
https://demo.flightpowers.com/blog/flex-dates-cheaper-flights (and the other 5 slugs)curl -s https://demo.flightpowers.com/ → the consumer engine (no more 000)curl -s https://flightpowers.com/robots.txt and /sitemap.xml and /llms.txt → 200NEXT_PUBLIC_SITE_URL=https://flightpowers.com
(it's already the default in site.ts) — nothing to change.flightpowers.com back to the consumer-engine
project in Vercel Domains — the engine still runs there untouched; the whole swap is
reversible in under a minute. The 301s to demo. only ever fire on the new project, so
rollback restores the exact prior state.Crawlers with JavaScript off must see complete pages: H1s, body copy, FAQ text, code
snippets. Client components are allowed only for interactions (the agent demo, tool forms,
code-tab switching, the key checker) and always hydrate on top of server-rendered copy.
After npm run build, every content route must be ○ (Static); only /api/* is ƒ.