Controllers
DocsController
SourceController for serving documentation pages.
Index
Task<IActionResult> Index()
Displays the documentation index view containing either curated proof paths from the repository-root landing doc metadata or the neutral docs landing fallback.
Returns
A view result whose model is a DocLandingViewModel
. The model includes curated featured cards when the repository-root README.md
metadata authors featured_page_groups
through inline front matter or a paired sidecar such as README.md.yml
; otherwise it includes the neutral fallback landing data.
VersionEntry
IActionResult VersionEntry()
Resolves the stable Docs entry to the recommended release or its archive fallback.
Returns
A redirect to the available recommended exact release, a view result describing available released versions plus the current preview surface when no release is mounted, or a redirect to the live docs home when versioning is disabled.
Versions
IActionResult Versions()
Displays the public docs version archive.
Returns
A view result that lists the published versions described by the configured version catalog, or a redirect to the live docs home when versioning is disabled.
Section
Task<IActionResult> Section(string sectionSlug)
Enters one normalized public documentation section.
Parameters
-
sectionSlugThe stable slug for the public section.
Returns
A redirect to the authored landing doc when one exists, otherwise a grouped section fallback or unavailable view.
Details
Task<IActionResult> Details(string path)
Displays the full or partial details view for a documentation item identified by the given path.
Parameters
-
pathThe public docs route, redirect alias, or.partial.htmlresource identifier of the documentation item to retrieve. Full-page source-shaped Markdown routes for public pages redirect to the clean canonical route.
Returns
An IActionResult
rendering the details view or the doc-content
RazorWire frame; returns NotFoundResult
when the path is invalid or no document is found after fallback resolution.
Remarks
Partial requests ending in .partial.html
are resolved through the same DocAggregator.GetDocDetailsAsync(string, CancellationToken)
flow as full-page requests. When a partial path resolves to an /index
resource, such as /index.partial.html
, the action transparently retries the parent document before returning NotFoundResult
. Successful requests load the complete docs corpus and public-section snapshots with DocAggregator.GetDocsAsync(CancellationToken)
and DocAggregator.GetPublicSectionsAsync(CancellationToken)
, then build the response model with BuildDetailsViewModel
. All aggregator calls observe HttpContext.RequestAborted
. Visible caller side effects are limited to returning either the full details view or a doc-content
frame for partial navigation.
DownloadMarkdown
Task<IActionResult> DownloadMarkdown(string path)
Returns an authorized, source-faithful Markdown attachment for one exact canonical Docs page.
Parameters
-
pathThe Docs-relative canonical route path supplied by the reserved download route.
Returns
A Markdown attachment, or 404
when the feature, route, or source entry is unavailable.
Remarks
Route registration owns authorization. This action defensively preserves the disabled-feature and canonical-route contract so direct invocation, source-shaped aliases, and normalized alternate paths cannot surface raw Markdown. Successful responses return the original harvested bytes, not rendered HTML or regenerated Markdown.
Search
Task<IActionResult> Search()
Displays the dedicated docs search workspace shell.
Returns
A ViewResult
whose model is a SearchPageViewModel
describing the search shell and its server-rendered recovery paths.
Remarks
The action returns a SearchPageViewModel
immediately so the workspace can render starter, loading, and retry UI before the client downloads the search index. Fallback link generation shares a linked cancellation token with the current request and is capped by SearchShellFallbackBudget
so slow aggregation does not block the shell from rendering. If aggregation times out or throws, the view still renders with default recovery links.
SearchIndex
Task<IActionResult> SearchIndex()
Returns docs search index data for live-hosted docs.
Returns
A JSON result containing searchable document metadata, including normalized page-type badge fields that keep search result rendering consistent with the built-in landing and details experiences. When HttpRequest.PathBase
is non-empty, only documents[*].path
values that already start with /
are rebased onto that path base before serialization so a mounted app returns links like /some-base/docs/guide.html
instead of /docs/guide.html
.
Remarks
The path-base rewrite is intentionally narrow. Only rooted documents[*].path
values are prefixed; blank, missing, or already non-rooted values such as guide.html
remain unchanged. The rewrite trims trailing slashes from the request path base before concatenation, so /some-base/
and /some-base
produce the same output. For example, a typed payload that contains documents[0].path = "/docs/guide.html"
becomes /some-base/docs/guide.html
when the request path base is /some-base
. This action always receives the typed DocsSearchIndexPayload
produced by DocAggregator.GetSearchIndexPayloadAsync(System.Threading.CancellationToken)
; raw JSON payloads without a top-level documents
array are outside this method's contract and must be handled before this action is invoked. The rewrite is idempotent when HttpRequest.PathBase
is null, empty, or /
.
RefreshSearchIndex
Task<IActionResult> RefreshSearchIndex()
Invalidates the current live docs search-index cache after host-owned operator authorization succeeds.
Returns
NoContentResult
when the configured policy authorizes the current user; otherwise HTTP 403. MVC anti-forgery validation runs before this action body and rejects missing or invalid tokens before policy checks.
Remarks
This endpoint is intentionally POST-only and side-effecting. Readers should fetch SearchIndex
; host operators should post to DocsUrlBuilder.Routes
. SearchIndexRefresh
with a valid anti-forgery token and a user that satisfies the effective AppSurface Docs operator-write policy. New hosts should configure AppSurfaceDocsDiagnosticsOptions.OperatorWritePolicy
; existing hosts may keep AppSurfaceDocsDiagnosticsOptions.SearchIndexRefreshPolicy
as the compatibility fallback.
Harvest
Task<IActionResult> Harvest(string? returnUrl = null, string? rebuild = null)
Displays the live harvest observatory for a trusted operator rebuild or an active startup harvest.
Parameters
-
returnUrlOptional app-relative docs URL to revisit after the active harvest completes. Unsafe values and harvest-loop targets fall back to the current docs home. -
rebuildOptional rebuild request result emitted byRebuildHarvestso the observatory can show whether the operator request started, queued, or was already queued.
Returns
The harvest observatory while a harvest is active or queued; otherwise a redirect to the validated return URL.
RebuildHarvest
Task<IActionResult> RebuildHarvest(string? returnUrl = null)
Starts or queues a full source-backed AppSurface Docs harvest rebuild after trusted operator authorization.
Parameters
-
returnUrlOptional app-relative docs URL to revisit after rebuild completion. Unsafe values, non-docs paths, and harvest loop targets fall back to the current docs home.
Returns
A redirect to the live harvest observatory when authorization succeeds; otherwise HTTP 403. MVC anti-forgery validation runs before this action body.
HarvestHealth
Task<IActionResult> HarvestHealth()
Displays the redacted operator-facing harvest health page for the current live docs surface.
Returns
A health page when health routes are exposed for the current environment; otherwise NotFoundResult
. Healthy and empty snapshots return HTTP 200. Degraded and failed snapshots render the same page with HTTP 503 so local verification and CI checks can fail quickly.
HarvestHealthJson
Task<IActionResult> HarvestHealthJson()
Returns redacted machine-readable harvest health for the current live docs surface.
Returns
A JSON health response when health routes are exposed for the current environment; otherwise NotFoundResult
. Healthy and empty snapshots return HTTP 200 with verification.ok=true
. Degraded and failed snapshots return HTTP 503 with verification.ok=false
.
RouteInspector
Task<IActionResult> RouteInspector(string? path = null)
Displays the human-facing route inspector for the current live docs surface.
Parameters
-
pathOptional path to probe. Values are trimmed, may be docs-root-relative or app-relative, may include the activeHttpRequest.PathBase, and have any query string or fragment stripped before route lookup. Absolute URLs, protocol-relative URLs, paths outside the active docs root, empty post-strip values, and.or..path segments produce an invalid-input probe instead of route lookup.
Returns
A no-store route inspector page when diagnostics are exposed for the current environment; otherwise NotFoundResult
. The page uses BuildRouteInspectorResponseAsync(string?)
for the same manifest and optional probe shape as the JSON endpoint.
Remarks
Use this endpoint for interactive maintainer inspection. It is intentionally separate from reader navigation and is hidden by AppSurfaceDocsDiagnosticsVisibility.IsRouteInspectorExposed(AppSurfaceDocsOptions, IHostEnvironment)
when the current environment or explicit diagnostics settings do not expose route diagnostics.
RouteInspectorJson
Task<IActionResult> RouteInspectorJson(string? path = null)
Returns machine-readable route identity for the current live docs surface.
Parameters
-
pathOptional path to probe. Values are trimmed, may be docs-root-relative or app-relative, may include the activeHttpRequest.PathBase, and have any query string or fragment stripped before route lookup. Absolute URLs, protocol-relative URLs, paths outside the active docs root, empty post-strip values, and.or..path segments produce an invalid-input probe in the JSON response.
Returns
A no-store JSON route inspector response when diagnostics are exposed for the current environment; otherwise NotFoundResult
.
Remarks
Use this endpoint for scripts, tests, and maintainer tools that need the AppSurfaceDocsRouteInspectorResponse
wire contract produced by BuildRouteInspectorResponseAsync(string?)
. Use RouteInspector(string?)
instead when a human needs the compact HTML probing surface.
CollectMetrics
Task<IActionResult> CollectMetrics()
Accepts low-trust browser AppSurface Docs metrics submissions for hosted collection.
Returns
NoContentResult
for accepted, invalid, or dropped submissions while hosted collection is enabled; otherwise NotFoundResult
. Unsupported media type and oversized bodies return HTTP 415 and 413 respectively without echoing submitted values.
Remarks
Route mapping constrains this collector to HTTP POST. The action intentionally opts out of antiforgery validation because it is an anonymous, low-trust JSON collector for hosted docs and static exports rather than an authenticated state-changing form post. The request body uses a narrow DTO containing only name
, properties
, and an optional client timestamp. Browser-supplied identity, route, URL, cookies, headers, and request metadata are not accepted into the event envelope. Every submitted event is revalidated through AppSurfaceProductEventRegistry
before the process-local read model or host-owned product-intelligence sinks see it.
SearchQuality
IActionResult SearchQuality()
Displays recent hosted AppSurface Docs search-quality diagnostics.
Returns
A no-store diagnostics page when hosted review is enabled and exposed; otherwise NotFoundResult
.
AuthorizeSearchIndexRefreshAsync
Task<SearchIndexRefreshAuthorizationResult> AuthorizeSearchIndexRefreshAsync(CancellationToken cancellationToken)
Authorizes a side-effecting search-index refresh request against the host-configured operator policy.
Parameters
-
cancellationTokenToken observed while resolving the configured authorization policy; caller cancellation does not turn policy or authorization failures into exceptions.
Returns
A SearchIndexRefreshAuthorizationResult
whose allowed state means cache invalidation may proceed. Denied results carry the specific SearchIndexRefreshAuthorizationFailure
reason for logging and explicit 403 responses.
Remarks
The decision flow is intentionally ordered from host configuration to caller identity: a missing or blank no effective AppSurfaceDocsDiagnosticsOptions.OperatorWritePolicy
or AppSurfaceDocsDiagnosticsOptions.SearchIndexRefreshPolicy
fallback returns SearchIndexRefreshAuthorizationFailure.MissingPolicyOption
; missing HttpContext
, request services, or IAuthorizationPolicyProvider
returns SearchIndexRefreshAuthorizationFailure.MissingPolicyProvider
; a missing IAuthorizationService
returns SearchIndexRefreshAuthorizationFailure.MissingAuthorizationService
; an unresolved configured policy returns SearchIndexRefreshAuthorizationFailure.PolicyNotFound
; a missing or unauthenticated user returns SearchIndexRefreshAuthorizationFailure.Unauthenticated
; and a policy evaluation failure returns SearchIndexRefreshAuthorizationFailure.AuthorizationFailed
. Authorization denials are reported as denied results rather than thrown exceptions. The policy lookup uses Task.WaitAsync(CancellationToken)
so cancellation can interrupt a slow policy provider before refresh side effects occur.
BuildHarvestUrlWithReturnUrl
string BuildHarvestUrlWithReturnUrl(string returnUrl, AppSurfaceDocsHarvestRebuildRequestResult rebuild)
Builds a path-base-aware harvest observatory URL that carries the verified docs return URL and rebuild result.
Parameters
-
returnUrlThe app-relative docs URL to revisit after the active or queued harvest completes. -
rebuildThe trusted rebuild request result to expose in the observatory status copy.
Returns
A local harvest URL containing URL-encoded returnUrl
and rebuild
query-string values.
Remarks
Callers should pass only return URLs produced by ResolveHarvestReturnUrl(string?)
or the current docs request. This helper only encodes the value for transport; it does not re-run the docs-root containment policy. Unknown rebuild enum values serialize as an empty marker and are ignored by the observatory parser.
ResolveHarvestReturnUrl
string ResolveHarvestReturnUrl(string? returnUrl)
Resolves request-provided harvest navigation back to a safe docs URL.
Parameters
-
returnUrlThe candidate app-relative return URL from the query string or rebuild form.
Returns
returnUrl
when it stays under the current docs root and avoids harvest routes; otherwise the path-base-aware docs home URL.
Remarks
This is the docs-specific return URL policy for the harvest loop. It intentionally rejects same-origin paths outside the active HttpRequest.PathBase
and docs surface, raw or encoded traversal, and _harvest
loops so a terminal progress update cannot navigate an operator away from the docs context being verified.
ResolveDocsOperatorWritePolicyName
string? ResolveDocsOperatorWritePolicyName()
Resolves the authorization policy used for trusted docs write operations.
Returns
The configured docs operator-write policy when present, otherwise the legacy search-index refresh policy, or null
when neither policy is configured.
Remarks
AppSurfaceDocsDiagnosticsOptions.OperatorWritePolicy
is preferred so hosts can give rebuild actions a neutral docs-operator policy name. The fallback to AppSurfaceDocsDiagnosticsOptions.SearchIndexRefreshPolicy
preserves compatibility for applications that already opted into the older refresh endpoint.
GetRebuildAuthorizationStatus
string GetRebuildAuthorizationStatus(SearchIndexRefreshAuthorizationFailure? failure)
Converts an authorization failure reason into the compact health-page rebuild status.
Parameters
-
failureThe failure reason returned by the shared operator authorization helper.
Returns
Unauthorized
for user/auth policy denials; otherwise Unavailable
.
Remarks
Missing policies and missing services are shown as unavailable rather than unauthorized so operators can distinguish host configuration problems from account permission problems.
GetRebuildAuthorizationDescription
string GetRebuildAuthorizationDescription(SearchIndexRefreshAuthorizationFailure? failure)
Builds the visible health-page explanation for a disabled rebuild action.
Parameters
-
failureThe failure reason returned by the shared operator authorization helper.
Returns
A short operator-facing explanation for why the rebuild form is disabled.
Remarks
The text avoids exposing policy internals while still separating sign-in, authorization, missing-policy, and unavailable-service cases for production troubleshooting.
GetHarvestRebuildRequestResultQueryValue
string GetHarvestRebuildRequestResultQueryValue(AppSurfaceDocsHarvestRebuildRequestResult result)
Gets the stable query-string marker used to carry a harvest rebuild request result into the observatory view.
Parameters
-
resultThe rebuild request result returned by the shared harvest coordinator.
Returns
The stable marker for a known result, or an empty string for an unknown enum value.
ParseHarvestRebuildRequestResult
AppSurfaceDocsHarvestRebuildRequestResult? ParseHarvestRebuildRequestResult(string? value)
Parses the stable query-string marker used by the harvest observatory rebuild status.
Parameters
-
valueThe rawrebuildquery-string value.
Returns
The matching rebuild request result, or null
for missing, blank, or unknown markers.
Remarks
Unknown values are ignored instead of displayed so stale links and hand-written URLs do not create misleading operator status copy.
IsSafeDocsHarvestReturnUrl
bool IsSafeDocsHarvestReturnUrl(string? url, string? pathBase, string docsRootPath)
Determines whether a harvest completion return URL stays inside the active docs surface and cannot loop back to the harvest observatory.
Parameters
-
urlThe candidate app-relative return URL. -
pathBaseThe active request path base, ornullwhen none is mounted. -
docsRootPathThe configured current docs root path.
Returns
true
when url
is a safe app-relative path under the current docs root and not _harvest
or _harvest/rebuild
; otherwise false
.
TryNormalizeReturnUrlPathForValidation
bool TryNormalizeReturnUrlPathForValidation(string path, out string normalizedPath)
Normalizes a harvest return URL path for containment checks after rejecting encoded traversal tricks.
Parameters
-
pathThe path portion of the candidate return URL. -
normalizedPathThe normalized decoded path when validation succeeds.
Returns
true
when path
can be decoded without revealing control characters, backslashes, raw dot segments, or encoded dot-segment traversal; otherwise false
.
TryValidateReturnUrlPercentEscapes
bool TryValidateReturnUrlPercentEscapes(string path)
Rejects malformed percent escapes and double-encoded sensitive path tokens in a harvest return URL path.
Parameters
-
pathThe path portion of the candidate return URL.
Returns
true
when every percent escape is syntactically valid and does not hide a second encoded control character, slash, backslash, or dot; otherwise false
.
IsSafeAppRelativeUrl
bool IsSafeAppRelativeUrl(string? url)
Determines whether a return URL is safe to use as an app-relative navigation target.
Parameters
-
urlThe candidate URL to validate.
Returns
true
when url
is a non-empty app-relative path that starts with /
, is not protocol-relative, is not slash-backslash rooted, and contains no backslashes or control characters; otherwise false
.
Remarks
Use IsSafeAppRelativeUrl(string?)
before echoing request-derived return URLs into redirects, links, or local path decisions. The helper intentionally rejects null
, empty or whitespace input, paths that do not start with /
, //
, /\
, any \
character, and any control character such as CR or LF. Checks are ordinal and culture-invariant; the method does not URL-decode or normalize Unicode, so callers should decode first when validating encoded input.
NormalizeReturnUrlPath
string NormalizeReturnUrlPath(string? path)
Normalizes a local return URL path into the shape used by docs containment checks.
Parameters
-
pathA candidate path, path base, or docs root value.
Returns
A leading-slash path with trailing slashes removed, or an empty string for blank input.
Remarks
The helper only trims and applies slash shape. It does not decode, collapse dot segments, or decide whether a path is safe; callers must validate encoded input and traversal before using the normalized value for redirects.
ContainsDotSegment
bool ContainsDotSegment(string path)
Detects dot-segment traversal after splitting a return URL path on literal path separators.
Parameters
-
pathThe raw or once-decoded path being evaluated for harvest return navigation.
Returns
true
when any path segment is exactly .
or ..
; otherwise false
.
Remarks
This helper is deliberately segment-based instead of substring-based so ordinary filenames containing dots remain valid. Callers must invoke it for both the raw path and the once-decoded path because percent-encoded traversal can be hidden until after decoding.
ContainsSensitivePercentEscape
bool ContainsSensitivePercentEscape(string path)
Detects percent escapes that still hide sensitive path bytes after the first decode pass.
Parameters
-
pathThe once-decoded path being checked for nested percent escapes.
Returns
true
when path
contains an encoded control character, slash, backslash, or dot; otherwise false
.
Remarks
Harvest return URLs are decoded once before redirect decisions. A second decoder later in the stack could otherwise turn split encodings such as %25%32%65
into %2e
and then into .
. Rejecting sensitive nested escapes keeps the docs-only containment decision stable across downstream URL normalization.
StartsWithHarvestRouteSegment
bool StartsWithHarvestRouteSegment(string relativePath)
Determines whether a docs-root-relative path begins with the reserved harvest route segment.
Parameters
-
relativePathThe decoded path relative to the current docs root.
Returns
true
when the first non-empty path segment is _harvest
; otherwise false
.
Remarks
Duplicate separators can appear after decoding an otherwise local URL. The harvest loop guard therefore evaluates the first meaningful segment instead of comparing the unnormalized relative path string.
IsHex
bool IsHex(char value)
Determines whether a character can participate in a percent-encoded byte.
Parameters
-
valueThe candidate hexadecimal digit.
Returns
true
for ASCII hexadecimal digits; otherwise false
.
Remarks
URL percent escapes are byte-oriented and ASCII-only. This intentionally does not accept Unicode lookalikes or culture-sensitive digits, and callers should only pass characters adjacent to a literal %
.
HexToByte
int HexToByte(char high, char low)
Converts two validated hexadecimal digits into the byte value represented by a percent escape.
Parameters
-
highThe high-order hexadecimal digit. -
lowThe low-order hexadecimal digit.
Returns
The decoded byte value from 0
through 255
.
Remarks
Callers must guard both inputs with IsHex(char)
before calling this helper. The method is intentionally allocation-free because it runs in the return-URL validation hot path.
HexValue
int HexValue(char value)
Maps a single validated hexadecimal digit to its numeric value.
Parameters
-
valueThe ASCII hexadecimal digit to convert.
Returns
An integer from 0
through 15
.
Remarks
This helper assumes value
has already passed IsHex(char)
. Passing any other character falls into the uppercase branch and produces a meaningless value, so validation order is part of the contract.
IsUnderPath
bool IsUnderPath(string candidatePath, string rootPath)
Determines whether a normalized candidate path is at or below a normalized root path.
Parameters
-
candidatePathThe normalized candidate path to evaluate. -
rootPathThe normalized root path that bounds the allowed surface.
Returns
true
when candidatePath
equals rootPath
or is a child path; otherwise false
.
Remarks
The root path /
accepts any absolute app path. Non-root comparisons are ordinal-ignore-case to match the existing docs route policy. Callers must pass already-normalized, decoded, traversal-free paths.
PrefixSearchIndexPathsForPathBase
DocsSearchIndexPayload PrefixSearchIndexPathsForPathBase(DocsSearchIndexPayload payload, string? requestPathBase)
Prefixes rooted search-document paths in a cached search-index payload for the active request path base.
Parameters
-
payloadThe cached search-index payload whose document paths may need rebasing. -
requestPathBaseThe current request path base that should be prepended when it is non-empty and not/.
Returns
The original payload when no rewrite is needed; otherwise a cloned payload whose rooted DocsSearchIndexDocument.Path
values are prefixed with the normalized path base.
Remarks
This helper operates on the typed DocsSearchIndexPayload
contract, which always exposes a top-level DocsSearchIndexPayload.Documents
list. It does not inspect or reshape arbitrary JSON payloads, so callers that hold raw JSON without a top-level documents
array must deserialize or otherwise handle that mismatch before calling this method. Within the typed payload, rooted DocsSearchIndexDocument.Path
and nested recommendation paths are rewritten. Non-rooted, blank, or otherwise unchanged values such as guide.html
are returned as-is, so callers should supply leading-slash browser paths for docs-local navigation when rebasing is expected. For example, rebasing a payload that contains documents[0].path = "/docs/guide.html"
with /some-base/
produces /some-base/docs/guide.html
. The supplied path base is trimmed of trailing slashes before concatenation, and paths are unchanged when requestPathBase
is null, empty, or /
. Recommendation rows and their reason lists are detached even for an unchanged mount. Target identities, raw authored references and explanations are preserved; no ranking runs during this projection.
BuildMarkdownDownloadFileName
string BuildMarkdownDownloadFileName(string canonicalPath)
Builds a safe attachment filename for a canonical Docs-relative Markdown route.
Parameters
-
canonicalPathThe canonical Docs-relative route path.
Returns
An ASCII-safe Markdown attachment filename.
Remarks
The route catalog normally supplies ASCII-safe segments. This internal boundary remains defensive so a future caller cannot emit a device name, an empty filename, or an attachment name outside the compatibility limit.
ProjectAliasArchiveEntry
AppSurfaceDocsVersionAliasArchiveEntryViewModel ProjectAliasArchiveEntry(AppSurfaceDocsResolvedVersionAlias alias, string unavailableAliasMessage)
Projects resolved alias state into the reader-facing archive model.
Parameters
-
aliasA public resolved alias already selected for the archive. -
unavailableAliasMessageThe safe fallback explanation for an unavailable alias.
Returns
A row whose link, availability flag and explanation agree.
Remarks
A row is linkable only when the alias reports availability, its target is public, and its root URL is nonblank. Unavailable rows omit the link and explain why; hidden or unknown targets omit target metadata and use the safe fallback message. Internal so tests can verify inconsistent resolved state without mocking the catalog loader.
IsApiSurfaceDoc
bool IsApiSurfaceDoc(DocNode doc)
Determines whether a documentation node should render with the API reference reading surface.
Remarks
Non-Markdown generated docs use the API surface by default because AppSurface Docs cannot assume extensionless generated pages have authored prose rhythm. Markdown docs opt into the API surface only when page_type
normalizes to api
or api-reference
. Extensionless authored content is therefore treated as generated API/reference content unless a future harvester exposes a stronger authorship signal.
IsApiSurfacePageType
bool IsApiSurfacePageType(string? pageType)
Determines whether raw page-type metadata explicitly requests the API reference reading surface.
Remarks
Values are normalized with DocMetadataPresentation.NormalizeToken(string?)
before comparison, so values such as api_reference
and API Reference
match api-reference
. Null or blank metadata does not opt a Markdown document into the API surface.
IsMarkdownDoc
bool IsMarkdownDoc(string path)
Determines whether a source path represents authored Markdown by checking known Markdown filename suffixes.
Remarks
Matching is case-insensitive and currently recognizes .md
and .markdown
. Callers should pass a non-null harvested path; extensionless paths are intentionally treated as non-Markdown generated docs.
SearchIndexRefreshAuthorizationResult
SourceRepresents the internal authorization outcome for an AppSurface Docs search-index refresh request.
Parameters
-
IsAllowedIndicates whether the refresh action may invalidate the search-index cache. -
ReasonThe denial reason whenIsAllowedisfalse; otherwisenull.
Remarks
Use Allowed
and Denied(SearchIndexRefreshAuthorizationFailure)
to preserve the two valid states: allowed results have IsAllowed == true
and no reason, while denied results have IsAllowed == false
and a concrete reason. Consumers should check IsAllowed
before reading Reason
because the reason is intentionally nullable for successful authorization. This immutable record struct is internal to the controller layer and should not become part of a public wire contract.
Allowed
SearchIndexRefreshAuthorizationResult Allowed()
Creates an authorization result that permits cache invalidation.
Returns
An allowed result with no failure reason.
Denied
SearchIndexRefreshAuthorizationResult Denied(SearchIndexRefreshAuthorizationFailure reason)
Creates an authorization result that denies cache invalidation for a specific reason.
Parameters
-
reasonThe concrete denial reason to expose to internal logging and branch-specific tests.
Returns
A denied result whose Reason
is set to reason
.
SearchIndexRefreshAuthorizationFailure
SourceEnumerates the internal reasons a search-index refresh request can be denied before cache invalidation.
Remarks
These reasons intentionally distinguish host setup failures from caller authorization failures so logs and tests can identify the remediation path. They are not serialized to clients; the packaged endpoint returns HTTP 403 for every denial after anti-forgery validation succeeds.