6babaa0166
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.9 KiB
2.9 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
A self-hosted HTTP service that looks up Swedish phone numbers ("who is
calling me?") by scraping reverse-lookup sites. Providers are WASM components
(Component Model / WASI p2) loaded from a directory at startup; the host does
all fetching and caching. Design spec:
docs/superpowers/specs/2026-06-05-wasm-provider-service-design.md.
Commands
just test # build components + run all tests (preferred)
just run # build components + run the service
just build # release build of everything
cargo test -p whoareyou-provider-hitta # provider parser tests (native, no WASM)
cargo test -p whoareyou-server --test component # WIT-boundary integration test
cargo +nightly fmt # always nightly, not stable
cargo clippy --workspace
./fetch-fixture <number> # refresh an HTML fixture from hitta.se
The integration test needs the component built first — run via just test,
or cargo build --release --target wasm32-wasip2 -p whoareyou-provider-hitta
before bare cargo test.
Architecture
wit/provider.wit— the provider contract (metadata/requests/parse). Components are pure: no network, no filesystem. The HOST fetches URLs.crates/providers/hitta— parse logic inparser.rsis plain Rust, unit-tested natively againstfixtures/hitta/*.html;component.rsis thin WIT glue, compiled only forwasm32(cargo testnever touches WASM here). hitta.se serves Next.js App Router pages — data lives in RSC flight payloads (self.__next_f.push), NOT__NEXT_DATA__(that's the dead 2019 format kept in old fixtures as a Failed-path regression case).crates/server— lib + thin bin.service.rsholds theProviderHandle+Fetchtraits andLookupService(moka cache, TTL 24h, keyprovider:number; fetch failures are NOT cached).wasm.rsimplementsProviderHandleover wasmtime (fresh Store per call, epoch deadline ≈5s —spawn_epoch_threadmust run once at startup or runaway guests hang instead of trapping).http.rsis axum:GET /api/v1/number/{number},GET /healthz.
Gotchas
- Components build with plain
cargo build --target wasm32-wasip2— no cargo-component. Output name uses underscores:whoareyou_provider_hitta.wasm; the justfile copies it tocomponents/hitta.wasm(gitignored). - One provider failing maps to a per-provider
statusin the JSON response — never a non-200 for the whole lookup.parse_failedin logs (WARN) means a site changed its markup: refresh a fixture with./fetch-fixtureand fix the parser. ParseError::NoDatavsFailed: a fetched page with no phone data is NoData (normal); a page that doesn't match the expected structure is Failed (scraper rot). Don't conflate them.