6babaa0166
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
61 lines
2.9 KiB
Markdown
61 lines
2.9 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
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 in `parser.rs` is plain Rust,
|
|
unit-tested natively against `fixtures/hitta/*.html`; `component.rs` is
|
|
thin WIT glue, compiled only for `wasm32` (`cargo test` never 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.rs` holds the `ProviderHandle` +
|
|
`Fetch` traits and `LookupService` (moka cache, TTL 24h, key
|
|
`provider:number`; fetch failures are NOT cached). `wasm.rs` implements
|
|
`ProviderHandle` over wasmtime (fresh Store per call, epoch deadline ≈5s —
|
|
`spawn_epoch_thread` must run once at startup or runaway guests hang
|
|
instead of trapping). `http.rs` is 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 to
|
|
`components/hitta.wasm` (gitignored).
|
|
- One provider failing maps to a per-provider `status` in the JSON response —
|
|
never a non-200 for the whole lookup. `parse_failed` in logs (WARN) means a
|
|
site changed its markup: refresh a fixture with `./fetch-fixture` and fix
|
|
the parser.
|
|
- `ParseError::NoData` vs `Failed`: 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.
|