You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update the written guides and generated OpenAPI metadata to match the
current repo layout, env-loading workflow, and API contract.
This also fixes the health/OpenAPI smoke test and documents the
remaining legacy Agora compatibility behavior more precisely.
Copy file name to clipboardExpand all lines: AGENTS.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,22 +1,22 @@
1
1
# Repository Guidelines
2
2
3
3
## Project Structure & Module Organization
4
-
The workspace is a multi-crate Cargo project. Service code lives under `api/` (Axum REST server with Swagger UI) and `indexers/{indexer-1,indexer-2,indexer-3}/` for ingestion services. Shared libraries (`shared/common`, `shared/db-core`, `shared/entities`) hold reusable logic and schema definitions. Database migrations reside in `migration/`, while service-specific settings inherit from the root `config.toml` alongside`api/config.toml` and `indexers/<name>/config.toml`.
4
+
The workspace is a multi-crate Cargo project. Service code lives under `api/` (Axum REST server with Swagger UI) and `indexers/{discourse-indexer,near-indexer,telegram-indexer}/` for ingestion services. Shared libraries (`shared/common`, `shared/db-core`, `shared/entities`) hold reusable logic and schema definitions. Database migrations reside in `migration/`, while service-specific defaults live in`api/config.toml` and `indexers/<name>/config.toml`.
5
5
6
6
## Build, Test, and Development Commands
7
-
Use `cargo check-all` to compile every crate before opening a PR. Run `cargo test-all` for the full workspace test suite; scope to a crate with commands such as `cargo test -p api` or `cargo test -p api handlers::health`. Development binaries include `cargo run-api` (serves at http://127.0.0.1:3000) and `cargo run-indexer-1` (similar for other indexers). Apply schema updates with `cargo migrate-up`, generate new migrations via `cargo migrate-generate <name>`, and rebuild SeaORM entities with `cargo generate-entities`.
7
+
Use `cargo check-all` to compile every crate before opening a PR. Run `cargo test-all` for the full workspace test suite; scope to a crate with commands such as `cargo test -p api` or `cargo test -p api health_`. Development binaries include `cargo run-api` (serves at http://127.0.0.1:3000) and `cargo run-indexer-1` (similar for other indexers). Apply schema updates with `cargo migrate-up`, generate new migrations via `cargo migrate-generate <name>`, and rebuild SeaORM entities with `cargo generate-entities`.
8
8
9
9
## Coding Style & Naming Conventions
10
10
Target Rust 2021 idioms with 4-space indentation, `snake_case` for modules/functions, and `CamelCase` types. Libraries favor `thiserror` for typed errors; binaries use `anyhow` for rich context. Always format with `cargo fmt` and consider `cargo clippy -- -D warnings` before pushing.
11
11
12
12
## Testing Guidelines
13
-
Tests mirror module layout (e.g., `api/tests/handlers/`). Prefer deterministic handler tests for business logic and route tests for HTTP behavior. Frameworks in use include `rstest`, `axum-test`, and `testcontainers` for PostgreSQL-backed scenarios. Run targeted suites during development, then confirm with `cargo test-all` prior to merge.
13
+
Tests mirror the service surface (for example, `api/tests/{unit,e2e}/`). Prefer deterministic handler tests for business logic and route tests for HTTP behavior. Frameworks in use include `rstest`, `axum-test`, and `testcontainers` for PostgreSQL-backed scenarios. Run targeted suites during development, then confirm with `cargo test-all` prior to merge.
14
14
15
15
## Commit & Pull Request Guidelines
16
16
Write concise, imperative commit subjects (≈50 characters) similar to "fix Railway caching" or "observability". Pull requests should summarize the change, link relevant issues, note testing performed, and call out config or migration impacts; include Swagger screenshots when UI behavior changes.
17
17
18
18
## Security & Configuration Tips
19
-
Never commit secrets. Copy `.env.example` to `.env` locally and configure runtime with environment variables such as `DATABASE_URL` and `RUST_LOG`. Override Figment settings by exporting keys like `APP_SERVER__HOST` or `APP_LOGGING__LEVEL` for service-specific tuning.
19
+
Never commit secrets. Copy `.env.example` to `.env.local` locally and configure runtime with environment variables such as `DATABASE_URL` and `APP_LOGGING__LEVEL`. If you use the checked-in `.envrc`, install the Doppler CLI because the direnv workflow invokes it before sourcing `.env.local`. Override Figment settings by exporting keys like `APP_SERVER__HOST` or `APP_LOGGING__LEVEL` for service-specific tuning, and use `RUST_LOG` only when you need a fine-grained tracing filter override.
20
20
21
21
## Documentation Maintenance
22
22
Keep the files in `docs/` in sync with the codebase. Update them as part of the same PR that introduces the change:
**Access**: API at http://localhost:3000 • [Swagger UI](http://localhost:3000/swagger-ui) • [OpenAPI spec](http://localhost:3000/api-docs/openapi.json)
36
36
37
+
If you do not use the checked-in `direnv` + Doppler workflow, export
38
+
`DATABASE_URL` manually before running DB-backed commands such as
This layout works on Railway, Fly.io, Render, Kubernetes, ECS, Nomad, or plain Docker Compose as long as the platform can run one container per service, inject environment variables, provide PostgreSQL connectivity, and expose public HTTP only for `api` and `web`.
307
314
308
-
Railway is the easiest fit today because this repo already includes one `railway.toml` per service, Dockerfile-based builds, watch patterns, and API support for Railway's injected `PORT` environment variable. If you use Railway, prefer one service per component, run migrations as a separate release step, and use private networking from `web` to `api` with a base URL like `http://${{api.RAILWAY_PRIVATE_DOMAIN}}:${{api.PORT}}/api/v1/venear`.
315
+
Railway is the easiest fit today because this repo already includes Railway manifests for the long-running services, Dockerfile-based builds for every deployable component, watch patterns, and API support for Railway's injected `PORT` environment variable. If you use Railway, prefer one service per component, run migrations as a separate release step, and use private networking from `web` to `api` with a base URL like `http://${{api.RAILWAY_PRIVATE_DOMAIN}}:${{api.PORT}}/api/v1/venear`.
309
316
310
317
## Testing
311
318
@@ -325,7 +332,7 @@ The platform uses `tracing` with `tracing-subscriber` and emits structured JSON
325
332
**Features**:
326
333
-**Logs**: Structured JSON logs for all services
327
334
-**Traces**: Span-aware request and background-job tracing
328
-
-**Filtering**: Log level control via `RUST_LOG`
335
+
-**Filtering**: Log level control via `APP_LOGGING__LEVEL`
Copy file name to clipboardExpand all lines: api/src/docs.rs
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ use utoipa::OpenApi;
8
8
info(
9
9
title = "HOS API",
10
10
version = "0.1.0",
11
-
description = "Read-only REST API for indexed identity, Discourse, Telegram, and veNEAR governance data.\n\nOpenAPI contract notes for AI clients:\n- The API is read-only. Every endpoint is discoverable through generated OpenAPI metadata.\n- List endpoints are consistently paginated with `limit` and `cursor`.\n- Cursor pagination uses opaque base64url cursors.\n - `limit` defaults to 20 and is clamped to a maximum of 100.\n - `cursor` is an opaque base64url token from a prior response and should be treated as an opaque string.\n - Omit `cursor` to request the first page in a sequence.\n - Continue until `next_cursor` is `null` or absent.\n- All paginated responses return `data`, `next_cursor`, and `has_more`.\n- `next_cursor` and pagination order are endpoint-specific; always follow the ordering declared in each endpoint description.\n- Timestamp fields use RFC 3339 / ISO-8601 format with timezone.\n- Error responses follow RFC 9457 Problem Details as `application/problem+json`, including machine-friendly `code` when present.\n- Indexers are asynchronous: newly emitted data may lag or reorder briefly during backfill.\n- `identity` values are stable while indexer-sourced entity references may vary by environment and snapshot time.",
11
+
description = "Read-only REST API for indexed identity, Discourse, Telegram, and veNEAR governance data.\n\nOpenAPI contract notes for AI clients:\n- The API is read-only. Every endpoint is discoverable through generated OpenAPI metadata.\n- `/api/v1` list endpoints use `limit` and `cursor` with opaque base64url cursors.\n - `limit` defaults to 20 and is clamped to a maximum of 100.\n - `cursor` is an opaque base64url token from a prior response and should be treated as an opaque string.\n - Omit `cursor` to request the first page in a sequence.\n - Continue until `next_cursor` is `null` or absent.\n- Paginated `/api/v1` responses return `data`, `next_cursor`, and `has_more`.\n- Legacy `/api/agora` endpoints intentionally preserve page-based params and older payload shapes for compatibility.\n- `next_cursor` and pagination order are endpoint-specific; always follow the ordering declared in each endpoint description.\n- Timestamp fields use RFC 3339 / ISO-8601 format with timezone.\n- Error responses follow RFC 9457 Problem Details as `application/problem+json`, including machine-friendly `code` when present.\n- Indexers are asynchronous: newly emitted data may lag or reorder briefly during backfill.\n- `identity` values are stable while indexer-sourced entity references may vary by environment and snapshot time.",
Copy file name to clipboardExpand all lines: api/src/handlers/health/health_check.rs
+1-2Lines changed: 1 addition & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -15,8 +15,7 @@ use tracing::{info, instrument};
15
15
description = "Performs service liveness checks and an optional database probe (`SELECT 1`). Returns `healthy` when the database probe succeeds and `degraded` when the database is unavailable or fails.",
16
16
tag = "health",
17
17
responses(
18
-
(status = 200, description = "Current API health report", body = HealthResponse),
0 commit comments