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
471 lines
14 KiB
YAML
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' |