diff --git a/services/api/openapi.json b/services/api/openapi.json index 4b2f8761c..9cec9a480 100644 --- a/services/api/openapi.json +++ b/services/api/openapi.json @@ -1 +1 @@ -{"components":{"schemas":{"Actor":{"properties":{"role":{"$ref":"#/components/schemas/Role"},"type":{"enum":["USER","SYSTEM"],"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["role","type"],"type":"object"},"AddBoardMemberRequest":{"properties":{"endDate":{"format":"date","type":"string"},"role":{"minLength":1,"type":"string"},"startDate":{"format":"date","type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["role","startDate","userId"],"type":"object"},"AddressResponse":{"properties":{"city":{"type":"string"},"country":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"houseNumber":{"type":"string"},"id":{"format":"int64","type":"integer"},"street":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"},"zipCode":{"type":"string"}},"required":["createdAt","id","updatedAt","version"],"type":"object"},"AnswerRequest":{"properties":{"optionSelections":{"items":{"type":"boolean"},"type":"array"},"questionId":{"format":"int64","type":"integer"},"textResponse":{"type":"string"}},"required":["questionId"],"type":"object"},"AnswerResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"optionSelections":{"items":{"type":"boolean"},"type":"array"},"questionId":{"format":"int64","type":"integer"},"textResponse":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","questionId","updatedAt","version"],"type":"object"},"ApiError":{"description":"Problem Details for HTTP APIs including validation errors.","properties":{"detail":{"description":"Human-readable explanation specific to this occurrence.","example":"Validation failed for request.","type":"string"},"errors":{"description":"List of field/object validation errors (present when binding/validation fails).","items":{"$ref":"#/components/schemas/FieldValidationError"},"type":"array"},"instance":{"description":"A URI reference that identifies the specific occurrence.","example":"/api/v1/users","format":"uri","type":"string"},"status":{"description":"HTTP status code.","example":400,"format":"int32","type":"integer"},"title":{"description":"Short, human-readable summary of the problem.","example":"Bad Request","type":"string"},"traceId":{"description":"Trace or correlation id if available (Spring may add this via problem detail handlers).","example":"a8c0c4e5f1c24a7e","type":"string"},"type":{"description":"Problem type URI (RFC 7807).","example":"about:blank","type":"string"}}},"BlogResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"html":{"type":"string"},"id":{"format":"int64","type":"integer"},"publishedAt":{"format":"date-time","type":"string"},"title":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"url":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","html","id","publishedAt","title","updatedAt","url","version"],"type":"object"},"BoardCreateMembershipRequest":{"properties":{"endDate":{"format":"date","type":"string"},"incasso":{"type":"boolean"},"memberType":{"$ref":"#/components/schemas/MemberType"},"startDate":{"format":"date","type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["incasso","memberType","userId"],"type":"object"},"BoardMemberResponse":{"properties":{"boardId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"endDate":{"format":"date","type":"string"},"role":{"type":"string"},"startDate":{"format":"date","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["boardId","createdAt","role","startDate","updatedAt","userId","version"],"type":"object"},"BoardResponse":{"properties":{"candidate":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"endDate":{"format":"date","type":"string"},"id":{"format":"int64","type":"integer"},"members":{"items":{"$ref":"#/components/schemas/BoardMemberResponse"},"type":"array"},"name":{"type":"string"},"pictureId":{"format":"int64","type":"integer"},"startDate":{"format":"date","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["candidate","createdAt","id","members","name","startDate","updatedAt","version"],"type":"object"},"CohortDetail":{"properties":{"externalId":{"type":"string"},"folder":{"type":"string"},"id":{"format":"int64","type":"integer"},"kind":{"$ref":"#/components/schemas/CohortKind"},"label":{"type":"string"},"memberCount":{"format":"int32","type":"integer"},"members":{"items":{"$ref":"#/components/schemas/CohortMemberRow"},"type":"array"},"rules":{"items":{"$ref":"#/components/schemas/CohortRule"},"type":"array"},"system":{"type":"string"}},"required":["id","kind","label","memberCount","members","rules","system"],"type":"object"},"CohortFactKind":{"enum":["ROLE","COMMITTEE","CONTRIBUTION_PAID","MEMBER_IN_PERIOD","NEWSLETTER","ACTIVE_IN_PERIOD"],"type":"string"},"CohortKind":{"enum":["LIST","ROLE","GROUP"],"type":"string"},"CohortMapping":{"properties":{"cohortId":{"format":"int64","type":"integer"},"externalId":{"type":"string"},"kind":{"$ref":"#/components/schemas/CohortKind"},"label":{"type":"string"},"system":{"description":"External system this mapping targets","enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},"required":["cohortId","kind","label","system"],"type":"object"},"CohortMemberRow":{"properties":{"cohortMemberId":{"format":"int64","type":"integer"},"isUserDeleted":{"type":"boolean"},"joinedAt":{"format":"date-time","type":"string"},"userEmail":{"type":"string"},"userFullName":{"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["cohortMemberId","isUserDeleted","joinedAt","userId"],"type":"object"},"CohortRepair":{"properties":{"cohortId":{"format":"int64","type":"integer"},"enqueuedAdds":{"format":"int32","type":"integer"}},"required":["cohortId","enqueuedAdds"],"type":"object"},"CohortRule":{"properties":{"enabled":{"type":"boolean"},"factKey":{"type":"string"},"factKind":{"$ref":"#/components/schemas/CohortFactKind"},"id":{"format":"int64","type":"integer"}},"required":["enabled","factKey","factKind","id"],"type":"object"},"CohortSubjectCategory":{"enum":["COMMITTEES","PERIODS","MEMBERS","OTHER"],"type":"string"},"CohortSubjectDetail":{"properties":{"category":{"$ref":"#/components/schemas/CohortSubjectCategory"},"description":{"type":"string"},"id":{"format":"int64","type":"integer"},"label":{"type":"string"},"mappings":{"items":{"$ref":"#/components/schemas/CohortMapping"},"type":"array"},"members":{"items":{"$ref":"#/components/schemas/CohortSubjectMember"},"type":"array"},"rules":{"items":{"$ref":"#/components/schemas/CohortSubjectRule"},"type":"array"},"type":{"$ref":"#/components/schemas/CohortSubjectType"}},"required":["category","id","label","mappings","members","rules","type"],"type":"object"},"CohortSubjectMember":{"properties":{"cohortMemberId":{"format":"int64","type":"integer"},"isUserDeleted":{"type":"boolean"},"joinedAt":{"format":"date-time","type":"string"},"userEmail":{"type":"string"},"userFullName":{"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["cohortMemberId","isUserDeleted","joinedAt","userId"],"type":"object"},"CohortSubjectRule":{"properties":{"enabled":{"type":"boolean"},"factKey":{"type":"string"},"factKind":{"$ref":"#/components/schemas/CohortFactKind"},"id":{"format":"int64","type":"integer"}},"required":["enabled","factKey","factKind","id"],"type":"object"},"CohortSubjectSummary":{"properties":{"category":{"$ref":"#/components/schemas/CohortSubjectCategory"},"id":{"format":"int64","type":"integer"},"label":{"type":"string"},"mappingCount":{"format":"int32","type":"integer"},"memberCount":{"format":"int32","type":"integer"},"type":{"$ref":"#/components/schemas/CohortSubjectType"}},"required":["category","id","label","mappingCount","memberCount","type"],"type":"object"},"CohortSubjectType":{"enum":["COMMITTEE_MEMBERS","PERIOD_PAYERS","PERIOD_MEMBERS","PERIOD_ACTIVE_MEMBERS","NEWSLETTER_SUBSCRIBERS","CUSTOM"],"type":"string"},"CohortSummary":{"properties":{"externalId":{"type":"string"},"folder":{"type":"string"},"id":{"format":"int64","type":"integer"},"kind":{"$ref":"#/components/schemas/CohortKind"},"label":{"type":"string"},"memberCount":{"format":"int32","type":"integer"},"system":{"type":"string"}},"required":["id","kind","label","memberCount","system"],"type":"object"},"CommitteeDetailResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"description":{"maxLength":4095,"minLength":0,"type":"string"},"id":{"format":"int64","type":"integer"},"members":{"items":{"$ref":"#/components/schemas/CommitteeMemberResponse"},"minItems":1,"type":"array"},"name":{"maxLength":255,"minLength":0,"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","description","id","members","name","updatedAt","version"],"type":"object"},"CommitteeMemberRequest":{"properties":{"role":{"minLength":1,"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["role","userId"],"type":"object"},"CommitteeMemberResponse":{"properties":{"committeeId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"role":{"minLength":1,"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["committeeId","createdAt","role","updatedAt","userId","version"],"type":"object"},"CommitteeResponse":{},"ContributionPeriodResponse":{"properties":{"alumniFee":{"format":"double","type":"number"},"contactListId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"endDate":{"format":"date","type":"string"},"fullYearFee":{"format":"double","type":"number"},"halfYearFee":{"format":"double","type":"number"},"id":{"format":"int64","type":"integer"},"startDate":{"format":"date","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["alumniFee","createdAt","endDate","fullYearFee","halfYearFee","id","startDate","updatedAt","version"],"type":"object"},"ContributionReminderResponse":{"properties":{"contributionPeriodId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"remindedAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["contributionPeriodId","createdAt","updatedAt","userId","version"],"type":"object"},"ContributionResponse":{"properties":{"contributionPeriodId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"remindedAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["contributionPeriodId","createdAt","updatedAt","userId","version"],"type":"object"},"CreateAddressRequest":{"properties":{"city":{"minLength":1,"type":"string"},"country":{"minLength":1,"type":"string"},"houseNumber":{"minLength":1,"type":"string"},"street":{"minLength":1,"type":"string"},"userId":{"format":"int64","type":"integer"},"zipCode":{"minLength":1,"type":"string"}},"required":["city","country","houseNumber","street","userId","zipCode"],"type":"object"},"CreateBlogRequest":{"properties":{"html":{"minLength":1,"type":"string"},"publishedAt":{"format":"date-time","type":"string"},"title":{"minLength":1,"type":"string"}},"required":["html","publishedAt","title"],"type":"object"},"CreateBoardRequest":{"properties":{"candidate":{"minLength":1,"type":"string"},"endDate":{"format":"date","type":"string"},"name":{"maxLength":100,"minLength":1,"type":"string"},"pictureId":{"format":"int64","type":"integer"},"startDate":{"format":"date","type":"string"}},"required":["candidate","name","startDate"],"type":"object"},"CreateCommitteeRequest":{"properties":{"description":{"maxLength":4095,"minLength":0,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/CommitteeMemberRequest"},"minItems":1,"type":"array"},"name":{"maxLength":255,"minLength":0,"type":"string"}},"required":["description","members","name"],"type":"object"},"CreateContributionPeriodRequest":{"properties":{"alumniFee":{"format":"double","type":"number"},"contactListId":{"format":"int64","type":"integer"},"endDate":{"format":"date","type":"string"},"fullYearFee":{"format":"double","type":"number"},"halfYearFee":{"format":"double","type":"number"},"startDate":{"format":"date","type":"string"}},"required":["alumniFee","endDate","fullYearFee","halfYearFee","startDate"],"type":"object"},"CreateContributionReminderRequest":{"properties":{"contributionPeriodId":{"format":"int64","type":"integer"},"userId":{"format":"int64","type":"integer"}},"required":["contributionPeriodId","userId"],"type":"object"},"CreateContributionRequest":{"properties":{"contributionPeriodId":{"format":"int64","type":"integer"},"userId":{"format":"int64","type":"integer"}},"required":["contributionPeriodId","userId"],"type":"object"},"CreateEventRequest":{"properties":{"approved":{"type":"boolean"},"banner":{"$ref":"#/components/schemas/EventBannerRequest"},"committeeId":{"format":"int64","type":"integer"},"description":{"maxLength":4095,"minLength":0,"type":"string"},"endTime":{"format":"date-time","type":"string"},"location":{"type":"string"},"memberPrice":{"format":"double","type":"number"},"membersOnly":{"type":"boolean"},"publicPrice":{"format":"double","type":"number"},"signUp":{"type":"boolean"},"signUpDeadline":{"format":"date-time","type":"string"},"signUpForm":{"$ref":"#/components/schemas/SurveyRequest"},"signUpLimit":{"format":"int32","minimum":1,"type":"integer"},"startTime":{"format":"date-time","type":"string"},"title":{"maxLength":255,"minLength":0,"type":"string"}},"required":["approved","committeeId","description","endTime","membersOnly","signUp","startTime","title"],"type":"object"},"CreateEventSignUpRequest":{"properties":{"answers":{"items":{"$ref":"#/components/schemas/AnswerRequest"},"type":"array"},"guest":{"$ref":"#/components/schemas/CreateGuestRequest"},"userId":{"format":"int64","type":"integer"}},"type":"object"},"CreateGuestRequest":{"properties":{"discord":{"minLength":1,"type":"string"},"email":{"minLength":1,"type":"string"},"name":{"minLength":1,"type":"string"},"phoneNumber":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["discord","email","name"],"type":"object"},"CreateMemberProfileRequest":{"properties":{"bhv":{"type":"boolean"},"dateOfBirth":{"format":"date","type":"string"},"ehbo":{"type":"boolean"},"gender":{"type":"string"},"nationality":{"minLength":1,"type":"string"},"studentNumber":{"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["bhv","dateOfBirth","ehbo","nationality","userId"],"type":"object"},"CreateSponsorRequest":{"properties":{"description":{"maxLength":4095,"minLength":0,"type":"string"},"name":{"maxLength":255,"minLength":0,"type":"string"}},"required":["description","name"],"type":"object"},"CreateTargetRequest":{"properties":{"folderHint":{"type":"string"},"label":{"minLength":1,"type":"string"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},"required":["label","system"],"type":"object"},"CreateTelemetryRequest":{"properties":{"platform":{"$ref":"#/components/schemas/PlatformType"},"url":{"minLength":1,"type":"string"}},"required":["platform","url"],"type":"object"},"CreateUserRequest":{"properties":{"consentPrivacy":{"type":"boolean"},"discord":{"minLength":1,"type":"string"},"email":{"minLength":1,"type":"string"},"firstName":{"minLength":1,"type":"string"},"fullName":{"type":"string"},"initials":{"minLength":1,"type":"string"},"lastName":{"minLength":1,"type":"string"},"memberProfile":{"$ref":"#/components/schemas/UpsertMemberProfileRequest"},"newsletter":{"type":"boolean"},"password":{"type":"string"},"phoneNumber":{"minLength":1,"type":"string"},"photoConsent":{"type":"boolean"},"prefix":{"type":"string"},"username":{"minLength":1,"type":"string"}},"required":["discord","email","firstName","initials","lastName","newsletter","phoneNumber","username"],"type":"object"},"CsrfToken":{"properties":{"headerName":{"type":"string"},"parameterName":{"type":"string"},"token":{"type":"string"}},"type":"object"},"DriftReport":{"properties":{"cohortId":{"format":"int64","type":"integer"},"externalCohortId":{"type":"string"},"extras":{"items":{"$ref":"#/components/schemas/ExtraRow"},"type":"array"},"lastReconciledAt":{"format":"date-time","type":"string"},"missing":{"items":{"$ref":"#/components/schemas/MissingRow"},"type":"array"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},"required":["cohortId","extras","missing","system"],"type":"object"},"Email":{"properties":{"attempts":{"format":"int32","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"deliveredAt":{"format":"date-time","type":"string"},"deliveryStatus":{"enum":["PENDING","SENT","DELIVERED","OPENED","BOUNCED","FAILED"],"type":"string"},"emailType":{"type":"string"},"errorReason":{"type":"string"},"errorType":{"type":"string"},"id":{"format":"int64","type":"integer"},"jobExecutionId":{"format":"int64","type":"integer"},"messageId":{"type":"string"},"openedAt":{"format":"date-time","type":"string"},"recipientEmail":{"type":"string"},"recipientName":{"type":"string"},"sentAt":{"format":"date-time","type":"string"},"subject":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"type":"object"},"EmailStats":{"properties":{"bouncedCount":{"format":"int64","type":"integer"},"deliveredCount":{"format":"int64","type":"integer"},"failedCount":{"format":"int64","type":"integer"},"openedCount":{"format":"int64","type":"integer"},"pendingCount":{"format":"int64","type":"integer"},"sentCount":{"format":"int64","type":"integer"},"totalCount":{"format":"int64","type":"integer"}},"required":["bouncedCount","deliveredCount","failedCount","openedCount","pendingCount","sentCount","totalCount"],"type":"object"},"EnqueueJobRequest":{"properties":{"jobType":{"minLength":1,"type":"string"},"payload":{"additionalProperties":{},"description":"Job payload fields keyed by name; shape depends on the job type","type":"object"}},"required":["jobType"],"type":"object"},"EventBannerRequest":{"properties":{"fileId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["fileId"],"type":"object"},"EventBannerResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"eventId":{"format":"int64","type":"integer"},"fileId":{"format":"int64","type":"integer"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","eventId","fileId","updatedAt","version"],"type":"object"},"EventResponse":{"properties":{"approved":{"type":"boolean"},"banner":{"$ref":"#/components/schemas/EventBannerResponse"},"committeeId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"description":{"maxLength":4095,"minLength":0,"type":"string"},"endTime":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"location":{"type":"string"},"memberPrice":{"format":"double","type":"number"},"membersOnly":{"type":"boolean"},"publicPrice":{"format":"double","type":"number"},"signUp":{"type":"boolean"},"signUpCount":{"format":"int64","type":"integer"},"signUpDeadline":{"format":"date-time","type":"string"},"signUpForm":{"$ref":"#/components/schemas/SurveyResponse"},"signUpLimit":{"format":"int32","type":"integer"},"startTime":{"format":"date-time","type":"string"},"title":{"maxLength":255,"minLength":0,"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["approved","createdAt","description","endTime","id","membersOnly","signUp","signUpCount","startTime","title","updatedAt","version"],"type":"object"},"EventSignUpResponse":{"properties":{"answers":{"items":{"$ref":"#/components/schemas/AnswerResponse"},"type":"array"},"createdAt":{"format":"date-time","type":"string"},"eventId":{"format":"int64","type":"integer"},"guest":{"$ref":"#/components/schemas/GuestResponse"},"id":{"format":"int64","type":"integer"},"updatedAt":{"format":"date-time","type":"string"},"user":{"$ref":"#/components/schemas/UserSummaryResponse"},"version":{"format":"int64","type":"integer"}},"required":["answers","createdAt","eventId","id","updatedAt","version"],"type":"object"},"ExtraRow":{"properties":{"email":{"type":"string"},"externalUserId":{"type":"string"},"fullName":{"type":"string"},"kind":{"enum":["KNOWN_LOCAL_USER","UNKNOWN_EXTERNAL"],"type":"string"},"label":{"type":"string"},"softDeleted":{"type":"boolean"},"userId":{"format":"int64","type":"integer"}},"required":["externalUserId","kind"],"type":"object"},"FieldValidationError":{"description":"Details about a single field/object validation error.","properties":{"code":{"description":"Validation code / constraint key.","example":"Email","type":"string"},"field":{"description":"Field that failed validation (null for global errors).","example":"email","type":"string"},"message":{"description":"Human-readable validation message.","example":"must be a well-formed email address","type":"string"},"objectName":{"description":"Object (target) name that failed validation.","example":"createUserRequest","type":"string"}}},"FileResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"mediaType":{"type":"string"},"name":{"maxLength":255,"minLength":0,"type":"string"},"path":{"type":"string"},"size":{"format":"int64","type":"integer"},"type":{"$ref":"#/components/schemas/FileType"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","mediaType","name","path","type","updatedAt","version"],"type":"object"},"FileType":{"enum":["DOCUMENT","PROFILE_PICTURE","EVENT_BANNER","EVENT_PICTURE","SPONSOR_PICTURE"],"type":"string"},"GuestResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"discord":{"type":"string"},"email":{"type":"string"},"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"phoneNumber":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","discord","email","id","name","updatedAt","version"],"type":"object"},"JobExecution":{"properties":{"actor":{"$ref":"#/components/schemas/Actor"},"attempts":{"format":"int32","type":"integer"},"category":{"$ref":"#/components/schemas/JobExecutionCategory"},"createdAt":{"format":"date-time","type":"string"},"dedupKey":{"type":"string"},"errorMessage":{"type":"string"},"errorReason":{"type":"string"},"errorType":{"type":"string"},"finishedAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"initiatedByDisplay":{"type":"string"},"initiatedByFullName":{"type":"string"},"initiatedByRole":{"$ref":"#/components/schemas/Role"},"initiatedByType":{"enum":["USER","SYSTEM"],"type":"string"},"initiatedByUserId":{"format":"int64","type":"integer"},"initiatedByUsername":{"type":"string"},"jobType":{"minLength":1,"type":"string"},"nextAttemptAt":{"format":"date-time","type":"string"},"payload":{"additionalProperties":{},"type":"object"},"queuedAt":{"format":"date-time","type":"string"},"relatedEntities":{"items":{"$ref":"#/components/schemas/JobExecutionRelatedEntity"},"type":"array"},"stackTrace":{"type":"string"},"startedAt":{"format":"date-time","type":"string"},"status":{"$ref":"#/components/schemas/JobExecutionStatus"},"targetSystem":{"enum":["BREVO"],"type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["attempts","jobType","relatedEntities","status"],"type":"object"},"JobExecutionCategory":{"enum":["calendar","contact","cohort","email","other"],"type":"string"},"JobExecutionRelatedEntity":{"properties":{"id":{"format":"int64","type":"integer"},"label":{"type":"string"},"type":{"type":"string"}},"required":["label","type"],"type":"object"},"JobExecutionStatus":{"enum":["QUEUED","RUNNING","SUCCESS","FAILED","DEAD"],"type":"string"},"JobPayloadField":{"properties":{"enumValues":{"items":{"type":"string"},"type":"array"},"kind":{"$ref":"#/components/schemas/JobPayloadFieldKind"},"name":{"type":"string"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["kind","name","required","type"],"type":"object"},"JobPayloadFieldKind":{"enum":["PRIMITIVE","ENUM","OBJECT"],"type":"string"},"JobStatsDTO":{"properties":{"avgSuccessDurationSeconds":{"format":"double","type":"number"},"deadCount":{"format":"int64","type":"integer"},"deadSinceStartup":{"format":"double","type":"number"},"failedCount":{"format":"int64","type":"integer"},"failedSinceStartup":{"format":"double","type":"number"},"queuedCount":{"format":"int64","type":"integer"},"recoveriesSinceStartup":{"format":"double","type":"number"},"runningCount":{"format":"int64","type":"integer"},"successCount":{"format":"int64","type":"integer"},"totalCount":{"format":"int64","type":"integer"}},"required":["avgSuccessDurationSeconds","deadCount","deadSinceStartup","failedCount","failedSinceStartup","queuedCount","recoveriesSinceStartup","runningCount","successCount","totalCount"],"type":"object"},"JobTypeDescriptor":{"properties":{"payloadFields":{"items":{"$ref":"#/components/schemas/JobPayloadField"},"type":"array"},"type":{"type":"string"}},"required":["payloadFields","type"],"type":"object"},"JwtRequest":{"properties":{"password":{"minLength":1,"type":"string"},"username":{"minLength":1,"type":"string"}},"required":["password","username"],"type":"object"},"LinkExistingTargetRequest":{"properties":{"externalId":{"minLength":1,"type":"string"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},"required":["externalId","system"],"type":"object"},"LinkUserRequest":{"properties":{"externalUserId":{"minLength":1,"type":"string"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["externalUserId","system","userId"],"type":"object"},"LinkedUser":{"properties":{"externalUserId":{"type":"string"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["externalUserId","system","userId"],"type":"object"},"LoginResponse":{"properties":{"addressId":{"format":"int64","type":"integer"},"expiration":{"format":"int64","type":"integer"},"roles":{"items":{"$ref":"#/components/schemas/Role"},"minItems":1,"type":"array"},"token":{"minLength":1,"type":"string"},"userId":{"format":"int64","type":"integer"},"username":{"minLength":1,"type":"string"}},"required":["expiration","roles","token","userId","username"],"type":"object"},"MemberActivationRequest":{"properties":{"password":{"maxLength":100,"minLength":8,"pattern":"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]+$","type":"string"},"token":{"minLength":1,"type":"string"},"username":{"minLength":1,"type":"string"}},"required":["password","token","username"],"type":"object"},"MemberProfileResponse":{"properties":{"bhv":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"dateOfBirth":{"format":"date","type":"string"},"ehbo":{"type":"boolean"},"gender":{"type":"string"},"id":{"format":"int64","type":"integer"},"nationality":{"type":"string"},"studentNumber":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["bhv","createdAt","ehbo","id","updatedAt","userId","version"]},"MemberType":{"enum":["ALUMNI","HONORARY","REGULAR","NONE"],"type":"string"},"MembershipResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"endDate":{"format":"date","type":"string"},"id":{"format":"int64","type":"integer"},"incasso":{"type":"boolean"},"memberType":{"$ref":"#/components/schemas/MemberType"},"startDate":{"format":"date","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","incasso","memberType","startDate","updatedAt","userId","version"],"type":"object"},"MissingRow":{"properties":{"hasExternalMapping":{"type":"boolean"},"userId":{"format":"int64","type":"integer"}},"required":["hasExternalMapping","userId"],"type":"object"},"PageMetadata":{"properties":{"number":{"format":"int64","type":"integer"},"size":{"format":"int64","type":"integer"},"totalElements":{"format":"int64","type":"integer"},"totalPages":{"format":"int64","type":"integer"}},"type":"object"},"PagedModelEmail":{"properties":{"content":{"items":{"$ref":"#/components/schemas/Email"},"type":"array"},"page":{"$ref":"#/components/schemas/PageMetadata"}},"type":"object"},"PagedModelEventResponse":{"properties":{"content":{"items":{"$ref":"#/components/schemas/EventResponse"},"type":"array"},"page":{"$ref":"#/components/schemas/PageMetadata"}},"type":"object"},"PagedModelJobExecution":{"properties":{"content":{"items":{"$ref":"#/components/schemas/JobExecution"},"type":"array"},"page":{"$ref":"#/components/schemas/PageMetadata"}},"type":"object"},"PagedModelUserDetailResponse":{"properties":{"content":{"items":{"$ref":"#/components/schemas/UserDetailResponse"},"type":"array"},"page":{"$ref":"#/components/schemas/PageMetadata"}},"type":"object"},"PasswordResetRequest":{"properties":{"password":{"maxLength":100,"minLength":8,"pattern":"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]+$","type":"string"},"token":{"minLength":1,"type":"string"}},"required":["password","token"],"type":"object"},"PlatformType":{"enum":["FACEBOOK","LINKEDIN","TWITTER","INSTAGRAM"],"type":"string"},"QuestionRequest":{"properties":{"choiceLabels":{"items":{"type":"string"},"type":"array"},"idx":{"format":"int64","type":"integer"},"label":{"maxLength":2055,"minLength":0,"type":"string"},"required":{"type":"boolean"},"type":{"$ref":"#/components/schemas/QuestionType"}},"required":["idx","label","type"],"type":"object"},"QuestionResponse":{"properties":{"choiceLabels":{"items":{"type":"string"},"type":"array"},"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"idx":{"format":"int64","type":"integer"},"label":{"maxLength":2055,"minLength":0,"type":"string"},"required":{"type":"boolean"},"surveyId":{"format":"int64","type":"integer"},"type":{"$ref":"#/components/schemas/QuestionType"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","idx","label","surveyId","type","updatedAt","version"],"type":"object"},"QuestionType":{"enum":["OPEN","RADIO","CHECKBOX","DESCRIPTION"],"type":"string"},"RedirectResponse":{"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},"Role":{"enum":["ANONYMOUS","VEGAN","GUEST","COMPANY","MEMBER","COMMITTEE","BOARD","TREASURER","ADMIN","SYSTEM"],"type":"string"},"ServiceEntry":{"properties":{"description":{"type":"string"},"iconUrl":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"}},"required":["description","iconUrl","id","name","url"],"type":"object"},"SponsorResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","description","id","name","updatedAt","version"],"type":"object"},"SurveyRequest":{"properties":{"questions":{"items":{"$ref":"#/components/schemas/QuestionRequest"},"minItems":1,"type":"array"}},"required":["questions"],"type":"object"},"SurveyResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"questions":{"items":{"$ref":"#/components/schemas/QuestionResponse"},"minItems":1,"type":"array"},"responseCount":{"format":"int64","type":"integer"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","questions","responseCount","updatedAt","version"],"type":"object"},"SwitchTargetRequest":{"properties":{"deletePrevious":{"type":"boolean"},"externalId":{"minLength":1,"type":"string"},"reconcileNow":{"type":"boolean"}},"required":["deletePrevious","externalId","reconcileNow"],"type":"object"},"TelemetryResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"platform":{"$ref":"#/components/schemas/PlatformType"},"updatedAt":{"format":"date-time","type":"string"},"url":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","platform","updatedAt","url","version"],"type":"object"},"UpdateAddressRequest":{"properties":{"city":{"minLength":1,"type":"string"},"country":{"minLength":1,"type":"string"},"houseNumber":{"minLength":1,"type":"string"},"street":{"minLength":1,"type":"string"},"version":{"format":"int64","type":"integer"},"zipCode":{"minLength":1,"type":"string"}},"required":["city","country","houseNumber","street","version","zipCode"],"type":"object"},"UpdateBlogRequest":{"properties":{"html":{"minLength":1,"type":"string"},"publishedAt":{"format":"date-time","type":"string"},"title":{"minLength":1,"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["html","publishedAt","title","version"],"type":"object"},"UpdateBoardRequest":{"properties":{"candidate":{"minLength":1,"type":"string"},"endDate":{"format":"date","type":"string"},"name":{"maxLength":100,"minLength":1,"type":"string"},"pictureId":{"format":"int64","type":"integer"},"startDate":{"format":"date","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["candidate","name","startDate","version"],"type":"object"},"UpdateCommitteeRequest":{"properties":{"description":{"maxLength":4095,"minLength":0,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/CommitteeMemberRequest"},"minItems":1,"type":"array"},"name":{"maxLength":255,"minLength":0,"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["description","members","name","version"],"type":"object"},"UpdateContributionPeriodRequest":{"properties":{"alumniFee":{"format":"double","type":"number"},"contactListId":{"format":"int64","type":"integer"},"endDate":{"format":"date","type":"string"},"fullYearFee":{"format":"double","type":"number"},"halfYearFee":{"format":"double","type":"number"},"startDate":{"format":"date","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["alumniFee","endDate","fullYearFee","halfYearFee","startDate","version"],"type":"object"},"UpdateEventRequest":{"properties":{"approved":{"type":"boolean"},"banner":{"$ref":"#/components/schemas/EventBannerRequest"},"committeeId":{"format":"int64","type":"integer"},"description":{"maxLength":4095,"minLength":0,"type":"string"},"endTime":{"format":"date-time","type":"string"},"location":{"type":"string"},"memberPrice":{"format":"double","type":"number"},"membersOnly":{"type":"boolean"},"publicPrice":{"format":"double","type":"number"},"removeExistingSignUps":{"type":"boolean"},"signUp":{"type":"boolean"},"signUpDeadline":{"format":"date-time","type":"string"},"signUpForm":{"$ref":"#/components/schemas/SurveyRequest"},"signUpLimit":{"format":"int32","minimum":1,"type":"integer"},"startTime":{"format":"date-time","type":"string"},"title":{"maxLength":255,"minLength":0,"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["approved","committeeId","description","endTime","membersOnly","signUp","startTime","title","version"],"type":"object"},"UpdateEventSignUpRequest":{"properties":{"answers":{"items":{"$ref":"#/components/schemas/AnswerRequest"},"type":"array"},"guest":{"$ref":"#/components/schemas/CreateGuestRequest"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"type":"object"},"UpdateMemberProfileRequest":{"properties":{"bhv":{"type":"boolean"},"dateOfBirth":{"format":"date","type":"string"},"ehbo":{"type":"boolean"},"gender":{"type":"string"},"nationality":{"minLength":1,"type":"string"},"studentNumber":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["bhv","dateOfBirth","ehbo","nationality","version"],"type":"object"},"UpdateMembershipRequest":{"properties":{"endDate":{"format":"date","type":"string"},"incasso":{"type":"boolean"},"memberType":{"$ref":"#/components/schemas/MemberType"},"startDate":{"format":"date","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["userId","version"],"type":"object"},"UpdateSponsorRequest":{"properties":{"description":{"maxLength":4095,"minLength":0,"type":"string"},"name":{"maxLength":255,"minLength":0,"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["description","name","version"],"type":"object"},"UpdateUserRequest":{"properties":{"discord":{"minLength":1,"type":"string"},"memberProfile":{"$ref":"#/components/schemas/UpsertMemberProfileRequest"},"newsletter":{"type":"boolean"},"phoneNumber":{"minLength":1,"type":"string"},"photoConsent":{"type":"boolean"},"version":{"format":"int64","type":"integer"}},"required":["discord","newsletter","phoneNumber","version"],"type":"object"},"UpsertMemberProfileRequest":{"properties":{"bhv":{"type":"boolean"},"dateOfBirth":{"format":"date","type":"string"},"ehbo":{"type":"boolean"},"gender":{"type":"string"},"nationality":{"minLength":1,"type":"string"},"studentNumber":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["bhv","dateOfBirth","ehbo","nationality"],"type":"object"},"UserActivationRequest":{"properties":{"token":{"minLength":1,"type":"string"}},"required":["token"],"type":"object"},"UserDetailResponse":{"properties":{"addressId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"discord":{"type":"string"},"email":{"type":"string"},"enabled":{"type":"boolean"},"firstName":{"type":"string"},"fullName":{"type":"string"},"id":{"format":"int64","type":"integer"},"initials":{"type":"string"},"lastName":{"type":"string"},"newsletter":{"type":"boolean"},"phoneNumber":{"type":"string"},"photoConsent":{"type":"boolean"},"prefix":{"type":"string"},"restoreUntilAt":{"format":"date-time","type":"string"},"roles":{"items":{"$ref":"#/components/schemas/Role"},"type":"array"},"updatedAt":{"format":"date-time","type":"string"},"username":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","email","enabled","firstName","fullName","id","initials","lastName","newsletter","photoConsent","roles","updatedAt","username","version"],"type":"object"},"UserSummaryResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"discord":{"type":"string"},"email":{"type":"string"},"fullName":{"type":"string"},"id":{"format":"int64","type":"integer"},"phoneNumber":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","email","fullName","id","updatedAt","version"],"type":"object"}}},"info":{"title":"OpenAPI definition","version":"v0"},"openapi":"3.1.0","paths":{"/addresses":{"get":{"operationId":"findAllAddresses","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AddressResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]},"post":{"operationId":"createAddress","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAddressRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]}},"/addresses/{id}":{"delete":{"operationId":"deleteAddressById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]},"get":{"operationId":"findAddressById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]},"put":{"operationId":"updateAddress","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAddressRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]}},"/auth":{"post":{"operationId":"authenticate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Authentication"]}},"/auth/logout":{"post":{"operationId":"logout","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Authentication"]}},"/blogs":{"get":{"operationId":"findBlogs","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BlogResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]},"post":{"operationId":"createBlog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBlogRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]}},"/blogs/{id}":{"delete":{"operationId":"deleteById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]},"get":{"operationId":"findBlogById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]},"post":{"operationId":"updateBlog","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBlogRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]}},"/boards":{"get":{"operationId":"findAllBoards","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BoardResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]},"post":{"operationId":"createBoard","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBoardRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]}},"/boards/{boardId}/members":{"post":{"operationId":"addMember","parameters":[{"in":"path","name":"boardId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddBoardMemberRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardMemberResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]}},"/boards/{boardId}/members/{userId}":{"delete":{"operationId":"removeMember","parameters":[{"in":"path","name":"boardId","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]}},"/boards/{id}":{"delete":{"operationId":"deleteBoard","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]},"get":{"operationId":"findBoardById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]},"put":{"operationId":"updateBoard","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBoardRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]}},"/committeeMembers/committees":{"get":{"operationId":"findCommitteesByUserId","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CommitteeResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]}},"/committees":{"get":{"operationId":"findCommittees","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CommitteeResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]},"post":{"operationId":"createCommittee","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommitteeRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitteeDetailResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]}},"/committees/{committeeId}":{"get":{"operationId":"findCommitteeById","parameters":[{"in":"path","name":"committeeId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitteeResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]}},"/committees/{id}":{"delete":{"operationId":"deleteCommitteeById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]},"put":{"operationId":"updateCommittee","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommitteeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitteeDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]}},"/contributionPeriods":{"get":{"operationId":"findContributionPeriods","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionPeriodResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]},"post":{"operationId":"createContributionPeriod","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContributionPeriodRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionPeriodResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]}},"/contributionPeriods/current":{"get":{"operationId":"findCurrentContributionPeriod","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionPeriodResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]}},"/contributionPeriods/{contributionPeriodId}/users/{userId}/contributions":{"delete":{"operationId":"deleteContribution","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"path","name":"contributionPeriodId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Contributions"]}},"/contributionPeriods/{id}":{"delete":{"operationId":"deleteContributionPeriodById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]},"put":{"operationId":"updateContributionPeriod","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContributionPeriodRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionPeriodResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]}},"/contributionPeriods/{periodId}/contributions":{"get":{"operationId":"findContributionsByPeriodId","parameters":[{"in":"path","name":"periodId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Contributions"]}},"/contributionReminders":{"get":{"operationId":"findContributionReminders","parameters":[{"in":"query","name":"contributionPeriodId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionReminderResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionReminders"]},"post":{"operationId":"sendContributionReminder","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContributionReminderRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionReminderResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionReminders"]}},"/contributionReminders/batch":{"post":{"operationId":"sendContributionReminderBatch","requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CreateContributionReminderRequest"},"type":"array"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionReminderResponse"},"type":"array"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionReminders"]}},"/contributions":{"get":{"operationId":"findContributions","parameters":[{"in":"query","name":"contributionPeriodId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Contributions"]},"post":{"operationId":"createContribution","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContributionRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Contributions"]}},"/csrf":{"get":{"operationId":"csrf","parameters":[{"in":"query","name":"csrfToken","required":true,"schema":{"$ref":"#/components/schemas/CsrfToken"}}],"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Security"]}},"/events":{"get":{"operationId":"findEvents","parameters":[{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":20,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"items":{"type":"string"},"type":"array"}},{"in":"query","name":"from","required":false,"schema":{"format":"date-time","type":"string"}},{"in":"query","name":"to","required":false,"schema":{"format":"date-time","type":"string"}},{"in":"query","name":"approved","required":false,"schema":{"type":"boolean"}},{"in":"query","name":"committeeId","required":false,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"titleContains","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelEventResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]},"post":{"operationId":"createEvent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]}},"/events/banners":{"post":{"operationId":"uploadEventBanner","requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"format":"binary","type":"string"}},"required":["file"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Files"]}},"/events/signups":{"get":{"operationId":"findEventSignUps","parameters":[{"in":"query","name":"from","required":false,"schema":{"format":"date-time","type":"string"}},{"in":"query","name":"to","required":false,"schema":{"format":"date-time","type":"string"}},{"in":"query","name":"userId","required":false,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"committeeId","required":false,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"approved","required":false,"schema":{"type":"boolean"}},{"in":"query","name":"eventId","required":false,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/EventSignUpResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]}},"/events/signups/byAccessToken":{"get":{"operationId":"findEventSignUpsByAccessToken","parameters":[{"in":"header","name":"X-Guest-Access-Token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/EventSignUpResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]}},"/events/signups/{id}":{"delete":{"operationId":"deleteEventSignup","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"header","name":"X-Guest-Access-Token","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]}},"/events/{eventId}":{"delete":{"operationId":"deleteEventById","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]}},"/events/{eventId}/banners":{"get":{"operationId":"downloadEventBanner","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"format":"binary","type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Files"]}},"/events/{eventId}/signups":{"get":{"operationId":"findEventSignUpsByEventId","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/EventSignUpResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]},"post":{"operationId":"createEventSignup","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventSignUpRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSignUpResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]},"put":{"operationId":"updateEventSignUp","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"header","name":"X-Guest-Access-Token","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventSignUpRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSignUpResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]}},"/events/{id}":{"get":{"operationId":"findEventById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]},"put":{"operationId":"updateEvent","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]}},"/events/{id}/approve":{"put":{"operationId":"approveEvent","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"approved","required":true,"schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]}},"/health":{"get":{"operationId":"healthCheck","responses":{"200":{"content":{"application/json":{"schema":{"type":"boolean"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Health"]}},"/management/cohort-subjects":{"get":{"operationId":"findCohortSubjects","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CohortSubjectSummary"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}":{"get":{"operationId":"findCohortSubjectById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortSubjectDetail"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/drift":{"get":{"operationId":"getDrift","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"system","required":true,"schema":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriftReport"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/drift/link-user":{"post":{"operationId":"linkUser","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkUserRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkedUser"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/targets/existing":{"post":{"operationId":"linkExistingTarget","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkExistingTargetRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortMapping"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/targets/new":{"post":{"operationId":"createTarget","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTargetRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortMapping"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/targets/{cohortId}":{"put":{"operationId":"switchTarget","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"path","name":"cohortId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchTargetRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortMapping"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohorts":{"get":{"operationId":"findCohorts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CohortSummary"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohorts"]}},"/management/cohorts/{id}":{"get":{"operationId":"findCohortById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortDetail"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohorts"]}},"/management/cohorts/{id}/repair-missing-adds":{"post":{"operationId":"repairMissingAdds","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortRepair"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohorts"]}},"/management/emails":{"get":{"operationId":"list_1","parameters":[{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":50,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"default":["createdAt,DESC"],"items":{"type":"string"},"type":"array"}},{"in":"query","name":"deliveryStatus","required":false,"schema":{"enum":["PENDING","SENT","DELIVERED","OPENED","BOUNCED","FAILED"],"type":"string"}},{"in":"query","name":"emailType","required":false,"schema":{"type":"string"}},{"in":"query","name":"search","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelEmail"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Email Management"]}},"/management/emails/stats":{"get":{"operationId":"getStats_1","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailStats"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Email Management"]}},"/management/emails/{id}/retry":{"post":{"operationId":"retry_1","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Email"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Email Management"]}},"/management/jobs":{"get":{"operationId":"list","parameters":[{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":50,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"default":["updatedAt,DESC"],"items":{"type":"string"},"type":"array"}},{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/JobExecutionStatus"}},{"in":"query","name":"category","required":false,"schema":{"$ref":"#/components/schemas/JobExecutionCategory"}},{"in":"query","name":"search","required":false,"schema":{"type":"string"}},{"in":"query","name":"initiatedByType","required":false,"schema":{"enum":["USER","SYSTEM"],"type":"string"}},{"in":"query","name":"jobType","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelJobExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/management/jobs/enqueue":{"post":{"operationId":"enqueue","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnqueueJobRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/management/jobs/stats":{"get":{"operationId":"getStats","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatsDTO"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/management/jobs/types":{"get":{"operationId":"jobTypes","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/JobTypeDescriptor"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/management/jobs/{id}/retry":{"post":{"operationId":"retry","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/me/services":{"get":{"operationId":"myServices","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ServiceEntry"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["My Services"]}},"/memberProfiles":{"post":{"operationId":"createMemberProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMemberProfileRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberProfileResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Member Profiles"]}},"/memberships":{"get":{"operationId":"findMemberships","parameters":[{"in":"query","name":"from","required":false,"schema":{"format":"date","type":"string"}},{"in":"query","name":"to","required":false,"schema":{"format":"date","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/MembershipResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]},"post":{"operationId":"createMembership","responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]}},"/memberships/{id}":{"get":{"operationId":"findMembershipById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]},"put":{"operationId":"updateMembership","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMembershipRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]}},"/oauth2/forward-auth":{"get":{"operationId":"forwardAuth","responses":{"200":{"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Forward Auth"]}},"/recovery/member/activate":{"post":{"operationId":"memberActivate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberActivationRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/password":{"post":{"operationId":"setPassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/password/reset/{username}":{"post":{"operationId":"resetPassword","parameters":[{"in":"path","name":"username","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/user/activate":{"post":{"operationId":"userActivate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserActivationRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/user/activate/resend/{username}":{"post":{"operationId":"resendUserActivation","parameters":[{"in":"path","name":"username","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/users/{userId}/resend/recovery":{"post":{"operationId":"resendMemberActivationEmail","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/sponsors":{"get":{"operationId":"findSponsors","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SponsorResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]},"post":{"operationId":"createSponsor","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSponsorRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SponsorResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]}},"/sponsors/{id}":{"delete":{"operationId":"deleteSponsorById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]},"get":{"operationId":"findSponsorById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SponsorResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]},"put":{"operationId":"updateSponsor","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSponsorRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SponsorResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]}},"/telemetry":{"post":{"operationId":"createTelemetry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTelemetryRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelemetryResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Telemetries"]}},"/telemetry/{id}":{"get":{"operationId":"findTelemetryById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelemetryResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Telemetries"]}},"/users":{"get":{"operationId":"findUsers","parameters":[{"in":"query","name":"username","required":false,"schema":{"type":"string"}},{"in":"query","name":"enabled","required":false,"schema":{"type":"boolean"}},{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":20,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"items":{"type":"string"},"type":"array"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelUserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]},"post":{"operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDetailResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/deleted":{"get":{"operationId":"findDeletedUsers","parameters":[{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":20,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"items":{"type":"string"},"type":"array"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelUserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/{id}":{"put":{"operationId":"updateUser","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/{userId}":{"delete":{"operationId":"deleteUserById","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]},"get":{"operationId":"findUserById","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/{userId}/memberProfiles":{"get":{"operationId":"findMemberProfileByUserId","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberProfileResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Member Profiles"]},"put":{"operationId":"updateMemberProfile","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMemberProfileRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberProfileResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Member Profiles"]}},"/users/{userId}/memberships":{"post":{"operationId":"boardCreateMembership","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardCreateMembershipRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]}},"/users/{userId}/restore":{"put":{"operationId":"restoreDeletedUserById","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/{userId}/roles":{"put":{"operationId":"toggleUserRole","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"role","required":true,"schema":{"$ref":"#/components/schemas/Role"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}}},"servers":[{"description":"Generated server url","url":"http://localhost:8080"}],"tags":[{"description":"Admin cohort listings + detail","name":"Cohorts"},{"description":"API for managing outbound emails","name":"Email Management"},{"description":"Admin: logical subjects + their per-system mappings","name":"Cohort Subjects"},{"description":"API for managing job executions","name":"Job Management"}]} +{"components":{"schemas":{"Actor":{"properties":{"role":{"$ref":"#/components/schemas/Role"},"type":{"enum":["USER","SYSTEM"],"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["role","type"],"type":"object"},"AddBoardMemberRequest":{"properties":{"endDate":{"format":"date","type":"string"},"role":{"minLength":1,"type":"string"},"startDate":{"format":"date","type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["role","startDate","userId"],"type":"object"},"AddressResponse":{"properties":{"city":{"type":"string"},"country":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"houseNumber":{"type":"string"},"id":{"format":"int64","type":"integer"},"street":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"},"zipCode":{"type":"string"}},"required":["createdAt","id","updatedAt","version"],"type":"object"},"AnswerRequest":{"properties":{"optionSelections":{"items":{"type":"boolean"},"type":"array"},"questionId":{"format":"int64","type":"integer"},"textResponse":{"type":"string"}},"required":["questionId"],"type":"object"},"AnswerResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"optionSelections":{"items":{"type":"boolean"},"type":"array"},"questionId":{"format":"int64","type":"integer"},"textResponse":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","questionId","updatedAt","version"],"type":"object"},"ApiError":{"description":"Problem Details for HTTP APIs including validation errors.","properties":{"detail":{"description":"Human-readable explanation specific to this occurrence.","example":"Validation failed for request.","type":"string"},"errors":{"description":"List of field/object validation errors (present when binding/validation fails).","items":{"$ref":"#/components/schemas/FieldValidationError"},"type":"array"},"instance":{"description":"A URI reference that identifies the specific occurrence.","example":"/api/v1/users","format":"uri","type":"string"},"status":{"description":"HTTP status code.","example":400,"format":"int32","type":"integer"},"title":{"description":"Short, human-readable summary of the problem.","example":"Bad Request","type":"string"},"traceId":{"description":"Trace or correlation id if available (Spring may add this via problem detail handlers).","example":"a8c0c4e5f1c24a7e","type":"string"},"type":{"description":"Problem type URI (RFC 7807).","example":"about:blank","type":"string"}}},"BlogResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"html":{"type":"string"},"id":{"format":"int64","type":"integer"},"publishedAt":{"format":"date-time","type":"string"},"title":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"url":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","html","id","publishedAt","title","updatedAt","url","version"],"type":"object"},"BoardCreateMembershipRequest":{"properties":{"endDate":{"format":"date","type":"string"},"incasso":{"type":"boolean"},"memberType":{"$ref":"#/components/schemas/MemberType"},"startDate":{"format":"date","type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["incasso","memberType","userId"],"type":"object"},"BoardMemberResponse":{"properties":{"boardId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"endDate":{"format":"date","type":"string"},"role":{"type":"string"},"startDate":{"format":"date","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["boardId","createdAt","role","startDate","updatedAt","userId","version"],"type":"object"},"BoardResponse":{"properties":{"candidate":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"endDate":{"format":"date","type":"string"},"id":{"format":"int64","type":"integer"},"members":{"items":{"$ref":"#/components/schemas/BoardMemberResponse"},"type":"array"},"name":{"type":"string"},"pictureId":{"format":"int64","type":"integer"},"startDate":{"format":"date","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["candidate","createdAt","id","members","name","startDate","updatedAt","version"],"type":"object"},"CohortDetail":{"properties":{"externalId":{"type":"string"},"folder":{"type":"string"},"id":{"format":"int64","type":"integer"},"kind":{"$ref":"#/components/schemas/CohortKind"},"label":{"type":"string"},"memberCount":{"format":"int32","type":"integer"},"members":{"items":{"$ref":"#/components/schemas/CohortMemberRow"},"type":"array"},"rules":{"items":{"$ref":"#/components/schemas/CohortRule"},"type":"array"},"system":{"type":"string"}},"required":["id","kind","label","memberCount","members","rules","system"],"type":"object"},"CohortFactKind":{"enum":["ROLE","COMMITTEE","CONTRIBUTION_PAID","MEMBER_IN_PERIOD","NEWSLETTER","ACTIVE_IN_PERIOD"],"type":"string"},"CohortKind":{"enum":["LIST","ROLE","GROUP"],"type":"string"},"CohortMapping":{"properties":{"cohortId":{"format":"int64","type":"integer"},"externalId":{"type":"string"},"kind":{"$ref":"#/components/schemas/CohortKind"},"label":{"type":"string"},"system":{"description":"External system this mapping targets","enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},"required":["cohortId","kind","label","system"],"type":"object"},"CohortMemberRow":{"properties":{"cohortMemberId":{"format":"int64","type":"integer"},"isUserDeleted":{"type":"boolean"},"joinedAt":{"format":"date-time","type":"string"},"userEmail":{"type":"string"},"userFullName":{"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["cohortMemberId","isUserDeleted","joinedAt","userId"],"type":"object"},"CohortRepair":{"properties":{"cohortId":{"format":"int64","type":"integer"},"enqueuedAdds":{"format":"int32","type":"integer"}},"required":["cohortId","enqueuedAdds"],"type":"object"},"CohortRule":{"properties":{"enabled":{"type":"boolean"},"factKey":{"type":"string"},"factKind":{"$ref":"#/components/schemas/CohortFactKind"},"id":{"format":"int64","type":"integer"}},"required":["enabled","factKey","factKind","id"],"type":"object"},"CohortSubjectCategory":{"enum":["COMMITTEES","PERIODS","MEMBERS","OTHER"],"type":"string"},"CohortSubjectDetail":{"properties":{"category":{"$ref":"#/components/schemas/CohortSubjectCategory"},"description":{"type":"string"},"id":{"format":"int64","type":"integer"},"label":{"type":"string"},"mappings":{"items":{"$ref":"#/components/schemas/CohortMapping"},"type":"array"},"members":{"items":{"$ref":"#/components/schemas/CohortSubjectMember"},"type":"array"},"rules":{"items":{"$ref":"#/components/schemas/CohortSubjectRule"},"type":"array"},"type":{"$ref":"#/components/schemas/CohortSubjectType"}},"required":["category","id","label","mappings","members","rules","type"],"type":"object"},"CohortSubjectMember":{"properties":{"cohortMemberId":{"format":"int64","type":"integer"},"isUserDeleted":{"type":"boolean"},"joinedAt":{"format":"date-time","type":"string"},"userEmail":{"type":"string"},"userFullName":{"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["cohortMemberId","isUserDeleted","joinedAt","userId"],"type":"object"},"CohortSubjectRule":{"properties":{"enabled":{"type":"boolean"},"factKey":{"type":"string"},"factKind":{"$ref":"#/components/schemas/CohortFactKind"},"id":{"format":"int64","type":"integer"}},"required":["enabled","factKey","factKind","id"],"type":"object"},"CohortSubjectSummary":{"properties":{"category":{"$ref":"#/components/schemas/CohortSubjectCategory"},"id":{"format":"int64","type":"integer"},"label":{"type":"string"},"mappingCount":{"format":"int32","type":"integer"},"memberCount":{"format":"int32","type":"integer"},"type":{"$ref":"#/components/schemas/CohortSubjectType"}},"required":["category","id","label","mappingCount","memberCount","type"],"type":"object"},"CohortSubjectType":{"enum":["COMMITTEE_MEMBERS","PERIOD_PAYERS","PERIOD_MEMBERS","PERIOD_ACTIVE_MEMBERS","NEWSLETTER_SUBSCRIBERS","CUSTOM"],"type":"string"},"CohortSummary":{"properties":{"externalId":{"type":"string"},"folder":{"type":"string"},"id":{"format":"int64","type":"integer"},"kind":{"$ref":"#/components/schemas/CohortKind"},"label":{"type":"string"},"memberCount":{"format":"int32","type":"integer"},"system":{"type":"string"}},"required":["id","kind","label","memberCount","system"],"type":"object"},"CommitteeDetailResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"description":{"maxLength":4095,"minLength":0,"type":"string"},"id":{"format":"int64","type":"integer"},"members":{"items":{"$ref":"#/components/schemas/CommitteeMemberResponse"},"minItems":1,"type":"array"},"name":{"maxLength":255,"minLength":0,"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","description","id","members","name","updatedAt","version"],"type":"object"},"CommitteeMemberRequest":{"properties":{"role":{"minLength":1,"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["role","userId"],"type":"object"},"CommitteeMemberResponse":{"properties":{"committeeId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"role":{"minLength":1,"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["committeeId","createdAt","role","updatedAt","userId","version"],"type":"object"},"CommitteeResponse":{},"ContributionPeriodResponse":{"properties":{"alumniFee":{"format":"double","type":"number"},"contactListId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"endDate":{"format":"date","type":"string"},"fullYearFee":{"format":"double","type":"number"},"halfYearFee":{"format":"double","type":"number"},"id":{"format":"int64","type":"integer"},"startDate":{"format":"date","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["alumniFee","createdAt","endDate","fullYearFee","halfYearFee","id","startDate","updatedAt","version"],"type":"object"},"ContributionReminderResponse":{"properties":{"contributionPeriodId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"remindedAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["contributionPeriodId","createdAt","updatedAt","userId","version"],"type":"object"},"ContributionResponse":{"properties":{"contributionPeriodId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"remindedAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["contributionPeriodId","createdAt","updatedAt","userId","version"],"type":"object"},"CreateAddressRequest":{"properties":{"city":{"minLength":1,"type":"string"},"country":{"minLength":1,"type":"string"},"houseNumber":{"minLength":1,"type":"string"},"street":{"minLength":1,"type":"string"},"userId":{"format":"int64","type":"integer"},"zipCode":{"minLength":1,"type":"string"}},"required":["city","country","houseNumber","street","userId","zipCode"],"type":"object"},"CreateBlogRequest":{"properties":{"html":{"minLength":1,"type":"string"},"publishedAt":{"format":"date-time","type":"string"},"title":{"minLength":1,"type":"string"}},"required":["html","publishedAt","title"],"type":"object"},"CreateBoardRequest":{"properties":{"candidate":{"minLength":1,"type":"string"},"endDate":{"format":"date","type":"string"},"name":{"maxLength":100,"minLength":1,"type":"string"},"pictureId":{"format":"int64","type":"integer"},"startDate":{"format":"date","type":"string"}},"required":["candidate","name","startDate"],"type":"object"},"CreateCommitteeRequest":{"properties":{"description":{"maxLength":4095,"minLength":0,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/CommitteeMemberRequest"},"minItems":1,"type":"array"},"name":{"maxLength":255,"minLength":0,"type":"string"}},"required":["description","members","name"],"type":"object"},"CreateContributionPeriodRequest":{"properties":{"alumniFee":{"format":"double","type":"number"},"contactListId":{"format":"int64","type":"integer"},"endDate":{"format":"date","type":"string"},"fullYearFee":{"format":"double","type":"number"},"halfYearFee":{"format":"double","type":"number"},"startDate":{"format":"date","type":"string"}},"required":["alumniFee","endDate","fullYearFee","halfYearFee","startDate"],"type":"object"},"CreateContributionReminderRequest":{"properties":{"contributionPeriodId":{"format":"int64","type":"integer"},"userId":{"format":"int64","type":"integer"}},"required":["contributionPeriodId","userId"],"type":"object"},"CreateContributionRequest":{"properties":{"contributionPeriodId":{"format":"int64","type":"integer"},"userId":{"format":"int64","type":"integer"}},"required":["contributionPeriodId","userId"],"type":"object"},"CreateEventRequest":{"properties":{"approved":{"type":"boolean"},"banner":{"$ref":"#/components/schemas/EventBannerRequest"},"committeeId":{"format":"int64","type":"integer"},"description":{"maxLength":4095,"minLength":0,"type":"string"},"endTime":{"format":"date-time","type":"string"},"location":{"type":"string"},"memberPrice":{"format":"double","type":"number"},"membersOnly":{"type":"boolean"},"publicPrice":{"format":"double","type":"number"},"signUp":{"type":"boolean"},"signUpDeadline":{"format":"date-time","type":"string"},"signUpForm":{"$ref":"#/components/schemas/SurveyRequest"},"signUpLimit":{"format":"int32","minimum":1,"type":"integer"},"startTime":{"format":"date-time","type":"string"},"title":{"maxLength":255,"minLength":0,"type":"string"}},"required":["approved","committeeId","description","endTime","membersOnly","signUp","startTime","title"],"type":"object"},"CreateEventSignUpRequest":{"properties":{"answers":{"items":{"$ref":"#/components/schemas/AnswerRequest"},"type":"array"},"guest":{"$ref":"#/components/schemas/CreateGuestRequest"},"userId":{"format":"int64","type":"integer"}},"type":"object"},"CreateGuestRequest":{"properties":{"discord":{"minLength":1,"type":"string"},"email":{"minLength":1,"type":"string"},"name":{"minLength":1,"type":"string"},"phoneNumber":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["discord","email","name"],"type":"object"},"CreateMemberProfileRequest":{"properties":{"bhv":{"type":"boolean"},"dateOfBirth":{"format":"date","type":"string"},"ehbo":{"type":"boolean"},"gender":{"type":"string"},"nationality":{"minLength":1,"type":"string"},"studentNumber":{"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["bhv","dateOfBirth","ehbo","nationality","userId"],"type":"object"},"CreateSponsorRequest":{"properties":{"description":{"maxLength":4095,"minLength":0,"type":"string"},"name":{"maxLength":255,"minLength":0,"type":"string"}},"required":["description","name"],"type":"object"},"CreateTargetRequest":{"properties":{"folderHint":{"type":"string"},"label":{"minLength":1,"type":"string"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},"required":["label","system"],"type":"object"},"CreateTelemetryRequest":{"properties":{"platform":{"$ref":"#/components/schemas/PlatformType"},"url":{"minLength":1,"type":"string"}},"required":["platform","url"],"type":"object"},"CreateUserRequest":{"properties":{"consentPrivacy":{"type":"boolean"},"discord":{"minLength":1,"type":"string"},"email":{"minLength":1,"type":"string"},"firstName":{"minLength":1,"type":"string"},"fullName":{"type":"string"},"initials":{"minLength":1,"type":"string"},"lastName":{"minLength":1,"type":"string"},"memberProfile":{"$ref":"#/components/schemas/UpsertMemberProfileRequest"},"newsletter":{"type":"boolean"},"password":{"type":"string"},"phoneNumber":{"minLength":1,"type":"string"},"photoConsent":{"type":"boolean"},"prefix":{"type":"string"},"username":{"minLength":1,"type":"string"}},"required":["discord","email","firstName","initials","lastName","newsletter","phoneNumber","username"],"type":"object"},"CsrfToken":{"properties":{"headerName":{"type":"string"},"parameterName":{"type":"string"},"token":{"type":"string"}},"type":"object"},"DriftReport":{"properties":{"cohortId":{"format":"int64","type":"integer"},"externalCohortId":{"type":"string"},"extras":{"items":{"$ref":"#/components/schemas/ExtraRow"},"type":"array"},"lastReconciledAt":{"format":"date-time","type":"string"},"missing":{"items":{"$ref":"#/components/schemas/MissingRow"},"type":"array"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},"required":["cohortId","extras","missing","system"],"type":"object"},"Email":{"properties":{"attempts":{"format":"int32","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"deliveredAt":{"format":"date-time","type":"string"},"deliveryStatus":{"enum":["PENDING","SENT","DELIVERED","OPENED","BOUNCED","FAILED"],"type":"string"},"emailType":{"type":"string"},"errorReason":{"type":"string"},"errorType":{"type":"string"},"id":{"format":"int64","type":"integer"},"jobExecutionId":{"format":"int64","type":"integer"},"messageId":{"type":"string"},"openedAt":{"format":"date-time","type":"string"},"recipientEmail":{"type":"string"},"recipientName":{"type":"string"},"sentAt":{"format":"date-time","type":"string"},"subject":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"type":"object"},"EmailStats":{"properties":{"bouncedCount":{"format":"int64","type":"integer"},"deliveredCount":{"format":"int64","type":"integer"},"failedCount":{"format":"int64","type":"integer"},"openedCount":{"format":"int64","type":"integer"},"pendingCount":{"format":"int64","type":"integer"},"sentCount":{"format":"int64","type":"integer"},"totalCount":{"format":"int64","type":"integer"}},"required":["bouncedCount","deliveredCount","failedCount","openedCount","pendingCount","sentCount","totalCount"],"type":"object"},"EnqueueJobRequest":{"properties":{"jobType":{"minLength":1,"type":"string"},"payload":{"additionalProperties":{},"description":"Job payload fields keyed by name; shape depends on the job type","type":"object"}},"required":["jobType"],"type":"object"},"EventBannerRequest":{"properties":{"fileId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["fileId"],"type":"object"},"EventBannerResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"eventId":{"format":"int64","type":"integer"},"fileId":{"format":"int64","type":"integer"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","eventId","fileId","updatedAt","version"],"type":"object"},"EventResponse":{"properties":{"approved":{"type":"boolean"},"banner":{"$ref":"#/components/schemas/EventBannerResponse"},"committeeId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"description":{"maxLength":4095,"minLength":0,"type":"string"},"endTime":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"location":{"type":"string"},"memberPrice":{"format":"double","type":"number"},"membersOnly":{"type":"boolean"},"publicPrice":{"format":"double","type":"number"},"signUp":{"type":"boolean"},"signUpCount":{"format":"int64","type":"integer"},"signUpDeadline":{"format":"date-time","type":"string"},"signUpForm":{"$ref":"#/components/schemas/SurveyResponse"},"signUpLimit":{"format":"int32","type":"integer"},"startTime":{"format":"date-time","type":"string"},"title":{"maxLength":255,"minLength":0,"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["approved","createdAt","description","endTime","id","membersOnly","signUp","signUpCount","startTime","title","updatedAt","version"],"type":"object"},"EventSignUpResponse":{"properties":{"answers":{"items":{"$ref":"#/components/schemas/AnswerResponse"},"type":"array"},"createdAt":{"format":"date-time","type":"string"},"eventId":{"format":"int64","type":"integer"},"guest":{"$ref":"#/components/schemas/GuestResponse"},"id":{"format":"int64","type":"integer"},"updatedAt":{"format":"date-time","type":"string"},"user":{"$ref":"#/components/schemas/UserSummaryResponse"},"version":{"format":"int64","type":"integer"}},"required":["answers","createdAt","eventId","id","updatedAt","version"],"type":"object"},"ExternalTarget":{"properties":{"externalId":{"type":"string"},"folderLabel":{"type":"string"},"kind":{"$ref":"#/components/schemas/CohortKind"},"label":{"type":"string"},"linkedCohortId":{"format":"int64","type":"integer"},"memberCount":{"format":"int64","type":"integer"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},"required":["externalId","kind","label","system"],"type":"object"},"ExtraRow":{"properties":{"email":{"type":"string"},"externalUserId":{"type":"string"},"fullName":{"type":"string"},"kind":{"enum":["KNOWN_LOCAL_USER","UNKNOWN_EXTERNAL"],"type":"string"},"label":{"type":"string"},"softDeleted":{"type":"boolean"},"userId":{"format":"int64","type":"integer"}},"required":["externalUserId","kind"],"type":"object"},"FieldValidationError":{"description":"Details about a single field/object validation error.","properties":{"code":{"description":"Validation code / constraint key.","example":"Email","type":"string"},"field":{"description":"Field that failed validation (null for global errors).","example":"email","type":"string"},"message":{"description":"Human-readable validation message.","example":"must be a well-formed email address","type":"string"},"objectName":{"description":"Object (target) name that failed validation.","example":"createUserRequest","type":"string"}}},"FileResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"mediaType":{"type":"string"},"name":{"maxLength":255,"minLength":0,"type":"string"},"path":{"type":"string"},"size":{"format":"int64","type":"integer"},"type":{"$ref":"#/components/schemas/FileType"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","mediaType","name","path","type","updatedAt","version"],"type":"object"},"FileType":{"enum":["DOCUMENT","PROFILE_PICTURE","EVENT_BANNER","EVENT_PICTURE","SPONSOR_PICTURE"],"type":"string"},"GuestResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"discord":{"type":"string"},"email":{"type":"string"},"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"phoneNumber":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","discord","email","id","name","updatedAt","version"],"type":"object"},"InboundReconcileApplyRequest":{"properties":{"previewToken":{"type":"string"},"selectedExternalUserIds":{"items":{"type":"string"},"type":"array"}},"required":["previewToken","selectedExternalUserIds"],"type":"object"},"InboundReconcileApplyResponse":{"properties":{"acceptedCount":{"format":"int32","type":"integer"},"jobId":{"format":"int64","type":"integer"},"skippedCount":{"format":"int32","type":"integer"}},"required":["acceptedCount","skippedCount"],"type":"object"},"InboundReconcilePreview":{"properties":{"fact":{"$ref":"#/components/schemas/SubjectFact"},"matched":{"items":{"$ref":"#/components/schemas/InboundReconcileRow"},"type":"array"},"previewToken":{"type":"string"},"remoteCount":{"format":"int32","type":"integer"},"skipped":{"items":{"$ref":"#/components/schemas/InboundReconcileRow"},"type":"array"},"writerSupported":{"type":"boolean"}},"required":["fact","matched","previewToken","remoteCount","skipped","writerSupported"],"type":"object"},"InboundReconcileRow":{"properties":{"alreadyTrue":{"type":"boolean"},"externalLabel":{"type":"string"},"externalUserId":{"type":"string"},"reason":{"enum":["DUPLICATE_REMOTE_ID","MAPPING_CONFLICT","DUPLICATE_USER_MATCH","MAPPED_USER_INACTIVE","UNMATCHED"],"type":"string"},"userEmail":{"type":"string"},"userFullName":{"type":"string"},"userId":{"format":"int64","type":"integer"},"writable":{"type":"boolean"}},"required":["alreadyTrue","externalUserId","writable"],"type":"object"},"JobExecution":{"properties":{"actor":{"$ref":"#/components/schemas/Actor"},"attempts":{"format":"int32","type":"integer"},"category":{"$ref":"#/components/schemas/JobExecutionCategory"},"createdAt":{"format":"date-time","type":"string"},"dedupKey":{"type":"string"},"errorMessage":{"type":"string"},"errorReason":{"type":"string"},"errorType":{"type":"string"},"finishedAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"initiatedByDisplay":{"type":"string"},"initiatedByFullName":{"type":"string"},"initiatedByRole":{"$ref":"#/components/schemas/Role"},"initiatedByType":{"enum":["USER","SYSTEM"],"type":"string"},"initiatedByUserId":{"format":"int64","type":"integer"},"initiatedByUsername":{"type":"string"},"jobType":{"minLength":1,"type":"string"},"nextAttemptAt":{"format":"date-time","type":"string"},"payload":{"additionalProperties":{},"type":"object"},"queuedAt":{"format":"date-time","type":"string"},"relatedEntities":{"items":{"$ref":"#/components/schemas/JobExecutionRelatedEntity"},"type":"array"},"stackTrace":{"type":"string"},"startedAt":{"format":"date-time","type":"string"},"status":{"$ref":"#/components/schemas/JobExecutionStatus"},"targetSystem":{"enum":["BREVO"],"type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["attempts","jobType","relatedEntities","status"],"type":"object"},"JobExecutionCategory":{"enum":["calendar","contact","cohort","email","other"],"type":"string"},"JobExecutionRelatedEntity":{"properties":{"id":{"format":"int64","type":"integer"},"label":{"type":"string"},"type":{"type":"string"}},"required":["label","type"],"type":"object"},"JobExecutionStatus":{"enum":["QUEUED","RUNNING","SUCCESS","FAILED","DEAD"],"type":"string"},"JobPayloadField":{"properties":{"enumValues":{"items":{"type":"string"},"type":"array"},"kind":{"$ref":"#/components/schemas/JobPayloadFieldKind"},"name":{"type":"string"},"required":{"type":"boolean"},"type":{"type":"string"}},"required":["kind","name","required","type"],"type":"object"},"JobPayloadFieldKind":{"enum":["PRIMITIVE","ENUM","OBJECT"],"type":"string"},"JobStatsDTO":{"properties":{"avgSuccessDurationSeconds":{"format":"double","type":"number"},"deadCount":{"format":"int64","type":"integer"},"deadSinceStartup":{"format":"double","type":"number"},"failedCount":{"format":"int64","type":"integer"},"failedSinceStartup":{"format":"double","type":"number"},"queuedCount":{"format":"int64","type":"integer"},"recoveriesSinceStartup":{"format":"double","type":"number"},"runningCount":{"format":"int64","type":"integer"},"successCount":{"format":"int64","type":"integer"},"totalCount":{"format":"int64","type":"integer"}},"required":["avgSuccessDurationSeconds","deadCount","deadSinceStartup","failedCount","failedSinceStartup","queuedCount","recoveriesSinceStartup","runningCount","successCount","totalCount"],"type":"object"},"JobTypeDescriptor":{"properties":{"payloadFields":{"items":{"$ref":"#/components/schemas/JobPayloadField"},"type":"array"},"type":{"type":"string"}},"required":["payloadFields","type"],"type":"object"},"JwtRequest":{"properties":{"password":{"minLength":1,"type":"string"},"username":{"minLength":1,"type":"string"}},"required":["password","username"],"type":"object"},"LinkExistingTargetRequest":{"properties":{"externalId":{"minLength":1,"type":"string"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},"required":["externalId","system"],"type":"object"},"LinkUserRequest":{"properties":{"externalUserId":{"minLength":1,"type":"string"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["externalUserId","system","userId"],"type":"object"},"LinkedUser":{"properties":{"externalUserId":{"type":"string"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"},"userId":{"format":"int64","type":"integer"}},"required":["externalUserId","system","userId"],"type":"object"},"LoginResponse":{"properties":{"addressId":{"format":"int64","type":"integer"},"expiration":{"format":"int64","type":"integer"},"roles":{"items":{"$ref":"#/components/schemas/Role"},"minItems":1,"type":"array"},"token":{"minLength":1,"type":"string"},"userId":{"format":"int64","type":"integer"},"username":{"minLength":1,"type":"string"}},"required":["expiration","roles","token","userId","username"],"type":"object"},"MemberActivationRequest":{"properties":{"password":{"maxLength":100,"minLength":8,"pattern":"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]+$","type":"string"},"token":{"minLength":1,"type":"string"},"username":{"minLength":1,"type":"string"}},"required":["password","token","username"],"type":"object"},"MemberProfileResponse":{"properties":{"bhv":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"dateOfBirth":{"format":"date","type":"string"},"ehbo":{"type":"boolean"},"gender":{"type":"string"},"id":{"format":"int64","type":"integer"},"nationality":{"type":"string"},"studentNumber":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["bhv","createdAt","ehbo","id","updatedAt","userId","version"]},"MemberType":{"enum":["ALUMNI","HONORARY","REGULAR","NONE"],"type":"string"},"MembershipResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"endDate":{"format":"date","type":"string"},"id":{"format":"int64","type":"integer"},"incasso":{"type":"boolean"},"memberType":{"$ref":"#/components/schemas/MemberType"},"startDate":{"format":"date","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","incasso","memberType","startDate","updatedAt","userId","version"],"type":"object"},"MissingRow":{"properties":{"hasExternalMapping":{"type":"boolean"},"userId":{"format":"int64","type":"integer"}},"required":["hasExternalMapping","userId"],"type":"object"},"PageMetadata":{"properties":{"number":{"format":"int64","type":"integer"},"size":{"format":"int64","type":"integer"},"totalElements":{"format":"int64","type":"integer"},"totalPages":{"format":"int64","type":"integer"}},"type":"object"},"PagedModelEmail":{"properties":{"content":{"items":{"$ref":"#/components/schemas/Email"},"type":"array"},"page":{"$ref":"#/components/schemas/PageMetadata"}},"type":"object"},"PagedModelEventResponse":{"properties":{"content":{"items":{"$ref":"#/components/schemas/EventResponse"},"type":"array"},"page":{"$ref":"#/components/schemas/PageMetadata"}},"type":"object"},"PagedModelJobExecution":{"properties":{"content":{"items":{"$ref":"#/components/schemas/JobExecution"},"type":"array"},"page":{"$ref":"#/components/schemas/PageMetadata"}},"type":"object"},"PagedModelUserDetailResponse":{"properties":{"content":{"items":{"$ref":"#/components/schemas/UserDetailResponse"},"type":"array"},"page":{"$ref":"#/components/schemas/PageMetadata"}},"type":"object"},"PasswordResetRequest":{"properties":{"password":{"maxLength":100,"minLength":8,"pattern":"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]+$","type":"string"},"token":{"minLength":1,"type":"string"}},"required":["password","token"],"type":"object"},"PlatformType":{"enum":["FACEBOOK","LINKEDIN","TWITTER","INSTAGRAM"],"type":"string"},"QuestionRequest":{"properties":{"choiceLabels":{"items":{"type":"string"},"type":"array"},"idx":{"format":"int64","type":"integer"},"label":{"maxLength":2055,"minLength":0,"type":"string"},"required":{"type":"boolean"},"type":{"$ref":"#/components/schemas/QuestionType"}},"required":["idx","label","type"],"type":"object"},"QuestionResponse":{"properties":{"choiceLabels":{"items":{"type":"string"},"type":"array"},"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"idx":{"format":"int64","type":"integer"},"label":{"maxLength":2055,"minLength":0,"type":"string"},"required":{"type":"boolean"},"surveyId":{"format":"int64","type":"integer"},"type":{"$ref":"#/components/schemas/QuestionType"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","idx","label","surveyId","type","updatedAt","version"],"type":"object"},"QuestionType":{"enum":["OPEN","RADIO","CHECKBOX","DESCRIPTION"],"type":"string"},"RedirectResponse":{"properties":{"path":{"type":"string"}},"required":["path"],"type":"object"},"Role":{"enum":["ANONYMOUS","VEGAN","GUEST","COMPANY","MEMBER","COMMITTEE","BOARD","TREASURER","ADMIN","SYSTEM"],"type":"string"},"ServiceEntry":{"properties":{"description":{"type":"string"},"iconUrl":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"}},"required":["description","iconUrl","id","name","url"],"type":"object"},"SponsorResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"description":{"type":"string"},"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","description","id","name","updatedAt","version"],"type":"object"},"SubjectFact":{"properties":{"key":{"type":"string"},"kind":{"$ref":"#/components/schemas/CohortFactKind"}},"required":["key","kind"],"type":"object"},"SurveyRequest":{"properties":{"questions":{"items":{"$ref":"#/components/schemas/QuestionRequest"},"minItems":1,"type":"array"}},"required":["questions"],"type":"object"},"SurveyResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"questions":{"items":{"$ref":"#/components/schemas/QuestionResponse"},"minItems":1,"type":"array"},"responseCount":{"format":"int64","type":"integer"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","questions","responseCount","updatedAt","version"],"type":"object"},"SwitchTargetRequest":{"properties":{"deletePrevious":{"type":"boolean"},"externalId":{"minLength":1,"type":"string"},"reconcileNow":{"type":"boolean"}},"required":["deletePrevious","externalId","reconcileNow"],"type":"object"},"TargetDescriptor":{"properties":{"capabilities":{"items":{"enum":["CATALOG","CREATE","READ_MEMBERS","WRITE_MEMBERS","DELETE"],"type":"string"},"type":"array","uniqueItems":true},"folderLabel":{"type":"string"},"idLabel":{"type":"string"},"kind":{"$ref":"#/components/schemas/CohortKind"},"system":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"},"systemLabel":{"type":"string"},"targetLabel":{"type":"string"}},"required":["capabilities","idLabel","kind","system","systemLabel","targetLabel"],"type":"object"},"TelemetryResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"id":{"format":"int64","type":"integer"},"platform":{"$ref":"#/components/schemas/PlatformType"},"updatedAt":{"format":"date-time","type":"string"},"url":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","id","platform","updatedAt","url","version"],"type":"object"},"UpdateAddressRequest":{"properties":{"city":{"minLength":1,"type":"string"},"country":{"minLength":1,"type":"string"},"houseNumber":{"minLength":1,"type":"string"},"street":{"minLength":1,"type":"string"},"version":{"format":"int64","type":"integer"},"zipCode":{"minLength":1,"type":"string"}},"required":["city","country","houseNumber","street","version","zipCode"],"type":"object"},"UpdateBlogRequest":{"properties":{"html":{"minLength":1,"type":"string"},"publishedAt":{"format":"date-time","type":"string"},"title":{"minLength":1,"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["html","publishedAt","title","version"],"type":"object"},"UpdateBoardRequest":{"properties":{"candidate":{"minLength":1,"type":"string"},"endDate":{"format":"date","type":"string"},"name":{"maxLength":100,"minLength":1,"type":"string"},"pictureId":{"format":"int64","type":"integer"},"startDate":{"format":"date","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["candidate","name","startDate","version"],"type":"object"},"UpdateCommitteeRequest":{"properties":{"description":{"maxLength":4095,"minLength":0,"type":"string"},"members":{"items":{"$ref":"#/components/schemas/CommitteeMemberRequest"},"minItems":1,"type":"array"},"name":{"maxLength":255,"minLength":0,"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["description","members","name","version"],"type":"object"},"UpdateContributionPeriodRequest":{"properties":{"alumniFee":{"format":"double","type":"number"},"contactListId":{"format":"int64","type":"integer"},"endDate":{"format":"date","type":"string"},"fullYearFee":{"format":"double","type":"number"},"halfYearFee":{"format":"double","type":"number"},"startDate":{"format":"date","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["alumniFee","endDate","fullYearFee","halfYearFee","startDate","version"],"type":"object"},"UpdateEventRequest":{"properties":{"approved":{"type":"boolean"},"banner":{"$ref":"#/components/schemas/EventBannerRequest"},"committeeId":{"format":"int64","type":"integer"},"description":{"maxLength":4095,"minLength":0,"type":"string"},"endTime":{"format":"date-time","type":"string"},"location":{"type":"string"},"memberPrice":{"format":"double","type":"number"},"membersOnly":{"type":"boolean"},"publicPrice":{"format":"double","type":"number"},"removeExistingSignUps":{"type":"boolean"},"signUp":{"type":"boolean"},"signUpDeadline":{"format":"date-time","type":"string"},"signUpForm":{"$ref":"#/components/schemas/SurveyRequest"},"signUpLimit":{"format":"int32","minimum":1,"type":"integer"},"startTime":{"format":"date-time","type":"string"},"title":{"maxLength":255,"minLength":0,"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["approved","committeeId","description","endTime","membersOnly","signUp","startTime","title","version"],"type":"object"},"UpdateEventSignUpRequest":{"properties":{"answers":{"items":{"$ref":"#/components/schemas/AnswerRequest"},"type":"array"},"guest":{"$ref":"#/components/schemas/CreateGuestRequest"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"type":"object"},"UpdateMemberProfileRequest":{"properties":{"bhv":{"type":"boolean"},"dateOfBirth":{"format":"date","type":"string"},"ehbo":{"type":"boolean"},"gender":{"type":"string"},"nationality":{"minLength":1,"type":"string"},"studentNumber":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["bhv","dateOfBirth","ehbo","nationality","version"],"type":"object"},"UpdateMembershipRequest":{"properties":{"endDate":{"format":"date","type":"string"},"incasso":{"type":"boolean"},"memberType":{"$ref":"#/components/schemas/MemberType"},"startDate":{"format":"date","type":"string"},"userId":{"format":"int64","type":"integer"},"version":{"format":"int64","type":"integer"}},"required":["userId","version"],"type":"object"},"UpdateSponsorRequest":{"properties":{"description":{"maxLength":4095,"minLength":0,"type":"string"},"name":{"maxLength":255,"minLength":0,"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["description","name","version"],"type":"object"},"UpdateUserRequest":{"properties":{"discord":{"minLength":1,"type":"string"},"memberProfile":{"$ref":"#/components/schemas/UpsertMemberProfileRequest"},"newsletter":{"type":"boolean"},"phoneNumber":{"minLength":1,"type":"string"},"photoConsent":{"type":"boolean"},"version":{"format":"int64","type":"integer"}},"required":["discord","newsletter","phoneNumber","version"],"type":"object"},"UpsertMemberProfileRequest":{"properties":{"bhv":{"type":"boolean"},"dateOfBirth":{"format":"date","type":"string"},"ehbo":{"type":"boolean"},"gender":{"type":"string"},"nationality":{"minLength":1,"type":"string"},"studentNumber":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["bhv","dateOfBirth","ehbo","nationality"],"type":"object"},"UserActivationRequest":{"properties":{"token":{"minLength":1,"type":"string"}},"required":["token"],"type":"object"},"UserDetailResponse":{"properties":{"addressId":{"format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"discord":{"type":"string"},"email":{"type":"string"},"enabled":{"type":"boolean"},"firstName":{"type":"string"},"fullName":{"type":"string"},"id":{"format":"int64","type":"integer"},"initials":{"type":"string"},"lastName":{"type":"string"},"newsletter":{"type":"boolean"},"phoneNumber":{"type":"string"},"photoConsent":{"type":"boolean"},"prefix":{"type":"string"},"restoreUntilAt":{"format":"date-time","type":"string"},"roles":{"items":{"$ref":"#/components/schemas/Role"},"type":"array"},"updatedAt":{"format":"date-time","type":"string"},"username":{"type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","email","enabled","firstName","fullName","id","initials","lastName","newsletter","photoConsent","roles","updatedAt","username","version"],"type":"object"},"UserSummaryResponse":{"properties":{"createdAt":{"format":"date-time","type":"string"},"discord":{"type":"string"},"email":{"type":"string"},"fullName":{"type":"string"},"id":{"format":"int64","type":"integer"},"phoneNumber":{"type":"string"},"updatedAt":{"format":"date-time","type":"string"},"version":{"format":"int64","type":"integer"}},"required":["createdAt","email","fullName","id","updatedAt","version"],"type":"object"}}},"info":{"title":"OpenAPI definition","version":"v0"},"openapi":"3.1.0","paths":{"/addresses":{"get":{"operationId":"findAllAddresses","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AddressResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]},"post":{"operationId":"createAddress","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAddressRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]}},"/addresses/{id}":{"delete":{"operationId":"deleteAddressById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]},"get":{"operationId":"findAddressById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]},"put":{"operationId":"updateAddress","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAddressRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Addresses"]}},"/auth":{"post":{"operationId":"authenticate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JwtRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Authentication"]}},"/auth/logout":{"post":{"operationId":"logout","responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Authentication"]}},"/blogs":{"get":{"operationId":"findBlogs","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BlogResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]},"post":{"operationId":"createBlog","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBlogRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]}},"/blogs/{id}":{"delete":{"operationId":"deleteById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]},"get":{"operationId":"findBlogById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]},"post":{"operationId":"updateBlog","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBlogRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Blogs"]}},"/boards":{"get":{"operationId":"findAllBoards","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BoardResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]},"post":{"operationId":"createBoard","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBoardRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]}},"/boards/{boardId}/members":{"post":{"operationId":"addMember","parameters":[{"in":"path","name":"boardId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddBoardMemberRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardMemberResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]}},"/boards/{boardId}/members/{userId}":{"delete":{"operationId":"removeMember","parameters":[{"in":"path","name":"boardId","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]}},"/boards/{id}":{"delete":{"operationId":"deleteBoard","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]},"get":{"operationId":"findBoardById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]},"put":{"operationId":"updateBoard","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBoardRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Boards"]}},"/committeeMembers/committees":{"get":{"operationId":"findCommitteesByUserId","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CommitteeResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]}},"/committees":{"get":{"operationId":"findCommittees","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CommitteeResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]},"post":{"operationId":"createCommittee","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommitteeRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitteeDetailResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]}},"/committees/{committeeId}":{"get":{"operationId":"findCommitteeById","parameters":[{"in":"path","name":"committeeId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitteeResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]}},"/committees/{id}":{"delete":{"operationId":"deleteCommitteeById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]},"put":{"operationId":"updateCommittee","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommitteeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitteeDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Committees"]}},"/contributionPeriods":{"get":{"operationId":"findContributionPeriods","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionPeriodResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]},"post":{"operationId":"createContributionPeriod","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContributionPeriodRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionPeriodResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]}},"/contributionPeriods/current":{"get":{"operationId":"findCurrentContributionPeriod","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionPeriodResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]}},"/contributionPeriods/{contributionPeriodId}/users/{userId}/contributions":{"delete":{"operationId":"deleteContribution","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"path","name":"contributionPeriodId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Contributions"]}},"/contributionPeriods/{id}":{"delete":{"operationId":"deleteContributionPeriodById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]},"put":{"operationId":"updateContributionPeriod","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContributionPeriodRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionPeriodResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionPeriods"]}},"/contributionPeriods/{periodId}/contributions":{"get":{"operationId":"findContributionsByPeriodId","parameters":[{"in":"path","name":"periodId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Contributions"]}},"/contributionReminders":{"get":{"operationId":"findContributionReminders","parameters":[{"in":"query","name":"contributionPeriodId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionReminderResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionReminders"]},"post":{"operationId":"sendContributionReminder","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContributionReminderRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionReminderResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionReminders"]}},"/contributionReminders/batch":{"post":{"operationId":"sendContributionReminderBatch","requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CreateContributionReminderRequest"},"type":"array"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionReminderResponse"},"type":"array"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["ContributionReminders"]}},"/contributions":{"get":{"operationId":"findContributions","parameters":[{"in":"query","name":"contributionPeriodId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ContributionResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Contributions"]},"post":{"operationId":"createContribution","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContributionRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributionResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Contributions"]}},"/csrf":{"get":{"operationId":"csrf","parameters":[{"in":"query","name":"csrfToken","required":true,"schema":{"$ref":"#/components/schemas/CsrfToken"}}],"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Security"]}},"/events":{"get":{"operationId":"findEvents","parameters":[{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":20,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"items":{"type":"string"},"type":"array"}},{"in":"query","name":"from","required":false,"schema":{"format":"date-time","type":"string"}},{"in":"query","name":"to","required":false,"schema":{"format":"date-time","type":"string"}},{"in":"query","name":"approved","required":false,"schema":{"type":"boolean"}},{"in":"query","name":"committeeId","required":false,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"titleContains","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelEventResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]},"post":{"operationId":"createEvent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]}},"/events/banners":{"post":{"operationId":"uploadEventBanner","requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"format":"binary","type":"string"}},"required":["file"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Files"]}},"/events/signups":{"get":{"operationId":"findEventSignUps","parameters":[{"in":"query","name":"from","required":false,"schema":{"format":"date-time","type":"string"}},{"in":"query","name":"to","required":false,"schema":{"format":"date-time","type":"string"}},{"in":"query","name":"userId","required":false,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"committeeId","required":false,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"approved","required":false,"schema":{"type":"boolean"}},{"in":"query","name":"eventId","required":false,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/EventSignUpResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]}},"/events/signups/byAccessToken":{"get":{"operationId":"findEventSignUpsByAccessToken","parameters":[{"in":"header","name":"X-Guest-Access-Token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/EventSignUpResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]}},"/events/signups/{id}":{"delete":{"operationId":"deleteEventSignup","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"header","name":"X-Guest-Access-Token","required":false,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]}},"/events/{eventId}":{"delete":{"operationId":"deleteEventById","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]}},"/events/{eventId}/banners":{"get":{"operationId":"downloadEventBanner","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"format":"binary","type":"string"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Files"]}},"/events/{eventId}/signups":{"get":{"operationId":"findEventSignUpsByEventId","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/EventSignUpResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]},"post":{"operationId":"createEventSignup","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventSignUpRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSignUpResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]},"put":{"operationId":"updateEventSignUp","parameters":[{"in":"path","name":"eventId","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"header","name":"X-Guest-Access-Token","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventSignUpRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventSignUpResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["EventSignUps"]}},"/events/{id}":{"get":{"operationId":"findEventById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]},"put":{"operationId":"updateEvent","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]}},"/events/{id}/approve":{"put":{"operationId":"approveEvent","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"approved","required":true,"schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Events"]}},"/health":{"get":{"operationId":"healthCheck","responses":{"200":{"content":{"application/json":{"schema":{"type":"boolean"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Health"]}},"/management/cohort-subjects":{"get":{"operationId":"findCohortSubjects","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CohortSubjectSummary"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}":{"get":{"operationId":"findCohortSubjectById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortSubjectDetail"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/drift":{"get":{"operationId":"getDrift","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"system","required":true,"schema":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriftReport"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/drift/link-user":{"post":{"operationId":"linkUser","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkUserRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkedUser"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/targets/existing":{"post":{"operationId":"linkExistingTarget","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkExistingTargetRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortMapping"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/targets/new":{"post":{"operationId":"createTarget","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTargetRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortMapping"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/targets/{cohortId}":{"put":{"operationId":"switchTarget","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"path","name":"cohortId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchTargetRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortMapping"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/targets/{cohortId}/inbound-reconcile/apply":{"post":{"operationId":"applyInboundReconcile","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"path","name":"cohortId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundReconcileApplyRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundReconcileApplyResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-subjects/{id}/targets/{cohortId}/inbound-reconcile/preview":{"post":{"operationId":"previewInboundReconcile","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"path","name":"cohortId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboundReconcilePreview"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Subjects"]}},"/management/cohort-targets/systems":{"get":{"operationId":"listCohortTargetSystems","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/TargetDescriptor"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Targets"]}},"/management/cohort-targets/{system}":{"get":{"operationId":"searchCohortTargets","parameters":[{"in":"path","name":"system","required":true,"schema":{"enum":["BREVO","GOOGLE_CALENDAR"],"type":"string"}},{"in":"query","name":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ExternalTarget"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohort Targets"]}},"/management/cohorts":{"get":{"operationId":"findCohorts","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CohortSummary"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohorts"]}},"/management/cohorts/{id}":{"get":{"operationId":"findCohortById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortDetail"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohorts"]}},"/management/cohorts/{id}/repair-missing-adds":{"post":{"operationId":"repairMissingAdds","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortRepair"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Cohorts"]}},"/management/emails":{"get":{"operationId":"list_1","parameters":[{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":50,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"default":["createdAt,DESC"],"items":{"type":"string"},"type":"array"}},{"in":"query","name":"deliveryStatus","required":false,"schema":{"enum":["PENDING","SENT","DELIVERED","OPENED","BOUNCED","FAILED"],"type":"string"}},{"in":"query","name":"emailType","required":false,"schema":{"type":"string"}},{"in":"query","name":"search","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelEmail"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Email Management"]}},"/management/emails/stats":{"get":{"operationId":"getStats_1","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailStats"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Email Management"]}},"/management/emails/{id}/retry":{"post":{"operationId":"retry_1","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Email"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Email Management"]}},"/management/jobs":{"get":{"operationId":"list","parameters":[{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":50,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"default":["updatedAt,DESC"],"items":{"type":"string"},"type":"array"}},{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/JobExecutionStatus"}},{"in":"query","name":"category","required":false,"schema":{"$ref":"#/components/schemas/JobExecutionCategory"}},{"in":"query","name":"search","required":false,"schema":{"type":"string"}},{"in":"query","name":"initiatedByType","required":false,"schema":{"enum":["USER","SYSTEM"],"type":"string"}},{"in":"query","name":"jobType","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelJobExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/management/jobs/enqueue":{"post":{"operationId":"enqueue","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnqueueJobRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/management/jobs/stats":{"get":{"operationId":"getStats","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatsDTO"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/management/jobs/types":{"get":{"operationId":"jobTypes","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/JobTypeDescriptor"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/management/jobs/{id}/retry":{"post":{"operationId":"retry","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobExecution"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Job Management"]}},"/me/services":{"get":{"operationId":"myServices","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ServiceEntry"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["My Services"]}},"/memberProfiles":{"post":{"operationId":"createMemberProfile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMemberProfileRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberProfileResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Member Profiles"]}},"/memberships":{"get":{"operationId":"findMemberships","parameters":[{"in":"query","name":"from","required":false,"schema":{"format":"date","type":"string"}},{"in":"query","name":"to","required":false,"schema":{"format":"date","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/MembershipResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]},"post":{"operationId":"createMembership","responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]}},"/memberships/{id}":{"get":{"operationId":"findMembershipById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]},"put":{"operationId":"updateMembership","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMembershipRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]}},"/oauth2/forward-auth":{"get":{"operationId":"forwardAuth","responses":{"200":{"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Forward Auth"]}},"/recovery/member/activate":{"post":{"operationId":"memberActivate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberActivationRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/password":{"post":{"operationId":"setPassword","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/password/reset/{username}":{"post":{"operationId":"resetPassword","parameters":[{"in":"path","name":"username","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/user/activate":{"post":{"operationId":"userActivate","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserActivationRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/user/activate/resend/{username}":{"post":{"operationId":"resendUserActivation","parameters":[{"in":"path","name":"username","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/recovery/users/{userId}/resend/recovery":{"post":{"operationId":"resendMemberActivationEmail","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Recovery"]}},"/sponsors":{"get":{"operationId":"findSponsors","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/SponsorResponse"},"type":"array"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]},"post":{"operationId":"createSponsor","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSponsorRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SponsorResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]}},"/sponsors/{id}":{"delete":{"operationId":"deleteSponsorById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]},"get":{"operationId":"findSponsorById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SponsorResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]},"put":{"operationId":"updateSponsor","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSponsorRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SponsorResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Sponsors"]}},"/telemetry":{"post":{"operationId":"createTelemetry","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTelemetryRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelemetryResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Telemetries"]}},"/telemetry/{id}":{"get":{"operationId":"findTelemetryById","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelemetryResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Telemetries"]}},"/users":{"get":{"operationId":"findUsers","parameters":[{"in":"query","name":"username","required":false,"schema":{"type":"string"}},{"in":"query","name":"enabled","required":false,"schema":{"type":"boolean"}},{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":20,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"items":{"type":"string"},"type":"array"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelUserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]},"post":{"operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDetailResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/deleted":{"get":{"operationId":"findDeletedUsers","parameters":[{"description":"Zero-based page index (0..N)","in":"query","name":"page","required":false,"schema":{"default":0,"minimum":0,"type":"integer"}},{"description":"The size of the page to be returned","in":"query","name":"size","required":false,"schema":{"default":20,"minimum":1,"type":"integer"}},{"description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","in":"query","name":"sort","required":false,"schema":{"items":{"type":"string"},"type":"array"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedModelUserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/{id}":{"put":{"operationId":"updateUser","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/{userId}":{"delete":{"operationId":"deleteUserById","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]},"get":{"operationId":"findUserById","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/{userId}/memberProfiles":{"get":{"operationId":"findMemberProfileByUserId","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberProfileResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Member Profiles"]},"put":{"operationId":"updateMemberProfile","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMemberProfileRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberProfileResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Member Profiles"]}},"/users/{userId}/memberships":{"post":{"operationId":"boardCreateMembership","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardCreateMembershipRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembershipResponse"}}},"description":"Created"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Memberships"]}},"/users/{userId}/restore":{"put":{"operationId":"restoreDeletedUserById","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"No Content"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}},"/users/{userId}/roles":{"put":{"operationId":"toggleUserRole","parameters":[{"in":"path","name":"userId","required":true,"schema":{"format":"int64","type":"integer"}},{"in":"query","name":"role","required":true,"schema":{"$ref":"#/components/schemas/Role"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDetailResponse"}}},"description":"OK"},"400":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Bad Request\",\n \"status\": 400,\n \"detail\": \"Validation failed for request.\",\n \"instance\": \"/api/users\",\n \"errors\": [\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"email\",\n \"message\": \"must be a well-formed email address\",\n \"code\": \"Email\"\n },\n {\n \"objectName\": \"createUserRequest\",\n \"field\": \"age\",\n \"message\": \"must be greater than or equal to 0\",\n \"code\": \"Min\"\n }\n ],\n \"traceId\": \"a8c0c4e5f1c24a7e\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Validation error"},"401":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Unauthorized\",\n \"status\": 401,\n \"detail\": \"Full authentication is required to access this resource\",\n \"instance\": \"/api/users\",\n \"traceId\": \"401401401401\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Forbidden\",\n \"status\": 403,\n \"detail\": \"Access is denied\",\n \"instance\": \"/api/users\",\n \"traceId\": \"403403403403\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Forbidden (access denied)"},"404":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Not Found\",\n \"status\": 404,\n \"detail\": \"User not found with id: 42\",\n \"instance\": \"/api/users/42\",\n \"traceId\": \"cdef1234abcd5678\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Not Found"},"500":{"content":{"application/json":{"example":"{\n \"type\": \"about:blank\",\n \"title\": \"Internal Server Error\",\n \"status\": 500,\n \"detail\": \"An unexpected error occurred.\",\n \"instance\": \"/api/users\",\n \"traceId\": \"ab12cd34ef56\"\n}\n","schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Server error"}},"tags":["Users"]}}},"servers":[{"description":"Generated server url","url":"http://localhost:8080"}],"tags":[{"description":"Admin cohort listings + detail","name":"Cohorts"},{"description":"API for managing outbound emails","name":"Email Management"},{"description":"Admin: external cohort target catalog","name":"Cohort Targets"},{"description":"Admin: logical subjects + their per-system mappings","name":"Cohort Subjects"},{"description":"API for managing job executions","name":"Job Management"}]} diff --git a/services/api/src/main/kotlin/net/blueshell/api/domain/contribution/application/ContributionService.kt b/services/api/src/main/kotlin/net/blueshell/api/domain/contribution/application/ContributionService.kt index 94d21d48d..280a76bf6 100644 --- a/services/api/src/main/kotlin/net/blueshell/api/domain/contribution/application/ContributionService.kt +++ b/services/api/src/main/kotlin/net/blueshell/api/domain/contribution/application/ContributionService.kt @@ -4,9 +4,11 @@ import net.blueshell.api.domain.contribution.application.event.ContributionChang import net.blueshell.api.domain.contribution.application.event.ContributionChanged import net.blueshell.api.domain.contribution.persistence.Contribution import net.blueshell.api.domain.contribution.persistence.repository.ContributionRepository +import net.blueshell.api.domain.user.application.UserService import net.blueshell.api.shared.event.TrackedEventPublisher import net.blueshell.api.shared.service.BaseModelService import org.springframework.beans.factory.annotation.Autowired +import org.springframework.dao.DataIntegrityViolationException import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -14,6 +16,7 @@ import org.springframework.transaction.annotation.Transactional class ContributionService @Autowired constructor( repository: ContributionRepository, private val periodService: ContributionPeriodService, + private val users: UserService, private val trackedEvents: TrackedEventPublisher ) : BaseModelService(repository) { @Transactional @@ -63,6 +66,23 @@ class ContributionService @Autowired constructor( return repository.existsById(Contribution.Id(userId, periodId)) } + @Transactional + fun ensurePaid(userId: Long, periodId: Long): Boolean { + if (existsByUserIdAndPeriodId(userId, periodId)) return false + try { + create( + Contribution( + user = users.findById(userId), + contributionPeriod = periodService.findById(periodId), + ), + ) + } catch (ex: DataIntegrityViolationException) { + if (existsByUserIdAndPeriodId(userId, periodId)) return false + throw ex + } + return true + } + private fun publishChange(contribution: Contribution, changeType: ContributionChange) { trackedEvents.publish { actor -> ContributionChanged( diff --git a/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/UserService.kt b/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/UserService.kt index b19620c0c..ab9f80dbf 100644 --- a/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/UserService.kt +++ b/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/UserService.kt @@ -114,6 +114,9 @@ class UserService @Autowired constructor( return repository.existsByDiscordAndIdNot(discord, id) } + fun existsActiveMembershipByUserId(userId: Long): Boolean = + repository.existsActiveMembershipByUserId(userId) + /** * Batch lookup. Returns the users whose ids are in [ids] in unspecified * order; ids without a corresponding active user are silently skipped. diff --git a/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/listener/MembershipEventListener.kt b/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/listener/MembershipEventListener.kt index 2aece97b5..d060afd97 100644 --- a/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/listener/MembershipEventListener.kt +++ b/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/listener/MembershipEventListener.kt @@ -20,7 +20,7 @@ class MembershipEventListener( when (evt.changeType) { MembershipChange.CREATED, MembershipChange.UPDATED -> { - if (evt.active) { + if (evt.active || users.existsActiveMembershipByUserId(evt.userId)) { log.info("Updating membership for user {} adding role {}", evt.userId, Role.MEMBER) users.addRole(evt.userId, Role.MEMBER) } else { @@ -29,8 +29,13 @@ class MembershipEventListener( } } MembershipChange.DELETED -> { - log.info("Deleting membership for user {} removing role {}", evt.userId, Role.MEMBER) - users.removeRole(evt.userId, Role.MEMBER) + if (users.existsActiveMembershipByUserId(evt.userId)) { + log.info("Deleting inactive membership for user {} while another active membership remains", evt.userId) + users.addRole(evt.userId, Role.MEMBER) + } else { + log.info("Deleting membership for user {} removing role {}", evt.userId, Role.MEMBER) + users.removeRole(evt.userId, Role.MEMBER) + } } } } diff --git a/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/listener/UserEventListener.kt b/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/listener/UserEventListener.kt index 2a2e0ccd2..414808d73 100644 --- a/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/listener/UserEventListener.kt +++ b/services/api/src/main/kotlin/net/blueshell/api/domain/user/application/listener/UserEventListener.kt @@ -19,7 +19,7 @@ class UserEventListener( @Transactional(propagation = Propagation.REQUIRES_NEW) fun onUpdate(evt: UserUpdated) { val u = users.findById(evt.userId) - if (!u.hasRole(Role.MEMBER)) { + if (!u.hasAuthority(Role.MEMBER)) { u.committeeMembers.forEach { committeeMembers.delete(it) } } } diff --git a/services/api/src/main/kotlin/net/blueshell/api/domain/user/persistence/repository/UserRepository.kt b/services/api/src/main/kotlin/net/blueshell/api/domain/user/persistence/repository/UserRepository.kt index 27738b39d..4cbc57d5b 100644 --- a/services/api/src/main/kotlin/net/blueshell/api/domain/user/persistence/repository/UserRepository.kt +++ b/services/api/src/main/kotlin/net/blueshell/api/domain/user/persistence/repository/UserRepository.kt @@ -28,6 +28,16 @@ interface UserRepository : BaseRepository { fun existsByPhoneNumberAndIdNot(phoneNumber: String, id: Long): Boolean + @Query( + """ + SELECT CASE WHEN COUNT(m) > 0 THEN true ELSE false END + FROM Membership m + WHERE m.user.id = :userId + AND m.endDate IS NULL + """, + ) + fun existsActiveMembershipByUserId(@Param("userId") userId: Long): Boolean + /** * Native query that bypasses the @SQLRestriction on User so callers can * tell "this user existed at some point" apart from "this id was never diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/brevo/BrevoTargetStrategy.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/brevo/BrevoTargetStrategy.kt new file mode 100644 index 000000000..b3d872026 --- /dev/null +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/brevo/BrevoTargetStrategy.kt @@ -0,0 +1,140 @@ +package net.blueshell.api.platform.integration.cohort.adapter.brevo + +import net.blueshell.api.platform.integration.cohort.persistence.CohortKind +import net.blueshell.api.platform.integration.cohort.port.out.ExternalMember +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget +import net.blueshell.api.platform.integration.cohort.port.out.TargetCapability +import net.blueshell.api.platform.integration.cohort.port.out.TargetDescriptor +import net.blueshell.api.platform.integration.cohort.port.out.TargetStrategy +import net.blueshell.api.platform.integration.contact.adapter.ContactListAdapter +import net.blueshell.api.platform.integration.contact.adapter.ContactServiceException +import net.blueshell.api.shared.enums.ContactSystem +import net.blueshell.api.shared.enums.TargetSystem +import net.blueshell.clients.brevo.api.ContactsApi +import net.blueshell.clients.brevo.model.GetLists200ResponseListsInner +import net.blueshell.clients.brevo.model.GetProcessesSortParameter +import org.slf4j.LoggerFactory +import org.springframework.context.annotation.Profile +import org.springframework.stereotype.Service +import org.springframework.web.client.RestClientResponseException + +@Service +@Profile("!test & !dev") +class BrevoTargetStrategy( + contactListAdapters: List, + private val contactsApi: ContactsApi, +) : TargetStrategy { + private val lists = contactListAdapters.single { it.system == ContactSystem.BREVO } + + override val descriptor = TargetDescriptor( + system = TargetSystem.BREVO, + kind = CohortKind.LIST, + systemLabel = "Brevo", + targetLabel = "Brevo list", + idLabel = "List id", + folderLabel = "Folder", + capabilities = setOf( + TargetCapability.CATALOG, + TargetCapability.CREATE, + TargetCapability.READ_MEMBERS, + TargetCapability.WRITE_MEMBERS, + TargetCapability.DELETE, + ), + ) + + override fun catalog(query: String?): List { + val q = query?.trim()?.lowercase().orEmpty() + return listTargets(folders()) + .filter { it.matches(q) } + .sortedWith(compareBy({ it.folderLabel.orEmpty() }, { it.label })) + } + + override fun create(label: String, folder: String?): ExternalTarget = ExternalTarget( + system = system, + externalId = lists.createList(label, folder).toString(), + kind = descriptor.kind, + label = label, + folderLabel = folder, + ) + + override fun members(target: ExternalTarget): List = + lists.listMembers(target.externalId.toBrevoId("externalId", "members")) + .map { ExternalMember(it.externalUserId.toString(), it.email) } + .filter { it.externalUserId.isNotBlank() } + + override fun add(target: ExternalTarget, externalUserId: String) { + lists.addToList( + externalUserId.toBrevoId("externalUserId", "add"), + target.externalId.toBrevoId("externalId", "add"), + ) + } + + override fun remove(target: ExternalTarget, externalUserId: String) { + lists.removeFromList( + externalUserId.toBrevoId("externalUserId", "remove"), + target.externalId.toBrevoId("externalId", "remove"), + ) + } + + override fun delete(target: ExternalTarget) { + lists.deleteList(target.externalId.toBrevoId("externalId", "delete")) + } + + private fun folders(): Map = + page("folders") { limit, offset -> + contactsApi.getFolders(limit, offset, GetProcessesSortParameter.ASC).let { page -> + Page(page.count, page.folders.orEmpty().associate { it.id.toString() to it.name }.entries.toList()) + } + }.associate { it.key to it.value } + + private fun listTargets(folderNames: Map): List = + page("lists") { limit, offset -> + contactsApi.getLists(limit, offset, GetProcessesSortParameter.ASC).let { page -> + Page(page.count, page.lists.orEmpty().map { it.toTarget(folderNames) }) + } + } + + private fun page(kind: String, fetch: (Long, Long) -> Page): List { + val results = mutableListOf() + var offset = 0L + while (true) { + val page = try { + fetch(PAGE_SIZE, offset) + } catch (e: RestClientResponseException) { + if (e.statusCode.value() == 429) log.warn("Brevo target catalog {} fetch was rate limited", kind) + throw ContactServiceException("Failed to fetch Brevo $kind catalog", e) + } + results += page.items + if (page.items.size < PAGE_SIZE || page.count != null && results.size >= page.count) break + offset += PAGE_SIZE + } + return results + } + + private fun ExternalTarget.matches(query: String): Boolean = + query.isBlank() || + externalId == query || + label.lowercase().contains(query) || + folderLabel.orEmpty().lowercase().contains(query) + + private fun String.toBrevoId(field: String, operation: String): Long = + toLongOrNull() ?: throw InvalidExternalIdException("Brevo $operation: $field \"$this\" is not numeric") + + private data class Page(val count: Long?, val items: List) + + companion object { + const val PAGE_SIZE: Long = 50 + private val log = LoggerFactory.getLogger(BrevoTargetStrategy::class.java) + } +} + +private fun GetLists200ResponseListsInner.toTarget(folderNames: Map): ExternalTarget { + return ExternalTarget( + system = TargetSystem.BREVO, + externalId = id.toString(), + kind = CohortKind.LIST, + label = name, + folderLabel = folderNames[folderId.toString()], + memberCount = uniqueSubscribers, + ) +} diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/job/ApplyInboundReconcileJobHandler.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/job/ApplyInboundReconcileJobHandler.kt new file mode 100644 index 000000000..f9a5b0280 --- /dev/null +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/job/ApplyInboundReconcileJobHandler.kt @@ -0,0 +1,22 @@ +package net.blueshell.api.platform.integration.cohort.adapter.job + +import net.blueshell.api.platform.integration.cohort.application.InboundReconcile +import net.blueshell.api.platform.integration.queue.AbstractJsonJobHandler +import net.blueshell.api.shared.job.CohortJobs +import org.springframework.stereotype.Component +import tools.jackson.databind.ObjectMapper + +@Component +class ApplyInboundReconcileJobHandler( + objectMapper: ObjectMapper, + private val inbound: InboundReconcile, +) : AbstractJsonJobHandler( + objectMapper, + CohortJobs.ApplyInboundReconcile.payloadType, +) { + override val jobType: String = CohortJobs.ApplyInboundReconcile.type + + override fun handlePayload(payload: CohortJobs.ApplyInboundReconcilePayload) { + inbound.applyJob(payload) + } +} diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/web/CohortSubjectController.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/web/CohortSubjectController.kt index ba1d39cba..ed49d6525 100644 --- a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/web/CohortSubjectController.kt +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/web/CohortSubjectController.kt @@ -11,6 +11,10 @@ import net.blueshell.api.platform.integration.cohort.application.CohortSubjectDe import net.blueshell.api.platform.integration.cohort.application.CohortSubjectQueryService import net.blueshell.api.platform.integration.cohort.application.CohortSubjectSummary import net.blueshell.api.platform.integration.cohort.application.DriftReport +import net.blueshell.api.platform.integration.cohort.application.InboundReconcile +import net.blueshell.api.platform.integration.cohort.application.InboundReconcileApplyRequest +import net.blueshell.api.platform.integration.cohort.application.InboundReconcileApplyResponse +import net.blueshell.api.platform.integration.cohort.application.InboundReconcilePreview import net.blueshell.api.platform.integration.cohort.persistence.CohortFactKind import net.blueshell.api.platform.integration.cohort.persistence.CohortKind import net.blueshell.api.platform.integration.cohort.persistence.CohortSubjectCategory @@ -49,6 +53,7 @@ class CohortSubjectController( private val drift: CohortDrift, private val remediation: CohortRemediation, private val targeting: CohortTargeting, + private val inboundReconcile: InboundReconcile, ) { @GetMapping fun findCohortSubjects(): List = @@ -104,6 +109,21 @@ class CohortSubjectController( @RequestBody @Valid body: SwitchTargetRequest, ): CohortMappingResponse = targeting.switchTarget(id, cohortId, body.externalId, body.deletePrevious, body.reconcileNow).toResponse() + + @PostMapping("/{id}/targets/{cohortId}/inbound-reconcile/preview") + fun previewInboundReconcile( + @PathVariable id: Long, + @PathVariable cohortId: Long, + ): InboundReconcilePreview = + inboundReconcile.preview(id, cohortId) + + @PostMapping("/{id}/targets/{cohortId}/inbound-reconcile/apply") + fun applyInboundReconcile( + @PathVariable id: Long, + @PathVariable cohortId: Long, + @RequestBody @Valid body: InboundReconcileApplyRequest, + ): InboundReconcileApplyResponse = + inboundReconcile.apply(id, cohortId, body) } // ── Request / response DTOs ────────────────────────────────────────────────── diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/web/CohortTargetController.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/web/CohortTargetController.kt new file mode 100644 index 000000000..15712f5ac --- /dev/null +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/adapter/web/CohortTargetController.kt @@ -0,0 +1,33 @@ +package net.blueshell.api.platform.integration.cohort.adapter.web + +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import net.blueshell.api.platform.integration.cohort.application.TargetCatalog +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget +import net.blueshell.api.platform.integration.cohort.port.out.TargetDescriptor +import net.blueshell.api.shared.enums.TargetSystem +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/management/cohort-targets") +@Tag(name = "Cohort Targets", description = "Admin: external cohort target catalog") +@PreAuthorize("hasAuthority('ADMIN')") +class CohortTargetController( + private val catalog: TargetCatalog, +) { + @GetMapping("/systems") + @Operation(operationId = "listCohortTargetSystems") + fun systems(): List = catalog.descriptors() + + @GetMapping("/{system}") + @Operation(operationId = "searchCohortTargets") + fun targets( + @PathVariable system: TargetSystem, + @RequestParam(required = false) query: String?, + ): List = catalog.search(system, query) +} diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortProvisioningService.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortProvisioningService.kt index 42279f86f..2c6871bcf 100644 --- a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortProvisioningService.kt +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortProvisioningService.kt @@ -2,7 +2,6 @@ package net.blueshell.api.platform.integration.cohort.application import net.blueshell.api.platform.integration.cohort.persistence.Cohort import net.blueshell.api.platform.integration.cohort.persistence.CohortFactKind -import net.blueshell.api.platform.integration.cohort.persistence.CohortKind import net.blueshell.api.platform.integration.cohort.persistence.CohortSubject import net.blueshell.api.platform.integration.cohort.persistence.CohortSubjectType import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortRepository @@ -23,6 +22,7 @@ import org.springframework.transaction.annotation.Transactional class CohortProvisioningService( private val subjects: CohortSubjectRepository, private val cohorts: CohortRepository, + private val strategies: TargetStrategies, ) { @Transactional fun provision(spec: CohortProvisioningSpec): CohortProvisioningResult { @@ -43,19 +43,14 @@ class CohortProvisioningService( ?: cohorts.save( Cohort( system = spec.system.name, - kind = kindFor(spec.system), + kind = strategies.descriptor(spec.system).kind, label = spec.label, folder = spec.folder, subjectId = subject.id, ), - ) + ) return CohortProvisioningResult.Ready(cohort) } - - private fun kindFor(system: TargetSystem): CohortKind = when (system) { - TargetSystem.BREVO -> CohortKind.LIST - TargetSystem.GOOGLE_CALENDAR -> error("$system has no cohort target kind") - } } /** diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortTargetingService.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortTargetingService.kt index e433fedb2..e09278dda 100644 --- a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortTargetingService.kt +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortTargetingService.kt @@ -1,12 +1,11 @@ package net.blueshell.api.platform.integration.cohort.application import net.blueshell.api.platform.integration.cohort.persistence.Cohort -import net.blueshell.api.platform.integration.cohort.persistence.CohortKind import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortRepository import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortSubjectRepository import net.blueshell.api.platform.integration.cohort.port.`in`.CohortTargeting import net.blueshell.api.platform.integration.cohort.port.`in`.CohortTargetRef -import net.blueshell.api.platform.integration.cohort.port.out.CohortPortRegistry +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget import net.blueshell.api.shared.enums.TargetSystem import net.blueshell.api.shared.job.CohortJobs import net.blueshell.api.shared.job.NonRetryableJobException @@ -29,7 +28,7 @@ class CohortTargetingService( private val cohortRepo: CohortRepository, private val subjectRepo: CohortSubjectRepository, private val targetIds: CohortTargetIds, - private val registry: CohortPortRegistry, + private val strategies: TargetStrategies, private val jobs: TrackedJobDispatcher, transactionManager: PlatformTransactionManager, ) : CohortTargeting { @@ -44,7 +43,12 @@ class CohortTargetingService( propagationBehavior = TransactionDefinition.PROPAGATION_NOT_SUPPORTED } - override fun linkExisting(subjectId: Long, system: TargetSystem, externalId: String): CohortMappingRow = + override fun linkExisting(subjectId: Long, system: TargetSystem, externalId: String): CohortMappingRow { + resolveTarget(system, externalId) + return linkExistingLocal(subjectId, system, externalId) + } + + private fun linkExistingLocal(subjectId: Long, system: TargetSystem, externalId: String): CohortMappingRow = writeTransaction.execute { val subject = requireSubject(subjectId) val existing = cohortRepo.findBySubjectIdAndSystem(subjectId, system.name) @@ -72,12 +76,12 @@ class CohortTargetingService( requireNoExistingMapping(subjectId, system) } - val externalId = outsideTransaction.execute { registry.require(system).createCohort(label, folderHint) }!! + val target = outsideTransaction.execute { strategies.require(system).create(label, folderHint) }!! return writeTransaction.execute { val cohort = cohortRepo.save(newCohort(system, label, folder = folderHint, subjectId = subjectId)) - targetIds.record(cohort, externalId) - CohortMappingRow(cohort, externalId) + targetIds.record(cohort, target.externalId) + CohortMappingRow(cohort, target.externalId) }!! } @@ -88,15 +92,14 @@ class CohortTargetingService( deletePrevious: Boolean, reconcileNow: Boolean, ): CohortMappingRow { + val prep = writeTransaction.execute { + val cohort = requireOwnedCohort(subjectId, cohortId) + TargetSystem.valueOf(cohort.system) + }!! + resolveTarget(prep, externalId) + val switched = writeTransaction.execute { - val cohort = cohortRepo.findById(cohortId).orElseThrow { - ResponseStatusException(HttpStatus.NOT_FOUND, "Cohort $cohortId not found") - } - // The route carries the subject id; reject a cohort that is not its - // target so a wrong-path admin call cannot repoint another subject's. - if (cohort.subjectId != subjectId) { - throw ResponseStatusException(HttpStatus.NOT_FOUND, "Cohort $cohortId is not a target of subject $subjectId") - } + val cohort = requireOwnedCohort(subjectId, cohortId) val system = TargetSystem.valueOf(cohort.system) val previousExternalId = targetIds.find(cohort) targetIds.record(cohort, externalId) @@ -133,7 +136,8 @@ class CohortTargetingService( } override fun deleteTarget(system: TargetSystem, externalTargetId: String) { - outsideTransaction.executeWithoutResult { registry.require(system).deleteCohort(externalTargetId) } + val target = ExternalTarget(system, externalTargetId, strategies.descriptor(system).kind, externalTargetId) + outsideTransaction.executeWithoutResult { strategies.require(system).delete(target) } } private fun requireSubject(subjectId: Long) = @@ -153,16 +157,24 @@ class CohortTargetingService( private fun newCohort(system: TargetSystem, label: String, folder: String?, subjectId: Long) = Cohort( system = system.name, - kind = kindFor(system), + kind = strategies.descriptor(system).kind, label = label, folder = folder, subjectId = subjectId, ) - private fun kindFor(system: TargetSystem): CohortKind = when (system) { - TargetSystem.BREVO -> CohortKind.LIST - TargetSystem.GOOGLE_CALENDAR -> - throw ResponseStatusException(HttpStatus.BAD_REQUEST, "$system has no cohort target kind") + private fun requireOwnedCohort(subjectId: Long, cohortId: Long): Cohort { + val cohort = cohortRepo.findById(cohortId).orElseThrow { + ResponseStatusException(HttpStatus.NOT_FOUND, "Cohort $cohortId not found") + } + if (cohort.subjectId != subjectId) { + throw ResponseStatusException(HttpStatus.NOT_FOUND, "Cohort $cohortId is not a target of subject $subjectId") + } + return cohort + } + + private fun resolveTarget(system: TargetSystem, externalId: String) { + outsideTransaction.execute { strategies.require(system).resolve(externalId) } } private data class Switched(val cohort: Cohort, val system: TargetSystem, val previousExternalId: String?) diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/FactWriters.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/FactWriters.kt new file mode 100644 index 000000000..6322d6621 --- /dev/null +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/FactWriters.kt @@ -0,0 +1,53 @@ +package net.blueshell.api.platform.integration.cohort.application + +import net.blueshell.api.domain.contribution.application.ContributionService +import net.blueshell.api.platform.integration.cohort.persistence.CohortFactKind +import net.blueshell.api.platform.integration.cohort.port.`in`.CohortReconciliation +import org.springframework.http.HttpStatus +import org.springframework.stereotype.Component +import org.springframework.web.server.ResponseStatusException + +data class SubjectFact(val kind: CohortFactKind, val key: String) + +fun SubjectFact.toUserFact(): UserFact = UserFact(kind, key) + +data class FactPreview(val alreadyTrue: Boolean) + +enum class FactWriteStatus { WRITTEN, NOOP_ALREADY_TRUE, UNSUPPORTED, SKIPPED_UNMATCHED, SKIPPED_MAPPING_CONFLICT, FAILED } + +interface FactWriter { + val kind: CohortFactKind + fun preview(userId: Long, fact: SubjectFact): FactPreview + fun apply(userId: Long, fact: SubjectFact): FactWriteStatus +} + +@Component +class FactWriters(writers: List) { + private val byKind = writers.associateBy { it.kind } + + fun find(kind: CohortFactKind): FactWriter? = byKind[kind] +} + +@Component +class ContributionPaidWriter( + private val facts: UserFactCollector, + private val contributions: ContributionService, + private val reconciliation: CohortReconciliation, +) : FactWriter { + override val kind: CohortFactKind = CohortFactKind.CONTRIBUTION_PAID + + override fun preview(userId: Long, fact: SubjectFact): FactPreview = + FactPreview(facts.collect(userId).contains(fact.toUserFact())) + + override fun apply(userId: Long, fact: SubjectFact): FactWriteStatus { + if (preview(userId, fact).alreadyTrue) { + reconciliation.evaluateUserCohorts(userId) + return FactWriteStatus.NOOP_ALREADY_TRUE + } + val periodId = fact.key.toLongOrNull() + ?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Contribution period id must be numeric") + val created = contributions.ensurePaid(userId, periodId) + reconciliation.evaluateUserCohorts(userId) + return if (created) FactWriteStatus.WRITTEN else FactWriteStatus.NOOP_ALREADY_TRUE + } +} diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/InboundReconcile.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/InboundReconcile.kt new file mode 100644 index 000000000..897438c77 --- /dev/null +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/InboundReconcile.kt @@ -0,0 +1,201 @@ +package net.blueshell.api.platform.integration.cohort.application + +import net.blueshell.api.domain.user.application.UserService +import net.blueshell.api.domain.user.persistence.User +import net.blueshell.api.platform.integration.cohort.application.InboundReconcileSkipReason.* +import net.blueshell.api.platform.integration.cohort.persistence.CohortFactKind +import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortMemberRepository +import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortRepository +import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortSubjectRepository +import net.blueshell.api.platform.integration.cohort.port.out.ExternalMember +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget +import net.blueshell.api.platform.integration.sync.application.ExternalIdMappingService +import net.blueshell.api.shared.enums.TargetSystem +import net.blueshell.api.shared.job.CohortJobs +import net.blueshell.api.shared.job.TrackedJobDispatcher +import org.springframework.http.HttpStatus +import org.springframework.stereotype.Service +import org.springframework.transaction.PlatformTransactionManager +import org.springframework.transaction.TransactionDefinition +import org.springframework.transaction.support.TransactionTemplate +import org.springframework.web.server.ResponseStatusException +import java.nio.charset.StandardCharsets +import java.security.MessageDigest + +@Service +class InboundReconcile( + private val subjects: CohortSubjectRepository, + private val cohorts: CohortRepository, + private val members: CohortMemberRepository, + private val externalIds: ExternalIdMappingService, + private val users: UserService, + private val writers: FactWriters, + private val jobs: TrackedJobDispatcher, + private val strategies: TargetStrategies, + transactionManager: PlatformTransactionManager, +) { + private val noTx = transactionManager.tx(TransactionDefinition.PROPAGATION_NOT_SUPPORTED) + private val itemTx = transactionManager.tx(TransactionDefinition.PROPAGATION_REQUIRES_NEW) + + fun preview(subjectId: Long, cohortId: Long): InboundReconcilePreview = + preview(loadTarget(subjectId, cohortId)) + + private fun preview(target: InboundTarget): InboundReconcilePreview { + val remote = noTx.execute { strategies.require(target.system).members(target.external) }.orEmpty() + val (matched, skipped) = match(target, remote) + val preview = InboundReconcilePreview(target.fact, target.writer != null, "", remote.size, matched, skipped) + return preview.copy(previewToken = token(target, preview)) + } + + fun apply(subjectId: Long, cohortId: Long, request: InboundReconcileApplyRequest): InboundReconcileApplyResponse { + val target = loadTarget(subjectId, cohortId) + val current = preview(target) + if (current.previewToken != request.previewToken) { + conflict("Inbound reconcile preview is stale") + } + val selectedIds = request.selectedExternalUserIds.toSet() + val byExternalId = current.matched.associateBy { it.externalUserId } + val selected = selectedIds.map { + val row = byExternalId[it] + ?: conflict("Selected external user $it is no longer matched") + if (!row.writable) bad("Selected external user $it is not writable") + CohortJobs.InboundReconcileSelectedUser(row.externalUserId, row.userId!!) + } + val payload = CohortJobs.ApplyInboundReconcilePayload( + target.subjectId, target.cohortId, target.system.name, target.external.externalId, + target.fact.kind.name, target.fact.key, selected, + ) + val skipped = current.skipped.size + current.matched.size - selected.size + return InboundReconcileApplyResponse(jobs.enqueue(CohortJobs.ApplyInboundReconcile, payload)?.id, selected.size, skipped) + } + + fun applyJob(payload: CohortJobs.ApplyInboundReconcilePayload): List { + val factKind = CohortFactKind.valueOf(payload.factKind) + val fact = SubjectFact(factKind, payload.factKey) + return payload.selected.map { selected -> + val status = itemTx.execute { applyOne(payload, fact, selected) } + ApplyInboundReconcileItemResult(selected.externalUserId, selected.userId, status) + } + } + + private fun loadTarget(subjectId: Long, cohortId: Long): InboundTarget { + val subject = subjects.findById(subjectId) + .orElseThrow { missing("Subject $subjectId not found") } + val cohort = cohorts.findById(cohortId) + .orElseThrow { missing("Cohort $cohortId not found") } + if (cohort.subjectId != subjectId) { + missing("Cohort $cohortId is not a target of subject $subjectId") + } + if (!subject.enabled) bad("Subject $subjectId is disabled") + val fact = SubjectFact( + subject.factKind ?: bad("Subject $subjectId has no fact kind"), + subject.factKey.required("Subject $subjectId has no fact key"), + ) + val system = TargetSystem.valueOf(cohort.system) + val externalId = cohort.externalId.required("Cohort $cohortId has no external target") + return InboundTarget(subjectId, cohortId, system, ExternalTarget(system, externalId, cohort.kind, cohort.label, cohort.folder), fact, writers.find(fact.kind)) + } + + private fun applyOne( + payload: CohortJobs.ApplyInboundReconcilePayload, + fact: SubjectFact, + selected: CohortJobs.InboundReconcileSelectedUser, + ): FactWriteStatus { + val target = loadTarget(payload.subjectId, payload.cohortId) + if (!target.matches(payload, fact)) return FactWriteStatus.FAILED + val mappings = externalIds.findByExternalIds( + ExternalIdMappingService.USER_AGGREGATE, + payload.system, + listOf(selected.externalUserId), + ).filter { it.externalId == selected.externalUserId } + val mappedUserId = mappings.singleOrNull()?.aggregateId + ?: return if (mappings.isEmpty()) FactWriteStatus.SKIPPED_UNMATCHED else FactWriteStatus.SKIPPED_MAPPING_CONFLICT + if (mappedUserId != selected.userId) return FactWriteStatus.SKIPPED_MAPPING_CONFLICT + val writer = writers.find(fact.kind) ?: return FactWriteStatus.UNSUPPORTED + return runCatching { writer.apply(selected.userId, fact) }.getOrElse { FactWriteStatus.FAILED } + } + + private fun match(target: InboundTarget, remote: List): Pair, List> { + val duplicateIds = remote.groupingBy { it.externalUserId }.eachCount().filterValues { it > 1 }.keys + val skipped = duplicateIds.map { remote.first { member -> member.externalUserId == it }.skip(DUPLICATE_REMOTE_ID) }.toMutableList() + val extras = remote.filterNot { it.externalUserId in duplicateIds || it.externalUserId in internalExternalIds(target) } + val mappings = mappings(target, extras) + val activeUsers = users.findAllByIds(mappings.values.flatten().map { it.aggregateId }.toSet()).associateBy { it.id!! } + val matched = mutableListOf() + val seenUsers = mutableSetOf() + extras.forEach { member -> + val memberMappings = mappings[member.externalUserId].orEmpty() + val mappedIds = memberMappings.map { it.aggregateId }.toSet() + val user = mappedIds.singleOrNull()?.let(activeUsers::get) + when { + memberMappings.isEmpty() -> skipped += member.skip(UNMATCHED) + mappedIds.size != 1 -> skipped += member.skip(MAPPING_CONFLICT) + user == null -> skipped += member.skip(MAPPED_USER_INACTIVE) + !seenUsers.add(user.id!!) -> skipped += member.skip(DUPLICATE_USER_MATCH) + else -> matched += target.row(member, user) + } + } + return matched to skipped + } + + private fun internalExternalIds(target: InboundTarget): Set { + val internalIds = members.findAllByCohortIdAndUserIdIsNotNull(target.cohortId).mapNotNull { it.userId }.toSet() + return externalIds.findBatch(ExternalIdMappingService.USER_AGGREGATE, internalIds, target.system.name) + .mapNotNull { it.externalId?.takeIf(String::isNotBlank) } + .toSet() + } + + private fun mappings(target: InboundTarget, members: List) = + externalIds.findByExternalIds( + ExternalIdMappingService.USER_AGGREGATE, + target.system.name, + members.map { it.externalUserId }, + ).filter { !it.externalId.isNullOrBlank() }.groupBy { it.externalId!! } + + private fun InboundTarget.row(member: ExternalMember, user: User): InboundReconcileRow { + val alreadyTrue = writer?.preview(user.id!!, fact)?.alreadyTrue ?: false + return InboundReconcileRow(member.externalUserId, member.label, user.id!!, user.fullName, user.email, alreadyTrue, writer != null && !alreadyTrue) + } + + private fun token(target: InboundTarget, preview: InboundReconcilePreview): String { + val rows = preview.matched.sortedBy { it.externalUserId } + .joinToString(",") { "${it.externalUserId}=${it.userId}:${it.writable}" } + val input = "${target.subjectId}|${target.cohortId}|${target.system}|${target.external.externalId}|${target.fact.kind}|${target.fact.key}|$rows" + return MessageDigest.getInstance("SHA-256").digest(input.toByteArray(StandardCharsets.UTF_8)) + .joinToString("") { "%02x".format(it) } + } + + private fun InboundTarget.matches(payload: CohortJobs.ApplyInboundReconcilePayload, fact: SubjectFact) = + system.name == payload.system && external.externalId == payload.externalTargetId && this.fact == fact + + private fun ExternalMember.skip(reason: InboundReconcileSkipReason) = + InboundReconcileRow(externalUserId = externalUserId, externalLabel = label, reason = reason) + + private fun String?.required(message: String) = takeIf { !it.isNullOrBlank() } ?: bad(message) + private fun bad(message: String): Nothing = throw ResponseStatusException(HttpStatus.BAD_REQUEST, message) + private fun conflict(message: String): Nothing = throw ResponseStatusException(HttpStatus.CONFLICT, message) + private fun missing(message: String): Nothing = throw ResponseStatusException(HttpStatus.NOT_FOUND, message) + private fun PlatformTransactionManager.tx(propagation: Int) = + TransactionTemplate(this).apply { propagationBehavior = propagation } +} + +private data class InboundTarget(val subjectId: Long, val cohortId: Long, val system: TargetSystem, val external: ExternalTarget, val fact: SubjectFact, val writer: FactWriter?) + +data class InboundReconcilePreview(val fact: SubjectFact, val writerSupported: Boolean, val previewToken: String, val remoteCount: Int, val matched: List, val skipped: List) + +data class InboundReconcileRow( + val externalUserId: String, + val externalLabel: String? = null, + val userId: Long? = null, + val userFullName: String? = null, + val userEmail: String? = null, + val alreadyTrue: Boolean = false, + val writable: Boolean = false, + val reason: InboundReconcileSkipReason? = null, +) + +enum class InboundReconcileSkipReason { DUPLICATE_REMOTE_ID, MAPPING_CONFLICT, DUPLICATE_USER_MATCH, MAPPED_USER_INACTIVE, UNMATCHED } + +data class InboundReconcileApplyRequest(val previewToken: String, val selectedExternalUserIds: List) +data class InboundReconcileApplyResponse(val jobId: Long?, val acceptedCount: Int, val skippedCount: Int) +data class ApplyInboundReconcileItemResult(val externalUserId: String, val userId: Long, val status: FactWriteStatus) diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/TargetCatalog.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/TargetCatalog.kt new file mode 100644 index 000000000..4cb20854e --- /dev/null +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/TargetCatalog.kt @@ -0,0 +1,34 @@ +package net.blueshell.api.platform.integration.cohort.application + +import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortRepository +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget +import net.blueshell.api.platform.integration.cohort.port.out.TargetCapability +import net.blueshell.api.platform.integration.cohort.port.out.TargetDescriptor +import net.blueshell.api.shared.enums.TargetSystem +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Propagation +import org.springframework.transaction.annotation.Transactional + +@Service +class TargetCatalog( + private val strategies: TargetStrategies, + private val cohorts: CohortRepository, +) { + @Transactional(propagation = Propagation.NOT_SUPPORTED) + fun search(system: TargetSystem, query: String?): List { + val strategy = strategies.require(system) + if (!strategy.descriptor.supports(TargetCapability.CATALOG)) return emptyList() + + val linked = linkedCohorts(system) + return strategy.catalog(query).map { target -> + target.copy(linkedCohortId = linked[target.externalId]) + } + } + + fun descriptors(): List = strategies.descriptors() + + private fun linkedCohorts(system: TargetSystem): Map = + cohorts.findAllBySystem(system.name) + .mapNotNull { cohort -> cohort.externalId?.takeIf { it.isNotBlank() }?.let { it to cohort.id!! } } + .toMap() +} diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/TargetStrategies.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/TargetStrategies.kt new file mode 100644 index 000000000..c8b2d0278 --- /dev/null +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/application/TargetStrategies.kt @@ -0,0 +1,22 @@ +package net.blueshell.api.platform.integration.cohort.application + +import net.blueshell.api.platform.integration.cohort.port.out.TargetDescriptor +import net.blueshell.api.platform.integration.cohort.port.out.TargetStrategy +import net.blueshell.api.shared.enums.TargetSystem +import org.springframework.http.HttpStatus +import org.springframework.stereotype.Component +import org.springframework.web.server.ResponseStatusException + +@Component +class TargetStrategies(strategies: List) { + private val bySystem = strategies.associateBy { it.system } + + fun require(system: TargetSystem): TargetStrategy = + bySystem[system] + ?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "$system is not a cohort target") + + fun descriptor(system: TargetSystem): TargetDescriptor = require(system).descriptor + + fun descriptors(): List = + bySystem.values.map { it.descriptor }.sortedBy { it.systemLabel } +} diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/port/out/TargetStrategy.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/port/out/TargetStrategy.kt new file mode 100644 index 000000000..4e1fa85a7 --- /dev/null +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/cohort/port/out/TargetStrategy.kt @@ -0,0 +1,50 @@ +package net.blueshell.api.platform.integration.cohort.port.out + +import net.blueshell.api.platform.integration.cohort.persistence.CohortKind +import net.blueshell.api.shared.enums.TargetSystem + +enum class TargetCapability { CATALOG, CREATE, READ_MEMBERS, WRITE_MEMBERS, DELETE } + +data class TargetDescriptor( + val system: TargetSystem, + val kind: CohortKind, + val systemLabel: String, + val targetLabel: String, + val idLabel: String, + val folderLabel: String? = null, + val capabilities: Set, +) { + fun supports(capability: TargetCapability): Boolean = capability in capabilities +} + +data class ExternalTarget( + val system: TargetSystem, + val externalId: String, + val kind: CohortKind, + val label: String, + val folderLabel: String? = null, + val memberCount: Long? = null, + val linkedCohortId: Long? = null, +) + +data class ExternalMember(val externalUserId: String, val label: String?) + +interface TargetStrategy { + val descriptor: TargetDescriptor + val system: TargetSystem get() = descriptor.system + + fun catalog(query: String?): List = emptyList() + + fun resolve(externalId: String): ExternalTarget? = + catalog(externalId).firstOrNull { it.externalId == externalId } + + fun members(target: ExternalTarget): List + + fun add(target: ExternalTarget, externalUserId: String) + + fun remove(target: ExternalTarget, externalUserId: String) + + fun create(label: String, folder: String?): ExternalTarget + + fun delete(target: ExternalTarget) +} diff --git a/services/api/src/main/kotlin/net/blueshell/api/platform/integration/mock/MockTargetStrategy.kt b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/mock/MockTargetStrategy.kt new file mode 100644 index 000000000..800e328b9 --- /dev/null +++ b/services/api/src/main/kotlin/net/blueshell/api/platform/integration/mock/MockTargetStrategy.kt @@ -0,0 +1,74 @@ +package net.blueshell.api.platform.integration.mock + +import net.blueshell.api.platform.integration.cohort.persistence.CohortKind +import net.blueshell.api.platform.integration.cohort.port.out.ExternalMember +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget +import net.blueshell.api.platform.integration.cohort.port.out.TargetCapability +import net.blueshell.api.platform.integration.cohort.port.out.TargetDescriptor +import net.blueshell.api.platform.integration.cohort.port.out.TargetStrategy +import net.blueshell.api.shared.enums.TargetSystem +import org.springframework.context.annotation.Primary +import org.springframework.context.annotation.Profile +import org.springframework.stereotype.Service +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicLong + +@Service +@Primary +@Profile("test | dev") +class MockTargetStrategy : TargetStrategy { + override val descriptor = TargetDescriptor( + system = TargetSystem.BREVO, + kind = CohortKind.LIST, + systemLabel = "Brevo", + targetLabel = "Brevo list", + idLabel = "List id", + folderLabel = "Folder", + capabilities = setOf( + TargetCapability.CATALOG, + TargetCapability.CREATE, + TargetCapability.READ_MEMBERS, + TargetCapability.WRITE_MEMBERS, + TargetCapability.DELETE, + ), + ) + + private val targets = ConcurrentHashMap() + private val members = ConcurrentHashMap, String>() + private val ids = AtomicLong(9000) + + override fun catalog(query: String?): List = + targets.values.filter { it.matches(query.orEmpty().trim().lowercase()) } + + override fun resolve(externalId: String): ExternalTarget? = targets[externalId] + + override fun create(label: String, folder: String?): ExternalTarget { + val target = ExternalTarget(system, ids.getAndIncrement().toString(), descriptor.kind, label, folder) + targets[target.externalId] = target + return target + } + + override fun members(target: ExternalTarget): List = + members.entries + .filter { it.key.second == target.externalId } + .map { ExternalMember(it.key.first, it.value.ifBlank { null }) } + + override fun add(target: ExternalTarget, externalUserId: String) { + members[externalUserId to target.externalId] = "" + } + + override fun remove(target: ExternalTarget, externalUserId: String) { + members.remove(externalUserId to target.externalId) + } + + override fun delete(target: ExternalTarget) { + targets.remove(target.externalId) + members.keys.removeIf { it.second == target.externalId } + } + + private fun ExternalTarget.matches(query: String): Boolean = + query.isBlank() || + externalId == query || + label.lowercase().contains(query) || + folderLabel.orEmpty().lowercase().contains(query) +} diff --git a/services/api/src/main/kotlin/net/blueshell/api/shared/job/CohortJobs.kt b/services/api/src/main/kotlin/net/blueshell/api/shared/job/CohortJobs.kt index 6fcb11771..af520e7f7 100644 --- a/services/api/src/main/kotlin/net/blueshell/api/shared/job/CohortJobs.kt +++ b/services/api/src/main/kotlin/net/blueshell/api/shared/job/CohortJobs.kt @@ -95,6 +95,12 @@ object CohortJobs { DeleteExternalTargetPayload::class.java } + object ApplyInboundReconcile : JobDefinition { + override val type: String = "cohort.inbound-reconcile-apply" + override val payloadType: Class = + ApplyInboundReconcilePayload::class.java + } + /** * Stale compatibility job for cohorts that already have a target id. * It returns the existing id or fails terminally when missing; target @@ -121,4 +127,14 @@ object CohortJobs { /** `system` holds a `TargetSystem.name()`; shared/job cannot depend on the sync.port package. */ data class DeleteExternalTargetPayload(val system: String, val externalTargetId: String) data class MaterializeCohortTargetPayload(val cohortId: Long) + data class ApplyInboundReconcilePayload( + val subjectId: Long, + val cohortId: Long, + val system: String, + val externalTargetId: String, + val factKind: String, + val factKey: String, + val selected: List, + ) + data class InboundReconcileSelectedUser(val externalUserId: String, val userId: Long) } diff --git a/services/api/src/test/kotlin/net/blueshell/api/domain/contribution/application/ContributionServiceTest.kt b/services/api/src/test/kotlin/net/blueshell/api/domain/contribution/application/ContributionServiceTest.kt new file mode 100644 index 000000000..25b703ef3 --- /dev/null +++ b/services/api/src/test/kotlin/net/blueshell/api/domain/contribution/application/ContributionServiceTest.kt @@ -0,0 +1,73 @@ +package net.blueshell.api.domain.contribution.application + +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify +import net.blueshell.api.domain.contribution.persistence.Contribution +import net.blueshell.api.domain.contribution.persistence.ContributionPeriod +import net.blueshell.api.domain.contribution.persistence.repository.ContributionRepository +import net.blueshell.api.domain.user.application.UserService +import net.blueshell.api.domain.user.persistence.User +import net.blueshell.api.shared.event.TrackedEventPublisher +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.dao.DataIntegrityViolationException +import java.time.LocalDate + +class ContributionServiceTest { + private val repository: ContributionRepository = mockk() + private val periods: ContributionPeriodService = mockk() + private val users: UserService = mockk() + private val trackedEvents: TrackedEventPublisher = mockk(relaxed = true) + private val service = spyk(ContributionService(repository, periods, users, trackedEvents)) + + @Test + fun `ensurePaid is a no-op when contribution already exists`() { + every { repository.existsById(Contribution.Id(7L, 12L)) } returns true + + val created = service.ensurePaid(7L, 12L) + + assertThat(created).isFalse() + verify(exactly = 0) { users.findById(any()) } + verify(exactly = 0) { periods.findById(any()) } + verify(exactly = 0) { service.create(any()) } + } + + @Test + fun `ensurePaid creates missing contribution row`() { + val user = mockk() + val period = ContributionPeriod(LocalDate.parse("2026-01-01"), LocalDate.parse("2026-12-31")) + every { repository.existsById(Contribution.Id(7L, 12L)) } returns false + every { users.findById(7L) } returns user + every { periods.findById(12L) } returns period + every { service.create(any()) } answers { firstArg() } + + val created = service.ensurePaid(7L, 12L) + + assertThat(created).isTrue() + verify { + service.create( + match { + it.user === user && + it.contributionPeriod === period + }, + ) + } + } + + @Test + fun `ensurePaid treats duplicate create as already paid`() { + val user = mockk() + val period = ContributionPeriod(LocalDate.parse("2026-01-01"), LocalDate.parse("2026-12-31")) + every { repository.existsById(Contribution.Id(7L, 12L)) } returnsMany listOf(false, true) + every { users.findById(7L) } returns user + every { periods.findById(12L) } returns period + every { service.create(any()) } throws DataIntegrityViolationException("duplicate contribution") + + val created = service.ensurePaid(7L, 12L) + + assertThat(created).isFalse() + verify(exactly = 1) { service.create(any()) } + } +} diff --git a/services/api/src/test/kotlin/net/blueshell/api/domain/user/application/listener/MembershipEventListenerTest.kt b/services/api/src/test/kotlin/net/blueshell/api/domain/user/application/listener/MembershipEventListenerTest.kt new file mode 100644 index 000000000..0e8bbf2d7 --- /dev/null +++ b/services/api/src/test/kotlin/net/blueshell/api/domain/user/application/listener/MembershipEventListenerTest.kt @@ -0,0 +1,33 @@ +package net.blueshell.api.domain.user.application.listener + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import net.blueshell.api.domain.user.application.UserService +import net.blueshell.api.domain.user.application.event.MembershipChange +import net.blueshell.api.domain.user.application.event.MembershipChanged +import net.blueshell.api.shared.enums.Role +import org.junit.jupiter.api.Test + +class MembershipEventListenerTest { + private val users: UserService = mockk(relaxed = true) + private val listener = MembershipEventListener(users) + + @Test + fun `closed historical membership does not remove member role while another active membership exists`() { + every { users.existsActiveMembershipByUserId(7L) } returns true + + listener.onChange(MembershipChanged(7L, active = false, changeType = MembershipChange.UPDATED)) + + verify(exactly = 0) { users.removeRole(7L, Role.MEMBER) } + } + + @Test + fun `last inactive membership removes member role when aggregate has no active membership`() { + every { users.existsActiveMembershipByUserId(7L) } returns false + + listener.onChange(MembershipChanged(7L, active = false, changeType = MembershipChange.DELETED)) + + verify { users.removeRole(7L, Role.MEMBER) } + } +} diff --git a/services/api/src/test/kotlin/net/blueshell/api/domain/user/application/listener/UserEventListenerTest.kt b/services/api/src/test/kotlin/net/blueshell/api/domain/user/application/listener/UserEventListenerTest.kt new file mode 100644 index 000000000..366d1438d --- /dev/null +++ b/services/api/src/test/kotlin/net/blueshell/api/domain/user/application/listener/UserEventListenerTest.kt @@ -0,0 +1,31 @@ +package net.blueshell.api.domain.user.application.listener + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import net.blueshell.api.domain.committee.application.CommitteeMemberService +import net.blueshell.api.domain.committee.persistence.CommitteeMember +import net.blueshell.api.domain.user.application.UserService +import net.blueshell.api.domain.user.application.event.UserUpdated +import net.blueshell.api.domain.user.persistence.User +import net.blueshell.api.shared.enums.Role +import org.junit.jupiter.api.Test + +class UserEventListenerTest { + private val users: UserService = mockk() + private val committeeMembers: CommitteeMemberService = mockk(relaxed = true) + private val listener = UserEventListener(users, committeeMembers) + + @Test + fun `committee authority satisfies member prerequisite and keeps committee memberships`() { + val membership = mockk() + val user = mockk() + every { user.hasAuthority(Role.MEMBER) } returns true + every { user.committeeMembers } returns setOf(membership) + every { users.findById(42L) } returns user + + listener.onUpdate(UserUpdated(42L)) + + verify(exactly = 0) { committeeMembers.delete(any()) } + } +} diff --git a/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/adapter/brevo/BrevoTargetStrategyTest.kt b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/adapter/brevo/BrevoTargetStrategyTest.kt new file mode 100644 index 000000000..71ec8e652 --- /dev/null +++ b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/adapter/brevo/BrevoTargetStrategyTest.kt @@ -0,0 +1,86 @@ +package net.blueshell.api.platform.integration.cohort.adapter.brevo + +import net.blueshell.api.platform.integration.contact.adapter.ContactListAdapter +import net.blueshell.api.platform.integration.contact.adapter.ContactServiceException +import net.blueshell.api.shared.enums.ContactSystem +import net.blueshell.clients.brevo.api.ContactsApi +import net.blueshell.clients.brevo.model.GetFolder +import net.blueshell.clients.brevo.model.GetFolders200Response +import net.blueshell.clients.brevo.model.GetLists200Response +import net.blueshell.clients.brevo.model.GetLists200ResponseListsInner +import net.blueshell.clients.brevo.model.GetProcessesSortParameter +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test +import org.mockito.kotlin.doThrow +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever +import org.springframework.web.client.RestClientResponseException + +class BrevoTargetStrategyTest { + private val contactsApi: ContactsApi = mock() + private val lists: ContactListAdapter = mock { + whenever(it.system).thenReturn(ContactSystem.BREVO) + } + private val strategy = BrevoTargetStrategy(listOf(lists), contactsApi) + + @Test + fun `pages folders and lists and maps folder names and counts`() { + whenever(contactsApi.getFolders(eq(50L), eq(0L), eq(GetProcessesSortParameter.ASC))) + .thenReturn(GetFolders200Response().count(51).folders((1L..50L).map { folder(it, "Folder $it") })) + whenever(contactsApi.getFolders(eq(50L), eq(50L), eq(GetProcessesSortParameter.ASC))) + .thenReturn(GetFolders200Response().count(51).folders(listOf(folder(51L, "Contribution periods")))) + whenever(contactsApi.getLists(eq(50L), eq(0L), eq(GetProcessesSortParameter.ASC))) + .thenReturn(GetLists200Response().count(51).lists((1L..50L).map { list(it, "List $it", 1L) })) + whenever(contactsApi.getLists(eq(50L), eq(50L), eq(GetProcessesSortParameter.ASC))) + .thenReturn(GetLists200Response().count(51).lists(listOf(list(99L, "Paid 2026", 51L, 728L)))) + + val targets = strategy.catalog(null) + val paid = targets.single { it.externalId == "99" } + + assertThat(targets).hasSize(51) + assertThat(paid.folderLabel).isEqualTo("Contribution periods") + assertThat(paid.memberCount).isEqualTo(728L) + } + + @Test + fun `filters by query after fetching the bounded catalog`() { + whenever(contactsApi.getFolders(eq(50L), eq(0L), eq(GetProcessesSortParameter.ASC))) + .thenReturn(GetFolders200Response().count(1).folders(listOf(folder(1L, "Members")))) + whenever(contactsApi.getLists(eq(50L), eq(0L), eq(GetProcessesSortParameter.ASC))) + .thenReturn(GetLists200Response().count(2).lists(listOf(list(10L, "Guests", 1L), list(11L, "Paid", 1L)))) + + val targets = strategy.catalog("paid") + + assertThat(targets).extracting { it.externalId }.containsExactly("11") + } + + @Test + fun `treats Brevo rate limiting as retryable`() { + doThrow(error(429)).whenever(contactsApi) + .getFolders(eq(50L), eq(0L), eq(GetProcessesSortParameter.ASC)) + + assertThatThrownBy { strategy.catalog(null) } + .isInstanceOf(ContactServiceException::class.java) + .hasCauseInstanceOf(RestClientResponseException::class.java) + } + + private fun folder(id: Long, name: String): GetFolder = + GetFolder().id(id).name(name) + + private fun list( + id: Long, + name: String, + folderId: Long, + unique: Long = 10L + id, + ): GetLists200ResponseListsInner = + GetLists200ResponseListsInner() + .id(id) + .name(name) + .folderId(folderId) + .uniqueSubscribers(unique) + + private fun error(status: Int): RestClientResponseException = + RestClientResponseException("$status error", status, "error", null, ByteArray(0), null) +} diff --git a/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortProvisioningServiceTest.kt b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortProvisioningServiceTest.kt index b47c683f9..6982133f8 100644 --- a/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortProvisioningServiceTest.kt +++ b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortProvisioningServiceTest.kt @@ -11,6 +11,11 @@ import net.blueshell.api.platform.integration.cohort.persistence.CohortSubject import net.blueshell.api.platform.integration.cohort.persistence.CohortSubjectType import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortRepository import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortSubjectRepository +import net.blueshell.api.platform.integration.cohort.port.out.ExternalMember +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget +import net.blueshell.api.platform.integration.cohort.port.out.TargetCapability +import net.blueshell.api.platform.integration.cohort.port.out.TargetDescriptor +import net.blueshell.api.platform.integration.cohort.port.out.TargetStrategy import net.blueshell.api.shared.enums.TargetSystem import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -19,7 +24,7 @@ class CohortProvisioningServiceTest { private val subjects: CohortSubjectRepository = mockk(relaxed = true) private val cohorts: CohortRepository = mockk(relaxed = true) - private val service = CohortProvisioningService(subjects, cohorts) + private val service = CohortProvisioningService(subjects, cohorts, TargetStrategies(listOf(TestStrategy))) private fun spec(system: TargetSystem = TargetSystem.BREVO) = CohortProvisioningSpec( factKind = CohortFactKind.COMMITTEE, @@ -108,4 +113,21 @@ class CohortProvisioningServiceTest { assertThat(result).isEqualTo(CohortProvisioningResult.Ready(googleCohort)) verify(exactly = 0) { subjects.save(any()) } } + + private object TestStrategy : TargetStrategy { + override val descriptor = TargetDescriptor( + system = TargetSystem.BREVO, + kind = CohortKind.LIST, + systemLabel = "Brevo", + targetLabel = "Brevo list", + idLabel = "List id", + capabilities = setOf(TargetCapability.CREATE), + ) + + override fun members(target: ExternalTarget): List = emptyList() + override fun add(target: ExternalTarget, externalUserId: String) = Unit + override fun remove(target: ExternalTarget, externalUserId: String) = Unit + override fun create(label: String, folder: String?): ExternalTarget = error("not used") + override fun delete(target: ExternalTarget) = Unit + } } diff --git a/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortTargetingServiceTest.kt b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortTargetingServiceTest.kt index 61121a693..3cfb50e7c 100644 --- a/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortTargetingServiceTest.kt +++ b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/CohortTargetingServiceTest.kt @@ -3,8 +3,13 @@ package net.blueshell.api.platform.integration.cohort.application import net.blueshell.api.platform.integration.cohort.persistence.Cohort import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortRepository import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortSubjectRepository -import net.blueshell.api.platform.integration.cohort.port.out.CohortPort -import net.blueshell.api.platform.integration.cohort.port.out.CohortPortRegistry +import net.blueshell.api.platform.integration.cohort.persistence.CohortKind +import net.blueshell.api.platform.integration.cohort.persistence.CohortSubject +import net.blueshell.api.platform.integration.cohort.persistence.CohortSubjectType +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget +import net.blueshell.api.platform.integration.cohort.port.out.TargetCapability +import net.blueshell.api.platform.integration.cohort.port.out.TargetDescriptor +import net.blueshell.api.platform.integration.cohort.port.out.TargetStrategy import net.blueshell.api.shared.enums.TargetSystem import net.blueshell.api.shared.job.CohortJobs import net.blueshell.api.shared.job.NonRetryableJobException @@ -27,7 +32,7 @@ import org.springframework.web.server.ResponseStatusException import java.util.Optional /** - * Unit test for [CohortTargetingService]. The port edges (CohortPort, + * Unit test for [CohortTargetingService]. The strategy edges, * CohortTargetIds, job dispatcher) are the seams — no Spring context. * A no-op transaction manager runs the TransactionTemplate callbacks inline. */ @@ -36,9 +41,9 @@ class CohortTargetingServiceTest { private val cohortRepo = mock() private val subjectRepo = mock() private val targetIds = mock() - private val registry = mock() private val jobs = mock() - private val port = mock() + private val strategy = mock() + private val strategies: TargetStrategies private val txManager = object : PlatformTransactionManager { override fun getTransaction(definition: TransactionDefinition?): TransactionStatus = SimpleTransactionStatus() @@ -46,7 +51,15 @@ class CohortTargetingServiceTest { override fun rollback(status: TransactionStatus) {} } - private val service = CohortTargetingService(cohortRepo, subjectRepo, targetIds, registry, jobs, txManager) + private val service: CohortTargetingService + + init { + whenever(strategy.system).thenReturn(TargetSystem.BREVO) + whenever(strategy.descriptor).thenReturn(brevoDescriptor) + whenever(strategy.resolve(any())).thenReturn(null) + strategies = TargetStrategies(listOf(strategy)) + service = CohortTargetingService(cohortRepo, subjectRepo, targetIds, strategies, jobs, txManager) + } @Test fun `create does not touch the provider when the subject already maps the system`() { @@ -57,7 +70,7 @@ class CohortTargetingServiceTest { service.create(1L, TargetSystem.BREVO, "Members", null) } - verifyNoInteractions(registry) + verify(strategy, never()).create(any(), any()) verify(cohortRepo, never()).save(any()) } @@ -66,13 +79,12 @@ class CohortTargetingServiceTest { val saved = mock { on { id } doReturn 42L } whenever(subjectRepo.findById(1L)).thenReturn(Optional.of(mock())) whenever(cohortRepo.findBySubjectIdAndSystem(1L, "BREVO")).thenReturn(null) - whenever(registry.require(TargetSystem.BREVO)).thenReturn(port) - whenever(port.createCohort("Members", "Lists")).thenReturn("999") + whenever(strategy.create("Members", "Lists")).thenReturn(target("999", "Members", "Lists")) whenever(cohortRepo.save(any())).thenReturn(saved) val row = service.create(1L, TargetSystem.BREVO, "Members", "Lists") - verify(port).createCohort("Members", "Lists") + verify(strategy).create("Members", "Lists") verify(targetIds).record(saved, "999") assert(row.externalId == "999") } @@ -87,13 +99,12 @@ class CohortTargetingServiceTest { } whenever(cohortRepo.findById(7L)).thenReturn(Optional.of(cohort)) whenever(targetIds.find(cohort)).thenReturn(null) - whenever(registry.require(TargetSystem.BREVO)).thenReturn(port) assertThrows { service.materialize(7L) } - verify(port, never()).createCohort(any(), any()) + verify(strategy, never()).create(any(), any()) verify(targetIds, never()).record(any(), any()) } @@ -106,7 +117,7 @@ class CohortTargetingServiceTest { val ref = service.materialize(7L) assert(ref.externalId == "existing") - verifyNoInteractions(registry) + verify(strategy, never()).create(any(), any()) verify(targetIds, never()).record(any(), any()) } @@ -122,12 +133,28 @@ class CohortTargetingServiceTest { val row = service.linkExisting(1L, TargetSystem.BREVO, "list-123") + verify(strategy).resolve("list-123") verify(cohortRepo, never()).save(any()) verify(targetIds).record(cohort, "list-123") assert(row.cohort == cohort) assert(row.externalId == "list-123") } + @Test + fun `linkExisting allows ids that are not present in the catalog`() { + val subject = CohortSubject(CohortSubjectType.CUSTOM, "Members") + val saved = mock { on { id } doReturn 7L } + whenever(subjectRepo.findById(1L)).thenReturn(Optional.of(subject)) + whenever(cohortRepo.findBySubjectIdAndSystem(1L, "BREVO")).thenReturn(null) + whenever(cohortRepo.save(any())).thenReturn(saved) + whenever(strategy.resolve("missing-list")).thenReturn(null) + + service.linkExisting(1L, TargetSystem.BREVO, "missing-list") + + verify(strategy).resolve("missing-list") + verify(targetIds).record(saved, "missing-list") + } + @Test fun `switch enqueues delete-previous and reconcile when asked`() { val cohort = mock { on { system } doReturn "BREVO"; on { subjectId } doReturn 1L } @@ -136,6 +163,7 @@ class CohortTargetingServiceTest { service.switchTarget(1L, 7L, "new-list", deletePrevious = true, reconcileNow = true) + verify(strategy).resolve("new-list") verify(targetIds).record(cohort, "new-list") verify(jobs).enqueue( eq(CohortJobs.DeleteExternalTarget), @@ -173,10 +201,23 @@ class CohortTargetingServiceTest { @Test fun `deleteTarget calls the provider`() { - whenever(registry.require(TargetSystem.BREVO)).thenReturn(port) - service.deleteTarget(TargetSystem.BREVO, "stale-list") - verify(port).deleteCohort("stale-list") + verify(strategy).delete(target("stale-list", "stale-list", null)) + } + + private fun target(id: String, label: String, folder: String?) = + ExternalTarget(TargetSystem.BREVO, id, CohortKind.LIST, label, folder) + + private companion object { + val brevoDescriptor = TargetDescriptor( + system = TargetSystem.BREVO, + kind = CohortKind.LIST, + systemLabel = "Brevo", + targetLabel = "Brevo list", + idLabel = "List id", + folderLabel = "Folder", + capabilities = setOf(TargetCapability.CATALOG, TargetCapability.CREATE, TargetCapability.DELETE), + ) } } diff --git a/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/FactWritersTest.kt b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/FactWritersTest.kt new file mode 100644 index 000000000..d1fe94b38 --- /dev/null +++ b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/FactWritersTest.kt @@ -0,0 +1,52 @@ +package net.blueshell.api.platform.integration.cohort.application + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import net.blueshell.api.domain.contribution.application.ContributionService +import net.blueshell.api.platform.integration.cohort.persistence.CohortFactKind +import net.blueshell.api.platform.integration.cohort.port.`in`.CohortReconciliation +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class FactWritersTest { + private val facts: UserFactCollector = mockk() + private val contributions: ContributionService = mockk(relaxed = true) + private val reconciliation: CohortReconciliation = mockk(relaxed = true) + private val writer = ContributionPaidWriter(facts, contributions, reconciliation) + private val writers = FactWriters(listOf(writer)) + + @Test + fun `registry resolves contribution paid and misses unsupported kinds`() { + assertThat(writers.find(CohortFactKind.CONTRIBUTION_PAID)).isSameAs(writer) + assertThat(writers.find(CohortFactKind.NEWSLETTER)).isNull() + } + + @Test + fun `contribution preview reports already true without writing`() { + every { facts.collect(5L) } returns setOf(SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12").toUserFact()) + + val result = writer.preview(5L, SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12")) + + assertThat(result.alreadyTrue).isTrue() + verify(exactly = 0) { contributions.ensurePaid(any(), any()) } + verify(exactly = 0) { reconciliation.evaluateUserCohorts(any()) } + } + + @Test + fun `contribution apply creates once then noops once true`() { + every { facts.collect(5L) } returnsMany listOf( + emptySet(), + setOf(SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12").toUserFact()), + ) + every { contributions.ensurePaid(5L, 12L) } returns true + + val first = writer.apply(5L, SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12")) + val second = writer.apply(5L, SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12")) + + assertThat(first).isEqualTo(FactWriteStatus.WRITTEN) + assertThat(second).isEqualTo(FactWriteStatus.NOOP_ALREADY_TRUE) + verify(exactly = 1) { contributions.ensurePaid(5L, 12L) } + verify(exactly = 2) { reconciliation.evaluateUserCohorts(5L) } + } +} diff --git a/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/InboundReconcileTest.kt b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/InboundReconcileTest.kt new file mode 100644 index 000000000..991e861f0 --- /dev/null +++ b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/InboundReconcileTest.kt @@ -0,0 +1,321 @@ +package net.blueshell.api.platform.integration.cohort.application + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import net.blueshell.api.domain.user.application.UserService +import net.blueshell.api.domain.user.persistence.User +import net.blueshell.api.platform.integration.cohort.persistence.Cohort +import net.blueshell.api.platform.integration.cohort.persistence.CohortFactKind +import net.blueshell.api.platform.integration.cohort.persistence.CohortKind +import net.blueshell.api.platform.integration.cohort.persistence.CohortMember +import net.blueshell.api.platform.integration.cohort.persistence.CohortSubject +import net.blueshell.api.platform.integration.cohort.persistence.CohortSubjectType +import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortMemberRepository +import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortRepository +import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortSubjectRepository +import net.blueshell.api.platform.integration.cohort.port.out.ExternalMember +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget +import net.blueshell.api.platform.integration.cohort.port.out.TargetCapability +import net.blueshell.api.platform.integration.cohort.port.out.TargetDescriptor +import net.blueshell.api.platform.integration.cohort.port.out.TargetStrategy +import net.blueshell.api.platform.integration.sync.application.ExternalIdMappingService +import net.blueshell.api.platform.integration.sync.persistence.ExternalIdMapping +import net.blueshell.api.shared.enums.TargetSystem +import net.blueshell.api.shared.job.CohortJobs +import net.blueshell.api.shared.job.JobExecution +import net.blueshell.api.shared.job.TrackedJobDispatcher +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test +import org.springframework.http.HttpStatus +import org.springframework.transaction.TransactionDefinition +import org.springframework.transaction.support.AbstractPlatformTransactionManager +import org.springframework.transaction.support.DefaultTransactionStatus +import org.springframework.transaction.support.TransactionSynchronizationManager +import org.springframework.web.server.ResponseStatusException +import java.util.Optional + +class InboundReconcileTest { + private val subjects: CohortSubjectRepository = mockk() + private val cohorts: CohortRepository = mockk() + private val members: CohortMemberRepository = mockk() + private val externalIds: ExternalIdMappingService = mockk(relaxed = true) + private val users: UserService = mockk() + private val writers: FactWriters = mockk() + private val contributionWriter: FactWriter = mockk() + private val jobs: TrackedJobDispatcher = mockk(relaxed = true) + private val strategy = RecordingTargetStrategy() + private val service = InboundReconcile( + subjects = subjects, + cohorts = cohorts, + members = members, + externalIds = externalIds, + users = users, + writers = writers, + jobs = jobs, + strategies = TargetStrategies(listOf(strategy)), + transactionManager = ImmediateTransactionManager(), + ) + + @Test + fun `preview is write-free external-id only and classifies duplicate conflict inactive and unmatched`() { + val target = givenContributionTarget() + val desired = CohortMember(target.cohort, userId = 9L, subject = target.subject) + strategy.remote = listOf( + ExternalMember("ext-internal", "Already internal"), + ExternalMember("ext-1", "Mapped One"), + ExternalMember("ext-dup", "Duplicate A"), + ExternalMember("ext-dup", "Duplicate B"), + ExternalMember("ext-conflict", "Conflict"), + ExternalMember("ext-missing", "Missing"), + ExternalMember("ext-inactive", "Inactive"), + ) + every { members.findAllByCohortIdAndUserIdIsNotNull(20L) } returns listOf(desired) + every { externalIds.findBatch("USER", setOf(9L), TargetSystem.BREVO.name) } returns listOf( + ExternalIdMapping("USER", 9L, TargetSystem.BREVO.name, "ext-internal"), + ) + every { externalIds.findByExternalIds("USER", TargetSystem.BREVO.name, any()) } returns listOf( + ExternalIdMapping("USER", 1L, TargetSystem.BREVO.name, "ext-1"), + ExternalIdMapping("USER", 2L, TargetSystem.BREVO.name, "ext-conflict"), + ExternalIdMapping("USER", 3L, TargetSystem.BREVO.name, "ext-conflict"), + ExternalIdMapping("USER", 4L, TargetSystem.BREVO.name, "ext-inactive"), + ) + every { users.findAllByIds(setOf(1L, 2L, 3L, 4L)) } returns listOf(user(1L, "mapped@example.org")) + every { writers.find(CohortFactKind.CONTRIBUTION_PAID) } returns contributionWriter + every { contributionWriter.preview(1L, SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12")) } returns + FactPreview(alreadyTrue = false) + + val preview = service.preview(10L, 20L) + + assertThat(strategy.listCalls).isEqualTo(1) + assertThat(strategy.sawTransactionDuringMembers).isFalse() + assertThat(preview.writerSupported).isTrue() + assertThat(preview.matched).extracting { it.userId }.containsExactly(1L) + assertThat(preview.matched.single().writable).isTrue() + assertThat(preview.skipped).extracting { it.reason } + .containsExactlyInAnyOrder( + InboundReconcileSkipReason.DUPLICATE_REMOTE_ID, + InboundReconcileSkipReason.MAPPING_CONFLICT, + InboundReconcileSkipReason.UNMATCHED, + InboundReconcileSkipReason.MAPPED_USER_INACTIVE, + ) + assertThat(preview.matched.map { it.externalUserId }).doesNotContain("ext-internal") + verify(exactly = 0) { externalIds.linkUser(any(), any(), any()) } + verify(exactly = 0) { contributionWriter.apply(any(), any()) } + verify(exactly = 0) { jobs.enqueue(CohortJobs.ApplyInboundReconcile, any()) } + } + + @Test + fun `preview returns disabled writable rows when fact kind has no writer`() { + givenNewsletterTarget() + strategy.remote = listOf(ExternalMember("ext-1", "Mapped One")) + every { members.findAllByCohortIdAndUserIdIsNotNull(20L) } returns emptyList() + every { externalIds.findBatch("USER", emptySet(), TargetSystem.BREVO.name) } returns emptyList() + every { externalIds.findByExternalIds("USER", TargetSystem.BREVO.name, listOf("ext-1")) } returns listOf( + ExternalIdMapping("USER", 1L, TargetSystem.BREVO.name, "ext-1"), + ) + every { users.findAllByIds(setOf(1L)) } returns listOf(user(1L, "mapped@example.org")) + every { writers.find(CohortFactKind.NEWSLETTER) } returns null + + val preview = service.preview(10L, 20L) + + assertThat(preview.writerSupported).isFalse() + assertThat(preview.matched.single().writable).isFalse() + assertThat(preview.matched.single().alreadyTrue).isFalse() + } + + @Test + fun `apply rejects stale preview token before enqueueing`() { + givenContributionTarget() + strategy.remote = listOf(ExternalMember("ext-1", "Mapped One")) + every { members.findAllByCohortIdAndUserIdIsNotNull(20L) } returns emptyList() + every { externalIds.findBatch("USER", emptySet(), TargetSystem.BREVO.name) } returns emptyList() + every { externalIds.findByExternalIds("USER", TargetSystem.BREVO.name, any()) } returns listOf( + ExternalIdMapping("USER", 1L, TargetSystem.BREVO.name, "ext-1"), + ) + every { users.findAllByIds(setOf(1L)) } returns listOf(user(1L, "mapped@example.org")) + every { writers.find(CohortFactKind.CONTRIBUTION_PAID) } returns contributionWriter + every { contributionWriter.preview(1L, SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12")) } returns + FactPreview(alreadyTrue = false) + + val preview = service.preview(10L, 20L) + strategy.remote = listOf(ExternalMember("ext-other", "Changed")) + every { externalIds.findByExternalIds("USER", TargetSystem.BREVO.name, any()) } returns emptyList() + every { users.findAllByIds(emptySet()) } returns emptyList() + + assertThatThrownBy { + service.apply(10L, 20L, InboundReconcileApplyRequest(preview.previewToken, listOf("ext-1"))) + }.isInstanceOf(ResponseStatusException::class.java) + .extracting("statusCode") + .isEqualTo(HttpStatus.CONFLICT) + verify(exactly = 0) { jobs.enqueue(CohortJobs.ApplyInboundReconcile, any()) } + } + + @Test + fun `apply enqueues selected matched users without linking external ids`() { + givenContributionTarget() + strategy.remote = listOf(ExternalMember("ext-1", "Mapped One"), ExternalMember("ext-2", "Mapped Two")) + every { members.findAllByCohortIdAndUserIdIsNotNull(20L) } returns emptyList() + every { externalIds.findBatch("USER", emptySet(), TargetSystem.BREVO.name) } returns emptyList() + every { externalIds.findByExternalIds("USER", TargetSystem.BREVO.name, any()) } returns listOf( + ExternalIdMapping("USER", 1L, TargetSystem.BREVO.name, "ext-1"), + ExternalIdMapping("USER", 2L, TargetSystem.BREVO.name, "ext-2"), + ) + every { users.findAllByIds(setOf(1L, 2L)) } returns listOf( + user(1L, "one@example.org"), + user(2L, "two@example.org"), + ) + every { writers.find(CohortFactKind.CONTRIBUTION_PAID) } returns contributionWriter + every { contributionWriter.preview(any(), SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12")) } returns + FactPreview(alreadyTrue = false) + every { jobs.enqueue(CohortJobs.ApplyInboundReconcile, any()) } returns + TestJobExecution(55L) + + val preview = service.preview(10L, 20L) + val result = service.apply(10L, 20L, InboundReconcileApplyRequest(preview.previewToken, listOf("ext-2"))) + + assertThat(result.jobId).isEqualTo(55L) + assertThat(result.acceptedCount).isEqualTo(1) + assertThat(result.skippedCount).isEqualTo(1) + verify { + jobs.enqueue( + CohortJobs.ApplyInboundReconcile, + match { + it.subjectId == 10L && + it.cohortId == 20L && + it.system == TargetSystem.BREVO.name && + it.externalTargetId == "list-20" && + it.factKind == CohortFactKind.CONTRIBUTION_PAID.name && + it.factKey == "12" && + it.selected == listOf(CohortJobs.InboundReconcileSelectedUser("ext-2", 2L)) + }, + ) + } + verify(exactly = 0) { externalIds.linkUser(any(), any(), any()) } + } + + @Test + fun `apply job revalidates mapping and writes fact in its own transaction`() { + val target = givenContributionTarget() + every { externalIds.findByExternalIds("USER", TargetSystem.BREVO.name, listOf("ext-1")) } returns listOf( + ExternalIdMapping("USER", 1L, TargetSystem.BREVO.name, "ext-1"), + ) + every { writers.find(CohortFactKind.CONTRIBUTION_PAID) } returns contributionWriter + every { contributionWriter.apply(1L, SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12")) } returns + FactWriteStatus.WRITTEN + + val result = service.applyJob( + CohortJobs.ApplyInboundReconcilePayload( + subjectId = target.subject.id!!, + cohortId = target.cohort.id!!, + system = TargetSystem.BREVO.name, + externalTargetId = "list-20", + factKind = CohortFactKind.CONTRIBUTION_PAID.name, + factKey = "12", + selected = listOf(CohortJobs.InboundReconcileSelectedUser("ext-1", 1L)), + ), + ) + + assertThat(result).containsExactly(ApplyInboundReconcileItemResult("ext-1", 1L, FactWriteStatus.WRITTEN)) + verify(exactly = 1) { contributionWriter.apply(1L, SubjectFact(CohortFactKind.CONTRIBUTION_PAID, "12")) } + verify(exactly = 0) { externalIds.linkUser(any(), any(), any()) } + } + + @Test + fun `apply job reports unsupported fact kinds without writing`() { + val target = givenNewsletterTarget() + every { externalIds.findByExternalIds("USER", TargetSystem.BREVO.name, listOf("ext-1")) } returns listOf( + ExternalIdMapping("USER", 1L, TargetSystem.BREVO.name, "ext-1"), + ) + every { writers.find(CohortFactKind.NEWSLETTER) } returns null + + val result = service.applyJob( + CohortJobs.ApplyInboundReconcilePayload( + subjectId = target.subject.id!!, + cohortId = target.cohort.id!!, + system = TargetSystem.BREVO.name, + externalTargetId = "list-20", + factKind = CohortFactKind.NEWSLETTER.name, + factKey = "true", + selected = listOf(CohortJobs.InboundReconcileSelectedUser("ext-1", 1L)), + ), + ) + + assertThat(result).containsExactly(ApplyInboundReconcileItemResult("ext-1", 1L, FactWriteStatus.UNSUPPORTED)) + verify(exactly = 0) { contributionWriter.apply(any(), any()) } + verify(exactly = 0) { externalIds.linkUser(any(), any(), any()) } + } + + private fun givenContributionTarget() = givenTarget(CohortFactKind.CONTRIBUTION_PAID, "12") + + private fun givenNewsletterTarget() = givenTarget(CohortFactKind.NEWSLETTER, "true") + + private fun givenTarget(kind: CohortFactKind, key: String): TargetFixture { + val subject = CohortSubject( + type = if (kind == CohortFactKind.NEWSLETTER) CohortSubjectType.NEWSLETTER_SUBSCRIBERS else CohortSubjectType.PERIOD_PAYERS, + label = "Subject", + factKind = kind, + factKey = key, + enabled = true, + ).apply { id = 10L } + val cohort = Cohort( + system = TargetSystem.BREVO.name, + kind = CohortKind.LIST, + label = "Subject", + subjectId = 10L, + externalId = "list-20", + ).apply { id = 20L } + every { subjects.findById(10L) } returns Optional.of(subject) + every { cohorts.findById(20L) } returns Optional.of(cohort) + return TargetFixture(subject, cohort) + } + + private fun user(id: Long, email: String): User { + val user = mockk() + every { user.id } returns id + every { user.fullName } returns "User $id" + every { user.email } returns email + return user + } + + private class RecordingTargetStrategy : TargetStrategy { + override val descriptor = TargetDescriptor( + system = TargetSystem.BREVO, + kind = CohortKind.LIST, + systemLabel = "Brevo", + targetLabel = "Brevo list", + idLabel = "List id", + capabilities = setOf(TargetCapability.READ_MEMBERS), + ) + var remote: List = emptyList() + var listCalls = 0 + var sawTransactionDuringMembers = false + + override fun members(target: ExternalTarget): List { + listCalls += 1 + sawTransactionDuringMembers = TransactionSynchronizationManager.isActualTransactionActive() + return remote + } + + override fun add(target: ExternalTarget, externalUserId: String) = error("not used") + override fun remove(target: ExternalTarget, externalUserId: String) = error("not used") + override fun create(label: String, folder: String?): ExternalTarget = error("not used") + override fun delete(target: ExternalTarget) = error("not used") + } + + private class ImmediateTransactionManager : AbstractPlatformTransactionManager() { + override fun doGetTransaction(): Any = Any() + override fun doBegin(transaction: Any, definition: TransactionDefinition) = Unit + override fun doCommit(status: DefaultTransactionStatus) = Unit + override fun doRollback(status: DefaultTransactionStatus) = Unit + } + + private data class TargetFixture(val subject: CohortSubject, val cohort: Cohort) + + private data class TestJobExecution(override val id: Long?) : JobExecution { + override val jobType: String = "test" + override val payload: String? = null + override val actor = net.blueshell.api.shared.tracking.Actor.system() + } +} diff --git a/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/TargetCatalogTest.kt b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/TargetCatalogTest.kt new file mode 100644 index 000000000..c9c9101b9 --- /dev/null +++ b/services/api/src/test/kotlin/net/blueshell/api/platform/integration/cohort/application/TargetCatalogTest.kt @@ -0,0 +1,68 @@ +package net.blueshell.api.platform.integration.cohort.application + +import net.blueshell.api.platform.integration.cohort.persistence.Cohort +import net.blueshell.api.platform.integration.cohort.persistence.CohortKind +import net.blueshell.api.platform.integration.cohort.persistence.repository.CohortRepository +import net.blueshell.api.platform.integration.cohort.port.out.ExternalMember +import net.blueshell.api.platform.integration.cohort.port.out.ExternalTarget +import net.blueshell.api.platform.integration.cohort.port.out.TargetCapability +import net.blueshell.api.platform.integration.cohort.port.out.TargetDescriptor +import net.blueshell.api.platform.integration.cohort.port.out.TargetStrategy +import net.blueshell.api.shared.enums.TargetSystem +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class TargetCatalogTest { + private val cohorts: CohortRepository = mock() + private val strategy = RecordingStrategy() + private val catalog = TargetCatalog(TargetStrategies(listOf(strategy)), cohorts) + + @Test + fun `descriptors come from registered target strategies`() { + assertThat(catalog.descriptors()).containsExactly(strategy.descriptor) + } + + @Test + fun `search annotates linked cohort ids from active mappings`() { + val linked = Cohort("BREVO", CohortKind.LIST, "Members").apply { + id = 42L + externalId = "2" + } + whenever(cohorts.findAllBySystem("BREVO")).thenReturn(listOf(linked)) + + val results = catalog.search(TargetSystem.BREVO, "members") + + assertThat(strategy.queries).containsExactly("members") + assertThat(results).extracting { it.linkedCohortId }.containsExactly(null, 42L) + } + + private class RecordingStrategy : TargetStrategy { + val queries = mutableListOf() + + override val descriptor = TargetDescriptor( + system = TargetSystem.BREVO, + kind = CohortKind.LIST, + systemLabel = "Brevo", + targetLabel = "Brevo list", + idLabel = "List id", + folderLabel = "Folder", + capabilities = setOf(TargetCapability.CATALOG), + ) + + override fun catalog(query: String?): List { + queries += query + return listOf(target("1", "Guests"), target("2", "Members")) + } + + override fun members(target: ExternalTarget): List = emptyList() + override fun add(target: ExternalTarget, externalUserId: String) = Unit + override fun remove(target: ExternalTarget, externalUserId: String) = Unit + override fun create(label: String, folder: String?): ExternalTarget = error("not used") + override fun delete(target: ExternalTarget) = Unit + + private fun target(id: String, label: String) = + ExternalTarget(TargetSystem.BREVO, id, CohortKind.LIST, label) + } +} diff --git a/services/frontend/src/domains/cohorts/adapters/cohorts.ts b/services/frontend/src/domains/cohorts/adapters/cohorts.ts index 93313c486..ea214c2e2 100644 --- a/services/frontend/src/domains/cohorts/adapters/cohorts.ts +++ b/services/frontend/src/domains/cohorts/adapters/cohorts.ts @@ -4,17 +4,25 @@ * from this module or from ../types. */ import { + applyInboundReconcile, createTarget, enqueue, getDrift, linkExistingTarget, linkUser, + listCohortTargetSystems, + previewInboundReconcile, + searchCohortTargets, switchTarget, } from "@/services/api" import type { CohortMapping as ApiCohortMapping, DriftReport as ApiDriftReport, + ExternalTarget as ApiExternalTarget, ExtraRow as ApiExtraRow, + InboundReconcileApplyResponse as ApiInboundReconcileApplyResponse, + InboundReconcilePreview as ApiInboundReconcilePreview, + TargetDescriptor as ApiTargetDescriptor, } from "@/services/api" export type TargetSystem = ApiDriftReport["system"] @@ -133,6 +141,31 @@ export type TargetMapping = { export type AddTargetResult = { type: "ok"; mapping: TargetMapping } | { type: "conflict" } +export type TargetCapability = ApiTargetDescriptor["capabilities"][number] + +export type TargetDescriptor = { + system: TargetSystem + kind: ApiTargetDescriptor["kind"] + systemLabel: string + targetLabel: string + idLabel: string + folderLabel: string | null + capabilities: TargetCapability[] +} + +export type ExternalTarget = { + system: TargetSystem + externalId: string + kind: ApiExternalTarget["kind"] + label: string + folderLabel: string | null + memberCount: number | null + linkedCohortId: number | null +} + +export type InboundReconcilePreview = ApiInboundReconcilePreview +export type InboundReconcileApplyResponse = ApiInboundReconcileApplyResponse + function toTargetMapping(raw: ApiCohortMapping): TargetMapping { return { cohortId: raw.cohortId, @@ -193,3 +226,58 @@ export async function switchCohortTarget( }) return toTargetMapping(res.data!) } + +export async function fetchTargetDescriptors(): Promise { + const res = await listCohortTargetSystems() + return (res.data ?? []).map(toTargetDescriptor) +} + +export async function fetchTargetOptions(system: TargetSystem): Promise { + const res = await searchCohortTargets({ path: { system } }) + return (res.data ?? []).map(toExternalTarget) +} + +function toTargetDescriptor(raw: ApiTargetDescriptor): TargetDescriptor { + return { + system: raw.system, + kind: raw.kind, + systemLabel: raw.systemLabel, + targetLabel: raw.targetLabel, + idLabel: raw.idLabel, + folderLabel: raw.folderLabel ?? null, + capabilities: [...raw.capabilities], + } +} + +function toExternalTarget(raw: ApiExternalTarget): ExternalTarget { + return { + system: raw.system, + externalId: raw.externalId, + kind: raw.kind, + label: raw.label, + folderLabel: raw.folderLabel ?? null, + memberCount: raw.memberCount ?? null, + linkedCohortId: raw.linkedCohortId ?? null, + } +} + +export async function fetchInboundReconcilePreview( + subjectId: number, + cohortId: number, +): Promise { + const res = await previewInboundReconcile({ path: { id: subjectId, cohortId } }) + return res.data! as InboundReconcilePreview +} + +export async function applyInboundReconcileSelection( + subjectId: number, + cohortId: number, + previewToken: string, + selectedExternalUserIds: string[], +): Promise { + const res = await applyInboundReconcile({ + path: { id: subjectId, cohortId }, + body: { previewToken, selectedExternalUserIds }, + }) + return res.data! +} diff --git a/services/frontend/src/domains/cohorts/components/InboundReconcileModal.vue b/services/frontend/src/domains/cohorts/components/InboundReconcileModal.vue new file mode 100644 index 000000000..58f153221 --- /dev/null +++ b/services/frontend/src/domains/cohorts/components/InboundReconcileModal.vue @@ -0,0 +1,222 @@ + + + + + diff --git a/services/frontend/src/domains/cohorts/components/TargetPickerModal.vue b/services/frontend/src/domains/cohorts/components/TargetPickerModal.vue index 6071b993a..b2241145e 100644 --- a/services/frontend/src/domains/cohorts/components/TargetPickerModal.vue +++ b/services/frontend/src/domains/cohorts/components/TargetPickerModal.vue @@ -1,5 +1,5 @@