TenantAtlas/specs/275-customer-facing-localization-adoption/contracts/customer-facing-localization-adoption.openapi.yaml
ahmido 71596ae590 feat: customer-facing localization adoption (275) (#327)
Automated pull request created via MCP: adds customer-facing localization adoption specs, tests and docs.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #327
2026-05-04 23:14:20 +00:00

471 lines
14 KiB
YAML

openapi: 3.1.0
info:
title: TenantPilot Customer-Facing Localization Adoption v1 (Conceptual)
version: 0.1.0
summary: Conceptual contract for localized customer-review surface adoption over existing locale and review foundations.
description: |
These paths document the existing locale endpoints and current customer-review
surfaces reused by the implementation. The schemas describe the expected
localized view behavior and invariance boundaries for planning purposes only;
they do not introduce a new public API or a new artifact family.
servers:
- url: /
paths:
/localization/context:
get:
summary: Resolve the effective locale for the current request.
operationId: resolveLocalizationContext
description: |
Reuses the existing locale precedence chain over explicit override,
user preference, workspace default, and system default.
responses:
'200':
description: Effective locale context for the current request.
content:
application/json:
schema:
$ref: '#/components/schemas/ResolvedLocaleContext'
/localization/override:
post:
summary: Set the explicit temporary locale override.
operationId: updateExplicitLocaleOverride
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LocaleOverrideUpdate'
responses:
'200':
description: Locale feedback result after the override becomes effective.
content:
application/json:
schema:
$ref: '#/components/schemas/LocaleFeedbackResult'
'400':
description: Unsupported locale input was rejected.
delete:
summary: Clear the explicit temporary locale override.
operationId: clearExplicitLocaleOverride
responses:
'200':
description: Locale feedback result after the override is cleared.
content:
application/json:
schema:
$ref: '#/components/schemas/LocaleFeedbackResult'
/users/me/locale-preference:
post:
summary: Persist the authenticated user's locale preference.
operationId: updateUserLocalePreference
description: |
Reuses the existing personal preference path for the workspace-bound user.
The slice does not add a second preference store or a new auth plane.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserLocalePreferenceUpdate'
responses:
'200':
description: Locale feedback result after saving or clearing the preference.
content:
application/json:
schema:
$ref: '#/components/schemas/LocaleFeedbackResult'
'400':
description: Unsupported locale input was rejected.
'404':
description: The preference path is unavailable outside the current authenticated workspace-user context.
/admin/reviews/workspace:
get:
summary: View the localized customer review workspace.
operationId: viewLocalizedCustomerReviewWorkspace
description: |
Existing admin-plane workspace page reused as the primary decision
surface for the customer-safe review flow. The route remains read-only
and keeps the current tenant filter and row-action behavior.
parameters:
- in: query
name: tenant
required: false
schema:
type: string
description: Optional existing tenant prefilter using tenant id or external id.
responses:
'200':
description: Localized workspace page rendered.
content:
text/html:
schema:
type: string
application/json:
schema:
$ref: '#/components/schemas/LocalizedCustomerReviewWorkspaceModel'
'404':
description: Not found for non-members, actors without entitled tenants, or explicit out-of-scope tenant targeting.
/admin/t/{tenant}/reviews/{review}:
get:
summary: View the localized released-review detail from the customer workspace.
operationId: viewLocalizedCustomerReviewDetail
description: |
Existing tenant-scoped review detail route reused as the secondary
context surface. The existing `customer_workspace=1` query flag keeps the
surface read-only and customer-safe.
parameters:
- in: path
name: tenant
required: true
schema:
type: integer
- in: path
name: review
required: true
schema:
type: integer
- in: query
name: customer_workspace
required: false
schema:
type: boolean
description: Existing query-context flag for customer-workspace mode.
responses:
'200':
description: Localized released-review detail rendered.
content:
text/html:
schema:
type: string
application/json:
schema:
$ref: '#/components/schemas/LocalizedCustomerReviewDetailModel'
'403':
description: Forbidden for an in-scope actor missing the record-level review permission.
'404':
description: Not found for tenant mismatches, non-members, or out-of-scope review targets.
/admin/review-packs/{reviewPack}/download:
get:
summary: Download the current governance-package artifact.
operationId: downloadCurrentGovernancePackage
description: |
Reuses the existing signed review-pack download path. Localization may
change the surrounding UI labels and reasons, but the artifact bytes and
machine-readable payload remain unchanged.
parameters:
- in: path
name: reviewPack
required: true
schema:
type: integer
responses:
'200':
description: Current review-pack artifact streamed unchanged.
content:
application/zip:
schema:
type: string
format: binary
'403':
description: Forbidden because of invalid signature or inaccessible pack download permission.
'404':
description: Review pack not found, unavailable for the current review flow, expired, or outside the accessible tenant scope. Supporting UI reasons such as missing or not-ready remain derived under the existing unavailable state.
/admin/t/{tenant}/evidence/{evidenceSnapshot}:
get:
summary: Open supporting proof from the localized customer review flow.
operationId: viewLocalizedCustomerReviewProof
description: |
Reuses the existing evidence detail route only after explicit drilldown.
The supporting proof path stays secondary and capability-gated.
parameters:
- in: path
name: tenant
required: true
schema:
type: integer
- in: path
name: evidenceSnapshot
required: true
schema:
type: integer
responses:
'200':
description: Evidence proof detail rendered.
content:
text/html:
schema:
type: string
'403':
description: Forbidden for an in-scope actor missing the evidence capability.
'404':
description: Not found for non-members, mismatched tenant scope, or unavailable proof targets.
components:
schemas:
SupportedLocale:
type: string
enum:
- en
- de
LocaleSource:
type: string
enum:
- explicit_override
- user_preference
- workspace_default
- system_default
ResolvedLocaleContext:
type: object
required:
- locale
- source
- fallback_locale
- machine_artifacts_invariant
properties:
locale:
$ref: '#/components/schemas/SupportedLocale'
source:
$ref: '#/components/schemas/LocaleSource'
fallback_locale:
type: string
const: en
user_preference_locale:
anyOf:
- $ref: '#/components/schemas/SupportedLocale'
- type: 'null'
workspace_default_locale:
anyOf:
- $ref: '#/components/schemas/SupportedLocale'
- type: 'null'
machine_artifacts_invariant:
type: boolean
const: true
LocaleOverrideUpdate:
type: object
required:
- locale
properties:
locale:
$ref: '#/components/schemas/SupportedLocale'
UserLocalePreferenceUpdate:
type: object
required:
- preferred_locale
properties:
preferred_locale:
anyOf:
- $ref: '#/components/schemas/SupportedLocale'
- type: 'null'
description: Null clears the personal preference and returns the user to inherited behavior.
LocaleFeedbackResult:
type: object
required:
- resolved_locale
- status_message
- machine_artifacts_invariant
properties:
resolved_locale:
$ref: '#/components/schemas/SupportedLocale'
source:
$ref: '#/components/schemas/LocaleSource'
status_message:
type: string
machine_artifacts_invariant:
type: boolean
const: true
LocalizedAccessMessage:
type: object
required:
- state
- label
properties:
state:
type: string
enum:
- available
- partial
- unavailable
- blocked
- expired
label:
type: string
description:
type: string
nullable: true
translation_key:
type: string
nullable: true
CustomerFacingGlossaryBoundary:
type: object
required:
- in_scope_terms
- out_of_scope_artifacts
- fallback_locale
properties:
in_scope_terms:
type: array
items:
type: string
example:
- customer review
- governance package
- current review pack
- proof access
- next step
- review status
- evidence
- accepted risk
out_of_scope_artifacts:
type: array
items:
type: string
example:
- exported review-pack file contents
- raw JSON payloads
- audit action ids and metadata
fallback_locale:
type: string
const: en
LocalizedCustomerReviewWorkspaceEntry:
type: object
required:
- tenant_id
- tenant_name
- governance_package
- proof_access
- primary_action_label
properties:
tenant_id:
type: integer
tenant_name:
type: string
latest_published_review_id:
type: integer
nullable: true
review_status_label:
type: string
nullable: true
accepted_risk_summary:
type: string
nullable: true
governance_package:
$ref: '#/components/schemas/LocalizedAccessMessage'
proof_access:
$ref: '#/components/schemas/LocalizedAccessMessage'
next_step_label:
type: string
nullable: true
primary_action_label:
type: string
primary_action_url:
type: string
nullable: true
glossary_terms_rendered:
type: array
items:
type: string
LocalizedCustomerReviewWorkspaceModel:
type: object
required:
- workspace_id
- resolved_locale
- glossary_scope
- heading_copy
- intro_copy
- disclosure_copy
- entries
- empty_state_copy
- untranslated_keys_detected
- machine_artifacts_invariant
- glossary_boundary
properties:
workspace_id:
type: integer
tenant_filter_id:
type: integer
nullable: true
resolved_locale:
$ref: '#/components/schemas/SupportedLocale'
glossary_scope:
type: string
const: customer_review
heading_copy:
type: string
intro_copy:
type: string
disclosure_copy:
type: string
entries:
type: array
items:
$ref: '#/components/schemas/LocalizedCustomerReviewWorkspaceEntry'
empty_state_copy:
type: string
nullable: true
untranslated_keys_detected:
type: boolean
const: false
machine_artifacts_invariant:
type: boolean
const: true
glossary_boundary:
$ref: '#/components/schemas/CustomerFacingGlossaryBoundary'
LocalizedCustomerReviewDetailModel:
type: object
required:
- review_id
- tenant_id
- resolved_locale
- launched_from_customer_workspace
- section_labels
- governance_package
- proof_access
- operator_actions_hidden
- machine_artifacts_invariant
- glossary_boundary
properties:
review_id:
type: integer
tenant_id:
type: integer
resolved_locale:
$ref: '#/components/schemas/SupportedLocale'
launched_from_customer_workspace:
type: boolean
const: true
dominant_action_label:
type: string
nullable: true
section_labels:
type: array
items:
type: string
accepted_risk_summary:
type: string
nullable: true
governance_package:
$ref: '#/components/schemas/LocalizedAccessMessage'
proof_access:
$ref: '#/components/schemas/LocalizedAccessMessage'
helper_copy:
type: array
items:
type: string
glossary_terms_rendered:
type: array
items:
type: string
operator_actions_hidden:
type: boolean
const: true
machine_artifacts_invariant:
type: boolean
const: true
glossary_boundary:
$ref: '#/components/schemas/CustomerFacingGlossaryBoundary'