diff --git a/apps/api-harmonization/src/app.config.ts b/apps/api-harmonization/src/app.config.ts index 8da0e5f9d..94b007b00 100644 --- a/apps/api-harmonization/src/app.config.ts +++ b/apps/api-harmonization/src/app.config.ts @@ -1,45 +1,7 @@ -import { - Articles, - Auth, - BillingAccounts, - CMS, - Cache, - Carts, - Checkout, - Customers, - Invoices, - Notifications, - Orders, - Organizations, - Payments, - Products, - Resources, - Search, - Tickets, - Users, -} from '@o2s/configs.integrations'; +import { integrations } from '@o2s/configs.integrations'; import { ApiConfig } from '@o2s/framework/modules'; export const AppConfig: ApiConfig = { - integrations: { - users: Users.UsersIntegrationConfig, - organizations: Organizations.OrganizationsIntegrationConfig, - tickets: Tickets.TicketsIntegrationConfig, - notifications: Notifications.NotificationsIntegrationConfig, - articles: Articles.ArticlesIntegrationConfig, - resources: Resources.ResourcesIntegrationConfig, - invoices: Invoices.InvoicesIntegrationConfig, - cms: CMS.CmsIntegrationConfig, - cache: Cache.CacheIntegrationConfig, - billingAccounts: BillingAccounts.BillingAccountsIntegrationConfig, - search: Search.SearchIntegrationConfig, - products: Products.ProductsIntegrationConfig, - orders: Orders.OrdersIntegrationConfig, - carts: Carts.CartsIntegrationConfig, - customers: Customers.CustomersIntegrationConfig, - payments: Payments.PaymentsIntegrationConfig, - checkout: Checkout.CheckoutIntegrationConfig, - auth: Auth.AuthIntegrationConfig, - }, + integrations, }; diff --git a/package-lock.json b/package-lock.json index 813430392..ca3770e26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51963,7 +51963,7 @@ }, "packages/integrations/mocked-dxp": { "name": "@o2s/integrations.mocked-dxp", - "version": "0.0.1", + "version": "1.0.0", "license": "MIT", "dependencies": { "@o2s/framework": "*", diff --git a/packages/configs/integrations/src/config.ts b/packages/configs/integrations/src/config.ts new file mode 100644 index 000000000..c999f5172 --- /dev/null +++ b/packages/configs/integrations/src/config.ts @@ -0,0 +1,51 @@ +import * as Mocked from '@o2s/integrations.mocked/integration'; + +import { createIntegrationConfig } from '@o2s/framework/config'; +import type { ApiConfig } from '@o2s/framework/modules'; + +// Single swap point: change Mocked → another integration per domain +// When swapping a domain, update BOTH the assignment below AND the matching export import +const result = createIntegrationConfig({ + articles: Mocked, + auth: Mocked, + billingAccounts: Mocked, + cache: Mocked, + carts: Mocked, + checkout: Mocked, + cms: Mocked, + customers: Mocked, + invoices: Mocked, + notifications: Mocked, + orders: Mocked, + organizations: Mocked, + payments: Mocked, + products: Mocked, + resources: Mocked, + search: Mocked, + tickets: Mocked, + users: Mocked, +}); + +export const integrations: ApiConfig['integrations'] = result.integrations; + +// Type exports — re-export the integration namespace so consumers get the correct types, +// including any model extensions defined by the integration (e.g. extended Notification). +// Keep these in sync with the createIntegrationConfig assignments above. +export import Articles = Mocked.Integration.Articles; +export import Auth = Mocked.Integration.Auth; +export import BillingAccounts = Mocked.Integration.BillingAccounts; +export import Cache = Mocked.Integration.Cache; +export import Carts = Mocked.Integration.Carts; +export import Checkout = Mocked.Integration.Checkout; +export import CMS = Mocked.Integration.CMS; +export import Customers = Mocked.Integration.Customers; +export import Invoices = Mocked.Integration.Invoices; +export import Notifications = Mocked.Integration.Notifications; +export import Orders = Mocked.Integration.Orders; +export import Organizations = Mocked.Integration.Organizations; +export import Payments = Mocked.Integration.Payments; +export import Products = Mocked.Integration.Products; +export import Resources = Mocked.Integration.Resources; +export import Search = Mocked.Integration.Search; +export import Tickets = Mocked.Integration.Tickets; +export import Users = Mocked.Integration.Users; diff --git a/packages/configs/integrations/src/models/articles.ts b/packages/configs/integrations/src/models/articles.ts deleted file mode 100644 index de4b3fea8..000000000 --- a/packages/configs/integrations/src/models/articles.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const ArticlesIntegrationConfig: ApiConfig['integrations']['articles'] = Config.articles!; - -export import Service = Integration.Articles.Service; -export import Request = Integration.Articles.Request; -export import Model = Integration.Articles.Model; diff --git a/packages/configs/integrations/src/models/auth.ts b/packages/configs/integrations/src/models/auth.ts deleted file mode 100644 index 6f792a45a..000000000 --- a/packages/configs/integrations/src/models/auth.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const AuthIntegrationConfig: ApiConfig['integrations']['auth'] = Config.auth!; - -export import Service = Integration.Auth.Service; -export import Model = Integration.Auth.Model; -export import Guards = Integration.Auth.Guards; diff --git a/packages/configs/integrations/src/models/billing-accounts.ts b/packages/configs/integrations/src/models/billing-accounts.ts deleted file mode 100644 index 2901ee271..000000000 --- a/packages/configs/integrations/src/models/billing-accounts.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const BillingAccountsIntegrationConfig: ApiConfig['integrations']['billingAccounts'] = Config.billingAccounts!; - -export import Service = Integration.BillingAccounts.Service; -export import Request = Integration.BillingAccounts.Request; -export import Model = Integration.BillingAccounts.Model; diff --git a/packages/configs/integrations/src/models/cache.ts b/packages/configs/integrations/src/models/cache.ts deleted file mode 100644 index 75808de9f..000000000 --- a/packages/configs/integrations/src/models/cache.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const CacheIntegrationConfig: ApiConfig['integrations']['cache'] = Config.cache!; - -export import Service = Integration.Cache.Service; diff --git a/packages/configs/integrations/src/models/carts.ts b/packages/configs/integrations/src/models/carts.ts deleted file mode 100644 index b8f1582ed..000000000 --- a/packages/configs/integrations/src/models/carts.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const CartsIntegrationConfig: ApiConfig['integrations']['carts'] = Config.carts!; - -export import Service = Integration.Carts.Service; -export import Request = Integration.Carts.Request; -export import Model = Integration.Carts.Model; diff --git a/packages/configs/integrations/src/models/checkout.ts b/packages/configs/integrations/src/models/checkout.ts deleted file mode 100644 index e267d6b5c..000000000 --- a/packages/configs/integrations/src/models/checkout.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const CheckoutIntegrationConfig: ApiConfig['integrations']['checkout'] = Config.checkout!; - -export import Service = Integration.Checkout.Service; -export import Request = Integration.Checkout.Request; -export import Model = Integration.Checkout.Model; diff --git a/packages/configs/integrations/src/models/cms.ts b/packages/configs/integrations/src/models/cms.ts deleted file mode 100644 index 0051b2e5c..000000000 --- a/packages/configs/integrations/src/models/cms.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const CmsIntegrationConfig: ApiConfig['integrations']['cms'] = Config.cms!; - -export import Service = Integration.CMS.Service; -export import Request = Integration.CMS.Request; -export import Model = Integration.CMS.Model; diff --git a/packages/configs/integrations/src/models/customers.ts b/packages/configs/integrations/src/models/customers.ts deleted file mode 100644 index 80f726acf..000000000 --- a/packages/configs/integrations/src/models/customers.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const CustomersIntegrationConfig: ApiConfig['integrations']['customers'] = Config.customers!; - -export import Service = Integration.Customers.Service; -export import Request = Integration.Customers.Request; -export import Model = Integration.Customers.Model; diff --git a/packages/configs/integrations/src/models/index.ts b/packages/configs/integrations/src/models/index.ts index 8cf0413f4..cb1cc4fb3 100644 --- a/packages/configs/integrations/src/models/index.ts +++ b/packages/configs/integrations/src/models/index.ts @@ -1,18 +1,21 @@ -export * as Articles from './articles'; -export * as Auth from './auth'; -export * as BillingAccounts from './billing-accounts'; -export * as Cache from './cache'; -export * as Carts from './carts'; -export * as Checkout from './checkout'; -export * as CMS from './cms'; -export * as Customers from './customers'; -export * as Invoices from './invoices'; -export * as Notifications from './notifications'; -export * as Orders from './orders'; -export * as Organizations from './organizations'; -export * as Payments from './payments'; -export * as Products from './products'; -export * as Resources from './resources'; -export * as Search from './search'; -export * as Tickets from './tickets'; -export * as Users from './users'; +export { + integrations, + Articles, + Auth, + BillingAccounts, + Cache, + Carts, + Checkout, + CMS, + Customers, + Invoices, + Notifications, + Orders, + Organizations, + Payments, + Products, + Resources, + Search, + Tickets, + Users, +} from '../config'; diff --git a/packages/configs/integrations/src/models/invoices.ts b/packages/configs/integrations/src/models/invoices.ts deleted file mode 100644 index 7c6c162d5..000000000 --- a/packages/configs/integrations/src/models/invoices.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const InvoicesIntegrationConfig: ApiConfig['integrations']['invoices'] = Config.invoices!; - -export import Service = Integration.Invoices.Service; -export import Request = Integration.Invoices.Request; -export import Model = Integration.Invoices.Model; diff --git a/packages/configs/integrations/src/models/notifications.ts b/packages/configs/integrations/src/models/notifications.ts deleted file mode 100644 index 7a5bc55c4..000000000 --- a/packages/configs/integrations/src/models/notifications.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const NotificationsIntegrationConfig: ApiConfig['integrations']['notifications'] = Config.notifications!; - -export import Service = Integration.Notifications.Service; -export import Request = Integration.Notifications.Request; -export import Model = Integration.Notifications.Model; diff --git a/packages/configs/integrations/src/models/orders.ts b/packages/configs/integrations/src/models/orders.ts deleted file mode 100644 index 413ebd794..000000000 --- a/packages/configs/integrations/src/models/orders.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const OrdersIntegrationConfig: ApiConfig['integrations']['orders'] = Config.orders!; - -export import Service = Integration.Orders.Service; -export import Request = Integration.Orders.Request; -export import Model = Integration.Orders.Model; diff --git a/packages/configs/integrations/src/models/organizations.ts b/packages/configs/integrations/src/models/organizations.ts deleted file mode 100644 index 2b0301d11..000000000 --- a/packages/configs/integrations/src/models/organizations.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const OrganizationsIntegrationConfig: ApiConfig['integrations']['organizations'] = Config.organizations!; - -export import Service = Integration.Organizations.Service; -export import Request = Integration.Organizations.Request; -export import Model = Integration.Organizations.Model; diff --git a/packages/configs/integrations/src/models/payments.ts b/packages/configs/integrations/src/models/payments.ts deleted file mode 100644 index b03c77fa5..000000000 --- a/packages/configs/integrations/src/models/payments.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const PaymentsIntegrationConfig: ApiConfig['integrations']['payments'] = Config.payments!; - -export import Service = Integration.Payments.Service; -export import Request = Integration.Payments.Request; -export import Model = Integration.Payments.Model; diff --git a/packages/configs/integrations/src/models/products.ts b/packages/configs/integrations/src/models/products.ts deleted file mode 100644 index b8d770415..000000000 --- a/packages/configs/integrations/src/models/products.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const ProductsIntegrationConfig: ApiConfig['integrations']['products'] = Config.products!; - -export import Service = Integration.Products.Service; -export import Request = Integration.Products.Request; -export import Model = Integration.Products.Model; diff --git a/packages/configs/integrations/src/models/resources.ts b/packages/configs/integrations/src/models/resources.ts deleted file mode 100644 index b0ac78b10..000000000 --- a/packages/configs/integrations/src/models/resources.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const ResourcesIntegrationConfig: ApiConfig['integrations']['resources'] = Config.resources!; - -export import Service = Integration.Resources.Service; -export import Request = Integration.Resources.Request; -export import Model = Integration.Resources.Model; diff --git a/packages/configs/integrations/src/models/search.ts b/packages/configs/integrations/src/models/search.ts deleted file mode 100644 index 29ee2fa36..000000000 --- a/packages/configs/integrations/src/models/search.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const SearchIntegrationConfig: ApiConfig['integrations']['search'] = Config.search!; - -export import Service = Integration.Search.Service; diff --git a/packages/configs/integrations/src/models/tickets.ts b/packages/configs/integrations/src/models/tickets.ts deleted file mode 100644 index 507024ea9..000000000 --- a/packages/configs/integrations/src/models/tickets.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const TicketsIntegrationConfig: ApiConfig['integrations']['tickets'] = Config.tickets!; -export import Service = Integration.Tickets.Service; -export import Request = Integration.Tickets.Request; -export import Model = Integration.Tickets.Model; diff --git a/packages/configs/integrations/src/models/users.ts b/packages/configs/integrations/src/models/users.ts deleted file mode 100644 index 3cada25f1..000000000 --- a/packages/configs/integrations/src/models/users.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Config, Integration } from '@o2s/integrations.mocked/integration'; - -import { ApiConfig } from '@o2s/framework/modules'; - -export const UsersIntegrationConfig: ApiConfig['integrations']['users'] = Config.users!; - -export import Service = Integration.Users.Service; -export import Request = Integration.Users.Request; -export import Model = Integration.Users.Model; diff --git a/packages/framework/package.json b/packages/framework/package.json index 9abce7747..b9efe2cb1 100644 --- a/packages/framework/package.json +++ b/packages/framework/package.json @@ -22,6 +22,10 @@ }, "type": "commonjs", "exports": { + "./config": { + "import": "./dist/src/config/index.js", + "require": "./dist/src/config/index.js" + }, "./modules": { "import": "./dist/src/index.js", "require": "./dist/src/index.js" diff --git a/packages/framework/src/config/create-integration-config.ts b/packages/framework/src/config/create-integration-config.ts new file mode 100644 index 000000000..96742181e --- /dev/null +++ b/packages/framework/src/config/create-integration-config.ts @@ -0,0 +1,78 @@ +import type { ApiConfig } from '../api-config'; + +/** + * Integration module must export Config with the domain's config and Integration namespace. + * Domain presence is validated at runtime by createIntegrationConfig. + */ +export type IntegrationWithDomain = { + Config: Record; + Integration: Record; +}; + +type DomainKey = keyof ApiConfig['integrations']; + +/** + * Input for createIntegrationConfig. Each domain maps to an integration that provides that domain. + */ +export type IntegrationConfigInput = { + [D in DomainKey]: IntegrationWithDomain; +}; + +const DOMAIN_KEYS: DomainKey[] = [ + 'articles', + 'auth', + 'billingAccounts', + 'cache', + 'carts', + 'checkout', + 'cms', + 'customers', + 'invoices', + 'notifications', + 'orders', + 'organizations', + 'payments', + 'products', + 'resources', + 'search', + 'tickets', + 'users', +]; + +/** + * Creates integration config from a domain-to-integration map. + * Validates at runtime that each integration provides the domain it's assigned to. + * + * @example + * const { integrations } = createIntegrationConfig({ + * cms: Mocked, + * tickets: Zendesk, // swap: change Mocked -> Zendesk + * articles: Mocked, + * // ... + * }); + */ +export function createIntegrationConfig( + config: T, +): { + integrations: ApiConfig['integrations']; +} { + const integrations: Record = {}; + + for (const domain of DOMAIN_KEYS) { + const integration = config[domain] as IntegrationWithDomain; + if (!integration?.Config) { + throw new Error(`Missing integration for domain: ${domain}`); + } + + const domainConfig = (integration.Config as Record)[domain]; + if (!domainConfig) { + throw new Error(`Integration does not provide config for domain: ${domain}`); + } + + integrations[domain] = domainConfig; + } + + return { + integrations: integrations as ApiConfig['integrations'], + }; +} diff --git a/packages/framework/src/config/index.ts b/packages/framework/src/config/index.ts new file mode 100644 index 000000000..02e2f6d19 --- /dev/null +++ b/packages/framework/src/config/index.ts @@ -0,0 +1,5 @@ +export { + createIntegrationConfig, + type IntegrationConfigInput, + type IntegrationWithDomain, +} from './create-integration-config'; diff --git a/packages/integrations/zendesk/scripts/oas/help-center-oas.yaml b/packages/integrations/zendesk/scripts/oas/help-center-oas.yaml index 8a32a5798..dd9735c69 100644 --- a/packages/integrations/zendesk/scripts/oas/help-center-oas.yaml +++ b/packages/integrations/zendesk/scripts/oas/help-center-oas.yaml @@ -4548,266 +4548,6 @@ paths: examples: default: $ref: '#/components/examples/MissingTranslationsResponseExample' - /api/v2/help_center/community/posts: - get: - operationId: ListPostsInternal - tags: - - Posts - summary: List Posts (legacy) - parameters: - - name: filter_by - in: query - description: Filter the results using the provided value - schema: - type: string - enum: - - planned - - not_planned - - completed - - answered - - none - - name: sort_by - in: query - description: Sorts the results using the provided value - schema: - type: string - enum: - - created_at - - edited_at - - updated_at - - recent_activity - - votes - - comments - responses: - "200": - description: OK Response - content: - application/json: - schema: - $ref: '#/components/schemas/PostsResponse' - examples: - default: - $ref: '#/components/examples/PostsResponseExample' - /api/v2/help_center/community/posts/{post_id}: - parameters: - - $ref: '#/components/parameters/PostId' - get: - operationId: ShowPostInternal - tags: - - Posts - summary: Show Post (legacy) - description: | - Gets information about a given post. - - #### Allowed for - - * Anonymous users - - #### Sideloads - The following sideloads are supported: - - | Name | Will sideload - |-------------|-------------- - | users | authors - | topics | topics - responses: - "200": - description: OK Response - content: - application/json: - schema: - $ref: '#/components/schemas/PostResponse' - examples: - default: - $ref: '#/components/examples/PostResponseExample' - put: - operationId: UpdatePostInternal - tags: - - Posts - summary: Update Post (legacy) - description: | - #### Allowed for - - * Agents - * The end user who created the post - responses: - "200": - description: OK Response - content: - application/json: - schema: - $ref: '#/components/schemas/PostResponse' - examples: - default: - $ref: '#/components/examples/PostResponseExample' - delete: - operationId: DeletePostInternal - tags: - - Posts - summary: Delete Post (legacy) - description: | - #### Allowed for - - * Agents - * The end user who created the post - responses: - "204": - description: Default success response - /api/v2/help_center/community/posts/{post_id}/comments/{post_comment_id}: - parameters: - - $ref: '#/components/parameters/PostId' - - $ref: '#/components/parameters/PostCommentId' - get: - operationId: ShowPostCommentInternal - tags: - - Post Comments - summary: Show Post Comment - description: | - Shows information about the specified comment. - - #### Allowed for - - * End users - - #### Sideloads - - The following sideloads are supported: - - | Name | Will sideload - |--------|-------------- - | users | The comment's author - | posts | The comment's post - responses: - "200": - description: OK Response - content: - application/json: - schema: - $ref: '#/components/schemas/PostCommentResponse' - examples: - default: - $ref: '#/components/examples/PostCommentResponseExample' - put: - operationId: UpdatePostCommentInternal - tags: - - Post Comments - summary: Update Post Comment - description: | - Updates the specified comment. - - #### Allowed for - - * Agents - * The end user who created the comment - responses: - "200": - description: OK Response - content: - application/json: - schema: - $ref: '#/components/schemas/PostCommentResponse' - examples: - default: - $ref: '#/components/examples/PostCommentResponseExample' - delete: - operationId: DeletePostCommentInternal - tags: - - Post Comments - summary: Delete Post Comment - description: | - Deletes the specified comment. - - #### Allowed for - - * Agents - * The end user who created the comment - responses: - "204": - description: Default success response - /api/v2/help_center/community/topics/{topic_id}/posts: - parameters: - - $ref: '#/components/parameters/TopicId' - get: - operationId: ListPostsByTopicInternal - tags: - - Posts - summary: List Posts in Topic (legacy) - parameters: - - name: filter_by - in: query - description: Filter the results using the provided value - schema: - type: string - enum: - - planned - - not_planned - - completed - - answered - - none - - name: sort_by - in: query - description: Sorts the results using the provided value - schema: - type: string - enum: - - created_at - - edited_at - - updated_at - - recent_activity - - votes - - comments - responses: - "200": - description: OK Response - content: - application/json: - schema: - $ref: '#/components/schemas/PostsResponse' - examples: - default: - $ref: '#/components/examples/PostsResponseExample' - /api/v2/help_center/community/users/{user_id}/posts: - parameters: - - $ref: '#/components/parameters/UserId' - get: - operationId: ListPostsByUserInternal - tags: - - Posts - summary: List Posts by User (legacy) - parameters: - - name: filter_by - in: query - description: Filter the results using the provided value - schema: - type: string - enum: - - planned - - not_planned - - completed - - answered - - none - - name: sort_by - in: query - description: Sorts the results using the provided value - schema: - type: string - enum: - - created_at - - edited_at - - updated_at - - recent_activity - - votes - - comments - responses: - "200": - description: OK Response - content: - application/json: - schema: - $ref: '#/components/schemas/PostsResponse' - examples: - default: - $ref: '#/components/examples/PostsResponseExample' /api/v2/help_center/community_posts/search: get: operationId: CommunityPostSearch @@ -6249,231 +5989,6 @@ paths: responses: "204": description: Default success response - /hc/api/internal/generative_answers: - post: - operationId: GenerativeAnswersHelpCenter - tags: - - Generative Answers - summary: Generate Answer for Help Center - description: | - Generates an answer for end-user search queries in Help Center. Accepts encrypted content references and returns a generated answer with source attribution. - - The endpoint is accessible to anonymous and authenticated end users. Queries must be at least 2 words (except for certain CJK languages). Returns up to 3 source contents used to generate the answer. - - #### Allowed for - - * Anonymous users - * End users - parameters: - - name: contents_data - in: query - description: Encrypted contents data. - required: true - schema: - type: string - example: BAh7DjoHaWRJIh8wMUo3ME0wRDZRNTAzNFRNNllGMDhQQVJQSgY6BkVUOg9hY2NvdW50X2lkaQSpphUBOgl0eXBlSSIcZXh0ZXJuYWxfY29udGVudF9yZWNvcmQGOwZUOgh1cmxJIn1odHRwczovL3N1cHBvcnQuemVuZGVzay5jb20vaGMvZW4tdXMvY29tbXVuaXR5L3Bvc3RzLzM2MDA0Njc1OTgzNy1Ib3ctdG8tbGVhdmUtZmVlZGJhY2stZm9yLUZlZGVyYXRlZC1IZWxwLUNlbnRlci1zZWFyY2gGOwZUOg5zZWFyY2hfaWRJIik2MDJkNGExMS05ZmRlLTQxZTgtOGM3NC00M2YzNjJjZGRjMjkGOwZGOglyYW5raQY6C2xvY2FsZUkiCmVuLXVzBjsGVDoKcXVlcnlJIhpXaGF0IGlzIGEgaGVscCBjZW50ZXIGOwZUOhJyZXN1bHRzX2NvdW50aQo - responses: - "200": - description: OK Response - content: - application/json: - schema: - $ref: '#/components/schemas/GenerativeAnswersHelpCenterResponse' - example: - answer_found: true - generated_answer: To deactivate your Help Center, go to the settings and select 'Deactivate'. - generated_answer_formatted: To deactivate your Help Center, go to the settings and select **Deactivate**. - llm_confidence_level: HIGH - search_id: 51D5084D-5C39-4522-B653-74BEDA56F618 - source_contents: - - id: "8201616519805" - title: Deactivating your Help Center - url: https://{subdomain}.zendesk-staging.com/hc/de/articles/8201616519805-Deactivating-your-Help-Center - "400": - description: Bad Request - content: - application/json: - schema: - type: object - properties: - error: - type: string - description: Error message describing the issue with the request. - example: - error: query parameter must be at least 2 words - "403": - description: Forbidden - content: - application/json: - schema: - type: object - properties: - error: - type: string - description: Error message describing the issue with the request. - example: - error: feature not available - /hc/api/internal/generative_answers_feedback: - post: - operationId: GenerativeAnswersFeedback - tags: - - Generative Answers - summary: Submits feedback for a generated answer - description: | - Submits feedback for a generated answer. This feedback can be used to improve the quality of future answers generated by the system. - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/GenerativeAnswersFeedbackRequest' - example: - channel: HELP_CENTER - feedback_category: OTHER - is_helpful: false - search_id: 28cac105-aea1-407c-b485-c0f16c8ced0c - text_feedback: The answer was not relevant to my query. - responses: - "204": - description: Feedback submitted successfully - "400": - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/BadRequestErrorResponse' - example: - errors: - feedback_category: is invalid - "403": - description: Forbidden - content: - application/json: - schema: - type: object - properties: - error: - type: string - description: Error message describing the issue with the request. - example: - error: feature not available - /hc/api/internal/generative_answers_knowledge: - post: - operationId: GenerativeAnswersKnowledge - tags: - - Generative Answers - summary: Generate Answer for Knowledge - description: | - Generates an answer for agents using Knowledge in the ticket workspace. Accepts a structured request with ticket context and content references, returning an answer localized to the ticket requester's language. - - The endpoint validates content references and returns only the cited source content. Used by the Agent Workspace for knowledge-assisted ticket responses. - - #### Allowed for - - * Agents - * Help Center managers - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/GenerativeAnswersKnowledgeRequest' - example: - contents: - - id: "8201616519805" - locale: en-us - search_id: 51D5084D-5C39-4522-B653-74BEDA56F618 - type: article - url: https://{subdomain}.zendesk-staging.com/hc/de/articles/8201616519805-Deactivating-your-Help-Center - query: How to deactivate help center - ticket_id: 1 - responses: - "200": - description: OK Response - content: - application/json: - schema: - $ref: '#/components/schemas/GenerativeAnswersKnowledgeResponse' - example: - answer: To deactivate your Help Center, go to the settings and select 'Deactivate'. - llm_confidence_level: HIGH - solved: true - source_contents: - - id: "8201616519805" - locale: en-us - search_id: 51D5084D-5C39-4522-B653-74BEDA56F618 - title: Deactivating your Help Center - type: article - url: https://{subdomain}.zendesk-staging.com/hc/de/articles/8201616519805-Deactivating-your-Help-Center - "400": - description: Bad Request - content: - application/json: - schema: - type: object - properties: - error: - type: string - description: Error message describing the issue with the request. - example: - error: contents must be an array - "403": - description: Forbidden - content: - application/json: - schema: - type: object - properties: - error: - type: string - description: Error message describing the issue with permissions. - example: - error: feature not available - /hc/api/internal/generative_answers_knowledge/actions: - post: - operationId: GenerativeAnswersKnowledgeActions - tags: - - Generative Answers - summary: Submits an action for a generated answer - description: | - Submits an action for a generated answer. This action indicates that user has perfomed further actions on the generated answer. - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/GenerativeAnswersKnowledgeActionsRequest' - example: - knowledge_action: COPIED_TO_CONVERSATION - search_id: 51D5084D-5C39-4522-B653-74BEDA56F618 - ticket_nice_id: "1" - responses: - "204": - description: Action performed successfully - "400": - description: Bad Request - content: - application/json: - schema: - type: object - properties: - error: - type: string - description: Error message describing the issue with the request. - example: - error: 'required properties missing: knowledge_action' - "403": - description: Forbidden - content: - application/json: - schema: - type: object - properties: - error: - type: string - description: Error message describing the issue with the request. - example: - error: feature not available components: schemas: ArticleAttachmentObject: @@ -7125,6 +6640,45 @@ components: url: type: string description: URL to access the content. + HelpCenterGenerativeSearchResponse: + type: object + properties: + answer: + type: string + description: The AI-generated answer for the query. May be null if no answer was generated. + nullable: true + answer_found: + type: boolean + description: Indicates whether an answer was successfully generated. + citations: + type: array + description: List of source contents cited in the generated answer. + items: + type: object + properties: + id: + type: string + description: Unique identifier for the cited content. + locale: + type: string + description: Locale of the cited content (e.g., "en-us"). + title: + type: string + description: Title of the cited content. + type: + type: string + description: Type of the cited content. + enum: + - article + - community_post + - external_content_record + url: + type: string + description: URL to access the cited content. For articles and community posts, includes brand-specific subdomain. + nullable: true + id: + type: string + description: Unique identifier for the search request. HelpCenterLocalesResponse: type: object properties: @@ -7142,6 +6696,185 @@ components: properties: current_session: $ref: '#/components/schemas/HelpCenterSessionObject' + KnowledgeQuickAnswersRequest: + type: object + properties: + filters: + type: object + description: Optional filters to narrow down search results. + properties: + article_category_ids: + type: array + description: Array of article category IDs to filter results. + items: + type: integer + article_section_ids: + type: array + description: Array of article section IDs to filter results. + items: + type: integer + brand_ids: + type: array + description: Array of brand IDs to filter results. + items: + type: integer + external_source_ids: + type: array + description: Array of external source IDs to filter results. + items: + type: string + external_type_ids: + type: array + description: Array of external type IDs to filter results. + items: + type: string + locales: + type: array + description: Array of locale codes to filter results (e.g., ["en-us", "de"]). + items: + type: string + record_types: + type: array + description: Array of record types to filter results. + items: + type: string + enum: + - article + - external_content + query: + type: string + description: The search query from the agent. + search_id: + type: string + description: Unique identifier for tracking the search request. + ticket_id: + type: integer + description: The ID of the ticket for which the answer is being generated. + required: + - query + - ticket_id + - search_id + KnowledgeQuickAnswersResponse: + type: object + properties: + answer: + type: string + description: The AI-generated answer for the query. May be null if no answer was generated. + nullable: true + answer_found: + type: boolean + description: Indicates whether an answer was successfully generated. + citations: + type: array + description: List of source contents cited in the generated answer. + items: + type: object + properties: + id: + type: string + description: Unique identifier for the cited content. + locale: + type: string + description: Locale of the cited content (e.g., "en-us"). + title: + type: string + description: Title of the cited content. + type: + type: string + description: Type of the cited content. + enum: + - article + - community_post + - external_content_record + url: + type: string + description: URL to access the cited content. For articles and community posts, includes brand-specific subdomain. + nullable: true + id: + type: string + description: Unique identifier for the search request. + KnowledgeSuggestionsRequest: + type: object + properties: + filters: + type: object + description: Optional filters to narrow down search results. + properties: + article_category_ids: + type: array + description: Array of article category IDs to filter results. + items: + type: integer + article_section_ids: + type: array + description: Array of article section IDs to filter results. + items: + type: integer + brand_ids: + type: array + description: Array of brand IDs to filter results. + items: + type: integer + external_source_ids: + type: array + description: Array of external source IDs to filter results. + items: + type: string + external_type_ids: + type: array + description: Array of external type IDs to filter results. + items: + type: string + locales: + type: array + description: Array of locale codes to filter results (e.g., ["en-us", "de"]). + items: + type: string + record_types: + type: array + description: Array of record types to filter results. + items: + type: string + enum: + - article + - external_content + query: + type: string + description: The search query for finding relevant knowledge suggestions. + required: + - query + KnowledgeSuggestionsResponse: + type: object + properties: + id: + type: string + description: Unique identifier for the suggestions request. + records: + type: array + description: List of suggested knowledge records matching the query. Automatically deduplicated when multiple chunks from the same article are returned. + items: + type: object + properties: + id: + type: string + description: Unique identifier for the suggested record. + locale: + type: string + description: Locale of the record (e.g., "en-us"). + title: + type: string + description: Title of the suggested record. + type: + type: string + description: Type of the suggested record. + enum: + - article + - community_post + - external_content_record + url: + type: string + description: URL to access the record. For articles and community posts, includes brand-specific subdomain. May be null for external content records. + nullable: true LabelObject: type: object properties: