Files
2026-05-27 23:29:53 +01:00

237 lines
6.0 KiB
Markdown

# OpenSpec Change: enterprise-api-docs
- **Change ID**: enterprise-api-docs
- **Package**: `@suaveplan/api-docs`
- **Category**: universal/docs
- **Target path**: `universal/docs/api-docs`
- **Status**: PROPOSED
- **Date**: 2026-04-24
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/api-docs.md`
---
## Summary
Deliver `@suaveplan/api-docs` on the genesis branch from scratch at enterprise quality. The package provides an API documentation generator: parse TypeDoc-annotated TypeScript source, extract public API surfaces (functions, classes, interfaces, type aliases, enumerations), generate structured documentation as JSON/Markdown/HTML, and emit OpenAPI 3.1 schemas from function signatures. Genesis adds structured errors via `@suaveplan/error`, Zod schemas for all doc types, OTel instrumentation on generation operations, `AbortSignal` on async generation, injectable `Clock` for build timestamps, and a plugin interface for custom output formatters.
---
## Current-state audit (genesis)
The package does not exist on genesis yet — this is a fresh build.
---
## Available workspace deps on genesis
| Package | Role |
|---|---|
| `@suaveplan/error` (`workspace:^`) | Base class for `ApiDocsError`; stable error codes |
| `@suaveplan/types` (`workspace:^`) | `LoggerLike`, `Clock` injectable interfaces |
| `@suaveplan/logger` (`workspace:^`) | Structured logging with OTel trace correlation |
| `@suaveplan/serialize` (`workspace:^`) | Structured serialization for doc export |
| `zod` (`catalog:forms`) | Zod schemas for all public doc types |
| `@opentelemetry/api` (`catalog:observability`) | Spans + counters on doc generation |
| `tslib` (`catalog:build`) | Runtime helpers |
Dev deps: `vitest`, `@vitest/coverage-istanbul`, `fast-check` (all `catalog:testing`).
---
## Public API surface
### Core
```ts
function createDocGenerator(options?: DocGeneratorOptions): DocGenerator
interface DocGenerator {
generate(input: DocInput, signal?: AbortSignal): Promise<DocOutput>
use(formatter: DocFormatter): this
}
```
### Input/output types
```ts
interface DocInput {
source: string | string[] // file paths or glob patterns
entryPoints?: string[]
tsconfig?: string
includePrivate?: boolean
includeInternal?: boolean
}
interface DocOutput {
readonly packages: ReadonlyArray<PackageDoc>
readonly generatedAt: number
toJSON(): string
toMarkdown(): string
toOpenApi(): OpenApiSchema
}
interface PackageDoc {
readonly name: string
readonly version?: string
readonly description?: string
readonly symbols: ReadonlyArray<SymbolDoc>
}
type SymbolDoc =
| FunctionDoc
| ClassDoc
| InterfaceDoc
| TypeAliasDoc
| EnumDoc
| VariableDoc
interface BaseSymbol {
name: string
kind: SymbolKind
description?: string
remarks?: string
examples?: string[]
deprecated?: string
since?: string
tags?: Record<string, string>
sourceFile?: string
sourceLine?: number
}
type SymbolKind = 'function' | 'class' | 'interface' | 'typeAlias' | 'enum' | 'variable'
interface FunctionDoc extends BaseSymbol {
kind: 'function'
signatures: ReadonlyArray<FunctionSignature>
}
interface FunctionSignature {
parameters: ReadonlyArray<ParameterDoc>
returnType: string
typeParameters?: ReadonlyArray<TypeParameterDoc>
overload?: number
}
interface ClassDoc extends BaseSymbol {
kind: 'class'
constructors: ReadonlyArray<FunctionSignature>
properties: ReadonlyArray<PropertyDoc>
methods: ReadonlyArray<FunctionDoc>
extends?: string
implements?: string[]
}
interface InterfaceDoc extends BaseSymbol {
kind: 'interface'
properties: ReadonlyArray<PropertyDoc>
methods: ReadonlyArray<FunctionDoc>
extends?: string[]
}
```
### Plugin interface
```ts
interface DocFormatter {
readonly name: string
readonly format: 'json' | 'markdown' | 'html' | 'openapi' | string
format(output: DocOutput): string | Promise<string>
}
function defineFormatter(formatter: DocFormatter): DocFormatter
```
### Options
```ts
interface DocGeneratorOptions {
logger?: LoggerLike
clock?: Clock
outputFormat?: 'json' | 'markdown' | 'html' | 'openapi'
excludePatterns?: string[]
includePatterns?: string[]
}
```
### Error codes
```ts
type ApiDocsErrorCode =
| 'API_DOCS_SOURCE_NOT_FOUND'
| 'API_DOCS_PARSE_FAILED'
| 'API_DOCS_GENERATE_FAILED'
| 'API_DOCS_FORMATTER_NOT_FOUND'
| 'API_DOCS_INVALID_INPUT'
function registerApiDocsErrorCodes(): void
```
---
## Genesis additions
1. **Structured `ApiDocsError`** extending `SuaveplanError` with stable `API_DOCS.*` codes
2. **Zod schemas** for `DocInput`, `DocGeneratorOptions`, `PackageDoc`
3. **Plugin formatter interface** — `use()` on `DocGenerator`; JSON, Markdown, and OpenAPI formatters built-in
4. **`AbortSignal` on `generate()`**
5. **Injectable `Clock`** for `generatedAt` timestamps
6. **OTel instrumentation** — span `api_docs.generate`, histogram `api_docs.generation_duration_ms`, counter `api_docs.symbols_parsed_total`
7. **OpenAPI 3.1 emission** from function signatures
---
## File layout
```text
universal/docs/api-docs/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
constants/
index.ts
types/
common.ts
common.md
core/
generator/
generator.ts
generator.md
generator.types.ts
generator.test.ts
index.ts
parser/
parser.ts
parser.md
parser.test.ts
index.ts
formatters/
json-formatter/
json-formatter.ts
json-formatter.md
json-formatter.test.ts
index.ts
markdown-formatter/
markdown-formatter.ts
markdown-formatter.md
markdown-formatter.test.ts
index.ts
openapi-formatter/
openapi-formatter.ts
openapi-formatter.md
openapi-formatter.test.ts
index.ts
tests/
integration.test.ts
```
---
## Impact
**Downstream packages**: `@suaveplan/docs` may depend on this for documentation site generation.
**Workspace dep prerequisites**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/logger`, `@suaveplan/serialize` must be published.