mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 10:19:51 -06:00
fix: openAPI spec for contact endpoints (#5247)
Co-authored-by: Victor Santos <victor@formbricks.com>
This commit is contained in:
@@ -27,7 +27,7 @@ const secondaryNavigation = [
|
||||
|
||||
export function Sidebar(): React.JSX.Element {
|
||||
return (
|
||||
<div className="flex grow flex-col overflow-y-auto bg-cyan-700 pb-4 pt-5">
|
||||
<div className="flex grow flex-col overflow-y-auto bg-cyan-700 pt-5 pb-4">
|
||||
<nav
|
||||
className="mt-5 flex flex-1 flex-col divide-y divide-cyan-800 overflow-y-auto"
|
||||
aria-label="Sidebar">
|
||||
@@ -38,7 +38,7 @@ export function Sidebar(): React.JSX.Element {
|
||||
href={item.href}
|
||||
className={classNames(
|
||||
item.current ? "bg-cyan-800 text-white" : "text-cyan-100 hover:bg-cyan-600 hover:text-white",
|
||||
"group flex items-center rounded-md px-2 py-2 text-sm font-medium leading-6"
|
||||
"group flex items-center rounded-md px-2 py-2 text-sm leading-6 font-medium"
|
||||
)}
|
||||
aria-current={item.current ? "page" : undefined}>
|
||||
<item.icon className="mr-4 h-6 w-6 shrink-0 text-cyan-200" aria-hidden="true" />
|
||||
@@ -52,7 +52,7 @@ export function Sidebar(): React.JSX.Element {
|
||||
<a
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
className="group flex items-center rounded-md px-2 py-2 text-sm font-medium leading-6 text-cyan-100 hover:bg-cyan-600 hover:text-white">
|
||||
className="group flex items-center rounded-md px-2 py-2 text-sm leading-6 font-medium text-cyan-100 hover:bg-cyan-600 hover:text-white">
|
||||
<item.icon className="mr-4 h-6 w-6 text-cyan-200" aria-hidden="true" />
|
||||
{item.name}
|
||||
</a>
|
||||
|
||||
@@ -96,10 +96,10 @@ export default function AppPage(): React.JSX.Element {
|
||||
<p className="text-slate-700 dark:text-slate-300">
|
||||
Copy the environment ID of your Formbricks app to the env variable in /apps/demo/.env
|
||||
</p>
|
||||
<Image src={fbsetup} alt="fb setup" className="rounded-xs mt-4" priority />
|
||||
<Image src={fbsetup} alt="fb setup" className="mt-4 rounded-xs" priority />
|
||||
|
||||
<div className="mt-4 flex-col items-start text-sm text-slate-700 sm:flex sm:items-center sm:text-base dark:text-slate-300">
|
||||
<p className="mb-1 sm:mb-0 sm:mr-2">You're connected with env:</p>
|
||||
<p className="mb-1 sm:mr-2 sm:mb-0">You're connected with env:</p>
|
||||
<div className="flex items-center">
|
||||
<strong className="w-32 truncate sm:w-auto">
|
||||
{process.env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID}
|
||||
|
||||
@@ -265,7 +265,7 @@ export const MainNavigation = ({
|
||||
size="icon"
|
||||
onClick={toggleSidebar}
|
||||
className={cn(
|
||||
"rounded-xl bg-slate-50 p-1 text-slate-600 transition-all hover:bg-slate-100 focus:outline-none focus:ring-0 focus:ring-transparent"
|
||||
"rounded-xl bg-slate-50 p-1 text-slate-600 transition-all hover:bg-slate-100 focus:ring-0 focus:ring-transparent focus:outline-none"
|
||||
)}>
|
||||
{isCollapsed ? (
|
||||
<PanelLeftOpenIcon strokeWidth={1.5} />
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { z } from "zod";
|
||||
import { extendZodWithOpenApi } from "zod-openapi";
|
||||
import { ZContactAttributeKey } from "@formbricks/database/zod/contact-attribute-keys";
|
||||
|
||||
extendZodWithOpenApi(z);
|
||||
|
||||
export const ZGetContactAttributeKeysFilter = z
|
||||
.object({
|
||||
limit: z.coerce.number().positive().min(1).max(100).optional().default(10),
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { z } from "zod";
|
||||
import { extendZodWithOpenApi } from "zod-openapi";
|
||||
import { ZContact } from "@formbricks/database/zod/contact";
|
||||
|
||||
extendZodWithOpenApi(z);
|
||||
|
||||
export const ZGetContactsFilter = z
|
||||
.object({
|
||||
limit: z.coerce.number().positive().min(1).max(100).optional().default(10),
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { ZContactLinkParams } from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/contacts/[contactId]/types/survey";
|
||||
import { makePartialSchema } from "@/modules/api/v2/types/openapi-response";
|
||||
import { z } from "zod";
|
||||
import { ZodOpenApiOperationObject } from "zod-openapi";
|
||||
|
||||
export const getPersonalizedSurveyLink: ZodOpenApiOperationObject = {
|
||||
operationId: "getPersonalizedSurveyLink",
|
||||
summary: "Get personalized survey link for a contact",
|
||||
description: "Retrieves a personalized link for a specific survey.",
|
||||
requestParams: {
|
||||
path: ZContactLinkParams,
|
||||
},
|
||||
tags: ["Management API > Surveys > Contact Links"],
|
||||
responses: {
|
||||
"200": {
|
||||
description: "Personalized survey link retrieved successfully.",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: makePartialSchema(
|
||||
z.object({
|
||||
data: z.object({
|
||||
surveyUrl: z.string().url(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -5,20 +5,14 @@ import { getEnvironmentId } from "@/modules/api/v2/management/lib/helper";
|
||||
import { getContact } from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/contacts/[contactId]/lib/contacts";
|
||||
import { getResponse } from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/contacts/[contactId]/lib/response";
|
||||
import { getSurvey } from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/contacts/[contactId]/lib/surveys";
|
||||
import {
|
||||
TContactLinkParams,
|
||||
ZContactLinkParams,
|
||||
} from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/contacts/[contactId]/types/survey";
|
||||
import { getContactSurveyLink } from "@/modules/ee/contacts/lib/contact-survey-link";
|
||||
import { hasPermission } from "@/modules/organization/settings/api-keys/lib/utils";
|
||||
import { z } from "zod";
|
||||
import { ZId } from "@formbricks/types/common";
|
||||
|
||||
const ZContactLinkParams = z.object({
|
||||
surveyId: ZId,
|
||||
contactId: ZId,
|
||||
});
|
||||
|
||||
export const GET = async (
|
||||
request: Request,
|
||||
props: { params: Promise<{ surveyId: string; contactId: string }> }
|
||||
) =>
|
||||
export const GET = async (request: Request, props: { params: Promise<TContactLinkParams> }) =>
|
||||
authenticatedApiClient({
|
||||
request,
|
||||
externalParams: props.params,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { z } from "zod";
|
||||
import { extendZodWithOpenApi } from "zod-openapi";
|
||||
|
||||
extendZodWithOpenApi(z);
|
||||
|
||||
export const ZContactLinkParams = z.object({
|
||||
surveyId: z
|
||||
.string()
|
||||
.cuid2()
|
||||
.openapi({
|
||||
description: "The ID of the survey",
|
||||
param: { name: "surveyId", in: "path" },
|
||||
}),
|
||||
contactId: z
|
||||
.string()
|
||||
.cuid2()
|
||||
.openapi({
|
||||
description: "The ID of the contact",
|
||||
param: { name: "contactId", in: "path" },
|
||||
}),
|
||||
});
|
||||
|
||||
export type TContactLinkParams = z.infer<typeof ZContactLinkParams>;
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
ZContactLinksBySegmentQuery,
|
||||
} from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/segments/[segmentId]/types/contact";
|
||||
import { makePartialSchema, responseWithMetaSchema } from "@/modules/api/v2/types/openapi-response";
|
||||
import { z } from "zod";
|
||||
import { ZodOpenApiOperationObject } from "zod-openapi";
|
||||
|
||||
export const getContactLinksBySegmentEndpoint: ZodOpenApiOperationObject = {
|
||||
@@ -21,7 +20,7 @@ export const getContactLinksBySegmentEndpoint: ZodOpenApiOperationObject = {
|
||||
description: "Contact links generated successfully.",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.array(responseWithMetaSchema(makePartialSchema(ZContactLinkResponse))),
|
||||
schema: responseWithMetaSchema(makePartialSchema(ZContactLinkResponse)),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
import { ZGetFilter } from "@/modules/api/v2/types/api-filter";
|
||||
import { z } from "zod";
|
||||
import { extendZodWithOpenApi } from "zod-openapi";
|
||||
|
||||
extendZodWithOpenApi(z);
|
||||
|
||||
export const ZContactLinksBySegmentParams = z.object({
|
||||
surveyId: z.string().cuid2().describe("The ID of the survey"),
|
||||
segmentId: z.string().cuid2().describe("The ID of the segment"),
|
||||
surveyId: z
|
||||
.string()
|
||||
.cuid2()
|
||||
.openapi({
|
||||
description: "The ID of the survey",
|
||||
param: { name: "surveyId", in: "path" },
|
||||
}),
|
||||
segmentId: z
|
||||
.string()
|
||||
.cuid2()
|
||||
.openapi({
|
||||
description: "The ID of the segment",
|
||||
param: { name: "segmentId", in: "path" },
|
||||
}),
|
||||
});
|
||||
|
||||
export const ZContactLinksBySegmentQuery = ZGetFilter.pick({
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// import {
|
||||
// deleteSurveyEndpoint,
|
||||
// getSurveyEndpoint,
|
||||
// updateSurveyEndpoint,
|
||||
// } from "@/modules/api/v2/management/surveys/[surveyId]/lib/openapi";
|
||||
import { managementServer } from "@/modules/api/v2/management/lib/openapi";
|
||||
import {
|
||||
deleteSurveyEndpoint,
|
||||
getSurveyEndpoint,
|
||||
updateSurveyEndpoint,
|
||||
} from "@/modules/api/v2/management/surveys/[surveyId]/lib/openapi";
|
||||
import { getPersonalizedSurveyLink } from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/contacts/[contactId]/lib/openapi";
|
||||
import { ZGetSurveysFilter, ZSurveyInput } from "@/modules/api/v2/management/surveys/types/surveys";
|
||||
import { z } from "zod";
|
||||
import { ZodOpenApiOperationObject, ZodOpenApiPathsObject } from "zod-openapi";
|
||||
@@ -56,15 +57,19 @@ export const createSurveyEndpoint: ZodOpenApiOperationObject = {
|
||||
};
|
||||
|
||||
export const surveyPaths: ZodOpenApiPathsObject = {
|
||||
"/surveys": {
|
||||
// "/surveys": {
|
||||
// servers: managementServer,
|
||||
// get: getSurveysEndpoint,
|
||||
// post: createSurveyEndpoint,
|
||||
// },
|
||||
// "/surveys/{id}": {
|
||||
// servers: managementServer,
|
||||
// get: getSurveyEndpoint,
|
||||
// put: updateSurveyEndpoint,
|
||||
// delete: deleteSurveyEndpoint,
|
||||
// },
|
||||
"/surveys/{surveyId}/contact-links/contacts/{contactId}/": {
|
||||
servers: managementServer,
|
||||
get: getSurveysEndpoint,
|
||||
post: createSurveyEndpoint,
|
||||
},
|
||||
"/surveys/{id}": {
|
||||
servers: managementServer,
|
||||
get: getSurveyEndpoint,
|
||||
put: updateSurveyEndpoint,
|
||||
delete: deleteSurveyEndpoint,
|
||||
get: getPersonalizedSurveyLink,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { z } from "zod";
|
||||
import { extendZodWithOpenApi } from "zod-openapi";
|
||||
import { ZSurveyWithoutQuestionType } from "@formbricks/database/zod/surveys";
|
||||
|
||||
extendZodWithOpenApi(z);
|
||||
|
||||
export const ZGetSurveysFilter = z
|
||||
.object({
|
||||
limit: z.coerce.number().positive().min(1).max(100).optional().default(10),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { contactAttributeKeyPaths } from "@/modules/api/v2/management/contact-attribute-keys/lib/openapi";
|
||||
import { contactAttributePaths } from "@/modules/api/v2/management/contact-attributes/lib/openapi";
|
||||
import { contactPaths } from "@/modules/api/v2/management/contacts/lib/openapi";
|
||||
// import { contactAttributeKeyPaths } from "@/modules/api/v2/management/contact-attribute-keys/lib/openapi";
|
||||
// import { contactAttributePaths } from "@/modules/api/v2/management/contact-attributes/lib/openapi";
|
||||
// import { contactPaths } from "@/modules/api/v2/management/contacts/lib/openapi";
|
||||
import { responsePaths } from "@/modules/api/v2/management/responses/lib/openapi";
|
||||
import { surveyContactLinksBySegmentPaths } from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/segments/lib/openapi";
|
||||
import { surveyPaths } from "@/modules/api/v2/management/surveys/lib/openapi";
|
||||
@@ -40,9 +40,9 @@ const document = createDocument({
|
||||
...mePaths,
|
||||
...responsePaths,
|
||||
...bulkContactPaths,
|
||||
...contactPaths,
|
||||
...contactAttributePaths,
|
||||
...contactAttributeKeyPaths,
|
||||
// ...contactPaths,
|
||||
// ...contactAttributePaths,
|
||||
// ...contactAttributeKeyPaths,
|
||||
...surveyPaths,
|
||||
...surveyContactLinksBySegmentPaths,
|
||||
...webhookPaths,
|
||||
@@ -52,7 +52,7 @@ const document = createDocument({
|
||||
},
|
||||
servers: [
|
||||
{
|
||||
url: `https://app.formbricks.com/api/v2/`,
|
||||
url: "https://app.formbricks.com/api/v2",
|
||||
description: "Formbricks Cloud",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -751,7 +751,7 @@ export const FollowUpModal = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-0 right-0 z-20 h-12 w-full bg-white p-2">
|
||||
<div className="absolute right-0 bottom-0 z-20 h-12 w-full bg-white p-2">
|
||||
<div className="flex justify-end space-x-2">
|
||||
<Button
|
||||
type="button"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -212,6 +212,7 @@
|
||||
"insights": "Einblicke",
|
||||
"integration": "Integration",
|
||||
"integrations": "Integrationen",
|
||||
"invalid_date": "Ungültiges Datum",
|
||||
"invalid_file_type": "Ungültiger Dateityp",
|
||||
"invite": "Einladen",
|
||||
"invite_them": "Lade sie ein",
|
||||
|
||||
@@ -212,6 +212,7 @@
|
||||
"insights": "Insights",
|
||||
"integration": "integration",
|
||||
"integrations": "Integrations",
|
||||
"invalid_date": "Invalid date",
|
||||
"invalid_file_type": "Invalid file type",
|
||||
"invite": "Invite",
|
||||
"invite_them": "Invite them",
|
||||
|
||||
@@ -212,6 +212,7 @@
|
||||
"insights": "Perspectives",
|
||||
"integration": "intégration",
|
||||
"integrations": "Intégrations",
|
||||
"invalid_date": "Date invalide",
|
||||
"invalid_file_type": "Type de fichier invalide",
|
||||
"invite": "Inviter",
|
||||
"invite_them": "Invitez-les",
|
||||
|
||||
@@ -212,6 +212,7 @@
|
||||
"insights": "Percepções",
|
||||
"integration": "integração",
|
||||
"integrations": "Integrações",
|
||||
"invalid_date": "Data inválida",
|
||||
"invalid_file_type": "Tipo de arquivo inválido",
|
||||
"invite": "convidar",
|
||||
"invite_them": "Convida eles",
|
||||
|
||||
@@ -212,6 +212,7 @@
|
||||
"insights": "Informações",
|
||||
"integration": "integração",
|
||||
"integrations": "Integrações",
|
||||
"invalid_date": "Data inválida",
|
||||
"invalid_file_type": "Tipo de ficheiro inválido",
|
||||
"invite": "Convidar",
|
||||
"invite_them": "Convide-os",
|
||||
|
||||
@@ -212,6 +212,7 @@
|
||||
"insights": "洞察",
|
||||
"integration": "整合",
|
||||
"integrations": "整合",
|
||||
"invalid_date": "無效日期",
|
||||
"invalid_file_type": "無效的檔案類型",
|
||||
"invite": "邀請",
|
||||
"invite_them": "邀請他們",
|
||||
|
||||
Reference in New Issue
Block a user