Use Node 24 (pinned in .nvmrc, which CI also reads) and the repository-pinned pnpm version. From the repository root:
pnpm install --frozen-lockfile
pnpm test:unit
pnpm check
pnpm buildpnpm test:unit runs the discovered tests under happyview-modules/tests/unit; unit tests use local fixtures and fake process/network adapters, and do not seed a database or contact HappyView. pnpm check also checks generated-source freshness, JavaScript and Lua lint, types, endpoint tests, and the @hypercerts-org/api package in packages/api/. pnpm build emits Lua handlers declared by the root and module manifests, builds the endpoint explorer, and builds @hypercerts-org/api. Shared Lua files are bundled into capability handlers rather than installed independently.
When a change affects registered query Lexicons or their schemas, refresh the committed explorer artifacts from the current API manifest:
pnpm docs:syncThis updates docs/sources/index.json, the committed Lexicon snapshots, docs/openapi.json, and docs/coverage.json. It uses the repository-pinned @hypercerts-org/lexicon dependency and makes no HappyView requests. Coverage reports manifest inclusion only; it does not validate runtime behavior or deployment. See docs/README.md for the source and snapshot policy.
The same changes, and changes to the @hypercerts-org/lexicon or @atproto/lex version in packages/api/package.json, require regenerating the @hypercerts-org/api TypeScript package:
pnpm client:generatepnpm check fails while the committed output in packages/api/src/ is stale. See packages/api/README.md.
pnpm test:http runs the suites in happyview-modules/tests/http against the activity, badge-definition, badge-query, EVM-link, acknowledgement, collection, context-measurement, context attachment and evaluation, contributor-information, funding, location, profile, organization, feature, work-scope-tag, rights, vocabulary-tag, graph, contribution, and feed-reaction query XRPC endpoints installed from this checkout. These tests exercise real HTTP behavior against PostgreSQL, not only Lua handlers with a fake database.
The local runner requires a local Docker Compose daemon, psql, and the pinned PostgreSQL and HappyView images already cached locally. Set PSQL_PATH to the absolute path of a trusted psql executable:
PSQL_PATH="$(command -v psql)" pnpm test:httpLocally, Compose uses --pull never; if a pinned image is missing, the test fails before service startup. CI explicitly pulls the two digest-pinned test images before running the same command.
The runner discovers *.http.test.js suites and *.fixture.js fixture modules, then creates a random Compose project with loopback-only dynamic ports, PostgreSQL data on tmpfs, and a task-owned default bridge network. It installs this checkout's manifest, seeds shared and HTTP fixtures, runs the suites, and tears down only that generated Compose project and its temporary credentials. Fixtures are seeded only into the task-owned disposable database; fixture SQL helpers require an explicit disposable loopback database opt-in.
The bridge network permits container egress. HappyView receives loopback placeholder upstream URLs and proxy variables pointing to 127.0.0.1:9; these are application-level settings, not network-level egress isolation. The installer and HTTP suites target only the task-owned loopback service.
The HTTP gate fails if it discovers no suites, executes no node:test cases, or runs only skipped cases. Current coverage includes:
- Funding record retrieval, repeated filters, publisher-sidecar hydration, and pagination.
- Badge-definition retrieval with an icon and allowed-issuer list, publisher-sidecar hydration, author and badge-type filters,
createdAt/URI pagination ties, and named error responses. - Rights record retrieval and author-filtered listing, nullable publisher sidecars, repeated-author OR filtering, and stable
createdAt/URI cursor pagination. - EVM-link lookup and listing, actor/address filters,
createdAt/URI pagination ties in both directions, nullable sidecar hydration, and named error responses. - Feature-query coverage in
happyview-modules/tests/http/features.http.test.jsexercises exact retrieval and hydrated or absent author sidecars, author/type and organization-presence filters, bidirectionalcreatedAt/URI pagination ties, and named request errors. - Contributor-information retrieval by exact AT-URI and listing with repeated-author filters, cursor pagination, hydrated and missing author sidecars, and named runtime errors.
- Work-scope-tag exact-URI retrieval, repeated-author filtering with an empty-result case, hydrated and null publisher sidecars, middle-position
indexedAtfallback, tied pagination in both directions, and named error responses. - Context-measurement exact retrieval and publisher-sidecar hydration, repeated author/subject filters and negative results, timestamp/URI tie pagination in both directions, missing sidecars, and named runtime errors.
- Acknowledgement exact retrieval and full-record preservation, hydrated and absent publisher sidecars, repeated author/subject filters, ascending and descending pagination across timestamp ties, and named errors.
- Badge-query baseline-aware definition feeds and discriminating filters, exact-version award/response lookups, recipient status, raw response history, bidirectional tied pagination, nullable sidecars, and named runtime errors.
- Profile and organization queries across all four endpoints for each record type, including batch null results, profile-sidecar hydration, filters,
createdAt/URI pagination ties, and named errors. - Vocabulary-tag exact-URI retrieval, repeated-author filtering and no-match behavior, hydrated and nullable sidecars, bidirectional pagination ties, unsupported-search rejection, and named errors.
- Context attachment and evaluation retrieval with publisher/evaluator sidecar hydration, list filters, pagination across tied
createdAtvalues, and named runtime errors. - Activity retrieval with contributor-sidecar hydration, author/organization/contributor/URI filters, tied timestamp pagination, and literal wildcard search.
- Collection retrieval with CBOR-derived CIDs, location/tag projections, author, organization, item and tag filters, title/shortDescription search,
createdAt/URI pagination ties, and source-order item pagination with exact-version resolution. - Graph actor/entity lookups and lists, tied-key pagination, nullable profile/organization sidecars, entity target resolution, entity-follower totals across pages and empty pages, and the global recent-follows
beforefilter. ThegetFollowsandgetEntityFollowsbatch queries also cover repeated target order and duplicates, explicit target keys, nullable raw views, and invalid-entry rejection. - Feed-reaction subject and actor queries, earliest duplicate selection, URI-only subject matching across CIDs, distinct-actor totals, tied cursor pagination, page-only sidecar hydration, raw
via/signature preservation, and actor queries without hydration. - Contribution exact-record retrieval, repeated publisher filters, tied ascending/descending cursor pagination, nullable publisher sidecars, and named errors.
- Badge, badge-query, acknowledgement, contribution, and rights HTTP fixtures with CBOR-derived record CIDs; contribution DIDs are distinct from baseline fixture identities.
- Location retrieval with nullable sidecars, repeated author/URI/location-type filters, unsupported-search errors, tied pagination in both directions, malformed/absent
createdAthandling, and named errors. - HTTP fixtures for activity, collection, funding, badge-definition, badge-query, EVM-link, acknowledgement, feature, work-scope-tag, contribution, contributor-information, actor, context-measurement, context attachment and evaluation, graph, location, measurement, and vocabulary-tag records use CBOR-derived CIDs.
For the pinned HappyView release, ordinary Lua error() exceptions return HTTP 500 JSON with error: "script_error" and errorType: "runtime"; the error name appears in message. Negative HTTP tests assert this observed behavior. It is not a statement of the ideal public HTTP status contract, and does not guarantee 4xx mapping for RecordNotFound or InvalidRequest.
For pull requests that change the installable API bundle or operator-visible behavior, add a release note following the Changesets guidance. Documentation-only or endpoint-explorer-only changes do not need a Changeset.
pnpm install:api sends admin requests to a HappyView instance and uploads declared assets. By default, conflicting declared assets stop the install before asset writes; pnpm install:api --override explicitly replaces only those conflicts. Override does not bypass source/dependency validation, authentication, or profile resolver-setting requirements. If a write request errors, the installer checks the installed asset and treats it as complete only if it matches the bundle. Writes are not rolled back if a later asset fails. Run the installer only for an explicitly approved target with an approved token. Review the target and release notes before installing a released bundle; see happyview-modules/README.md for release installation and HYPERCERTS_HANDLE_RESOLVER_URL setup, permission requirements, and retained-setting behavior.