Initial Commit
This commit is contained in:
101
packages/api-stack/api/api-plugin-site/README.md
Normal file
101
packages/api-stack/api/api-plugin-site/README.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# @suaveplan/api-plugin-site - Multi-site / multi-domain management plugin for @suaveplan/api. Stores `site` records with name / slug / theme / settings / push config, resolves Host headers to a site through DomainResolverService, exposes public + private OpenAPI route trees, ships an injectable domain-resolver Hono middleware, emits site:settings:updated events, optionally auto-creates a default site on organization:created. 14 SITE.* error codes, 5 OTel instruments, owner-scoped queries, server-tier.
|
||||
|
||||
Multi-site / multi-domain management plugin for `@suaveplan/api`. Stores `site` records (name, slug, theme, settings, push config) in SurrealDB, resolves incoming `Host` headers to a site via `DomainResolverService`, exposes public + private OpenAPI Hono route trees, and emits the `site:settings:updated` event whenever a site's settings change so downstream caches / CDNs can react.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Owns the stable `SITE.*` error-code registry and the `SiteError` class used by every public API path in `@suaveplan/api…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Owns the stable `SITE.*` error-code registry and the `SiteError` class used by every public API path in `@suaveplan/api…
|
||||
- [integration](./src/integration/middleware-recommendations.md) — `MIDDLEWARE_RECOMMENDATIONS` is a frozen, typed bundle of recommended rate-limit and audit configuration for each docum…
|
||||
- [middleware-recommendations](./src/integration/middleware-recommendations.md) — `MIDDLEWARE_RECOMMENDATIONS` is a frozen, typed bundle of recommended rate-limit and audit configuration for each docum…
|
||||
- [middleware](./src/middleware/domain-resolver.md) — Factory that builds a Hono middleware which resolves the incoming request's `Host` header to a `site` + `organization`…
|
||||
- [domain-resolver](./src/middleware/domain-resolver.md) — Factory that builds a Hono middleware which resolves the incoming request's `Host` header to a `site` + `organization`…
|
||||
- [otel](./src/otel/instruments.md) — Owns the lazy-built OpenTelemetry instrument bundle (`SiteInstruments`) that every observable code path in `@suaveplan/…
|
||||
- [instruments](./src/otel/instruments.md) — Owns the lazy-built OpenTelemetry instrument bundle (`SiteInstruments`) that every observable code path in `@suaveplan/…
|
||||
- [plugin](./src/plugin/plugin.md) — Owns `createSitePlugin`, the canonical factory that produces the `PluginDescriptor` consumed by `@suaveplan/api-plugin`…
|
||||
- [plugin](./src/plugin/plugin.md) — Owns `createSitePlugin`, the canonical factory that produces the `PluginDescriptor` consumed by `@suaveplan/api-plugin`…
|
||||
- [private-routes](./src/routes/private-routes.md) — Builds the authenticated Hono route tree for site CRUD and domain management. The factory is intentionally auth-agnosti…
|
||||
- [public-routes](./src/routes/public-routes.md) — Builds the public (no-auth) Hono route tree that the plugin mounts under the configured `routePrefix`. The two endpoint…
|
||||
- [domain](./src/schemas/domain.md) — Zod schemas for every domain-shaped value: the validated domain literal itself, the request/response shapes for `addDom…
|
||||
- [options](./src/schemas/options.md) — Owns the plugin-options schema and the `mergeConfig` / `DEFAULT_CONFIG` helpers used by `createSitePlugin(...)`. Every…
|
||||
- [push](./src/schemas/push.md) — Schemas and a pure validator for the per-site push-notification configuration. The site plugin treats push config as op…
|
||||
- [site](./src/schemas/site.md) — Defines the Zod schemas that describe the canonical `site` entity, its create/update inputs, the public-facing slice, a…
|
||||
- [db-port](./src/service/db-port.md) — Declares `SiteDb`, the structural database port that `SiteService` and `DomainResolverService` consume. suaveplan's found…
|
||||
- [domain-resolver](./src/service/domain-resolver.md) — `DomainResolverService` maps a request's `Host` (or arbitrary domain string) to a persisted `site` record and the ownin…
|
||||
- [normalize-domain](./src/service/normalize-domain.md) — Pure helper that mirrors the SurrealDB `fn::site::domain::normalize` function in TypeScript so application-tier code (t…
|
||||
- [site](./src/service/site.md) — `SiteService` is the application-tier owner of every CRUD path against the SurrealDB `site` table. It mediates between…
|
||||
- [services](./src/services/registry-augmentation.md) — Augments the `ServiceRegistry` interface from `@suaveplan/api-plugin` so the three slots the site plugin owns — `siteSe…
|
||||
- [registry-augmentation](./src/services/registry-augmentation.md) — Augments the `ServiceRegistry` interface from `@suaveplan/api-plugin` so the three slots the site plugin owns — `siteSe…
|
||||
- [types](./src/types/types.md) — Runtime-free type module that defines every shared shape used by the site plugin: persisted `Site` / `SiteSettings` / `…
|
||||
- [types](./src/types/types.md) — Runtime-free type module that defines every shared shape used by the site plugin: persisted `Site` / `SiteSettings` / `…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
bun add @suaveplan/api-plugin-site
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
```ts
|
||||
import { createPluginRegistry } from "@suaveplan/api-plugin";
|
||||
import { createDatabasePlugin } from "@suaveplan/api-plugin-database";
|
||||
import { createSitePlugin } from "@suaveplan/api-plugin-site";
|
||||
|
||||
const registry = createPluginRegistry();
|
||||
registry.register(createDatabasePlugin({ /* surrealdb config */ }));
|
||||
registry.register(createSitePlugin({
|
||||
maxSitesPerOrg: 10,
|
||||
maxDomainsPerSite: 5,
|
||||
autoCreateDefaultSite: true,
|
||||
defaultDomainPattern: "{slug}.suaveplan.app",
|
||||
}));
|
||||
await registry.start();
|
||||
```
|
||||
|
||||
After `registry.start()`, the site plugin exposes three services on `ServiceRegistry`:
|
||||
|
||||
- `siteService: SiteService` — CRUD + settings + domain management.
|
||||
- `domainResolver: DomainResolverService` — `resolve(domain)` returning `{success, site, organization}`.
|
||||
- `domainResolverMiddleware: Hono Middleware` — request-scoped resolver that injects `site` / `organization` / `siteId` / `organizationId` into `c`.
|
||||
|
||||
## What it does
|
||||
|
||||
- Persists `site` records under SurrealDB with per-table SurQL migration shipped in `surql/tables/site.surql`.
|
||||
- Enforces per-organization and per-site caps (`maxSitesPerOrg`, `maxDomainsPerSite`).
|
||||
- Public route: `GET /sites/resolve/{domain}` — domain → site/org lookup.
|
||||
- Public route: `GET /sites/{id}/public` — sanitised `SitePublicInfo` projection (no push secrets).
|
||||
- Private routes: `POST /sites`, `PATCH /sites/{id}`, `POST /sites/{id}/domains`, `DELETE /sites/{id}/domains`.
|
||||
- Optional `organization:created` listener that auto-creates a default site per new organisation, with `site:bootstrap:failed` events on failure.
|
||||
- 14 stable `SITE.*` error codes raised through `SiteError extends SuaveplanError`.
|
||||
- OTel instruments: `site.sites_created_total{outcome}`, `site.sites_updated_total{kind}`, `site.domain_resolutions_total{outcome}`, `site.domain_resolution_duration_ms`, `site.bootstrap_failed_total`.
|
||||
|
||||
## Modules
|
||||
|
||||
- [`src/error-codes/error-codes.md`](./src/error-codes/error-codes.md) — `SITE_CODES` + `SiteError`.
|
||||
- [`src/otel/instruments.md`](./src/otel/instruments.md) — OTel instrument bundle.
|
||||
- [`src/schemas/site.md`](./src/schemas/site.md) — `SiteSchema`, `CreateSiteSchema`, `UpdateSiteSchema`, `SitePublicInfoSchema`.
|
||||
- [`src/schemas/domain.md`](./src/schemas/domain.md) — `DomainSchema`, resolve / add / remove request+response.
|
||||
- [`src/schemas/push.md`](./src/schemas/push.md) — `ApplePushConfigSchema`, `FirebasePushConfigSchema`, `validatePushConfig`.
|
||||
- [`src/schemas/options.md`](./src/schemas/options.md) — `SitePluginOptionsSchema`, `mergeConfig`, `DEFAULT_CONFIG`.
|
||||
- [`src/service/site.md`](./src/service/site.md) — `SiteService`.
|
||||
- [`src/service/domain-resolver.md`](./src/service/domain-resolver.md) — `DomainResolverService`.
|
||||
- [`src/service/db-port.md`](./src/service/db-port.md) — `SiteDb` structural port.
|
||||
- [`src/service/normalize-domain.md`](./src/service/normalize-domain.md) — domain canonicalisation.
|
||||
- [`src/middleware/domain-resolver.md`](./src/middleware/domain-resolver.md) — Hono middleware factory.
|
||||
- [`src/routes/public-routes.md`](./src/routes/public-routes.md) — public OpenAPI router.
|
||||
- [`src/routes/private-routes.md`](./src/routes/private-routes.md) — private OpenAPI router (auth supplied by caller).
|
||||
- [`src/plugin/plugin.md`](./src/plugin/plugin.md) — `createSitePlugin` factory.
|
||||
- [`src/services/registry-augmentation.md`](./src/services/registry-augmentation.md) — `ServiceRegistry` module augmentation.
|
||||
- [`src/integration/middleware-recommendations.md`](./src/integration/middleware-recommendations.md) — `MIDDLEWARE_RECOMMENDATIONS` constant + types.
|
||||
|
||||
## Middleware composition
|
||||
|
||||
The site plugin ships **zero runtime dependencies** on `@suaveplan/api-plugin-rate-limit` and `@suaveplan/api-plugin-audit`. Composition stays in the host application via Hono's `app.use(prefix, middleware)` pattern.
|
||||
|
||||
- See [`docs/middleware-integration.md`](./docs/middleware-integration.md) for the canonical end-to-end wiring example and the recommended layering order (audit OUTERMOST → rate-limit MIDDLE → site routes INNERMOST).
|
||||
- See [`src/integration/middleware-recommendations.md`](./src/integration/middleware-recommendations.md) for the `MIDDLEWARE_RECOMMENDATIONS` constant exposing recommended rate-limit windows and audit categories per route group.
|
||||
- The pattern is proven by [`src/integration/middleware-composition.integration.test.ts`](./src/integration/middleware-composition.integration.test.ts) — a runnable composition asserting site behaviour, rate-limit headers, and audit event emission.
|
||||
|
||||
Reference in New Issue
Block a user