# Getting Started


## Installation

```bash
pnpm add @primebrick/sdk
```

The SDK has runtime dependencies: `jose` (JWT/OIDC), `json-bigint`
(BigInt-safe JSON), `nats` (NATS™ client), `redis` (optional cache), and
`reflect-metadata` (cache metadata). These are installed automatically.

### Redis (optional)

Redis is NOT required to run Primebrick. If you want to enable the optional
cache layer for hot single-row reads, install Redis and set the `redis_url`
key in the `auth_configurations` table. See [Cache layer](cache-layer) for
details. Without `redis_url`, the system runs DB-only with no cache.

Redis is also used by the optional **presence** module (collaboration
awareness — who is viewing/editing an entity). Like the cache, presence is
best-effort: if Redis is unavailable, the BE wrapper turns presence calls
into no-ops and the UI simply shows no other users. See [Presence](presence)
for the contract.

## Minimal microservice setup

A Primebrick microservice is a single `createMicroservice()` call — the SDK
owns env validation (`assertDbEnv` closed set), DAL init, own-schema
migrations, `ConfigLoader`, NATS connection, service registration +
heartbeat, the HTTP server (with `/health`), and graceful shutdown:

```ts
import "dotenv/config";
import "reflect-metadata";
import { join } from "node:path";
import {
  createMicroservice,
  assertDbEnv,
  pgServerBanner,
  CachingApiKeyPort,
  NatsApiKeyPort,
} from "@primebrick/sdk";
import * as dalMigrations from "@primebrick/dal-pg";
import { initDal, getDal } from "./db/dal.js";
import { ENTITY_REGISTRY } from "./domain/entities/registry.js";
import { ConfigRepositoryAdapter } from "./adapters/config-repository-adapter.js";
import { HealthCheckAdapter } from "./adapters/health-check-adapter.js";
import { MyAuthConfigPort } from "./adapters/auth-ports-adapter.js";
import { myRouteHandler } from "./controllers/http/router.js";

await createMicroservice({
  serviceName: "my-service",
  serviceDisplayName: "My Service",
  serviceDescription: "What this service does",
  icon: "mail",
  iconType: "icon",

  // Closed-set env contract: DATABASE_URL + DATABASE_SCHEMA are the ONLY
  // env vars — enforced by assertDbEnv(). envSchema has no keys left.
  envSchema: {},

  initDal,
  dalClose: async () => { await getDal().close(); },
  dbBanner: () => pgServerBanner(getDal(), process.env.DATABASE_URL!),

  // Own-schema migrations run BEFORE ConfigLoader reads config_entries.
  dbPatches: {
    engine: dalMigrations,
    pool: () => getDal().getPool(),
    schema: () => assertDbEnv().schemas[0],
    patchesDir: join(process.cwd(), "db-meta", "patches"),
    entityRegistry: [...ENTITY_REGISTRY],
    // NODE_ENV is a platform var (Docker ENV / launch env — never .env):
    // production trusts only release-signed patches.
    allowedTrust:
      process.env.NODE_ENV === "production" ? ["release"] : ["dev", "release"],
  },

  configRepositoryAdapter: () => new ConfigRepositoryAdapter(),
  authConfigPort: (configLoader) => new MyAuthConfigPort(configLoader),
  apiKeyPort: () => new CachingApiKeyPort(new NatsApiKeyPort(3000)),
  healthCheckPort: () => new HealthCheckAdapter(getDal()),

  routeHandler: myRouteHandler,
  endpoints: { my_endpoint: "/my-endpoint" },
});
```

Mandatory `config_entries` keys (seeded via `db-meta/patches`):
`nats_url`, `service_code`, `http_port`, `service_base_url`,
`be_base_url`, `service_client_shield_key` — `createMicroservice`
`configLoader.require`s them at boot and crashes when missing.

## Verify the health endpoint

After running the service, verify it is up with a single curl:

```bash
curl http://localhost:3002/health
```

```json
{
  "ok": true,
  "service": "emailsender",
  "version": "1.0.0",
  "url": "http://localhost:3002",
  "checks": { "nats": { "ok": true } }
}
```

If any check fails, the HTTP status is `503` and `ok` is `false` — the FE's 503
interceptor probes `/health` and shows the right health chip. See
[HTTP Server](http-server) for the full `HealthResponse` shape and how to
register custom checks (db, redis, idp).

## Importing sub-modules

The SDK exports everything from the package root:

```ts
import { NatsClient, verifyAuth, extJsonStringify, Permission } from "@primebrick/sdk";
```

The Ext-JSON module is also available as a sub-path import (useful when you need
only JSON serialization without pulling in the NATS™/auth code paths):

```ts
import { extJsonStringify, extJsonParse } from "@primebrick/sdk/json";
```

## Next steps

- [Authentication](authentication) — configure auth for STANDALONE or GATEWAY-RESOLVED mode
- [NATS Client](nats-client) — publish/subscribe patterns
- [Service Registration](service-registration) — lifecycle events
- [HTTP Server](http-server) — the unified `/health` response shape and custom checks
- [Cache layer](cache-layer) — optional Redis cache for hot single-row reads
- [Presence](presence) — optional real-time collaboration awareness
- [API Reference](api-reference) — full API listing
