Skip to content

Share routes, show both frontiers, explain each step, harden the API - #37

Merged
mdhishaamakhtar merged 1 commit into
GDGVIT:masterfrom
mdhishaamakhtar:feature/elevate
Oct 24, 2026
Merged

mdhishaamakhtar merged 1 commit into
GDGVIT:masterfrom
mdhishaamakhtar:feature/elevate

Conversation

@mdhishaamakhtar

Copy link
Copy Markdown
Collaborator

What this adds

Shareable routes

  • /?from=Banana&to=Shah%20Rukh%20Khan opens that route, or runs the search if it isn't saved. The address bar updates once a route is found, and there's a Copy link button (the system share sheet on touch devices).
  • Shared links unfurl as an image of the route: /api/og.png is drawn with Pillow in the OG image's style, and the page carries per-route Open Graph and Twitter tags. Found routes are kept for 30 days (route:{start}:{end}).

Easier searching

  • Title suggestions as you type (/api/suggest): an ARIA combobox with redirects resolved and disambiguation pages flagged before they fail.
  • Three example routes and a "Surprise me" button for first-time visitors.

Visible algorithm

  • Progress now carries per-side counts and the pages each frontier read last. The waiting scene shows both ends, each with its recent pages and a fill that grows toward the other side.
  • Results name the page where the frontiers met and how many pages each side read; the route list explains this in one sentence.

Article context on each step

  • /api/context quotes the sentence in each article that links to the next step, with its section, parsed from wikitext (app/wikitext.py). A link found only in an infobox or a navigation box is labelled as such instead.

Performance and robustness

  • Progress streams over Server-Sent Events (/tasks/stream/<id>), falling back to polling. Gunicorn now runs gthread workers for this.
  • Per-IP rate limits in Redis: 10 searches a minute, 120 requests a minute to the lighter endpoints, with 429 and Retry-After beyond that. ProxyFix makes remote_addr the real client behind Railway's proxy.
  • Hub articles (500+ links) are cached for a week instead of a day.

Deploy cleanup

  • The Dockerfile copies entrypoint.sh once (it's now executable in git), runs it as CMD, and pins uv to 0.10.11.
  • railway.toml no longer repeats the start command.

Quality and polish

  • CI runs format, lint, types, the script syntax check, tests (95% coverage minimum) and a Docker build. Pre-commit hooks pin tool versions from uv.lock.
  • README: architecture diagram, API table, and a measured cold-cache benchmark (0.97–8.70 s across six routes).
  • Adaptive SVG favicon (no JavaScript swapper), favicon.ico, touch and manifest icons, and a real 404 page.
  • /robots.txt and /favicon.ico are now served at the root; before this they redirected to /, so crawlers never saw robots.txt.
  • nosniff and Referrer-Policy headers.

Testing

  • 158 tests pass at 97% coverage. Redis is fakeredis and only Wikipedia is stubbed. New tests cover the wikitext parser, suggestions, link context, hub TTLs, the SSE stream, rate limits, the share image and tags (including escaping and proxy scheme), frontier invariants, and root files.
  • On a real Redis + Celery worker + gthread Gunicorn stack, I ran a live search through the event stream; suggestions, article context, the share image and tags, and the 429 all behaved as expected.
  • The Docker image builds and contains an executable entrypoint, Pillow, and the fonts.

Not yet checked

  • The UI hasn't been checked by hand in a browser on desktop or mobile.
  • Only one of the eight example routes (Coffee → Moon) was actually run.
  • On macOS, Gunicorn's forked workers crash on their first outbound HTTPS call (Objective-C fork safety). Production on Linux and ./dev.sh are unaffected.

🤖 Generated with Claude Code

Sharing: /?from=&to= opens or runs a route and carries per-route Open
Graph tags; /api/og.png draws the route with Pillow and the bundled
JetBrains Mono. Found routes are kept 30 days under route:{start}:{end}.

Search input: title suggestions (/api/suggest, resolved redirects,
disambiguation flagged), example routes and "Surprise me".

Visible algorithm: progress carries per-side counts and the pages each
frontier read last; the wait scene draws both sides growing toward each
other. Results name the meeting page and per-side totals.

Link context: /api/context quotes the sentence in each article that links
to the next step, parsed from wikitext (app/wikitext.py).

Robustness: progress streams over SSE (/tasks/stream/<id>) with polling
as the fallback, so Gunicorn runs gthread workers. Per-IP rate limits in
Redis, ProxyFix for the real client IP, hub link lists cached a week.

Deploy: the Dockerfile copies entrypoint.sh once (executable in git) and
pins uv; railway.toml no longer repeats the start command.

Quality: CI (format, lint, types, script syntax, tests at 95% coverage,
Docker build), pre-commit hooks, README architecture and measured
benchmark. Also an adaptive SVG favicon, touch icons, manifest, a real
404 page, root robots.txt/favicon.ico (previously redirected to /), and
nosniff/referrer headers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mdhishaamakhtar
mdhishaamakhtar merged commit bc5d9a4 into GDGVIT:master Oct 24, 2026
2 checks passed
@mdhishaamakhtar
mdhishaamakhtar deleted the feature/elevate branch October 24, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant