Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,188 @@
# Design: enterprise-docs
> Non-normative architecture for `@suaveplan/docs`. Normative requirements live in `./specs/docs/spec.md`.
## Package position
`@suaveplan/docs` is a server-tier devtools library: it walks a monorepo file
tree, parses every Markdown file via `remark` + `gray-matter`, and exposes a
documentation graph, hierarchy, and search index. It is consumed by tooling
(doc-site generators, link checkers, completeness audits) — never by a runtime
application.
Path: `packages/devtools/docs/docs/` per `scripts/folder-reorg/assignment.yml`
(`devtools` → `docs` plugin → `docs` package).
## Public surface
Upstream parity (preserved verbatim):
```ts
discoverDocs(options: DiscoverOptions): Promise<DocFile[]>
parseDoc(absolutePath: string, relativePath: string, rawContent: string): DocFile
buildGraph(docs: DocFile[]): DocGraph
findOrphans(graph: DocGraph): OrphanInfo[]
buildHierarchy(graph: DocGraph, options?: BuildHierarchyOptions): DocHierarchy
searchDocs(docs: DocFile[], query: string, limit?: number): SearchResult[]
```
Genesis additions:
```ts
const DOCS_CODES = defineCodes("DOCS", [...] as const)
class DocsError extends SuaveplanError<DocsErrorCode>
createDocsObservability(opts?): DocsObservability
DiscoverOptionsSchema: z.ZodType<DiscoverOptions>
```
## File layout (Pattern B per CLAUDE.md)
```text
packages/devtools/docs/docs/
package.json
README.md
tsconfig.lib.json
vite.config.ts
vitest.config.ts
src/
index.ts # explicit named re-exports
discovery/
discover.ts
discover.test.ts
discover.md
index.ts
parser/
parse.ts
parse.test.ts
parse.md
index.ts
graph/
build-graph.ts
build-graph.test.ts
build-graph.md
find-orphans.ts
find-orphans.test.ts
find-orphans.md
index.ts
hierarchy/
build-hierarchy.ts
build-hierarchy.test.ts
build-hierarchy.md
index.ts
search/
search.ts
search.test.ts
search.md
index.ts
errors/
errors.ts
errors.test.ts
errors.md
index.ts
observability/
observability.ts
observability.test.ts
observability.md
observability.types.ts
index.ts
types/
docs.types.ts
index.ts
```
## Error code registry
```ts
export const DOCS_CODES = defineCodes("DOCS", [
"INVALID_OPTIONS", // Zod validation of DiscoverOptions failed
"READ_FAILED", // node:fs/promises.readFile threw
"PARSE_FAILED", // gray-matter / remark threw on malformed input
"GLOB_FAILED", // glob threw (permission / IO at directory level)
"ABORTED", // signal.aborted observed during discovery
"LINK_RESOLUTION_FAILED", // graph link resolver hit an unexpected state
"HIERARCHY_CYCLE_LIMIT", // depth limit reached while walking hierarchy
"SEARCH_INVALID_QUERY", // searchDocs called with non-string query
] as const);
```
Every code is reachable from a real call site and exercised by tests.
## OTel instruments
| Name | Type | Description |
|---|---|---|
| `docs_discovered_total` | counter | Total docs successfully parsed across all `discoverDocs` calls. |
| `docs_parse_error_total` | counter | Total `parseDoc` failures partitioned by `code`. |
| `docs_io_error_total` | counter | Total `readFile` / `glob` failures during discovery. |
| `docs_search_total` | counter | Total `searchDocs` invocations. |
| `docs_discover_duration_ms` | histogram | Wall-clock time of each `discoverDocs` call. |
| `docs_parse_duration_ms` | histogram | Wall-clock time of each `parseDoc` call. |
| `docs_graph_build_duration_ms` | histogram | Wall-clock time of each `buildGraph` call. |
| `docs_search_duration_ms` | histogram | Wall-clock time of each `searchDocs` call. |
Observability is created via `createDocsObservability(opts?)` and accepted
optionally on every public entrypoint. Default uses the no-op `metrics` /
`trace` providers so tests pass without an SDK.
## Typed mdast traversal
Upstream uses `node as any` to read `Heading` and `Link` children. Genesis
imports `Heading`, `Link`, `Text` from `@types/mdast` and narrows with type
guards (`if (node.type === "heading")` etc.). No `any`, no casts.
## Discovery — error surfacing + AbortSignal
Upstream silently swallows `readFile` failures (`catch {}`). Genesis emits
`docs_io_error_total{code:"DOCS.READ_FAILED"}` per failure, continues the sweep
(non-fatal — a per-file IO error must not abort a 10k-file monorepo scan), and
exposes the count via the observability counter. Callers wanting hard-fail can
inspect the counter after the call.
`AbortSignal` is checked (a) before glob, (b) between glob and parse, and (c)
after every batch of 64 parsed files. On abort, a `DocsError(DOCS.ABORTED)` is
thrown and the discovery histogram records the partial duration.
## Category derivation
Eighteen genesis categories per the closed vocabulary in CLAUDE.md / Layout
section:
```ts
const GENESIS_CATEGORIES = [
"foundation", "persistence", "networking", "communication", "api-stack",
"identity", "security-stack", "observability", "media", "ui", "threejs",
"localization", "geospatial", "money", "commerce", "testkit", "devtools",
"gaming",
] as const;
type DocCategory = (typeof GENESIS_CATEGORIES)[number] | "root";
```
`deriveCategory(relativePath)` reads the second path segment after `packages/`
to recover the category. Upstream's six-tier union (`universal`/`react`/`server`
/`browser`/`three`/`finance`) is replaced — the test suite no longer asserts
those upstream values.
## Hierarchy depth limit
Upstream hard-codes depth 8. Genesis preserves the default but accepts an
optional `maxDepth` field on `BuildHierarchyOptions` so doc-site builders with
larger forests can opt in.
## Deps
Runtime: `@suaveplan/error`, `@suaveplan/opentelemetry`, `@suaveplan/types`,
`tslib`, `zod`, `glob`, `gray-matter`, `remark-parse`, `remark-gfm`, `unified`,
`unist-util-visit`, `@types/mdast` (runtime types only).
Catalog: a new `markdown` catalog key carries `glob`, `gray-matter`, `remark-*`,
`unified`, `unist-util-visit`, `@types/mdast`. The root `package.json`
`catalogs` block is extended in the same commit.
Dev: `vitest`, `@vitest/coverage-istanbul`, `@suaveplan/testing`, `@types/node`,
`vite`, `vite-plugin-dts`, `typescript`.
## Testing strategy
Real `node:fs/promises` against `mkdtemp` temp dirs — never mocks. Coverage
target: 100/100/100/100 with `provider: 'istanbul'`. Every error code is
exercised by at least one negative-path test.