Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
8f69d35
feat(core): TenantContext + CommunityId — the server-resolved tenant …
tlongwell-block Jun 27, 2026
d948830
feat(lane0): community_id-native schema + host normalization
tlongwell-block Jun 27, 2026
4b7654a
feat(lane0): fold review round 2 — FTS column, drop stale migrations
tlongwell-block Jun 27, 2026
b7f249c
fix(db): scope relay rows by community
tlongwell-block Jun 27, 2026
785eefb
fix(db): require community scope for row lookups
tlongwell-block Jun 27, 2026
2620e49
fix(db): add tenant-safe query defaults and reaper host provenance
tlongwell-block Jun 27, 2026
c74c22c
feat(auth): community-scope RateLimiter pubkey quotas
tlongwell-block Jun 27, 2026
31e87b5
feat(auth): NIP-98 replay seen-set — shared, community-scoped, atomic
tlongwell-block Jun 27, 2026
aa4bf64
hardening(auth): TTL ceiling, key-case invariant, structured error tr…
tlongwell-block Jun 27, 2026
e43ea25
fence(auth): host-binding side door + access-checker community fence
tlongwell-block Jun 27, 2026
eae8dfc
feat(pubsub): scope redis topics by community
tlongwell-block Jun 27, 2026
433ee1e
test(pubsub): pin tenant-scoped topic refcounts
tlongwell-block Jun 27, 2026
c2477ba
rewrite(search): Postgres FTS, community-scoped, drop Typesense
tlongwell-block Jun 27, 2026
38708b8
rewrite(search): ChannelScope enum closes ChannelLessOnly fence hole
tlongwell-block Jun 27, 2026
81b064f
feat(audit): per-community hash chain on the frozen audit_log DDL
tlongwell-block Jun 27, 2026
fec1834
feat(audit): widen NewAuditEntry.community_id to CommunityId
tlongwell-block Jun 27, 2026
c6ec9a3
feat(relay): row-zero host-binding seam (HostResolver + fail-closed b…
tlongwell-block Jun 27, 2026
be56652
feat(relay): huddle-audio-unavailable guardrail under horizontal scal…
tlongwell-block Jun 27, 2026
787774f
test(conformance): multi-tenant A/B isolation harness skeleton
tlongwell-block Jun 27, 2026
ec22cdb
feat(relay): RelayInfo::build static-input fence (conformance NIP-11 …
tlongwell-block Jun 27, 2026
031b84e
fix(db): scope archived identities by community
tlongwell-block Jun 27, 2026
a8a9dd9
feat(relay): wire relay + admin call sites to community-scoped v3 API
tlongwell-block Jun 27, 2026
46124f3
fix(db): add communities to schema snapshot
tlongwell-block Jun 27, 2026
3e57144
fix(relay-mt): clear clippy -D warnings introduced by tenant threading
tlongwell-block Jun 27, 2026
f1b459b
fix(db): reconcile schema snapshot with mt migration
tlongwell-block Jun 27, 2026
528c4a9
test(e2e): seed localhost:3000 community for multi-tenant e2e suites
tlongwell-block Jun 27, 2026
107aa69
test(e2e): converge e2e host on localhost + seed before relay boot
tlongwell-block Jun 27, 2026
8ff38c0
test(e2e): seed community before relay boot in desktop e2e integration
tlongwell-block Jun 27, 2026
139d6db
fix(relay): preserve relay URL port for deployment binding
Jun 27, 2026
fb0d6a4
fix(relay): use deployment tenant binding for startup membership
Jun 27, 2026
b182187
fix(relay): bind fanout to receiver community
Jun 27, 2026
61d3492
perf(relay): add bus scaling harness
Jun 27, 2026
989f87e
fix(relay): fail closed on empty/whitespace host in bind_community
Jun 27, 2026
2738faf
fix(relay): scope DM command writes by community
Jun 27, 2026
bc453f3
fix(relay): clear clippy on integrated multi-tenant stack
Jun 27, 2026
e1b090e
feat(conformance): runtime trace schema + independent replay checker
Jun 27, 2026
acb01e4
feat(relay): wire conformance emitter into ingest seam
Jun 27, 2026
e6ed8e9
test(relay): EmitGuard coverage-breach self-test
Jun 27, 2026
1d3fb3c
feat(relay): emit AuthCheck on REQ membership decision
Jun 27, 2026
36485ad
feat(relay): emit read-row trace steps with (B) projection
Jun 27, 2026
726c831
fix(relay): share NIP-98 replay guard via Redis
Jun 27, 2026
9e2959e
test(buzz-db): pin communities_of_channels missing-channel-absent con…
Jun 27, 2026
34ffb8a
test(relay): red-team Attack 3 — same-pod regression + fail-closed proof
Jun 27, 2026
3fd16cc
fix(search): restore privacy kind exclusions at the FTS storage layer
Jun 27, 2026
be9d26e
relay/auth: NIP-98 u-URL host is per-tenant, not config-global
Jun 27, 2026
481e623
Measure relay bus scaling with Redis
Jun 27, 2026
4b6e1e4
buzz-db: scope api_tokens lookups to community_id (Gap 2 / row 44)
Jun 27, 2026
809ff9f
test(conformance): nip11_relay_info — NIP-11 is host-agnostic, not a …
Jun 27, 2026
bf8a1a4
buzz-relay: bind NIP-42 AUTH `relay` tag to per-tenant host (row 44 s…
Jun 27, 2026
1d7db98
test(conformance): audit_log isolation — doc-only row + integrated re…
tlongwell-block Jun 27, 2026
f7ec53b
test(conformance): fill row_zero_host_binding (unmapped fail-closed +…
Jun 27, 2026
b02d767
test(conformance): fill search_fts row — two-host NIP-50 isolation + …
Jun 27, 2026
6aa0cec
test(conformance): fill users_profiles_nip05 row — kind:0 + NIP-05 lo…
Jun 27, 2026
ae703c5
test(conformance): fill channels_membership row — same channel UUID c…
Jun 27, 2026
da6051f
test(conformance): fill api_tokens_nip98_replay row — doc-only api_to…
Jun 27, 2026
b9fa51e
test: cover pubsub presence typing isolation
Jun 27, 2026
d7600de
fix(relay): scope media and git substrate by tenant
Jun 27, 2026
bfbfe57
test(conformance): document status-code-as-layer-discriminator on nip…
Jun 27, 2026
f1f6bbf
refactor(relay): drop dead Typesense config + correct stale search co…
Jun 27, 2026
73aae6a
chore(chart): remove the eval-only Typesense subsystem from the Helm …
Jun 27, 2026
9d9cbe1
chore(compose,scripts): drop Typesense from local dev/test stacks
Jun 27, 2026
c258393
docs: rename Typesense references to Postgres FTS
Jun 27, 2026
4e117ad
docs: update multi-tenant spec search obligation to Postgres FTS
Jun 27, 2026
a7d3817
ci: drop Typesense from the integration-test workflow
Jun 27, 2026
c77f2c2
fix(relay): scope local-echo dedup by community
Jun 27, 2026
6846a8f
fix(relay): claim reminders before publishing
Jun 27, 2026
1151eca
fix(relay): scope relay membership to its community
Jun 27, 2026
2adae32
fix(db): scope reminder claim/release to their community
Jun 27, 2026
ce747ec
fix(admin): derive admin tenant host via shared relay_url_authority
Jun 27, 2026
c81b893
fix(workflow): scope workflow execution and approvals to their community
Jun 27, 2026
f649747
fix(workflow): wire community-scoped durable claim into scheduler
Jun 27, 2026
9e0534e
fix(workflow): add scheduled_workflow_fires.workflow_run_id for the a…
Jun 27, 2026
ea687cc
fix(workflow): seed interval cold-start anchor so new schedules fire
Jun 27, 2026
08a0399
style(workflow): rustfmt the multi-tenant fix set
Jun 27, 2026
16c55a1
test(conformance): wire-live workflow trigger community-confinement row
Jun 27, 2026
982fa1f
relay: complete multi-tenant scoping for reactions, allowlist, git na…
Jun 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 52 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ jobs:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- uses: cashapp/activate-hermit@e49f5cb4dd64ff0b0b659d1d8df499595451155a # v1
- name: Start integration services
run: docker compose up -d postgres redis typesense minio minio-init
run: docker compose up -d postgres redis minio minio-init
- name: Get pnpm store directory
id: pnpm-cache
run: echo "STORE_PATH=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -357,22 +357,43 @@ jobs:
}
wait_healthy "Postgres" "buzz-postgres"
wait_healthy "Redis" "buzz-redis"
wait_healthy "Typesense" "buzz-typesense"
wait_healthy "MinIO" "buzz-minio"
- name: Download relay binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: desktop-e2e-relay
path: target/ci
- name: Apply schema and seed deployment community
# MT: the relay resolves each request's tenant from the communities host
# map and fails closed on an unmapped host. The channel reconciler binds
# the deployment community ONCE at boot (outside its retry loop) and
# exits permanently on an unmapped host, so the 'localhost:3000'
# community MUST exist before the relay starts — the retry loop only
# handles late-seeded channels, not a late-seeded community. The relay
# migrates at boot via BUZZ_AUTO_MIGRATE, but that's too late for the
# pre-boot seed, so apply the schema here first (then drop AUTO_MIGRATE
# below). lower(host) is the unique index → ON CONFLICT target. psql
# isn't on PATH in hermit → exec into the buzz-postgres container.
env:
PGHOST: localhost
PGPORT: "5432"
PGUSER: buzz
PGPASSWORD: buzz_dev
PGDATABASE: buzz
run: |
./bin/pgschema apply --file schema/schema.sql --auto-approve
docker exec -e PGPASSWORD=buzz_dev buzz-postgres \
psql -U buzz -d buzz -qtA -c "
INSERT INTO communities (id, host)
VALUES ('00000000-0000-4000-8000-00000000c0de', 'localhost:3000')
ON CONFLICT (lower(host)) DO NOTHING
;"
- name: Start relay
run: |
chmod +x ./target/ci/buzz-relay
nohup env \
DATABASE_URL=postgres://buzz:buzz_dev@localhost:5432/buzz \
BUZZ_AUTO_MIGRATE=true \
REDIS_URL=redis://localhost:6379 \
TYPESENSE_URL=http://localhost:8108 \
TYPESENSE_API_KEY=buzz_dev_key \
RELAY_URL=ws://localhost:3000 \
BUZZ_BIND_ADDR=0.0.0.0:3000 \
BUZZ_REQUIRE_AUTH_TOKEN=false \
Expand Down Expand Up @@ -448,7 +469,7 @@ jobs:
with:
save-if: ${{ github.event_name != 'pull_request' }}
- name: Start integration services
run: docker compose up -d postgres redis typesense minio minio-init
run: docker compose up -d postgres redis minio minio-init
- name: Wait for integration services
run: |
wait_healthy() {
Expand All @@ -467,22 +488,43 @@ jobs:
}
wait_healthy "Postgres" "buzz-postgres"
wait_healthy "Redis" "buzz-redis"
wait_healthy "Typesense" "buzz-typesense"
wait_healthy "MinIO" "buzz-minio"
- name: Download relay binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: desktop-e2e-relay
path: target/ci
- name: Apply schema and seed deployment community
# MT: the relay resolves each request's tenant from the communities host
# map and fails closed on an unmapped host. The reminder scheduler binds
# the deployment community ONCE at boot and exits permanently on an
# unmapped host (no retry, unlike the channel reconciler), so the
# 'localhost:3000' community MUST exist before the relay starts — seeding
# after boot leaves the scheduler dead. The relay migrates at boot via
# BUZZ_AUTO_MIGRATE, but that's too late for the pre-boot seed, so apply
# the schema here first (then drop AUTO_MIGRATE below). lower(host) is the
# unique index → ON CONFLICT target. psql isn't on PATH in hermit → exec
# into the buzz-postgres container.
env:
PGHOST: localhost
PGPORT: "5432"
PGUSER: buzz
PGPASSWORD: buzz_dev
PGDATABASE: buzz
run: |
./bin/pgschema apply --file schema/schema.sql --auto-approve
docker exec -e PGPASSWORD=buzz_dev buzz-postgres \
psql -U buzz -d buzz -qtA -c "
INSERT INTO communities (id, host)
VALUES ('00000000-0000-4000-8000-00000000c0de', 'localhost:3000')
ON CONFLICT (lower(host)) DO NOTHING
;"
- name: Start relay
run: |
chmod +x ./target/ci/buzz-relay
nohup env \
DATABASE_URL=postgres://buzz:buzz_dev@localhost:5432/buzz \
BUZZ_AUTO_MIGRATE=true \
REDIS_URL=redis://localhost:6379 \
TYPESENSE_URL=http://localhost:8108 \
TYPESENSE_API_KEY=buzz_dev_key \
RELAY_URL=ws://localhost:3000 \
BUZZ_BIND_ADDR=0.0.0.0:3000 \
BUZZ_REQUIRE_AUTH_TOKEN=false \
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ crates/
buzz-db # Postgres event store and data access layer
buzz-auth # Authentication and authorization
buzz-pubsub # Redis pub/sub fan-out, presence, typing indicators
buzz-search # Typesense-backed full-text search
buzz-search # Postgres FTS full-text search
buzz-audit # Hash-chain audit log
buzz-media # Blossom/S3 media storage
# Agent surface
Expand Down Expand Up @@ -130,7 +130,7 @@ to be duplicated:

- `POST /events` — submit any signed event (same path the WebSocket uses).
- `POST /query` — Nostr REQ filters over HTTP. NIP-50 `search` filters
are routed to `buzz-search` (Typesense-backed) automatically.
are routed to `buzz-search` (Postgres FTS) automatically.
- `POST /count` — Nostr COUNT filters over HTTP.

If you find yourself reaching for a new REST endpoint, first check whether
Expand Down
57 changes: 37 additions & 20 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ Buzz is a Rust monorepo, licensed Apache 2.0 under Block, Inc.
(multi-node fan-out wired; local-echo dedup via AppState.local_event_ids).

┌──────────────┐
Typesense │ ← buzz-search (bounded worker queue)
│ (full-text │
Postgres │ ← buzz-search (FTS over the search_tsv
│ (full-text │ generated column + GIN index)
│ search) │
└──────────────┘
```
Expand All @@ -80,7 +80,7 @@ buzz-core (zero I/O — types, verification, filter matching, kind registry)
├── buzz-db (Postgres: events, channels, tokens, workflows, audit)
├── buzz-auth (NIP-42, NIP-98, API tokens, scopes, rate limiting)
├── buzz-pubsub (Redis pub/sub, presence, typing indicators)
├── buzz-search (Typesense: index, query, delete)
├── buzz-search (Postgres FTS: query, delete)
├── buzz-audit (hash-chain tamper-evident log)
└── buzz-workflow (YAML-as-code automation engine)
Expand Down Expand Up @@ -462,21 +462,32 @@ EXPIRE buzz:typing:{channel_id} 60

---

### buzz-search — Typesense Integration
### buzz-search — Postgres FTS Integration

Full-text search via Typesense. All HTTP calls use `reqwest` with `X-TYPESENSE-API-KEY`. In multi-community mode, indexed documents and every query filter include `community_id`; the shared Typesense collection is infrastructure, not a cross-community result space.

**Collection schema (7 fields):** `id`, `content`, `kind` (int32), `pubkey` (facet), `channel_id` (facet, optional), `created_at` (int64, default sort), `tags_flat` (string[]).
Full-text search via Postgres FTS. Events are searchable through the
`events.search_tsv` generated `tsvector` column (populated on insert, indexed
by a GIN index) — there is no separate search service or out-of-band indexer.
Privacy-sensitive kinds are excluded at the storage level (the `search_tsv`
`CASE WHEN kind IN (...)` yields `NULL`, which never matches `@@`). In
multi-community mode every query filter includes `community_id`, so the shared
`events` table is infrastructure, not a cross-community result space; the relay
re-authorizes every candidate hit before returning it.

**Key behaviors:**
- `ensure_collection()` is idempotent: handles 409 race condition (another process created it between check and create).
- Tag flattening uses `\x1f` (ASCII unit separator) to avoid ambiguity with tag values containing colons (e.g., URLs in `r` tags).
- Upsert indexing: `POST /documents?action=upsert` (single), `POST /documents/import?action=upsert` (batch JSONL).
- `delete_event()` validates event ID (64-char hex) before constructing the URL — prevents path injection.
- `delete_event()` is idempotent: 404 treated as success.
- Permission filtering is **caller's responsibility** — `buzz-search` provides the `filter_by` mechanism but does not enforce access policy.

**Does NOT:** enforce channel membership or access control. Does NOT store events in Postgres.
- `SearchService::new(pool)` wraps a `PgPool`; `search(&SearchQuery)` runs a
parameterized FTS query against the `events.search_tsv` GIN index and returns
`SearchResult` (candidate `SearchHit`s).
- `ChannelScope` makes the channel constraint explicit (`Any` /
`ChannelLessOnly` / `Channels` / `ChannelsOrChannelLess`), closing the
ambiguity the old `Option<Vec<Uuid>> + bool` matrix could not express.
- Every query carries `community_id`; the FTS predicate is BitmapAnd-ed with
the community-leading btree filters so a query never crosses tenants.
- Permission filtering is **caller's responsibility** — `buzz-search` returns
candidate hits; the relay re-authorizes each one (channel membership, `#p`,
owner gates) before delivering it.

**Does NOT:** enforce channel membership or access control. Does NOT write
events (indexing is the `search_tsv` generated column on the `events` insert).

---

Expand Down Expand Up @@ -652,7 +663,7 @@ pub enum AuthState { Pending { challenge: String }, Authenticated(AuthContext),
| GET | `/api/channels/{channel_id}/messages` | List channel messages |
| GET | `/api/channels/{channel_id}/threads/{event_id}` | Get message thread |
| GET/POST | `/api/channels/{channel_id}/workflows` | List/create channel workflows |
| GET | `/api/search` | Full-text search via Typesense |
| GET | `/api/search` | Full-text search via Postgres FTS |
| GET | `/api/agents` | List agent accounts |
| GET/PUT | `/api/presence` | Presence status (bulk) / set presence |
| GET | `/api/feed` | Personalized feed (mentions/needs-action/activity) |
Expand Down Expand Up @@ -831,9 +842,8 @@ Docker Compose provides the full local development stack. All services include h

| Service | Image | Port | Purpose |
|---------|-------|------|---------|
| Postgres | `postgres:17-alpine` | 5432 | Primary event store — events, channels, tokens, workflows, audit |
| Postgres | `postgres:17-alpine` | 5432 | Primary event store — events, channels, tokens, workflows, audit; full-text search (`search_tsv` GIN) |
| Redis | `redis:7-alpine` | 6379 | Pub/sub fan-out, presence (SET EX), typing (sorted sets) |
| Typesense | `typesense/typesense:27.1` | 8108 | Full-text search index |
| Adminer | `adminer` | 8082 | DB web UI (dev only) |
| MinIO | `minio/minio` | 9000 (API), 9001 (console) | S3-compatible object storage (media) |
| Prometheus | `prom/prometheus` | 9090 | Metrics collection |
Expand All @@ -859,9 +869,16 @@ Docker Compose provides the full local development stack. All services include h
| `buzz:presence:{pubkey_hex}` | String | 90s | Online/away status (single-community form; shared multi-community Redis must scope by community) |
| `buzz:typing:{channel_uuid}` | Sorted Set | 60s | Active typers (5s window; shared multi-community Redis must scope by community) |

### Typesense Collection
### Full-Text Search (Postgres FTS)

Single collection (`events` by default, configurable via `TYPESENSE_COLLECTION`). Schema today: `id`, `content`, `kind` (int32), `pubkey` (facet), `channel_id` (facet, optional), `created_at` (int64, default sort), `tags_flat` (string[]). Multi-community mode adds faceted `community_id` and either prefixes document IDs with community or makes all upsert/delete/refetch paths carry community context.
Search runs over the `events.search_tsv` generated `tsvector` column on the
`events` table (no separate collection or service). The column is populated on
insert — `to_tsvector('simple', content)` — and excludes privacy-sensitive
kinds via `CASE WHEN kind IN (1059, 30300, 30622) THEN NULL`, so those rows are
storage-level unsearchable (a `NULL` tsvector never matches `@@`). A GIN index
(`idx_events_search_tsv`) backs the `@@` probe; in multi-community mode the
community-leading btree filters BitmapAnd with the GIN probe so every query is
fenced to its `community_id`.

---

Expand Down
15 changes: 9 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ unacceptable behavior to **conduct@buzz-relay.org**.
| Node.js | 24+ | Required for desktop app commands and `just ci` |
| pnpm | 10+ | Required for desktop app commands and `just ci` |
| Flutter | 3.41+ | Required for mobile app — install via [flutter.dev](https://docs.flutter.dev/get-started/install) |
| Docker | 24+ | For Postgres, Redis, Typesense |
| Docker | 24+ | For Postgres, Redis, MinIO |
| `just` | latest | Task runner — `cargo install just` |
| `lefthook` | latest | Optional; run `lefthook install` for local Git hooks |
| `sqlx` migrations | workspace crate | `just migrate` applies embedded migrations from `migrations/` |
Expand Down Expand Up @@ -85,9 +85,9 @@ cached thereafter). You can also run `just bootstrap` independently at any time;
it is safe to re-run.

`just setup` then starts Docker services (Postgres on `:5432`, Redis on `:6379`,
Typesense on `:8108`, Adminer on `:8082`, Keycloak on `:8180` for local
OAuth/OIDC testing, MinIO on `:9000` for media storage, and Prometheus on
`:9090` for metrics) and runs all pending database migrations.
Adminer on `:8082`, Keycloak on `:8180` for local OAuth/OIDC testing, MinIO on
`:9000` for media storage, and Prometheus on `:9090` for metrics) and runs all
pending database migrations.

### Running the Relay and Desktop App

Expand Down Expand Up @@ -380,8 +380,11 @@ for team access setup, onboarding, and the full repo inventory. See
handler in `buzz-db/src/` (e.g., `buzz-db/src/my_feature.rs`) with
the appropriate `INSERT` and `SELECT` queries.

6. **Index for search** (if applicable) — add the kind to the Typesense
indexing logic in `buzz-search/src/index.rs`.
6. **Index for search** (if applicable) — Postgres FTS indexes persisted
events automatically via the `events.search_tsv` generated column. To
exclude a privacy-sensitive kind from search, add it to the `CASE WHEN
kind IN (...)` exclusion in the `search_tsv` definition (see the initial
schema migration) rather than wiring a separate indexer.

7. **Audit** — the audit log captures all events automatically; no changes
needed unless you need custom audit metadata.
Expand Down
21 changes: 14 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
members = [
"crates/buzz-relay",
"crates/buzz-core",
"crates/buzz-conformance",
"crates/buzz-db",
"crates/buzz-pubsub",
"crates/buzz-auth",
Expand Down Expand Up @@ -78,7 +79,7 @@ anyhow = "1"
uuid = { version = "1", features = ["v4", "serde"] }
chrono = { version = "0.4", features = ["serde"] }

# HTTP client (webhook delivery, Typesense indexing)
# HTTP client (webhook delivery)
reqwest = { version = "0.13", features = ["json", "rustls"], default-features = false }

# Cryptography
Expand Down Expand Up @@ -108,6 +109,7 @@ schemars = { version = "1", default-features = false }

# Internal crates
buzz-core = { path = "crates/buzz-core" }
buzz-conformance = { path = "crates/buzz-conformance" }
buzz-db = { path = "crates/buzz-db" }
buzz-auth = { path = "crates/buzz-auth" }
buzz-pubsub = { path = "crates/buzz-pubsub" }
Expand Down
7 changes: 0 additions & 7 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -427,13 +427,6 @@ migrate: _ensure-migrations

# ─── Utilities ────────────────────────────────────────────────────────────────

# Rebuild Typesense docs for all kind:0 (user profile) events.
# Required once after deploying the indexer change that flattens kind:0 content
# for searchability; new/updated profiles are indexed correctly automatically.
# Safe to run repeatedly — Typesense upserts.
reindex-kind0:
cargo run --release -p buzz-relay --bin buzz-reindex-kind0

# Remove build artifacts
clean:
cargo clean
Expand Down
Loading
Loading