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'