79 lines
3.4 KiB
Markdown
79 lines
3.4 KiB
Markdown
# litenote-jetstream
|
|
|
|
Backend for [Remanso](https://remanso.space), a blogging platform on the AT
|
|
Protocol. Listens to the Jetstream firehose for `space.remanso.note` records and
|
|
serves them via a REST API.
|
|
|
|
## Prerequisites
|
|
|
|
- [Deno](https://deno.land/)
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
# Initialize the SQLite database
|
|
deno task migrate
|
|
```
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Run the Jetstream listener (with watch)
|
|
deno task jetstream
|
|
|
|
# Run the API server (with watch)
|
|
deno task server
|
|
```
|
|
|
|
## Production
|
|
|
|
```bash
|
|
# Run both processes
|
|
deno task jetstream:prod & deno task server:prod
|
|
```
|
|
|
|
### Docker
|
|
|
|
```bash
|
|
docker build -t litenote-jetstream .
|
|
docker run -p 8080:8080 -v litenote-data:/data litenote-jetstream
|
|
```
|
|
|
|
## API
|
|
|
|
| Endpoint | Description |
|
|
| ------------------------------------ | ----------------------------------------------------------------------------------------------- |
|
|
| `GET /notes?cursor=&limit=` | Paginated notes from all users (discoverable only) |
|
|
| `GET /:did/notes?cursor=&limit=` | Paginated notes for a specific DID (discoverable only) |
|
|
| `GET /search?q=&cursor=&limit=` | Full-text fuzzy search across discoverable notes. Returns `{ results, cursor? }` |
|
|
| `GET /:did/search?q=&cursor=&limit=` | Owner-scoped search incl. non-discoverable. Requires `Authorization: Bearer <jwt>` for that DID |
|
|
|
|
Search hits include `{ did, rkey, title, snippet, score, publishedAt }`. The
|
|
`snippet` is a sentence-bounded fragment from the matching content with the
|
|
query terms wrapped in `<em>` tags. Queries use OpenSearch `multi_match` with
|
|
`fuzziness: AUTO`, so small typos still match.
|
|
|
|
## Environment Variables
|
|
|
|
| Variable | Default | Description |
|
|
| --------------------- | ---------- | ------------------------------------------------------------------------------------------------------ |
|
|
| `SQLITE_PATH` | `notes.db` | Path to the SQLite database file |
|
|
| `OPENSEARCH_URL` | _(unset)_ | OpenSearch base URL (e.g. `http://opensearch:9200`). When unset, indexing and search degrade to no-ops |
|
|
| `OPENSEARCH_USERNAME` | _(unset)_ | Optional basic-auth user |
|
|
| `OPENSEARCH_PASSWORD` | _(unset)_ | Optional basic-auth password |
|
|
| `OPENSEARCH_INDEX` | `notes` | Index name to read/write |
|
|
| `ADMIN_DIDS` | _(empty)_ | Comma-separated DIDs allowed to hit `/admin/*` |
|
|
|
|
## OpenSearch backfill
|
|
|
|
Note content arrives via the jetstream firehose only for new and updated
|
|
records. To populate the index with pre-existing notes, run:
|
|
|
|
```bash
|
|
OPENSEARCH_URL=http://localhost:9200 deno task backfill:search
|
|
```
|
|
|
|
The script reads every DID in the local SQLite database, resolves each one's
|
|
PDS, and reindexes their notes via `com.atproto.repo.listRecords`. Safe to
|
|
re-run; document IDs are deterministic (`<did>:<rkey>`).
|