@ -2,9 +2,57 @@ This is a web application written using the Phoenix web framework.
## Project guidelines
## Project guidelines
- **Always** run unit tests with `mix test.unit` and autoformat with `mix format` after making edits
- Use `mix precommit` alias when you are done with all changes and fix any pending issues
- Use `mix precommit` alias when you are done with all changes and fix any pending issues
- Use the already included and available `:req` (`Req`) library for HTTP requests, **avoid**`:httpoison`, `:tesla`, and `:httpc`. Req is included by default and is the preferred HTTP client for Phoenix apps
- Use the already included and available `:req` (`Req`) library for HTTP requests, **avoid**`:httpoison`, `:tesla`, and `:httpc`. Req is included by default and is the preferred HTTP client for Phoenix apps
## Commands
- `mix test.unit` — Run unit tests (no database required). **Always run after edits.**
- `mix test.integration` — Run integration tests (requires database).
- `mix format` — Apply autoformatting. **Always run after edits.**
- `mix precommit` — Full pre-commit check: compile with warnings-as-errors, unlock unused deps, format, and run integration tests.
- `mix test test/path/to/file_test.exs` — Run a single test file.
- `mix test --failed` — Re-run previously failed tests.
## Database
Requires Apache AGE (PostgreSQL with graph extensions) via Docker:
```bash
docker build -t age -f ./db/Dockerfile ./db
docker run -d -p 5455:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=gc_index_relay_dev age
```
Unit tests run without a database by default (`config :gc_index_relay, :start_repo, false` in test config). Integration tests set `REQUIRE_DB=true` to start the Repo.
## Architecture
This is a Nostr relay built with Phoenix 1.8 / Elixir. It stores and serves Nostr events, with plans for WebSocket API (NIP-01), REST API, graph queries (Apache AGE), and semantic search (pgvector).
### Domain Layer (`lib/gc_index_relay/nostr/`)
- **`PubEvent`** — Application domain model for a Nostr event. JSON-serializable struct with hex-encoded fields. Converts to/from the database representation.
- **`Event`** — Ecto schema (DB representation). Stores `id`, `pubkey`, and `sig` as binary; `created_at` as `utc_datetime`. Primary key is the cryptographic event ID (`autogenerate: false`).
- **`Tag`** — Ecto schema for event tags. 1:N association with Event (`name`, `value`, `additional_values`). Always created/deleted with their parent event.
- **`Validator`** — Validates event IDs (SHA-256 hash of serialized event) and Schnorr signatures (BIP-340) using `lib_secp256k1`.
- **`Filter`** — Parses and validates NIP-01 filter maps, then builds Ecto queries. Tag filters use `#<letter>` keys in JSON, stored internally as single-letter keys in a `tags` map.
`GcIndexRelay.Nostr` — CRUD operations for events. Events are validated (ID + signature) before insertion. No update operations (Nostr events are immutable once signed).
### Web Layer (`lib/gc_index_relay_web/`)
REST API at `/api/events` (show, create, delete) with JSON rendering. Uses `FallbackController` for error handling.
### Test Structure
- Tests tagged `@moduletag :unit` run with `mix test.unit` (no DB).
- Tests tagged `@moduletag :integration` run with `mix test.integration` (requires DB).
- Test fixtures in `test/support/fixtures/nostr_fixtures.ex` generate cryptographically valid Nostr events using hardcoded test keypairs and live Schnorr signing.
- Unit tests use `ExUnit.Case, async: true`; integration tests use `GcIndexRelay.DataCase`.
### Phoenix v1.8 guidelines
### Phoenix v1.8 guidelines
- **Always** begin your LiveView templates with `<Layouts.app flash={@flash} ...>` which wraps all inner content
- **Always** begin your LiveView templates with `<Layouts.app flash={@flash} ...>` which wraps all inner content
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
All Claude directives are maintained in [AGENTS.md](./AGENTS.md) — that file is the source of truth for coding conventions, framework guidelines, project commands, architecture details, and development workflows. **Read AGENTS.md before making any changes.**