diff --git a/.editorconfig b/.editorconfig index 783c31927..179ea6900 100644 --- a/.editorconfig +++ b/.editorconfig @@ -165,3 +165,14 @@ dotnet_diagnostic.S1118.severity = none [*.{yml,yaml}] indent_size = 2 end_of_line = lf + +# Verify settings +# https://github.com/VerifyTests/Verify?tab=readme-ov-file#editorconfig-settings +[*.{received,verified}.{json,txt,xml}] +charset = "utf-8-bom" +end_of_line = lf +indent_size = unset +indent_style = unset +insert_final_newline = false +tab_width = unset +trim_trailing_whitespace = false diff --git a/src/Altinn.App.Api/Altinn.App.Api.csproj b/src/Altinn.App.Api/Altinn.App.Api.csproj index abbf2b29e..a465a7110 100644 --- a/src/Altinn.App.Api/Altinn.App.Api.csproj +++ b/src/Altinn.App.Api/Altinn.App.Api.csproj @@ -25,6 +25,7 @@ + diff --git a/src/Altinn.App.Api/Controllers/CustomOpenApiController.cs b/src/Altinn.App.Api/Controllers/CustomOpenApiController.cs new file mode 100644 index 000000000..cfc046cfa --- /dev/null +++ b/src/Altinn.App.Api/Controllers/CustomOpenApiController.cs @@ -0,0 +1,1142 @@ +namespace Altinn.App.Api.Controllers; + +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using Altinn.App.Api.Models; +using Altinn.App.Core.Internal.App; +using Altinn.App.Core.Internal.AppModel; +using Altinn.App.Core.Models; +using Altinn.Platform.Storage.Interface.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Microsoft.OpenApi; +using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Extensions; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Services; +using Swashbuckle.AspNetCore.SwaggerGen; +using DataType = Altinn.Platform.Storage.Interface.Models.DataType; + +/// +/// Generate custom OpenAPI documentation for the app that includes all the data types and operations +/// +[ApiController] +[ApiExplorerSettings(IgnoreApi = true)] +public class CustomOpenApiController : Controller +{ + private readonly IAppMetadata _appMetadata; + private readonly IAppModel _appModel; + private readonly SchemaGenerator _schemaGenerator; + private readonly SchemaRepository _schemaRepository; + + /// + /// Constructor with services from dependency injection + /// + public CustomOpenApiController( + IAppModel appModel, + IAppMetadata appMetadata, + ISerializerDataContractResolver dataContractResolver, + IOptions mvcOptions + ) + { + _appModel = appModel; + _appMetadata = appMetadata; + _schemaGenerator = new SchemaGenerator(new SchemaGeneratorOptions(), dataContractResolver, mvcOptions); + _schemaRepository = new SchemaRepository(); + } + + /// + /// Generate the custom OpenAPI documentation for the app + /// + [HttpGet("/{org}/{app}/v1/customOpenapi.json")] + public async Task Index() + { + var appMetadata = await _appMetadata.GetApplicationMetadata(); + var document = new OpenApiDocument() + { + Info = new() + { + Title = + "Altinn 3 App API for " + + ( + appMetadata.Title.TryGetValue("en", out var englishTitle) ? englishTitle + : appMetadata.Title.TryGetValue("nb", out var norwegianTitle) ? norwegianTitle + : "Unknown" + ), + Contact = new() + { + Name = "Digitaliseringsdirektoratet (altinn)", + Url = new("https://altinn.slack.com"), + }, + Version = appMetadata.AltinnNugetVersion, + Description = GetIntroDoc(appMetadata), + }, + ExternalDocs = new() { Description = "Altinn 3 Documentation", Url = new("https://docs.altinn.studio") }, + Paths = [], // Add to this later + Components = new OpenApiComponents() + { + Schemas = _schemaRepository.Schemas, + SecuritySchemes = { ["AltinnToken"] = Snippets.AltinnTokenSecurityScheme }, + Responses = { ["ProblemDetails"] = Snippets.ProblemDetailsResponseSchema }, + Parameters = Snippets.ComponentParameters, + }, + SecurityRequirements = [new OpenApiSecurityRequirement() { [Snippets.AltinnTokenSecurityScheme] = [] }], + Servers = + { + new OpenApiServer() { Url = $"http://local.altinn.cloud", Description = "Local development server" }, + new OpenApiServer() + { + Url = $"https://{appMetadata.Org}.apps.tt02.altinn.no", + Description = "TT02 server", + }, + new OpenApiServer() + { + Url = $"https://{appMetadata.Org}.apps.altinn.no", + Description = "Production server", + }, + }, + }; + + AddCommonRoutes(document, appMetadata); + + foreach (var dataType in appMetadata.DataTypes) + { + AddRoutsForDataType(document, appMetadata, dataType); + } + + // Fix issues in the schemas + var walker = new OpenApiWalker(new SchemaPostVisitor()); + walker.Walk(document); + + return Ok(document.Serialize(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json)); + } + + private static string GetIntroDoc(ApplicationMetadata appMetadata) + { + StringBuilder sb = new(); + sb.AppendLine("This is the API for an Altinn 3 app. The API is based on the OpenAPI 3.0 specification."); + sb.AppendLine("This app has the following data types:"); + sb.AppendLine("| DataTypeId | Type | Allowed number | MimeTypes | TaskId |"); + sb.AppendLine("|------------|------|----------------|-----------|--------|"); + foreach (var dataType in appMetadata.DataTypes) + { + sb.Append('|'); + sb.Append(dataType.Id); + sb.Append('|'); + if (dataType.AppLogic?.ClassRef is null) + { + sb.Append("Attachment"); + } + else + { + sb.Append("FormData"); + if (dataType.AppLogic?.AutoCreate == true) + { + sb.Append(" (AutoCreate)"); + } + } + sb.Append('|'); + if (dataType.MaxCount == dataType.MinCount) + { + if (dataType.MaxCount == 0) + { + sb.Append('-'); + } + else + { + sb.Append(dataType.MaxCount); + } + } + else if (dataType.MaxCount > 0 && dataType.MinCount > 0) + { + sb.Append(CultureInfo.InvariantCulture, $"{dataType.MinCount}-{dataType.MaxCount}"); + } + else if (dataType.MaxCount > 0) + { + sb.Append(CultureInfo.InvariantCulture, $"0-{dataType.MaxCount}"); + } + else if (dataType.MinCount > 0) + { + sb.Append(CultureInfo.InvariantCulture, $"{dataType.MinCount}-∞"); + } + else + { + sb.Append('-'); + } + sb.Append('|'); + if (dataType.AllowedContentTypes is not null) + { + sb.Append(string.Join(", ", dataType.AllowedContentTypes)); + } + else + { + sb.Append('*'); + } + sb.Append('|'); + sb.Append(dataType.TaskId); + sb.Append('|'); + sb.AppendLine(); + } + return sb.ToString(); + } + + private void AddCommonRoutes(OpenApiDocument document, ApplicationMetadata appMetadata) + { + OpenApiTag[] instanceTags = [new() { Name = "Instances", Description = "Operations on instances" }]; + var instanceSchema = _schemaGenerator.GenerateSchema(typeof(Instance), _schemaRepository); + document.Components.Schemas.Add("InstanceWrite", Snippets.InstanceWriteSchema); + var instanceWriteSchema = new OpenApiSchema() + { + Reference = new OpenApiReference() { Id = "InstanceWrite", Type = ReferenceType.Schema }, + }; + + OpenApiMediaType multipartMediaType = new OpenApiMediaType() + { + Schema = new OpenApiSchema() { Type = "object", Properties = { ["instance"] = instanceWriteSchema } }, + Encoding = { ["instance"] = new OpenApiEncoding() { ContentType = "application/json" } }, + }; + foreach (var dataType in appMetadata.DataTypes) + { + multipartMediaType.Schema.Properties.Add( + dataType.Id, + new OpenApiSchema() { Type = "string", Format = "binary" } + ); + multipartMediaType.Encoding.Add( + dataType.Id, + new OpenApiEncoding() + { + ContentType = dataType.AllowedContentTypes is [.. var contentTypes] + ? string.Join(' ', contentTypes) + : "application/octet-stream", + } + ); + } + document.Paths.Add( + $"/{appMetadata.Id}/instances", + new OpenApiPathItem() + { + Summary = "Operations for instances", + Description = "CRUD operations for instances", + Servers = [new OpenApiServer() { Url = $"/{appMetadata.Id}" }], + Operations = + { + [OperationType.Post] = new OpenApiOperation() + { + Tags = instanceTags, + Summary = "Create new instance", + Description = "The main api for creating new instances. ", + Parameters = + { + new OpenApiParameter(Snippets.InstanceOwnerPartyIdParameterReference) + { + // Use snippet, but override + Description = + "The party id of the instance owner (use either this or an instance document in the body)", + In = ParameterLocation.Query, + Required = false, + }, + Snippets.LanguageParameterReference, + }, + RequestBody = new OpenApiRequestBody() + { + Required = false, + Description = """ + Instance document, formData and attachments + + Any mime type that is not ``"application/json"`` or ``"multipart/form-data"`` with an instance document + will require the ``instanceOwnerPartyId`` parameter. Otherwise you must use the simplified instance document to specify instance owner. + Either using ``instanceOwner.partyId`` or ``instanceOwner.personNumber`` or ``instanceOwner.organisationNumber`` (or ``instanceOwner.username`` see [app-lib-dotnet/#652](https://github.com/Altinn/app-lib-dotnet/issues/652)). + """, + Content = + { + ["empty"] = new OpenApiMediaType() + { + Schema = new OpenApiSchema() { Type = "", Example = new OpenApiString("") }, + }, + ["application/json"] = new OpenApiMediaType() { Schema = instanceWriteSchema }, + ["multipart/form-data"] = multipartMediaType, + }, + }, + Responses = Snippets.AddCommonErrorResponses( + HttpStatusCode.Created, + new OpenApiResponse() + { + Description = "Instance created", + Content = { ["application/json"] = new OpenApiMediaType() { Schema = instanceSchema } }, + } + ), + }, + }, + } + ); + document.Paths.Add( + $"/{appMetadata.Id}/instances/{{instanceOwnerPartyId}}/{{instanceGuid}}", + new OpenApiPathItem() + { + Summary = "Operations for instance", + Description = "CRUD operations for a specific instance", + Operations = + { + [OperationType.Get] = new OpenApiOperation() + { + Tags = instanceTags, + OperationId = "GetInstance", + Summary = "Get instance", + Description = "Get a specific instance", + Responses = new() + { + ["200"] = new OpenApiResponse() + { + Description = "Instance found", + Content = { ["application/json"] = new OpenApiMediaType() { Schema = instanceSchema } }, + }, + ["404"] = new OpenApiResponse() { Description = "Instance not found" }, + }, + }, + [OperationType.Delete] = new OpenApiOperation() + { + Tags = instanceTags, + Summary = "Delete instance", + Description = "Delete a specific instance", + Responses = new() + { + ["204"] = new OpenApiResponse() { Description = "Instance deleted" }, + ["404"] = new OpenApiResponse() { Description = "Instance not found" }, + }, + }, + [OperationType.Patch] = new OpenApiOperation() + { + Tags = instanceTags, + Summary = "Patch data elements on instance", + RequestBody = new OpenApiRequestBody() + { + Required = true, + Content = + { + ["application/json"] = new OpenApiMediaType() + { + Schema = Snippets.PatchSchema, + // Schema = _schemaGenerator.GenerateSchema( + // typeof(DataPatchRequestMultiple), + // _schemaRepository + // ), + }, + }, + }, + Responses = new() + { + ["200"] = new OpenApiResponse() + { + Description = "Data elements patched", + Content = + { + ["application/json"] = new OpenApiMediaType() + { + Schema = _schemaGenerator.GenerateSchema( + typeof(DataPatchResponseMultiple), + _schemaRepository + ), + }, + }, + }, + ["404"] = new OpenApiResponse() { Description = "Instance not found" }, + }, + }, + }, + Parameters = + [ + Snippets.InstanceOwnerPartyIdParameterReference, + Snippets.InstanceGuidParameterReference, + Snippets.LanguageParameterReference, + ], + } + ); + + document.Paths.Add( + $"/{appMetadata.Id}/instances/{{instanceOwnerPartyId}}/{{instanceGuid}}/data/{{dataGuid}}", + new OpenApiPathItem() + { + Summary = $"Delete data element", + Operations = + { + [OperationType.Delete] = new OpenApiOperation() + { + Tags = instanceTags, + Summary = "Delete data element", + Description = "Delete data for a specific data element", + Responses = new() + { + ["204"] = new OpenApiResponse() { Description = "Data deleted" }, + ["404"] = new OpenApiResponse() { Description = "Data not found" }, + }, + }, + }, + Parameters = + [ + Snippets.InstanceOwnerPartyIdParameterReference, + Snippets.InstanceGuidParameterReference, + Snippets.DataGuidParameterReference, + ], + } + ); + + var commonTags = new[] + { + new OpenApiTag() { Name = "Static", Description = "Static info about the application" }, + }; + + document.Paths.Add( + $"/{appMetadata.Id}/api/v1/applicationmetadata", + new OpenApiPathItem() + { + Summary = "Get application metadata", + Description = "Get the metadata for the application", + Operations = + { + [OperationType.Get] = new OpenApiOperation() + { + Tags = commonTags, + Summary = "Get application metadata", + Description = "Get the metadata for the application", + Security = { }, + Responses = new() + { + ["200"] = new OpenApiResponse() + { + Description = "Application metadata found", + Content = + { + ["application/json"] = new OpenApiMediaType() + { + Schema = _schemaGenerator.GenerateSchema( + typeof(ApplicationMetadata), + _schemaRepository + ), + }, + }, + }, + }, + }, + }, + } + ); + // Auth exchange endpoint + var authTags = new[] + { + new OpenApiTag() + { + Name = "Authentication", + Description = "Operations for exchanging maskinporten or idporten tokens to altinn tokens", + }, + }; + document.Paths.Add( + "/authentication/api/v1/exchange/{tokenProvider}", + new OpenApiPathItem() + { + Operations = + { + [OperationType.Get] = new OpenApiOperation() + { + Tags = authTags, + Summary = + "Action for exchanging a JWT generated by a trusted token provider with a new JWT for further use as authentication against rest of Altinn.", + Parameters = + { + new OpenApiParameter() + { + Name = "tokenProvider", + In = ParameterLocation.Path, + Required = true, + Schema = new OpenApiSchema() + { + Type = "string", + Enum = [new OpenApiString("maskinporten"), new OpenApiString("id-porten")], + }, + }, + new OpenApiParameter() + { + Name = "Autorization", + Description = + "Bearer token from the selected token provider to exchange for an altinn token", + In = ParameterLocation.Header, + Example = new OpenApiString("Bearer "), + Required = true, + Schema = new OpenApiSchema() { Type = "string" }, + }, + // Test parameter is not relevant for external users? + // new OpenApiParameter() + // { + // Name = "test", + // In = ParameterLocation.Query, + // Schema = new OpenApiSchema() + // { + // Type = "boolean" + // } + // } + }, + Responses = new OpenApiResponses() + { + ["200"] = new OpenApiResponse() + { + Description = "Exchanged token", + Content = + { + ["text/plain"] = new OpenApiMediaType() + { + Schema = new OpenApiSchema() + { + Type = "string", + Example = new OpenApiString( + "eyJraWQiOiJIdFlaMU1UbFZXUGNCV0JQVWV3TmxZd1RCRklicU1Hb081O" + ), + }, + }, + }, + }, + ["401"] = new OpenApiResponse() { Description = "Unauthorized" }, + ["400"] = new OpenApiResponse() { Description = "Bad Request" }, + ["429"] = new OpenApiResponse() { Description = "Too Many Requests" }, + }, + }, + }, + Servers = + [ + new OpenApiServer { Description = "Production environment", Url = "https://platform.altinn.no" }, + new OpenApiServer { Description = "Test environment", Url = "https://platform.tt02.altinn.no" }, + ], + } + ); + document.Paths.Add( + "http://local.altinn.cloud/Home/GetTestUserToken", + new OpenApiPathItem() + { + Operations = + { + [OperationType.Get] = new OpenApiOperation() + { + Tags = authTags, + Summary = "Get a test user token", + Description = "Get a test user token for use in the local development environment", + Parameters = + [ + new OpenApiParameter() + { + Name = "userId", + Description = "The user id of the test user", + In = ParameterLocation.Query, + Required = true, + Schema = new OpenApiSchema() { Type = "int32", Example = new OpenApiString("1337") }, + }, + new OpenApiParameter() + { + Name = "authenticationLevel", + Description = "The authentication level of the test user", + In = ParameterLocation.Query, + Schema = new OpenApiSchema() + { + Type = "int32", + Enum = + [ + new OpenApiInteger(0), + new OpenApiInteger(1), + new OpenApiInteger(2), + new OpenApiInteger(3), + new OpenApiInteger(4), + new OpenApiInteger(5), + ], + Default = new OpenApiInteger(3), + }, + Required = true, + }, + ], + Responses = new OpenApiResponses() + { + ["200"] = new OpenApiResponse() + { + Description = "Test user token", + Content = + { + ["text/plain"] = new OpenApiMediaType() + { + Schema = new OpenApiSchema() + { + Type = "string", + Example = new OpenApiString( + "eyJraWQiOiJIdFlaMU1UbFZXUGNCV0JQVWV3TmxZd1RCRklicU1Hb081O" + ), + }, + }, + }, + }, + }, + }, + }, + } + ); + } + + private void AddRoutsForDataType(OpenApiDocument doc, ApplicationMetadata appMetadata, DataType dataType) + { + var tags = new[] + { + new OpenApiTag() + { + Name = $"{(dataType.AppLogic?.ClassRef is null ? "FileData" : "FormData")} {dataType.Id}", + Description = $"Operations on data elements of type {dataType.Id}", + }, + }; + var schema = GetSchemaForDataType(dataType); + if (schema is not null) + { + AddOperationsForFormData(doc, tags, schema, dataType, appMetadata); + } + else + { + AddRoutsForAttachmentDataType(doc, tags, dataType, appMetadata); + } + } + + private static void AddOperationsForFormData( + OpenApiDocument doc, + OpenApiTag[] tags, + OpenApiSchema schema, + DataType dataType, + ApplicationMetadata appMetadata + ) + { + var jsonType = new OpenApiMediaType() { Schema = schema }; + var xmlType = new OpenApiMediaType() + { + Schema = new OpenApiSchema() + { + Type = "string", + Format = "binary", + Title = "Xml", + Description = $"""See [xml schema](/{appMetadata.Id}/xmlSchema/{dataType.Id})""", + }, + Example = new OpenApiString(""), + }; + doc.Paths.Add( + $"/{appMetadata.Id}/instances/{{instanceOwnerPartyId}}/{{instanceGuid}}/data/{{dataGuid}}/{dataType.Id}", + new OpenApiPathItem() + { + Summary = $"Operations for {dataType.Id}", + Description = $"CRUD operations for data of type {dataType.Id}", + Operations = + { + [OperationType.Get] = new OpenApiOperation() + { + Tags = tags, + Summary = "Get data", + Description = $""" + Get data for a specific data element + + see [JSON Schema](/{appMetadata.Id}/api/jsonschema/{dataType.Id}) + """, + Responses = Snippets.AddCommonErrorResponses( + HttpStatusCode.OK, + new OpenApiResponse() + { + Description = """ + # Data found + + The response body contains the data in the format specified by the Accept header. + + + """, + Content = { ["application/json"] = jsonType, ["application/xml"] = xmlType }, + } + ), + }, + [OperationType.Put] = new OpenApiOperation() + { + Tags = tags, + Summary = "Replace data element content", + Description = "Update data for a specific data element", + RequestBody = new OpenApiRequestBody() + { + Required = true, + Content = { ["application/json"] = jsonType, ["application/xml"] = xmlType }, + }, + }, + }, + Parameters = + [ + Snippets.InstanceOwnerPartyIdParameterReference, + Snippets.InstanceGuidParameterReference, + Snippets.DataGuidParameterReference, + ], + } + ); + doc.Paths.Add( + $"/{appMetadata.Id}/instances/{{instanceOwnerPartyId}}/{{instanceGuid}}/data/{dataType.Id}", + new OpenApiPathItem() + { + Summary = $"Operations for {dataType.Id}", + Description = $"CRUD operations for data of type {dataType.Id}", + Operations = + { + [OperationType.Post] = new OpenApiOperation() + { + Tags = tags, + Summary = "Create data", + Description = "Create data for a specific data element", + RequestBody = new OpenApiRequestBody() + { + Required = true, + Content = { ["application/json"] = jsonType, ["application/xml"] = xmlType }, + }, + }, + }, + Parameters = + [ + Snippets.InstanceOwnerPartyIdParameterReference, + Snippets.InstanceGuidParameterReference, + Snippets.DataGuidParameterReference, + ], + } + ); + } + + private static void AddRoutsForAttachmentDataType( + OpenApiDocument doc, + OpenApiTag[] tags, + DataType dataType, + ApplicationMetadata appMetadata + ) + { + doc.Paths.Add( + $"/{appMetadata.Id}/instances/{{instanceOwnerPartyId}}/{{instanceGuid}}/data/{{dataGuid}}/{dataType.Id}", + new OpenApiPathItem() + { + Summary = $"Operations for {dataType.Id}", + Description = $"CRUD operations for data of type {dataType.Id}", + Operations = + { + [OperationType.Get] = new OpenApiOperation() + { + Tags = tags, + Summary = "Get attachment", + Description = "Get attachment for a specific data element", + Responses = new() + { + ["200"] = new OpenApiResponse() + { + Description = "Attachment found", + Content = + { + ["application/octet-stream"] = new OpenApiMediaType() + { + Schema = new OpenApiSchema() { Format = "binary" }, + }, + }, + }, + ["404"] = new OpenApiResponse() { Description = "Attachment not found" }, + }, + }, + }, + Parameters = + [ + Snippets.InstanceOwnerPartyIdParameterReference, + Snippets.InstanceGuidParameterReference, + Snippets.DataGuidParameterReference, + ], + } + ); + doc.Paths.Add( + $"/{appMetadata.Id}/instances/{{instanceOwnerPartyId}}/{{instanceGuid}}/data/{dataType.Id}", + new OpenApiPathItem() + { + Summary = $"Operations for {dataType.Id}", + Description = $"CRUD operations for data of type {dataType.Id}", + Operations = + { + [OperationType.Post] = new OpenApiOperation() + { + Tags = tags, + Summary = "Create attachment", + RequestBody = new OpenApiRequestBody() + { + Required = true, + Content = + dataType.AllowedContentTypes?.ToDictionary( + contentType => contentType, + contentType => new OpenApiMediaType() + ) + ?? new Dictionary() + { + ["application/octet-stream"] = new OpenApiMediaType(), + }, + }, + Responses = new() { ["201"] = new OpenApiResponse() { Description = "Attachment created" } }, + }, + }, + Parameters = + [ + Snippets.InstanceOwnerPartyIdParameterReference, + Snippets.InstanceGuidParameterReference, + Snippets.DataGuidParameterReference, + ], + } + ); + } + + private OpenApiSchema? GetSchemaForDataType(DataType dataType) + { + var classRef = dataType.AppLogic?.ClassRef; + if (classRef == null) + { + return null; + } + var model = _appModel.GetModelType(classRef); + if (model == null) + { + return null; + } + var schema = _schemaGenerator.GenerateSchema(model, _schemaRepository); + schema.Title = dataType.Id; + schema.Description = + dataType.Description?.GetValueOrDefault("en") + ?? dataType.Description?.GetValueOrDefault("nb") + ?? dataType.Description?.FirstOrDefault().Value; + return schema; + } +} + +/// +/// Common parts from the schema generator +/// +public static class Snippets +{ + /// + /// Schema for the POST endpoint for creating a new instance + /// + public static OpenApiSchema InstanceWriteSchema => + new() + { + Title = "InstanceWrite", + Properties = + { + ["instanceOwner"] = new OpenApiSchema() + { + Type = "object", + Title = "Altnernate ways to spcecify the instance owner", + Description = "Only one of these should be spcecified when creating a new inistance", + Properties = + { + ["partyId"] = new OpenApiSchema() + { + Type = "string", + Nullable = true, + Format = "int32", + }, + ["personNumber"] = new OpenApiSchema() + { + Type = "string", + Nullable = true, + Pattern = @"^\d{11}$", + }, + ["organisationNumber"] = new OpenApiSchema() + { + Type = "string", + Nullable = true, + Pattern = @"^\d{9}$", + }, + ["username"] = new OpenApiSchema() + { + Type = "string", + Nullable = true, + Description = + "Initialization based on username is not yet supported (https://github.com/Altinn/app-lib-dotnet/issues/652)", + }, + }, + }, + ["dueBefore"] = new OpenApiSchema() { Type = "string", Format = "date-time" }, + ["visibleAfter"] = new OpenApiSchema() { Type = "string", Format = "date-time" }, + }, + }; + + /// + /// Schema for patching multiple data elements at once + /// + public static OpenApiSchema PatchSchema => + new() + { + Title = "Run patches on multiple Form data elements at once", + Type = "object", + Properties = + { + ["patches"] = new() + { + Type = "array", + Items = new() + { + Type = "object", + Properties = + { + ["dataElementId"] = new() { Type = "string", Format = "guid" }, + ["patch"] = new() + { + Type = "object", + Title = "Json patch", + Description = "A standard RFC 6902 document describing changes to one data element", + Properties = + { + ["operations"] = new() + { + Type = "array", + Items = new() + { + Type = "object", + Required = new HashSet() { "op", "path" }, + Properties = + { + ["op"] = new() + { + Title = "Patch operation", + Type = "string", + Enum = + [ + new OpenApiString("add"), + new OpenApiString("remove"), + new OpenApiString("replace"), + new OpenApiString("move"), + new OpenApiString("copy"), + new OpenApiString("test"), + ], + }, + ["from"] = new() { Title = "JsonPointer", Type = "string" }, + ["path"] = new() { Title = "JsonPointer" }, + ["value"] = new() { Type = "any" }, + }, + }, + }, + }, + }, + }, + }, + }, + ["ignoredValidators"] = new() + { + Title = "List of validators to not run incrementally", + Description = + "This is used for saving server resources, when frontend has a duplicated version of the validator. The validators will be executed on process/next anyway", + Items = new() { Type = "string" }, + }, + }, + }; + + /// + /// Reference to the shared instance owner party id parameter + /// + public static OpenApiParameter InstanceOwnerPartyIdParameterReference => + new() + { + Reference = new OpenApiReference() { Id = "instanceOwnerPartyId", Type = ReferenceType.Parameter }, + }; + + /// + /// Reference to the shared instance guid parameter + /// + public static OpenApiParameter InstanceGuidParameterReference => + new() + { + Reference = new OpenApiReference() { Id = "instanceGuid", Type = ReferenceType.Parameter }, + }; + + /// + /// Reference to the shared data guid parameter + /// + public static OpenApiParameter DataGuidParameterReference => + new() + { + Reference = new OpenApiReference() { Id = "dataGuid", Type = ReferenceType.Parameter }, + }; + + /// + /// Reference to the shared language parameter + /// + public static OpenApiParameter LanguageParameterReference => + new() + { + Reference = new OpenApiReference() { Id = "language", Type = ReferenceType.Parameter }, + }; + + /// + /// q + /// + public static IDictionary ComponentParameters => + new Dictionary + { + [InstanceOwnerPartyIdParameterReference.Reference.Id] = new() + { + Name = "instanceOwnerPartyId", + Description = + "PartyId for the owner of the instance, this is altinns internal id for the organisation, person or self registered user. Might be the current user, or ", + In = ParameterLocation.Path, + Required = true, + Schema = new OpenApiSchema() { Type = "integer" }, + }, + [InstanceGuidParameterReference.Reference.Id] = new() + { + Name = "instanceGuid", + Description = "The guid part of instance.Id", + In = ParameterLocation.Path, + Required = true, + Schema = new OpenApiSchema() { Type = "guid" }, + }, + ["dataGuid"] = new() + { + Name = "dataGuid", + Description = "Id of this data element that belongs to an instance", + In = ParameterLocation.Path, + Required = true, + Schema = new OpenApiSchema() { Type = "guid" }, + }, + ["language"] = new() + { + Name = "language", + In = ParameterLocation.Query, + AllowEmptyValue = false, + Example = new OpenApiString("nb"), + Description = + "Some apps make changes to the data models or validation based on the active language of the user", + Required = false, + Schema = new OpenApiSchema() { Type = "string", Pattern = @"\w\w" }, + }, + }; + + /// + /// Schema for problem details + /// + public static OpenApiResponse ProblemDetailsResponseSchema => + new OpenApiResponse() + { + Description = "Problem details", + Content = + { + ["application/problem+json"] = new OpenApiMediaType() + { + Schema = new() + { + Type = "object", + Properties = + { + ["type"] = new OpenApiSchema() + { + Type = "string", + Nullable = true, + Example = new OpenApiString("https://datatracker.ietf.org/doc/html/rfc6902/"), + }, + ["title"] = new OpenApiSchema() + { + Type = "string", + Nullable = true, + Example = new OpenApiString("Error in data processing"), + }, + ["status"] = new OpenApiSchema() + { + Type = "integer", + Format = "int32", + Nullable = true, + Example = new OpenApiInteger(400), + }, + ["detail"] = new OpenApiSchema() + { + Type = "string", + Nullable = true, + Example = new OpenApiString("Actually usefull description of the error"), + }, + ["instance"] = new OpenApiSchema() { Type = "string", Nullable = true }, + }, + }, + }, + }, + }; + + /// + /// Security scheme for Altinn token + /// + public static readonly OpenApiSecurityScheme AltinnTokenSecurityScheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() { Id = "AltinnToken", Type = ReferenceType.SecurityScheme }, + Scheme = "Bearer", + BearerFormat = "JWT", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + Description = """ + Get a token for [localtest](http://local.altinn.cloud/Home/Tokens) + or by exchanging a maskinporten token with the [token exchange endpoint](https://docs.altinn.studio/api/authentication/spec/#/Authentication/get_exchange__tokenProvider_) + """, + }; + + /// + /// Reference to the ProblemDetails common response + /// + public static readonly OpenApiReference ProblemDetailsResponseReference = new() + { + Id = "ProblemDetails", + Type = ReferenceType.Response, + }; + + /// + /// Add common error responses to a response collection + /// + public static OpenApiResponses AddCommonErrorResponses(HttpStatusCode statusCode, OpenApiResponse response) + { + var responses = new OpenApiResponses() + { + [((int)statusCode).ToString(CultureInfo.InvariantCulture)] = response, + }; + return AddCommonErrorResponses(responses); + } + + /// + /// Add common error responses to a response collection + /// + public static OpenApiResponses AddCommonErrorResponses(OpenApiResponses responses) + { + responses.TryAdd( + "400", + new OpenApiResponse() { Description = "Bad request", Reference = ProblemDetailsResponseReference } + ); + responses.TryAdd( + "401", + new OpenApiResponse() { Description = "Unauthorized", Reference = ProblemDetailsResponseReference } + ); + responses.TryAdd( + "403", + new OpenApiResponse() { Description = "Forbidden", Reference = ProblemDetailsResponseReference } + ); + responses.TryAdd( + "404", + new OpenApiResponse() { Description = "Not found", Reference = ProblemDetailsResponseReference } + ); + responses.TryAdd( + "500", + new OpenApiResponse() { Description = "Internal server error", Reference = ProblemDetailsResponseReference } + ); + return responses; + } +} + +/// +/// Visitor that modifies the schema after it has been generated +/// +public class SchemaPostVisitor : OpenApiVisitorBase +{ + /// + public override void Visit(OpenApiSchema schema) + { + // Remove `altinnRowId` from the data element schema (they are not intended for external usage) + schema.Properties.Remove("altinnRowId"); + + // openapi has xml extensions, but they can't represent tags with both attributes and values + // value, so we just zero properties from SwaggerGen + schema.Xml = null; + } +} diff --git a/test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj b/test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj index 869e33c9f..9676ff58a 100644 --- a/test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj +++ b/test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj @@ -13,7 +13,6 @@ - runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveCustomOpenApiSpec.verified.txt b/test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveCustomOpenApiSpec.verified.txt new file mode 100644 index 000000000..0fe68993a --- /dev/null +++ b/test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveCustomOpenApiSpec.verified.txt @@ -0,0 +1,2418 @@ +{ + openapi: 3.0.1, + info: { + title: Altinn 3 App API for Endring av navn (RF-1453), + description: +This is the API for an Altinn 3 app. The API is based on the OpenAPI 3.0 specification. +This app has the following data types: +| DataTypeId | Type | Allowed number | MimeTypes | TaskId | +|------------|------|----------------|-----------|--------| +|default|FormData (AutoCreate)|0-1|application/xml|Task_1| +|customElement|Attachment|0-1|*|Task_1| +|9edd53de-f46f-40a1-bb4d-3efb93dc113d|Attachment|0-1|*|Task_1| +|specificFileType|Attachment|0-1|application/pdf, image/png, application/json|Task_1| +|userInteractionUnspecified|FormData|0-10|application/xml|Task_1| +|disallowUserCreate|FormData|0-10|application/xml|Task_1| +|disallowUserDelete|FormData|0-10|application/xml|Task_1| +, + contact: { + name: Digitaliseringsdirektoratet (altinn), + url: https://altinn.slack.com + }, + version: 8.0.0.0 + }, + servers: [ + { + url: http://local.altinn.cloud, + description: Local development server + }, + { + url: https://tdd.apps.tt02.altinn.no, + description: TT02 server + }, + { + url: https://tdd.apps.altinn.no, + description: Production server + } + ], + paths: { + /tdd/contributer-restriction/instances: { + summary: Operations for instances, + description: CRUD operations for instances, + post: { + tags: [ + Instances + ], + summary: Create new instance, + description: The main api for creating new instances. , + parameters: [ + null, + null + ], + requestBody: { + description: +Instance document, formData and attachments + +Any mime type that is not ``"application/json"`` or ``"multipart/form-data"`` with an instance document +will require the ``instanceOwnerPartyId`` parameter. Otherwise you must use the simplified instance document to specify instance owner. +Either using ``instanceOwner.partyId`` or ``instanceOwner.personNumber`` or ``instanceOwner.organisationNumber`` (or ``instanceOwner.username`` see [app-lib-dotnet/#652](https://github.com/Altinn/app-lib-dotnet/issues/652))., + content: { + empty: { + schema: { + type: , + example: + } + }, + application/json: { + schema: { + $ref: #/components/schemas/InstanceWrite + } + }, + multipart/form-data: { + schema: { + type: object, + properties: { + instance: { + $ref: #/components/schemas/InstanceWrite + }, + default: { + type: string, + format: binary + }, + customElement: { + type: string, + format: binary + }, + Guid_1: { + type: string, + format: binary + }, + specificFileType: { + type: string, + format: binary + }, + userInteractionUnspecified: { + type: string, + format: binary + }, + disallowUserCreate: { + type: string, + format: binary + }, + disallowUserDelete: { + type: string, + format: binary + } + } + }, + encoding: { + instance: { + contentType: application/json + }, + default: { + contentType: application/xml + }, + customElement: { + contentType: application/octet-stream + }, + Guid_1: { + contentType: application/octet-stream + }, + specificFileType: { + contentType: application/pdf image/png application/json + }, + userInteractionUnspecified: { + contentType: application/xml + }, + disallowUserCreate: { + contentType: application/xml + }, + disallowUserDelete: { + contentType: application/xml + } + } + } + } + }, + responses: { + 201: { + description: Instance created, + content: { + application/json: { + schema: { + $ref: #/components/schemas/Instance + } + } + } + }, + 400: { + $ref: #/components/responses/ProblemDetails + }, + 401: { + $ref: #/components/responses/ProblemDetails + }, + 403: { + $ref: #/components/responses/ProblemDetails + }, + 404: { + $ref: #/components/responses/ProblemDetails + }, + 500: { + $ref: #/components/responses/ProblemDetails + } + } + }, + servers: [ + { + url: /tdd/contributer-restriction + } + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}: { + summary: Operations for instance, + description: CRUD operations for a specific instance, + get: { + tags: [ + Instances + ], + summary: Get instance, + description: Get a specific instance, + operationId: GetInstance, + responses: { + 200: { + description: Instance found, + content: { + application/json: { + schema: { + $ref: #/components/schemas/Instance + } + } + } + }, + 404: { + description: Instance not found + } + } + }, + delete: { + tags: [ + Instances + ], + summary: Delete instance, + description: Delete a specific instance, + responses: { + 204: { + description: Instance deleted + }, + 404: { + description: Instance not found + } + } + }, + patch: { + tags: [ + Instances + ], + summary: Patch data elements on instance, + requestBody: { + content: { + application/json: { + schema: { + title: Run patches on multiple Form data elements at once, + type: object, + properties: { + patches: { + type: array, + items: { + type: object, + properties: { + dataElementId: { + type: string, + format: guid + }, + patch: { + title: Json patch, + type: object, + properties: { + operations: { + type: array, + items: { + required: [ + op, + path + ], + type: object, + properties: { + op: { + title: Patch operation, + enum: [ + add, + remove, + replace, + move, + copy, + test + ], + type: string + }, + from: { + title: JsonPointer, + type: string + }, + path: { + title: JsonPointer + }, + value: { + type: any + } + } + } + } + }, + description: A standard RFC 6902 document describing changes to one data element + } + } + } + }, + ignoredValidators: { + title: List of validators to not run incrementally, + items: { + type: string + }, + description: This is used for saving server resources, when frontend has a duplicated version of the validator. The validators will be executed on process/next anyway + } + } + } + } + }, + required: true + }, + responses: { + 200: { + description: Data elements patched, + content: { + application/json: { + schema: { + $ref: #/components/schemas/DataPatchResponseMultiple + } + } + } + }, + 404: { + description: Instance not found + } + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}: { + summary: Delete data element, + delete: { + tags: [ + Instances + ], + summary: Delete data element, + description: Delete data for a specific data element, + responses: { + 204: { + description: Data deleted + }, + 404: { + description: Data not found + } + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/api/v1/applicationmetadata: { + summary: Get application metadata, + description: Get the metadata for the application, + get: { + tags: [ + Static + ], + summary: Get application metadata, + description: Get the metadata for the application, + responses: { + 200: { + description: Application metadata found, + content: { + application/json: { + schema: { + $ref: #/components/schemas/ApplicationMetadata + } + } + } + } + } + } + }, + /authentication/api/v1/exchange/{tokenProvider}: { + get: { + tags: [ + Authentication + ], + summary: Action for exchanging a JWT generated by a trusted token provider with a new JWT for further use as authentication against rest of Altinn., + parameters: [ + { + name: tokenProvider, + in: path, + required: true, + schema: { + enum: [ + maskinporten, + id-porten + ], + type: string + } + }, + { + name: Autorization, + in: header, + description: Bearer token from the selected token provider to exchange for an altinn token, + required: true, + schema: { + type: string + }, + example: Bearer + } + ], + responses: { + 200: { + description: Exchanged token, + content: { + text/plain: { + schema: { + type: string, + example: eyJraWQiOiJIdFlaMU1UbFZXUGNCV0JQVWV3TmxZd1RCRklicU1Hb081O + } + } + } + }, + 401: { + description: Unauthorized + }, + 400: { + description: Bad Request + }, + 429: { + description: Too Many Requests + } + } + }, + servers: [ + { + url: https://platform.altinn.no, + description: Production environment + }, + { + url: https://platform.tt02.altinn.no, + description: Test environment + } + ] + }, + http://local.altinn.cloud/Home/GetTestUserToken: { + get: { + tags: [ + Authentication + ], + summary: Get a test user token, + description: Get a test user token for use in the local development environment, + parameters: [ + { + name: userId, + in: query, + description: The user id of the test user, + required: true, + schema: { + type: int32, + example: 1337 + } + }, + { + name: authenticationLevel, + in: query, + description: The authentication level of the test user, + required: true, + schema: { + enum: [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + type: int32, + default: 3 + } + } + ], + responses: { + 200: { + description: Test user token, + content: { + text/plain: { + schema: { + type: string, + example: eyJraWQiOiJIdFlaMU1UbFZXUGNCV0JQVWV3TmxZd1RCRklicU1Hb081O + } + } + } + } + } + } + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/default: { + summary: Operations for default, + description: CRUD operations for data of type default, + get: { + tags: [ + FormData default + ], + summary: Get data, + description: +Get data for a specific data element + +see [JSON Schema](/tdd/contributer-restriction/api/jsonschema/default), + responses: { + 200: { + description: +# Data found + +The response body contains the data in the format specified by the Accept header. + +, + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/default), + format: binary + }, + example: + } + } + }, + 400: { + $ref: #/components/responses/ProblemDetails + }, + 401: { + $ref: #/components/responses/ProblemDetails + }, + 403: { + $ref: #/components/responses/ProblemDetails + }, + 404: { + $ref: #/components/responses/ProblemDetails + }, + 500: { + $ref: #/components/responses/ProblemDetails + } + } + }, + put: { + tags: [ + FormData default + ], + summary: Replace data element content, + description: Update data for a specific data element, + requestBody: { + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/default), + format: binary + }, + example: + } + }, + required: true + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/default: { + summary: Operations for default, + description: CRUD operations for data of type default, + post: { + tags: [ + FormData default + ], + summary: Create data, + description: Create data for a specific data element, + requestBody: { + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/default), + format: binary + }, + example: + } + }, + required: true + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/customElement: { + summary: Operations for customElement, + description: CRUD operations for data of type customElement, + get: { + tags: [ + FileData customElement + ], + summary: Get attachment, + description: Get attachment for a specific data element, + responses: { + 200: { + description: Attachment found, + content: { + application/octet-stream: { + schema: { + format: binary + } + } + } + }, + 404: { + description: Attachment not found + } + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/customElement: { + summary: Operations for customElement, + description: CRUD operations for data of type customElement, + post: { + tags: [ + FileData customElement + ], + summary: Create attachment, + requestBody: { + content: {}, + required: true + }, + responses: { + 201: { + description: Attachment created + } + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/9edd53de-f46f-40a1-bb4d-3efb93dc113d: { + summary: Operations for 9edd53de-f46f-40a1-bb4d-3efb93dc113d, + description: CRUD operations for data of type 9edd53de-f46f-40a1-bb4d-3efb93dc113d, + get: { + tags: [ + FileData 9edd53de-f46f-40a1-bb4d-3efb93dc113d + ], + summary: Get attachment, + description: Get attachment for a specific data element, + responses: { + 200: { + description: Attachment found, + content: { + application/octet-stream: { + schema: { + format: binary + } + } + } + }, + 404: { + description: Attachment not found + } + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/9edd53de-f46f-40a1-bb4d-3efb93dc113d: { + summary: Operations for 9edd53de-f46f-40a1-bb4d-3efb93dc113d, + description: CRUD operations for data of type 9edd53de-f46f-40a1-bb4d-3efb93dc113d, + post: { + tags: [ + FileData 9edd53de-f46f-40a1-bb4d-3efb93dc113d + ], + summary: Create attachment, + requestBody: { + content: {}, + required: true + }, + responses: { + 201: { + description: Attachment created + } + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/specificFileType: { + summary: Operations for specificFileType, + description: CRUD operations for data of type specificFileType, + get: { + tags: [ + FileData specificFileType + ], + summary: Get attachment, + description: Get attachment for a specific data element, + responses: { + 200: { + description: Attachment found, + content: { + application/octet-stream: { + schema: { + format: binary + } + } + } + }, + 404: { + description: Attachment not found + } + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/specificFileType: { + summary: Operations for specificFileType, + description: CRUD operations for data of type specificFileType, + post: { + tags: [ + FileData specificFileType + ], + summary: Create attachment, + requestBody: { + content: {}, + required: true + }, + responses: { + 201: { + description: Attachment created + } + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/userInteractionUnspecified: { + summary: Operations for userInteractionUnspecified, + description: CRUD operations for data of type userInteractionUnspecified, + get: { + tags: [ + FormData userInteractionUnspecified + ], + summary: Get data, + description: +Get data for a specific data element + +see [JSON Schema](/tdd/contributer-restriction/api/jsonschema/userInteractionUnspecified), + responses: { + 200: { + description: +# Data found + +The response body contains the data in the format specified by the Accept header. + +, + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/userInteractionUnspecified), + format: binary + }, + example: + } + } + }, + 400: { + $ref: #/components/responses/ProblemDetails + }, + 401: { + $ref: #/components/responses/ProblemDetails + }, + 403: { + $ref: #/components/responses/ProblemDetails + }, + 404: { + $ref: #/components/responses/ProblemDetails + }, + 500: { + $ref: #/components/responses/ProblemDetails + } + } + }, + put: { + tags: [ + FormData userInteractionUnspecified + ], + summary: Replace data element content, + description: Update data for a specific data element, + requestBody: { + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/userInteractionUnspecified), + format: binary + }, + example: + } + }, + required: true + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/userInteractionUnspecified: { + summary: Operations for userInteractionUnspecified, + description: CRUD operations for data of type userInteractionUnspecified, + post: { + tags: [ + FormData userInteractionUnspecified + ], + summary: Create data, + description: Create data for a specific data element, + requestBody: { + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/userInteractionUnspecified), + format: binary + }, + example: + } + }, + required: true + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/disallowUserCreate: { + summary: Operations for disallowUserCreate, + description: CRUD operations for data of type disallowUserCreate, + get: { + tags: [ + FormData disallowUserCreate + ], + summary: Get data, + description: +Get data for a specific data element + +see [JSON Schema](/tdd/contributer-restriction/api/jsonschema/disallowUserCreate), + responses: { + 200: { + description: +# Data found + +The response body contains the data in the format specified by the Accept header. + +, + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/disallowUserCreate), + format: binary + }, + example: + } + } + }, + 400: { + $ref: #/components/responses/ProblemDetails + }, + 401: { + $ref: #/components/responses/ProblemDetails + }, + 403: { + $ref: #/components/responses/ProblemDetails + }, + 404: { + $ref: #/components/responses/ProblemDetails + }, + 500: { + $ref: #/components/responses/ProblemDetails + } + } + }, + put: { + tags: [ + FormData disallowUserCreate + ], + summary: Replace data element content, + description: Update data for a specific data element, + requestBody: { + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/disallowUserCreate), + format: binary + }, + example: + } + }, + required: true + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/disallowUserCreate: { + summary: Operations for disallowUserCreate, + description: CRUD operations for data of type disallowUserCreate, + post: { + tags: [ + FormData disallowUserCreate + ], + summary: Create data, + description: Create data for a specific data element, + requestBody: { + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/disallowUserCreate), + format: binary + }, + example: + } + }, + required: true + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/disallowUserDelete: { + summary: Operations for disallowUserDelete, + description: CRUD operations for data of type disallowUserDelete, + get: { + tags: [ + FormData disallowUserDelete + ], + summary: Get data, + description: +Get data for a specific data element + +see [JSON Schema](/tdd/contributer-restriction/api/jsonschema/disallowUserDelete), + responses: { + 200: { + description: +# Data found + +The response body contains the data in the format specified by the Accept header. + +, + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/disallowUserDelete), + format: binary + }, + example: + } + } + }, + 400: { + $ref: #/components/responses/ProblemDetails + }, + 401: { + $ref: #/components/responses/ProblemDetails + }, + 403: { + $ref: #/components/responses/ProblemDetails + }, + 404: { + $ref: #/components/responses/ProblemDetails + }, + 500: { + $ref: #/components/responses/ProblemDetails + } + } + }, + put: { + tags: [ + FormData disallowUserDelete + ], + summary: Replace data element content, + description: Update data for a specific data element, + requestBody: { + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/disallowUserDelete), + format: binary + }, + example: + } + }, + required: true + } + }, + parameters: [ + null, + null, + null + ] + }, + /tdd/contributer-restriction/instances/{instanceOwnerPartyId}/{instanceGuid}/data/disallowUserDelete: { + summary: Operations for disallowUserDelete, + description: CRUD operations for data of type disallowUserDelete, + post: { + tags: [ + FormData disallowUserDelete + ], + summary: Create data, + description: Create data for a specific data element, + requestBody: { + content: { + application/json: { + schema: { + $ref: #/components/schemas/Skjema + } + }, + application/xml: { + schema: { + title: Xml, + type: string, + description: See [xml schema](/tdd/contributer-restriction/xmlSchema/disallowUserDelete), + format: binary + }, + example: + } + }, + required: true + } + }, + parameters: [ + null, + null, + null + ] + } + }, + components: { + schemas: { + InstanceOwner: { + type: object, + properties: { + partyId: { + type: string, + nullable: true + }, + personNumber: { + type: string, + nullable: true + }, + organisationNumber: { + type: string, + nullable: true + }, + username: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + ResourceLinks: { + type: object, + properties: { + apps: { + type: string, + nullable: true + }, + platform: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + ValidationStatus: { + type: object, + properties: { + timestamp: { + type: string, + format: date-time, + nullable: true + }, + canCompleteTask: { + type: boolean + } + }, + additionalProperties: false + }, + ProcessElementInfo: { + type: object, + properties: { + flow: { + type: integer, + format: int32, + nullable: true + }, + started: { + type: string, + format: date-time, + nullable: true + }, + elementId: { + type: string, + nullable: true + }, + name: { + type: string, + nullable: true + }, + altinnTaskType: { + type: string, + nullable: true + }, + ended: { + type: string, + format: date-time, + nullable: true + }, + validated: { + $ref: #/components/schemas/ValidationStatus + }, + flowType: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + ProcessState: { + type: object, + properties: { + started: { + type: string, + format: date-time, + nullable: true + }, + startEvent: { + type: string, + nullable: true + }, + currentTask: { + $ref: #/components/schemas/ProcessElementInfo + }, + ended: { + type: string, + format: date-time, + nullable: true + }, + endEvent: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + ReadStatus: { + enum: [ + 0, + 1, + 2 + ], + type: integer, + format: int32 + }, + Substatus: { + type: object, + properties: { + label: { + type: string, + nullable: true + }, + description: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + InstanceStatus: { + type: object, + properties: { + isArchived: { + type: boolean + }, + archived: { + type: string, + format: date-time, + nullable: true + }, + isSoftDeleted: { + type: boolean + }, + softDeleted: { + type: string, + format: date-time, + nullable: true + }, + isHardDeleted: { + type: boolean + }, + hardDeleted: { + type: string, + format: date-time, + nullable: true + }, + readStatus: { + $ref: #/components/schemas/ReadStatus + }, + substatus: { + $ref: #/components/schemas/Substatus + } + }, + additionalProperties: false + }, + CompleteConfirmation: { + type: object, + properties: { + stakeholderId: { + type: string, + nullable: true + }, + confirmedOn: { + type: string, + format: date-time + } + }, + additionalProperties: false + }, + KeyValueEntry: { + type: object, + properties: { + key: { + type: string, + nullable: true + }, + value: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + DeleteStatus: { + type: object, + properties: { + isHardDeleted: { + type: boolean + }, + hardDeleted: { + type: string, + format: date-time, + nullable: true + } + }, + additionalProperties: false + }, + FileScanResult: { + enum: [ + NotApplicable, + Pending, + Clean, + Infected + ], + type: string + }, + RelationType: { + enum: [ + GeneratedFrom + ], + type: string + }, + ReferenceType: { + enum: [ + DataElement, + Task + ], + type: string + }, + Reference: { + type: object, + properties: { + value: { + type: string, + nullable: true + }, + relation: { + $ref: #/components/schemas/RelationType + }, + valueType: { + $ref: #/components/schemas/ReferenceType + } + }, + additionalProperties: false + }, + DataElement: { + type: object, + properties: { + created: { + type: string, + format: date-time, + nullable: true + }, + createdBy: { + type: string, + nullable: true + }, + lastChanged: { + type: string, + format: date-time, + nullable: true + }, + lastChangedBy: { + type: string, + nullable: true + }, + id: { + type: string, + nullable: true + }, + instanceGuid: { + type: string, + nullable: true + }, + dataType: { + type: string, + nullable: true + }, + filename: { + type: string, + nullable: true + }, + contentType: { + type: string, + nullable: true + }, + blobStoragePath: { + type: string, + nullable: true + }, + selfLinks: { + $ref: #/components/schemas/ResourceLinks + }, + size: { + type: integer, + format: int64 + }, + contentHash: { + type: string, + nullable: true + }, + locked: { + type: boolean + }, + refs: { + type: array, + items: { + type: string, + format: uuid + }, + nullable: true + }, + isRead: { + type: boolean + }, + tags: { + type: array, + items: { + type: string + }, + nullable: true + }, + userDefinedMetadata: { + type: array, + items: { + $ref: #/components/schemas/KeyValueEntry + }, + nullable: true + }, + metadata: { + type: array, + items: { + $ref: #/components/schemas/KeyValueEntry + }, + nullable: true + }, + deleteStatus: { + $ref: #/components/schemas/DeleteStatus + }, + fileScanResult: { + $ref: #/components/schemas/FileScanResult + }, + references: { + type: array, + items: { + $ref: #/components/schemas/Reference + }, + nullable: true + } + }, + additionalProperties: false + }, + Instance: { + type: object, + properties: { + created: { + type: string, + format: date-time, + nullable: true + }, + createdBy: { + type: string, + nullable: true + }, + lastChanged: { + type: string, + format: date-time, + nullable: true + }, + lastChangedBy: { + type: string, + nullable: true + }, + id: { + type: string, + nullable: true + }, + instanceOwner: { + $ref: #/components/schemas/InstanceOwner + }, + appId: { + type: string, + nullable: true + }, + org: { + type: string, + nullable: true + }, + selfLinks: { + $ref: #/components/schemas/ResourceLinks + }, + dueBefore: { + type: string, + format: date-time, + nullable: true + }, + visibleAfter: { + type: string, + format: date-time, + nullable: true + }, + process: { + $ref: #/components/schemas/ProcessState + }, + status: { + $ref: #/components/schemas/InstanceStatus + }, + completeConfirmations: { + type: array, + items: { + $ref: #/components/schemas/CompleteConfirmation + }, + nullable: true + }, + data: { + type: array, + items: { + $ref: #/components/schemas/DataElement + }, + nullable: true + }, + presentationTexts: { + type: object, + additionalProperties: { + type: string, + nullable: true + }, + nullable: true + }, + dataValues: { + type: object, + additionalProperties: { + type: string, + nullable: true + }, + nullable: true + } + }, + additionalProperties: false + }, + InstanceWrite: { + title: InstanceWrite, + properties: { + instanceOwner: { + title: Altnernate ways to spcecify the instance owner, + type: object, + properties: { + partyId: { + type: string, + format: int32, + nullable: true + }, + personNumber: { + pattern: ^\d{11}$, + type: string, + nullable: true + }, + organisationNumber: { + pattern: ^\d{9}$, + type: string, + nullable: true + }, + username: { + type: string, + description: Initialization based on username is not yet supported (https://github.com/Altinn/app-lib-dotnet/issues/652), + nullable: true + } + }, + description: Only one of these should be spcecified when creating a new inistance + }, + dueBefore: { + type: string, + format: date-time + }, + visibleAfter: { + type: string, + format: date-time + } + } + }, + ValidationIssueSeverity: { + enum: [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + type: integer, + format: int32 + }, + ValidationIssueWithSource: { + required: [ + code, + description, + severity, + source + ], + type: object, + properties: { + severity: { + $ref: #/components/schemas/ValidationIssueSeverity + }, + dataElementId: { + type: string, + nullable: true + }, + field: { + type: string, + nullable: true + }, + code: { + type: string, + nullable: true + }, + description: { + type: string, + nullable: true + }, + source: { + type: string, + nullable: true + }, + noIncrementalUpdates: { + type: boolean + }, + customTextKey: { + type: string, + nullable: true + }, + customTextParams: { + type: array, + items: { + type: string + }, + nullable: true + } + }, + additionalProperties: false + }, + ValidationSourcePair: { + type: object, + properties: { + source: { + type: string, + nullable: true + }, + issues: { + type: array, + items: { + $ref: #/components/schemas/ValidationIssueWithSource + }, + nullable: true + } + }, + additionalProperties: false + }, + DataModelPairResponse: { + type: object, + properties: { + dataElementId: { + type: string, + format: uuid + }, + data: { + nullable: true + } + }, + additionalProperties: false + }, + DataPatchResponseMultiple: { + required: [ + instance, + newDataModels, + validationIssues + ], + type: object, + properties: { + validationIssues: { + type: array, + items: { + $ref: #/components/schemas/ValidationSourcePair + }, + nullable: true + }, + newDataModels: { + type: array, + items: { + $ref: #/components/schemas/DataModelPairResponse + }, + nullable: true + }, + instance: { + $ref: #/components/schemas/Instance + } + }, + additionalProperties: false + }, + ShadowFields: { + type: object, + properties: { + prefix: { + type: string, + nullable: true + }, + saveToDataType: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + ApplicationLogic: { + type: object, + properties: { + autoCreate: { + type: boolean, + nullable: true + }, + classRef: { + type: string, + nullable: true + }, + schemaRef: { + type: string, + nullable: true + }, + allowAnonymousOnStateless: { + type: boolean + }, + autoDeleteOnProcessEnd: { + type: boolean + }, + disallowUserCreate: { + type: boolean + }, + disallowUserDelete: { + type: boolean + }, + allowInSubform: { + type: boolean, + deprecated: true + }, + shadowFields: { + $ref: #/components/schemas/ShadowFields + } + }, + additionalProperties: false + }, + DataType: { + type: object, + properties: { + id: { + type: string, + nullable: true + }, + description: { + type: object, + additionalProperties: { + type: string + }, + nullable: true + }, + allowedContentTypes: { + type: array, + items: { + type: string + }, + nullable: true + }, + allowedContributers: { + type: array, + items: { + type: string + }, + nullable: true + }, + appLogic: { + $ref: #/components/schemas/ApplicationLogic + }, + taskId: { + type: string, + nullable: true + }, + maxSize: { + type: integer, + format: int32, + nullable: true + }, + maxCount: { + type: integer, + format: int32, + default: 1 + }, + minCount: { + type: integer, + format: int32, + default: 1 + }, + grouping: { + type: string, + nullable: true + }, + enablePdfCreation: { + type: boolean + }, + enableFileScan: { + type: boolean + }, + validationErrorOnPendingFileScan: { + type: boolean + }, + enabledFileAnalysers: { + type: array, + items: { + type: string + }, + nullable: true + }, + enabledFileValidators: { + type: array, + items: { + type: string + }, + nullable: true + }, + allowedKeysForUserDefinedMetadata: { + type: array, + items: { + type: string + }, + nullable: true + } + }, + additionalProperties: false + }, + PartyTypesAllowed: { + type: object, + properties: { + bankruptcyEstate: { + type: boolean + }, + organisation: { + type: boolean + }, + person: { + type: boolean + }, + subUnit: { + type: boolean + } + }, + additionalProperties: false + }, + DataField: { + type: object, + properties: { + id: { + type: string, + nullable: true + }, + path: { + type: string, + nullable: true + }, + dataTypeId: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + EFormidlingContract: { + type: object, + properties: { + serviceId: { + type: string, + nullable: true + }, + dpfShipmentType: { + type: string, + nullable: true + }, + receiver: { + type: string, + nullable: true + }, + sendAfterTaskId: { + type: string, + nullable: true + }, + process: { + type: string, + nullable: true + }, + standard: { + type: string, + nullable: true + }, + typeVersion: { + type: string, + nullable: true + }, + type: { + type: string, + nullable: true + }, + securityLevel: { + type: integer, + format: int32 + }, + dataTypes: { + type: array, + items: { + type: string + }, + nullable: true + } + }, + additionalProperties: false + }, + OnEntryConfig: { + type: object, + properties: { + show: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + HideSettings: { + type: object, + properties: { + hideAlways: { + type: boolean + }, + hideOnTask: { + type: array, + items: { + type: string + }, + nullable: true + } + }, + additionalProperties: false + }, + MessageBoxConfig: { + type: object, + properties: { + hideSettings: { + $ref: #/components/schemas/HideSettings + } + }, + additionalProperties: false + }, + CopyInstanceSettings: { + type: object, + properties: { + enabled: { + type: boolean + }, + excludedDataTypes: { + type: array, + items: { + type: string + }, + nullable: true + }, + excludedDataFields: { + type: array, + items: { + type: string + }, + nullable: true + } + }, + additionalProperties: false + }, + InstanceSelection: { + type: object, + properties: { + rowsPerPageOptions: { + type: array, + items: { + type: integer, + format: int32 + }, + nullable: true + }, + defaultRowsPerPage: { + type: integer, + format: int32, + nullable: true + }, + defaultSelectedOption: { + type: integer, + format: int32, + nullable: true + }, + sortDirection: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + OnEntry: { + type: object, + properties: { + show: { + type: string, + nullable: true + }, + instanceSelection: { + $ref: #/components/schemas/InstanceSelection + } + }, + additionalProperties: false + }, + Logo: { + type: object, + properties: { + displayAppOwnerNameInHeader: { + type: boolean + }, + source: { + type: string, + nullable: true + }, + size: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + ApplicationMetadata: { + type: object, + properties: { + created: { + type: string, + format: date-time, + nullable: true + }, + createdBy: { + type: string, + nullable: true + }, + lastChanged: { + type: string, + format: date-time, + nullable: true + }, + lastChangedBy: { + type: string, + nullable: true + }, + versionId: { + type: string, + nullable: true + }, + org: { + type: string, + nullable: true + }, + title: { + type: object, + additionalProperties: { + type: string, + nullable: true + }, + nullable: true + }, + validFrom: { + type: string, + format: date-time, + nullable: true + }, + validTo: { + type: string, + format: date-time, + nullable: true + }, + processId: { + type: string, + nullable: true + }, + dataTypes: { + type: array, + items: { + $ref: #/components/schemas/DataType + }, + nullable: true + }, + partyTypesAllowed: { + $ref: #/components/schemas/PartyTypesAllowed + }, + autoDeleteOnProcessEnd: { + type: boolean + }, + presentationFields: { + type: array, + items: { + $ref: #/components/schemas/DataField + }, + nullable: true + }, + dataFields: { + type: array, + items: { + $ref: #/components/schemas/DataField + }, + nullable: true + }, + eFormidling: { + $ref: #/components/schemas/EFormidlingContract + }, + onEntry: { + $ref: #/components/schemas/OnEntry + }, + messageBoxConfig: { + $ref: #/components/schemas/MessageBoxConfig + }, + copyInstanceSettings: { + $ref: #/components/schemas/CopyInstanceSettings + }, + storageAccountNumber: { + type: integer, + format: int32, + nullable: true + }, + disallowUserInstantiation: { + type: boolean + }, + id: { + type: string, + nullable: true + }, + features: { + type: object, + additionalProperties: { + type: boolean + }, + nullable: true + }, + logo: { + $ref: #/components/schemas/Logo + }, + altinnNugetVersion: { + type: string, + nullable: true + }, + externalApiIds: { + type: array, + items: { + type: string + }, + nullable: true + } + } + }, + SimpleKeyvalues: { + type: object, + properties: { + key: { + type: string, + nullable: true + }, + doubleValue: { + type: number, + format: double, + nullable: true + }, + intValue: { + maximum: 2147483647, + minimum: -2147483648, + type: number, + format: double, + nullable: true + } + }, + additionalProperties: false + }, + ValuesList: { + type: object, + properties: { + simple_keyvalues: { + type: array, + items: { + $ref: #/components/schemas/SimpleKeyvalues + }, + nullable: true + } + }, + additionalProperties: false + }, + Nested: { + type: object, + properties: { + key: { + type: string, + nullable: true + }, + values: { + type: array, + items: { + $ref: #/components/schemas/SimpleKeyvalues + }, + nullable: true + } + }, + additionalProperties: false + }, + TagWithAttribute: { + type: object, + properties: { + orid: { + maximum: 2147483647, + minimum: 1, + type: number, + format: double + }, + value: { + maxLength: 60, + minLength: 1, + type: string, + nullable: true + } + }, + additionalProperties: false + }, + Dummy: { + type: object, + properties: { + name: { + type: string, + nullable: true + }, + random: { + type: string, + nullable: true + }, + tags: { + type: string, + nullable: true + }, + simple_list: { + $ref: #/components/schemas/ValuesList + }, + nested_list: { + type: array, + items: { + $ref: #/components/schemas/Nested + }, + nullable: true + }, + toggle: { + type: boolean + }, + tag-with-attribute: { + $ref: #/components/schemas/TagWithAttribute + }, + hidden: { + type: string, + nullable: true + }, + SF_test: { + type: string, + nullable: true + } + }, + additionalProperties: false + }, + Skjema: { + type: object, + properties: { + melding: { + $ref: #/components/schemas/Dummy + } + }, + additionalProperties: false + } + }, + responses: { + ProblemDetails: { + description: Problem details, + content: { + application/problem+json: { + schema: { + type: object, + properties: { + type: { + type: string, + nullable: true, + example: https://datatracker.ietf.org/doc/html/rfc6902/ + }, + title: { + type: string, + nullable: true, + example: Error in data processing + }, + status: { + type: integer, + format: int32, + nullable: true, + example: 400 + }, + detail: { + type: string, + nullable: true, + example: Actually usefull description of the error + }, + instance: { + type: string, + nullable: true + } + } + } + } + } + } + }, + parameters: { + instanceOwnerPartyId: { + name: instanceOwnerPartyId, + in: path, + description: PartyId for the owner of the instance, this is altinns internal id for the organisation, person or self registered user. Might be the current user, or , + required: true, + schema: { + type: integer + } + }, + instanceGuid: { + name: instanceGuid, + in: path, + description: The guid part of instance.Id, + required: true, + schema: { + type: guid + } + }, + dataGuid: { + name: dataGuid, + in: path, + description: Id of this data element that belongs to an instance, + required: true, + schema: { + type: guid + } + }, + language: { + name: language, + in: query, + description: Some apps make changes to the data models or validation based on the active language of the user, + schema: { + pattern: \w\w, + type: string + }, + example: nb + } + }, + securitySchemes: { + AltinnToken: { + type: http, + description: +Get a token for [localtest](http://local.altinn.cloud/Home/Tokens) +or by exchanging a maskinporten token with the [token exchange endpoint](https://docs.altinn.studio/api/authentication/spec/#/Authentication/get_exchange__tokenProvider_), + scheme: Bearer, + bearerFormat: JWT + } + } + }, + security: [ + {} + ], + externalDocs: { + description: Altinn 3 Documentation, + url: https://docs.altinn.studio + } +} \ No newline at end of file diff --git a/test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.cs b/test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.cs index 187d73a36..71ed86595 100644 --- a/test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.cs +++ b/test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.cs @@ -1,4 +1,3 @@ -using System.Net.Http.Headers; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using Xunit.Abstractions; @@ -30,23 +29,15 @@ public async Task SaveJsonSwagger() } [Fact] - public async Task SaveYamlSwagger() + public async Task SaveCustomOpenApiSpec() { - HttpClient client = GetRootedClient("tdd", "contributer-restriction"); + var org = "tdd"; + var app = "contributer-restriction"; + HttpClient client = GetRootedClient(org, app); // The test project exposes swagger.json at /swagger/v1/swagger.json not /{org}/{app}/swagger/v1/swagger.json - using var request = new HttpRequestMessage(HttpMethod.Get, "/swagger/v1/swagger.yaml"); - request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/yaml")); - HttpResponseMessage response = await client.SendAsync(request); + HttpResponseMessage response = await client.GetAsync($"/{org}/{app}/v1/customOpenapi.json"); string openApiSpec = await response.Content.ReadAsStringAsync(); response.EnsureSuccessStatusCode(); - var originalSpec = await File.ReadAllTextAsync("../../../OpenApi/swagger.yaml"); - await File.WriteAllTextAsync("../../../OpenApi/swagger.yaml", openApiSpec); - openApiSpec - .ReplaceLineEndings() - .Should() - .BeEquivalentTo( - originalSpec.ReplaceLineEndings(), - because: "The OpenAPI spec in the repo should be up do date with the code. If this test fails, update the OpenAPI spec in the repo with the new one from the code. This ensures that tests fails in CI if spec is not updated." - ); + await VerifyJson(response.Content.ReadAsStreamAsync()); } } diff --git a/test/Altinn.App.Api.Tests/OpenApi/swagger.yaml b/test/Altinn.App.Api.Tests/OpenApi/swagger.yaml deleted file mode 100644 index b51ddaa7e..000000000 --- a/test/Altinn.App.Api.Tests/OpenApi/swagger.yaml +++ /dev/null @@ -1,4815 +0,0 @@ -openapi: 3.0.1 -info: - title: Altinn App Api - version: v1 -paths: - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/actions': - post: - tags: - - Actions - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: language - in: query - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UserActionRequest' - text/json: - schema: - $ref: '#/components/schemas/UserActionRequest' - application/*+json: - schema: - $ref: '#/components/schemas/UserActionRequest' - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/UserActionResponse' - application/json: - schema: - $ref: '#/components/schemas/UserActionResponse' - text/json: - schema: - $ref: '#/components/schemas/UserActionResponse' - '400': - description: Bad Request - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '409': - description: Conflict - '500': - description: Internal Server Error - '401': - description: Unauthorized - '/{org}/{app}/api/v1/applicationlanguages': - get: - tags: - - ApplicationLanguage - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - type: array - items: - $ref: '#/components/schemas/ApplicationLanguage' - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/ApplicationLanguage' - text/json: - schema: - type: array - items: - $ref: '#/components/schemas/ApplicationLanguage' - application/xml: - schema: - type: array - items: - $ref: '#/components/schemas/ApplicationLanguage' - text/xml: - schema: - type: array - items: - $ref: '#/components/schemas/ApplicationLanguage' - '404': - description: Not Found - '/{org}/{app}/api/v1/applicationmetadata': - get: - tags: - - ApplicationMetadata - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: checkOrgApp - in: query - schema: - type: boolean - default: true - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/ApplicationMetadata' - application/json: - schema: - $ref: '#/components/schemas/ApplicationMetadata' - text/json: - schema: - $ref: '#/components/schemas/ApplicationMetadata' - '/{org}/{app}/api/v1/meta/authorizationpolicy': - get: - tags: - - ApplicationMetadata - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - type: string - application/json: - schema: - type: string - text/json: - schema: - type: string - application/xml: - schema: - type: string - text/xml: - schema: - type: string - '/{org}/{app}/api/v1/meta/process': - get: - tags: - - ApplicationMetadata - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - type: string - application/json: - schema: - type: string - text/json: - schema: - type: string - application/xml: - schema: - type: string - text/xml: - schema: - type: string - '/{org}/{app}/api/v1/applicationsettings': - get: - tags: - - ApplicationSettings - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/Authentication/keepAlive': - get: - tags: - - Authentication - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/Authentication/invalidatecookie': - put: - tags: - - Authentication - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/authorization/parties/current': - get: - tags: - - Authorization - parameters: - - name: returnPartyObject - in: query - schema: - type: boolean - default: false - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/data': - post: - tags: - - Data - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataType - in: query - schema: - type: string - responses: - '201': - description: Created - content: - text/plain: - schema: - $ref: '#/components/schemas/DataElement' - application/json: - schema: - $ref: '#/components/schemas/DataElement' - text/json: - schema: - $ref: '#/components/schemas/DataElement' - application/xml: - schema: - $ref: '#/components/schemas/DataElement' - text/xml: - schema: - $ref: '#/components/schemas/DataElement' - deprecated: true - patch: - tags: - - Data - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: language - in: query - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/DataPatchRequestMultiple' - text/json: - schema: - $ref: '#/components/schemas/DataPatchRequestMultiple' - application/*+json: - schema: - $ref: '#/components/schemas/DataPatchRequestMultiple' - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/DataPatchResponseMultiple' - application/json: - schema: - $ref: '#/components/schemas/DataPatchResponseMultiple' - text/json: - schema: - $ref: '#/components/schemas/DataPatchResponseMultiple' - '409': - description: Conflict - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '422': - description: Unprocessable Content - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '400': - description: Bad Request - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataType}': - post: - tags: - - Data - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataType - in: path - required: true - schema: - type: string - - name: ignoredValidators - in: query - schema: - type: string - - name: language - in: query - schema: - type: string - responses: - '201': - description: Created - content: - text/plain: - schema: - $ref: '#/components/schemas/DataPostResponse' - application/json: - schema: - $ref: '#/components/schemas/DataPostResponse' - text/json: - schema: - $ref: '#/components/schemas/DataPostResponse' - '409': - description: Conflict - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '400': - description: Bad Request - content: - text/plain: - schema: - $ref: '#/components/schemas/DataPostErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/DataPostErrorResponse' - text/json: - schema: - $ref: '#/components/schemas/DataPostErrorResponse' - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}': - get: - tags: - - Data - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - - name: includeRowId - in: query - schema: - type: boolean - default: false - - name: language - in: query - schema: - type: string - responses: - '200': - description: OK - put: - tags: - - Data - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - - name: language - in: query - schema: - type: string - responses: - '201': - description: Created - content: - text/plain: - schema: - $ref: '#/components/schemas/DataElement' - application/json: - schema: - $ref: '#/components/schemas/DataElement' - text/json: - schema: - $ref: '#/components/schemas/DataElement' - application/xml: - schema: - $ref: '#/components/schemas/DataElement' - text/xml: - schema: - $ref: '#/components/schemas/DataElement' - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/CalculationResult' - application/json: - schema: - $ref: '#/components/schemas/CalculationResult' - text/json: - schema: - $ref: '#/components/schemas/CalculationResult' - patch: - tags: - - Data - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - - name: language - in: query - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/DataPatchRequest' - text/json: - schema: - $ref: '#/components/schemas/DataPatchRequest' - application/*+json: - schema: - $ref: '#/components/schemas/DataPatchRequest' - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/DataPatchResponse' - application/json: - schema: - $ref: '#/components/schemas/DataPatchResponse' - text/json: - schema: - $ref: '#/components/schemas/DataPatchResponse' - '409': - description: Conflict - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '422': - description: Unprocessable Content - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - deprecated: true - delete: - tags: - - Data - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - - name: ignoredValidators - in: query - schema: - type: string - - name: language - in: query - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/DataPostResponse' - application/json: - schema: - $ref: '#/components/schemas/DataPostResponse' - text/json: - schema: - $ref: '#/components/schemas/DataPostResponse' - '/{org}/{app}/api/datalists/{id}': - get: - tags: - - DataLists - parameters: - - name: id - in: path - required: true - schema: - type: string - - name: queryParams - in: query - schema: - type: object - additionalProperties: - type: string - - name: language - in: query - schema: - type: string - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/datalists/{id}': - get: - tags: - - DataLists - parameters: - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: id - in: path - required: true - schema: - type: string - - name: queryParams - in: query - schema: - type: object - additionalProperties: - type: string - - name: language - in: query - schema: - type: string - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/tags': - get: - tags: - - DataTags - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/TagsList' - post: - tags: - - DataTags - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - requestBody: - content: - application/json: - schema: - type: string - responses: - '201': - description: Created - content: - application/json: - schema: - $ref: '#/components/schemas/TagsList' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/tags/{tag}': - delete: - tags: - - DataTags - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - - name: tag - in: path - required: true - schema: - type: string - responses: - '204': - description: No Content - '/{org}/{app}/api/v1/eventsreceiver': - post: - tags: - - EventsReceiver - parameters: - - name: code - in: query - schema: - type: string - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CloudEvent' - text/json: - schema: - $ref: '#/components/schemas/CloudEvent' - application/*+json: - schema: - $ref: '#/components/schemas/CloudEvent' - responses: - '200': - description: OK - '425': - description: Too Early - '500': - description: Internal Server Error - '401': - description: Unauthorized - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/api/external/{externalApiId}': - get: - tags: - - ExternalApi - parameters: - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: externalApiId - in: path - required: true - schema: - type: string - - name: queryParams - in: query - schema: - type: object - additionalProperties: - type: string - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/filescanresult': - get: - tags: - - FileScan - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/InstanceFileScanResult' - application/json: - schema: - $ref: '#/components/schemas/InstanceFileScanResult' - text/json: - schema: - $ref: '#/components/schemas/InstanceFileScanResult' - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}': - get: - tags: - - Home - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: dontChooseReportee - in: query - schema: - type: boolean - responses: - '200': - description: OK - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}': - get: - tags: - - Instances - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Instance' - '400': - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - delete: - tags: - - Instances - parameters: - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: hard - in: query - schema: - type: boolean - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Instance' - '/{org}/{app}/instances': - post: - tags: - - Instances - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: query - schema: - type: integer - format: int32 - - name: language - in: query - schema: - type: string - responses: - '201': - description: Created - content: - application/json: - schema: - $ref: '#/components/schemas/Instance' - '400': - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/create': - post: - tags: - - Instances - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/InstansiationInstance' - text/json: - schema: - $ref: '#/components/schemas/InstansiationInstance' - application/*+json: - schema: - $ref: '#/components/schemas/InstansiationInstance' - responses: - '201': - description: Created - content: - application/json: - schema: - $ref: '#/components/schemas/Instance' - '400': - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/complete': - post: - tags: - - Instances - parameters: - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Instance' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/substatus': - put: - tags: - - Instances - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/Substatus' - text/json: - schema: - $ref: '#/components/schemas/Substatus' - application/*+json: - schema: - $ref: '#/components/schemas/Substatus' - application/xml: - schema: - $ref: '#/components/schemas/Substatus' - text/xml: - schema: - $ref: '#/components/schemas/Substatus' - application/*+xml: - schema: - $ref: '#/components/schemas/Substatus' - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Instance' - '400': - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/active': - get: - tags: - - Instances - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - responses: - '200': - description: OK - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/SimpleInstance' - '/{org}/{app}/api/options/{optionsId}': - get: - tags: - - Options - parameters: - - name: optionsId - in: path - required: true - schema: - type: string - - name: queryParams - in: query - schema: - type: object - additionalProperties: - type: string - - name: language - in: query - schema: - type: string - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/options/{optionsId}': - get: - tags: - - Options - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: optionsId - in: path - required: true - schema: - type: string - - name: language - in: query - schema: - type: string - - name: queryParams - in: query - schema: - type: object - additionalProperties: - type: string - responses: - '200': - description: OK - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/pages/order': - post: - tags: - - Pages - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: layoutSetId - in: query - schema: - type: string - - name: currentPage - in: query - schema: - type: string - - name: dataTypeId - in: query - schema: - type: string - requestBody: - content: - application/json: - schema: { } - text/json: - schema: { } - application/*+json: - schema: { } - application/xml: - schema: { } - text/xml: - schema: { } - application/*+xml: - schema: { } - responses: - '200': - description: OK - content: - text/plain: - schema: - type: array - items: - type: string - application/json: - schema: - type: array - items: - type: string - text/json: - schema: - type: array - items: - type: string - application/xml: - schema: - type: array - items: - type: string - text/xml: - schema: - type: array - items: - type: string - deprecated: true - '/{org}/{app}/api/v1/parties': - get: - tags: - - Parties - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: allowedToInstantiateFilter - in: query - schema: - type: boolean - default: false - responses: - '200': - description: OK - '/{org}/{app}/api/v1/parties/validateInstantiation': - post: - tags: - - Parties - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: partyId - in: query - schema: - type: integer - format: int32 - responses: - '200': - description: OK - '/{org}/{app}/api/v1/parties/{partyId}': - put: - tags: - - Parties - parameters: - - name: partyId - in: path - required: true - schema: - type: integer - format: int32 - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/payment': - get: - tags: - - Payment - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: language - in: query - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/PaymentInformation' - application/json: - schema: - $ref: '#/components/schemas/PaymentInformation' - text/json: - schema: - $ref: '#/components/schemas/PaymentInformation' - application/xml: - schema: - $ref: '#/components/schemas/PaymentInformation' - text/xml: - schema: - $ref: '#/components/schemas/PaymentInformation' - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/payment/order-details': - get: - tags: - - Payment - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: language - in: query - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/OrderDetails' - application/json: - schema: - $ref: '#/components/schemas/OrderDetails' - text/json: - schema: - $ref: '#/components/schemas/OrderDetails' - application/xml: - schema: - $ref: '#/components/schemas/OrderDetails' - text/xml: - schema: - $ref: '#/components/schemas/OrderDetails' - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/pdf/format': - get: - tags: - - Pdf - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - responses: - '200': - description: OK - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/process': - get: - tags: - - Process - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/AppProcessState' - application/json: - schema: - $ref: '#/components/schemas/AppProcessState' - text/json: - schema: - $ref: '#/components/schemas/AppProcessState' - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/process/start': - post: - tags: - - Process - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: startEvent - in: query - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/AppProcessState' - application/json: - schema: - $ref: '#/components/schemas/AppProcessState' - text/json: - schema: - $ref: '#/components/schemas/AppProcessState' - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '409': - description: Conflict - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/process/next': - get: - tags: - - Process - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - responses: - '200': - description: OK - content: - text/plain: - schema: - type: array - items: - type: string - application/json: - schema: - type: array - items: - type: string - text/json: - schema: - type: array - items: - type: string - application/xml: - schema: - type: array - items: - type: string - text/xml: - schema: - type: array - items: - type: string - '409': - description: Conflict - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - deprecated: true - put: - tags: - - Process - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: elementId - in: query - schema: - type: string - - name: language - in: query - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/ProcessNext' - text/json: - schema: - $ref: '#/components/schemas/ProcessNext' - application/*+json: - schema: - $ref: '#/components/schemas/ProcessNext' - application/xml: - schema: - $ref: '#/components/schemas/ProcessNext' - text/xml: - schema: - $ref: '#/components/schemas/ProcessNext' - application/*+xml: - schema: - $ref: '#/components/schemas/ProcessNext' - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/AppProcessState' - application/json: - schema: - $ref: '#/components/schemas/AppProcessState' - text/json: - schema: - $ref: '#/components/schemas/AppProcessState' - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '409': - description: Conflict - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/process/completeProcess': - put: - tags: - - Process - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: language - in: query - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/AppProcessState' - application/json: - schema: - $ref: '#/components/schemas/AppProcessState' - text/json: - schema: - $ref: '#/components/schemas/AppProcessState' - '404': - description: Not Found - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '409': - description: Conflict - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/process/history': - get: - tags: - - Process - parameters: - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/ProcessHistoryList' - application/json: - schema: - $ref: '#/components/schemas/ProcessHistoryList' - text/json: - schema: - $ref: '#/components/schemas/ProcessHistoryList' - application/xml: - schema: - $ref: '#/components/schemas/ProcessHistoryList' - text/xml: - schema: - $ref: '#/components/schemas/ProcessHistoryList' - '/{org}/{app}/api/v1/profile/user': - get: - tags: - - Profile - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/v1/redirect': - get: - tags: - - Redirect - parameters: - - name: url - in: query - required: true - schema: - type: string - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - type: string - application/json: - schema: - type: string - text/json: - schema: - type: string - application/xml: - schema: - type: string - text/xml: - schema: - type: string - '400': - description: Bad Request - content: - text/plain: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/json: - schema: - $ref: '#/components/schemas/ProblemDetails' - application/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - text/xml: - schema: - $ref: '#/components/schemas/ProblemDetails' - '/{org}/{app}/api/jsonschema/{id}': - get: - tags: - - Resource - parameters: - - name: id - in: path - required: true - schema: - type: string - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/layouts': - get: - tags: - - Resource - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/layouts/{id}': - get: - tags: - - Resource - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/layoutsettings': - get: - tags: - - Resource - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/layoutsettings/{id}': - get: - tags: - - Resource - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/layoutsets': - get: - tags: - - Resource - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/rulehandler/{id}': - get: - tags: - - Resource - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/ruleconfiguration/{id}': - get: - tags: - - Resource - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/v1/footer': - get: - tags: - - Resource - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/api/validationconfig/{dataTypeId}': - get: - tags: - - Resource - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: dataTypeId - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - '/{org}/{app}/v1/data': - get: - tags: - - StatelessData - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: dataType - in: query - schema: - type: string - - name: party - in: header - schema: - type: string - - name: language - in: query - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/DataElement' - application/json: - schema: - $ref: '#/components/schemas/DataElement' - text/json: - schema: - $ref: '#/components/schemas/DataElement' - application/xml: - schema: - $ref: '#/components/schemas/DataElement' - text/xml: - schema: - $ref: '#/components/schemas/DataElement' - post: - tags: - - StatelessData - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: dataType - in: query - schema: - type: string - - name: party - in: header - schema: - type: string - - name: language - in: query - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/DataElement' - application/json: - schema: - $ref: '#/components/schemas/DataElement' - text/json: - schema: - $ref: '#/components/schemas/DataElement' - application/xml: - schema: - $ref: '#/components/schemas/DataElement' - text/xml: - schema: - $ref: '#/components/schemas/DataElement' - '/{org}/{app}/v1/data/anonymous': - get: - tags: - - StatelessData - parameters: - - name: dataType - in: query - schema: - type: string - - name: language - in: query - schema: - type: string - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/DataElement' - application/json: - schema: - $ref: '#/components/schemas/DataElement' - text/json: - schema: - $ref: '#/components/schemas/DataElement' - application/xml: - schema: - $ref: '#/components/schemas/DataElement' - text/xml: - schema: - $ref: '#/components/schemas/DataElement' - post: - tags: - - StatelessData - parameters: - - name: dataType - in: query - schema: - type: string - - name: language - in: query - schema: - type: string - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/DataElement' - application/json: - schema: - $ref: '#/components/schemas/DataElement' - text/json: - schema: - $ref: '#/components/schemas/DataElement' - application/xml: - schema: - $ref: '#/components/schemas/DataElement' - text/xml: - schema: - $ref: '#/components/schemas/DataElement' - '/{org}/{app}/v1/pages/order': - post: - tags: - - StatelessPages - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: layoutSetId - in: query - schema: - type: string - - name: currentPage - in: query - schema: - type: string - - name: dataTypeId - in: query - schema: - type: string - requestBody: - content: - application/json: - schema: { } - text/json: - schema: { } - application/*+json: - schema: { } - application/xml: - schema: { } - text/xml: - schema: { } - application/*+xml: - schema: { } - responses: - '200': - description: OK - content: - text/plain: - schema: - type: array - items: - type: string - application/json: - schema: - type: array - items: - type: string - text/json: - schema: - type: array - items: - type: string - application/xml: - schema: - type: array - items: - type: string - text/xml: - schema: - type: array - items: - type: string - deprecated: true - '/{org}/{app}/api/v1/texts/{language}': - get: - tags: - - Texts - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: language - in: path - required: true - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/TextResource' - application/json: - schema: - $ref: '#/components/schemas/TextResource' - text/json: - schema: - $ref: '#/components/schemas/TextResource' - application/xml: - schema: - $ref: '#/components/schemas/TextResource' - text/xml: - schema: - $ref: '#/components/schemas/TextResource' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/data/{dataGuid}/user-defined-metadata': - get: - tags: - - UserDefinedMetadata - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/UserDefinedMetadataDto' - put: - tags: - - UserDefinedMetadata - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UserDefinedMetadataDto' - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/UserDefinedMetadataDto' - '/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/validate': - get: - tags: - - Validate - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerPartyId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceGuid - in: path - required: true - schema: - type: string - format: uuid - - name: ignoredValidators - in: query - schema: - type: string - - name: onlyIncrementalValidators - in: query - schema: - type: boolean - - name: language - in: query - schema: - type: string - responses: - '200': - description: OK - content: - text/plain: - schema: - $ref: '#/components/schemas/ValidationIssueWithSource' - application/json: - schema: - $ref: '#/components/schemas/ValidationIssueWithSource' - text/json: - schema: - $ref: '#/components/schemas/ValidationIssueWithSource' - application/xml: - schema: - $ref: '#/components/schemas/ValidationIssueWithSource' - text/xml: - schema: - $ref: '#/components/schemas/ValidationIssueWithSource' - '/{org}/{app}/instances/{instanceOwnerId}/{instanceId}/data/{dataGuid}/validate': - get: - tags: - - Validate - parameters: - - name: org - in: path - required: true - schema: - type: string - - name: app - in: path - required: true - schema: - type: string - - name: instanceOwnerId - in: path - required: true - schema: - type: integer - format: int32 - - name: instanceId - in: path - required: true - schema: - type: string - format: uuid - - name: dataGuid - in: path - required: true - schema: - type: string - format: uuid - - name: language - in: query - schema: - type: string - responses: - '200': - description: OK - deprecated: true -components: - schemas: - ActionError: - type: object - properties: - code: - type: string - nullable: true - message: - type: string - nullable: true - metadata: - type: object - additionalProperties: - type: string - nullable: true - additionalProperties: false - ActionType: - enum: - - 0 - - 1 - type: integer - format: int32 - Address: - type: object - properties: - name: - type: string - nullable: true - addressLine1: - type: string - nullable: true - addressLine2: - type: string - nullable: true - postalCode: - type: string - nullable: true - city: - type: string - nullable: true - country: - type: string - nullable: true - additionalProperties: false - AppProcessElementInfo: - type: object - properties: - flow: - type: integer - format: int32 - nullable: true - started: - type: string - format: date-time - nullable: true - elementId: - type: string - nullable: true - name: - type: string - nullable: true - altinnTaskType: - type: string - nullable: true - ended: - type: string - format: date-time - nullable: true - validated: - $ref: '#/components/schemas/ValidationStatus' - flowType: - type: string - nullable: true - actions: - type: object - additionalProperties: - type: boolean - nullable: true - userActions: - type: array - items: - $ref: '#/components/schemas/UserAction' - nullable: true - read: - type: boolean - write: - type: boolean - additionalProperties: false - AppProcessState: - type: object - properties: - started: - type: string - format: date-time - nullable: true - startEvent: - type: string - nullable: true - currentTask: - $ref: '#/components/schemas/AppProcessElementInfo' - ended: - type: string - format: date-time - nullable: true - endEvent: - type: string - nullable: true - processTasks: - type: array - items: - $ref: '#/components/schemas/AppProcessTaskTypeInfo' - nullable: true - additionalProperties: false - AppProcessTaskTypeInfo: - type: object - properties: - altinnTaskType: - type: string - nullable: true - elementId: - type: string - nullable: true - additionalProperties: false - ApplicationLanguage: - type: object - properties: - language: - type: string - nullable: true - additionalProperties: false - ApplicationLogic: - type: object - properties: - autoCreate: - type: boolean - nullable: true - classRef: - type: string - nullable: true - schemaRef: - type: string - nullable: true - allowAnonymousOnStateless: - type: boolean - autoDeleteOnProcessEnd: - type: boolean - disallowUserCreate: - type: boolean - disallowUserDelete: - type: boolean - allowInSubform: - type: boolean - deprecated: true - shadowFields: - $ref: '#/components/schemas/ShadowFields' - additionalProperties: false - ApplicationMetadata: - type: object - properties: - created: - type: string - format: date-time - nullable: true - createdBy: - type: string - nullable: true - lastChanged: - type: string - format: date-time - nullable: true - lastChangedBy: - type: string - nullable: true - versionId: - type: string - nullable: true - org: - type: string - nullable: true - title: - type: object - additionalProperties: - type: string - nullable: true - nullable: true - validFrom: - type: string - format: date-time - nullable: true - validTo: - type: string - format: date-time - nullable: true - processId: - type: string - nullable: true - dataTypes: - type: array - items: - $ref: '#/components/schemas/DataType' - nullable: true - partyTypesAllowed: - $ref: '#/components/schemas/PartyTypesAllowed' - autoDeleteOnProcessEnd: - type: boolean - presentationFields: - type: array - items: - $ref: '#/components/schemas/DataField' - nullable: true - dataFields: - type: array - items: - $ref: '#/components/schemas/DataField' - nullable: true - eFormidling: - $ref: '#/components/schemas/EFormidlingContract' - onEntry: - $ref: '#/components/schemas/OnEntry' - messageBoxConfig: - $ref: '#/components/schemas/MessageBoxConfig' - copyInstanceSettings: - $ref: '#/components/schemas/CopyInstanceSettings' - storageAccountNumber: - type: integer - format: int32 - nullable: true - disallowUserInstantiation: - type: boolean - id: - type: string - nullable: true - features: - type: object - additionalProperties: - type: boolean - nullable: true - logo: - $ref: '#/components/schemas/Logo' - altinnNugetVersion: - type: string - nullable: true - externalApiIds: - type: array - items: - type: string - nullable: true - additionalProperties: { } - CalculationResult: - type: object - properties: - created: - type: string - format: date-time - nullable: true - createdBy: - type: string - nullable: true - lastChanged: - type: string - format: date-time - nullable: true - lastChangedBy: - type: string - nullable: true - id: - type: string - nullable: true - instanceGuid: - type: string - nullable: true - dataType: - type: string - nullable: true - filename: - type: string - nullable: true - contentType: - type: string - nullable: true - blobStoragePath: - type: string - nullable: true - selfLinks: - $ref: '#/components/schemas/ResourceLinks' - size: - type: integer - format: int64 - contentHash: - type: string - nullable: true - locked: - type: boolean - refs: - type: array - items: - type: string - format: uuid - nullable: true - isRead: - type: boolean - tags: - type: array - items: - type: string - nullable: true - userDefinedMetadata: - type: array - items: - $ref: '#/components/schemas/KeyValueEntry' - nullable: true - metadata: - type: array - items: - $ref: '#/components/schemas/KeyValueEntry' - nullable: true - deleteStatus: - $ref: '#/components/schemas/DeleteStatus' - fileScanResult: - $ref: '#/components/schemas/FileScanResult' - references: - type: array - items: - $ref: '#/components/schemas/Reference' - nullable: true - changedFields: - type: object - additionalProperties: - nullable: true - nullable: true - additionalProperties: false - CardDetails: - type: object - properties: - maskedPan: - type: string - nullable: true - expiryDate: - type: string - nullable: true - additionalProperties: false - ClientAction: - type: object - properties: - id: - type: string - nullable: true - metadata: - type: object - additionalProperties: { } - nullable: true - additionalProperties: false - CloudEvent: - type: object - properties: - id: - type: string - nullable: true - source: - type: string - format: uri - nullable: true - specversion: - type: string - nullable: true - type: - type: string - nullable: true - subject: - type: string - nullable: true - time: - type: string - format: date-time - alternativesubject: - type: string - nullable: true - data: - nullable: true - dataschema: - type: string - format: uri - nullable: true - contenttype: - $ref: '#/components/schemas/ContentType' - additionalProperties: false - CompleteConfirmation: - type: object - properties: - stakeholderId: - type: string - nullable: true - confirmedOn: - type: string - format: date-time - additionalProperties: false - ContentType: - type: object - properties: - boundary: - type: string - nullable: true - charSet: - type: string - nullable: true - mediaType: - type: string - nullable: true - name: - type: string - nullable: true - parameters: - type: array - items: { } - nullable: true - readOnly: true - additionalProperties: false - CopyInstanceSettings: - type: object - properties: - enabled: - type: boolean - excludedDataTypes: - type: array - items: - type: string - nullable: true - excludedDataFields: - type: array - items: - type: string - nullable: true - additionalProperties: false - DataElement: - type: object - properties: - created: - type: string - format: date-time - nullable: true - createdBy: - type: string - nullable: true - lastChanged: - type: string - format: date-time - nullable: true - lastChangedBy: - type: string - nullable: true - id: - type: string - nullable: true - instanceGuid: - type: string - nullable: true - dataType: - type: string - nullable: true - filename: - type: string - nullable: true - contentType: - type: string - nullable: true - blobStoragePath: - type: string - nullable: true - selfLinks: - $ref: '#/components/schemas/ResourceLinks' - size: - type: integer - format: int64 - contentHash: - type: string - nullable: true - locked: - type: boolean - refs: - type: array - items: - type: string - format: uuid - nullable: true - isRead: - type: boolean - tags: - type: array - items: - type: string - nullable: true - userDefinedMetadata: - type: array - items: - $ref: '#/components/schemas/KeyValueEntry' - nullable: true - metadata: - type: array - items: - $ref: '#/components/schemas/KeyValueEntry' - nullable: true - deleteStatus: - $ref: '#/components/schemas/DeleteStatus' - fileScanResult: - $ref: '#/components/schemas/FileScanResult' - references: - type: array - items: - $ref: '#/components/schemas/Reference' - nullable: true - additionalProperties: false - DataElementFileScanResult: - type: object - properties: - id: - type: string - nullable: true - fileScanResult: - $ref: '#/components/schemas/FileScanResult' - additionalProperties: false - DataField: - type: object - properties: - id: - type: string - nullable: true - path: - type: string - nullable: true - dataTypeId: - type: string - nullable: true - additionalProperties: false - DataModelPairResponse: - type: object - properties: - dataElementId: - type: string - format: uuid - data: - nullable: true - additionalProperties: false - DataPatchRequest: - required: - - ignoredValidators - - patch - type: object - properties: - patch: - $ref: '#/components/schemas/JsonPatch' - ignoredValidators: - type: array - items: - type: string - nullable: true - additionalProperties: false - DataPatchRequestMultiple: - required: - - ignoredValidators - - patches - type: object - properties: - patches: - type: array - items: - $ref: '#/components/schemas/PatchListItem' - nullable: true - ignoredValidators: - type: array - items: - type: string - nullable: true - additionalProperties: false - DataPatchResponse: - required: - - instance - - newDataModel - - validationIssues - type: object - properties: - validationIssues: - type: object - additionalProperties: - type: array - items: - $ref: '#/components/schemas/ValidationIssueWithSource' - nullable: true - newDataModel: - nullable: true - instance: - $ref: '#/components/schemas/Instance' - additionalProperties: false - DataPatchResponseMultiple: - required: - - instance - - newDataModels - - validationIssues - type: object - properties: - validationIssues: - type: array - items: - $ref: '#/components/schemas/ValidationSourcePair' - nullable: true - newDataModels: - type: array - items: - $ref: '#/components/schemas/DataModelPairResponse' - nullable: true - instance: - $ref: '#/components/schemas/Instance' - additionalProperties: false - DataPostErrorResponse: - type: object - properties: - type: - type: string - nullable: true - title: - type: string - nullable: true - status: - type: integer - format: int32 - nullable: true - detail: - type: string - nullable: true - instance: - type: string - nullable: true - uploadValidationIssues: - type: array - items: - $ref: '#/components/schemas/ValidationIssueWithSource' - nullable: true - readOnly: true - additionalProperties: { } - DataPostResponse: - required: - - instance - - newDataElementId - - newDataModels - - validationIssues - type: object - properties: - newDataElementId: - type: string - format: uuid - instance: - $ref: '#/components/schemas/Instance' - validationIssues: - type: array - items: - $ref: '#/components/schemas/ValidationSourcePair' - nullable: true - newDataModels: - type: array - items: - $ref: '#/components/schemas/DataModelPairResponse' - nullable: true - additionalProperties: false - DataType: - type: object - properties: - id: - type: string - nullable: true - description: - type: object - additionalProperties: - type: string - nullable: true - allowedContentTypes: - type: array - items: - type: string - nullable: true - allowedContributers: - type: array - items: - type: string - nullable: true - appLogic: - $ref: '#/components/schemas/ApplicationLogic' - taskId: - type: string - nullable: true - maxSize: - type: integer - format: int32 - nullable: true - maxCount: - type: integer - format: int32 - default: 1 - minCount: - type: integer - format: int32 - default: 1 - grouping: - type: string - nullable: true - enablePdfCreation: - type: boolean - enableFileScan: - type: boolean - validationErrorOnPendingFileScan: - type: boolean - enabledFileAnalysers: - type: array - items: - type: string - nullable: true - enabledFileValidators: - type: array - items: - type: string - nullable: true - allowedKeysForUserDefinedMetadata: - type: array - items: - type: string - nullable: true - additionalProperties: false - DeleteStatus: - type: object - properties: - isHardDeleted: - type: boolean - hardDeleted: - type: string - format: date-time - nullable: true - additionalProperties: false - EFormidlingContract: - type: object - properties: - serviceId: - type: string - nullable: true - dpfShipmentType: - type: string - nullable: true - receiver: - type: string - nullable: true - sendAfterTaskId: - type: string - nullable: true - process: - type: string - nullable: true - standard: - type: string - nullable: true - typeVersion: - type: string - nullable: true - type: - type: string - nullable: true - securityLevel: - type: integer - format: int32 - dataTypes: - type: array - items: - type: string - nullable: true - additionalProperties: false - FileScanResult: - enum: - - NotApplicable - - Pending - - Clean - - Infected - type: string - HideSettings: - type: object - properties: - hideAlways: - type: boolean - hideOnTask: - type: array - items: - type: string - nullable: true - additionalProperties: false - Instance: - type: object - properties: - created: - type: string - format: date-time - nullable: true - createdBy: - type: string - nullable: true - lastChanged: - type: string - format: date-time - nullable: true - lastChangedBy: - type: string - nullable: true - id: - type: string - nullable: true - instanceOwner: - $ref: '#/components/schemas/InstanceOwner' - appId: - type: string - nullable: true - org: - type: string - nullable: true - selfLinks: - $ref: '#/components/schemas/ResourceLinks' - dueBefore: - type: string - format: date-time - nullable: true - visibleAfter: - type: string - format: date-time - nullable: true - process: - $ref: '#/components/schemas/ProcessState' - status: - $ref: '#/components/schemas/InstanceStatus' - completeConfirmations: - type: array - items: - $ref: '#/components/schemas/CompleteConfirmation' - nullable: true - data: - type: array - items: - $ref: '#/components/schemas/DataElement' - nullable: true - presentationTexts: - type: object - additionalProperties: - type: string - nullable: true - nullable: true - dataValues: - type: object - additionalProperties: - type: string - nullable: true - nullable: true - additionalProperties: false - InstanceFileScanResult: - type: object - properties: - id: - type: string - nullable: true - readOnly: true - fileScanResult: - $ref: '#/components/schemas/FileScanResult' - data: - type: array - items: - $ref: '#/components/schemas/DataElementFileScanResult' - nullable: true - readOnly: true - additionalProperties: false - InstanceOwner: - type: object - properties: - partyId: - type: string - nullable: true - personNumber: - type: string - nullable: true - organisationNumber: - type: string - nullable: true - username: - type: string - nullable: true - additionalProperties: false - InstanceSelection: - type: object - properties: - rowsPerPageOptions: - type: array - items: - type: integer - format: int32 - nullable: true - defaultRowsPerPage: - type: integer - format: int32 - nullable: true - defaultSelectedOption: - type: integer - format: int32 - nullable: true - sortDirection: - type: string - nullable: true - additionalProperties: false - InstanceStatus: - type: object - properties: - isArchived: - type: boolean - archived: - type: string - format: date-time - nullable: true - isSoftDeleted: - type: boolean - softDeleted: - type: string - format: date-time - nullable: true - isHardDeleted: - type: boolean - hardDeleted: - type: string - format: date-time - nullable: true - readStatus: - $ref: '#/components/schemas/ReadStatus' - substatus: - $ref: '#/components/schemas/Substatus' - additionalProperties: false - InstansiationInstance: - type: object - properties: - instanceOwner: - $ref: '#/components/schemas/InstanceOwner' - dueBefore: - type: string - format: date-time - nullable: true - visibleAfter: - type: string - format: date-time - nullable: true - prefill: - type: object - additionalProperties: - type: string - nullable: true - nullable: true - sourceInstanceId: - type: string - nullable: true - additionalProperties: false - InvoiceDetails: - type: object - properties: - invoiceNumber: - type: string - nullable: true - additionalProperties: false - JsonNode: - type: object - properties: - options: - $ref: '#/components/schemas/JsonNodeOptions' - parent: - $ref: '#/components/schemas/JsonNode' - root: - $ref: '#/components/schemas/JsonNode' - additionalProperties: false - JsonNodeOptions: - type: object - properties: - propertyNameCaseInsensitive: - type: boolean - additionalProperties: false - JsonPatch: - type: object - properties: - operations: - type: array - items: - $ref: '#/components/schemas/PatchOperation' - nullable: true - additionalProperties: false - KeyValueEntry: - type: object - properties: - key: - type: string - nullable: true - value: - type: string - nullable: true - additionalProperties: false - Logo: - type: object - properties: - displayAppOwnerNameInHeader: - type: boolean - source: - type: string - nullable: true - size: - type: string - nullable: true - additionalProperties: false - MessageBoxConfig: - type: object - properties: - hideSettings: - $ref: '#/components/schemas/HideSettings' - additionalProperties: false - OnEntry: - type: object - properties: - show: - type: string - nullable: true - instanceSelection: - $ref: '#/components/schemas/InstanceSelection' - additionalProperties: false - OnEntryConfig: - type: object - properties: - show: - type: string - nullable: true - additionalProperties: false - OperationType: - enum: - - Unknown - - add - - remove - - replace - - move - - copy - - test - type: string - OrderDetails: - required: - - currency - - orderLines - - paymentProcessorId - - receiver - type: object - properties: - paymentProcessorId: - type: string - nullable: true - receiver: - $ref: '#/components/schemas/PaymentReceiver' - payer: - $ref: '#/components/schemas/Payer' - currency: - type: string - nullable: true - orderLines: - type: array - items: - $ref: '#/components/schemas/PaymentOrderLine' - nullable: true - allowedPayerTypes: - type: array - items: - $ref: '#/components/schemas/PayerType' - nullable: true - orderReference: - type: string - nullable: true - totalPriceExVat: - type: number - format: double - readOnly: true - totalVat: - type: number - format: double - readOnly: true - totalPriceIncVat: - type: number - format: double - readOnly: true - additionalProperties: false - PartyTypesAllowed: - type: object - properties: - bankruptcyEstate: - type: boolean - organisation: - type: boolean - person: - type: boolean - subUnit: - type: boolean - additionalProperties: false - PatchListItem: - type: object - properties: - dataElementId: - type: string - format: uuid - patch: - $ref: '#/components/schemas/JsonPatch' - additionalProperties: false - PatchOperation: - type: object - properties: - op: - $ref: '#/components/schemas/OperationType' - from: - type: array - items: - type: string - nullable: true - readOnly: true - path: - type: array - items: - type: string - nullable: true - readOnly: true - value: - $ref: '#/components/schemas/JsonNode' - additionalProperties: false - Payer: - type: object - properties: - privatePerson: - $ref: '#/components/schemas/PayerPrivatePerson' - company: - $ref: '#/components/schemas/PayerCompany' - shippingAddress: - $ref: '#/components/schemas/Address' - billingAddress: - $ref: '#/components/schemas/Address' - additionalProperties: false - PayerCompany: - type: object - properties: - organisationNumber: - type: string - nullable: true - name: - type: string - nullable: true - contactPerson: - $ref: '#/components/schemas/PayerPrivatePerson' - additionalProperties: false - PayerPrivatePerson: - type: object - properties: - firstName: - type: string - nullable: true - lastName: - type: string - nullable: true - email: - type: string - nullable: true - phoneNumber: - $ref: '#/components/schemas/PhoneNumber' - additionalProperties: false - PayerType: - enum: - - Person - - Company - type: string - PaymentDetails: - required: - - paymentId - type: object - properties: - paymentId: - type: string - nullable: true - redirectUrl: - type: string - nullable: true - payer: - $ref: '#/components/schemas/Payer' - paymentType: - type: string - nullable: true - paymentMethod: - type: string - nullable: true - createdDate: - type: string - nullable: true - chargedDate: - type: string - nullable: true - invoiceDetails: - $ref: '#/components/schemas/InvoiceDetails' - cardDetails: - $ref: '#/components/schemas/CardDetails' - additionalProperties: false - PaymentInformation: - required: - - orderDetails - - status - - taskId - type: object - properties: - taskId: - type: string - nullable: true - status: - $ref: '#/components/schemas/PaymentStatus' - orderDetails: - $ref: '#/components/schemas/OrderDetails' - paymentDetails: - $ref: '#/components/schemas/PaymentDetails' - additionalProperties: false - PaymentOrderLine: - required: - - id - - name - - priceExVat - - vatPercent - type: object - properties: - id: - type: string - nullable: true - name: - type: string - nullable: true - textResourceKey: - type: string - nullable: true - priceExVat: - type: number - format: double - quantity: - type: integer - format: int32 - vatPercent: - type: number - format: double - unit: - type: string - nullable: true - additionalProperties: false - PaymentReceiver: - type: object - properties: - organisationNumber: - type: string - nullable: true - name: - type: string - nullable: true - postalAddress: - $ref: '#/components/schemas/Address' - bankAccountNumber: - type: string - nullable: true - email: - type: string - nullable: true - phoneNumber: - $ref: '#/components/schemas/PhoneNumber' - additionalProperties: false - PaymentStatus: - enum: - - Uninitialized - - Created - - Paid - - Failed - - Cancelled - - Skipped - type: string - PhoneNumber: - type: object - properties: - prefix: - type: string - nullable: true - number: - type: string - nullable: true - additionalProperties: false - ProblemDetails: - type: object - properties: - type: - type: string - nullable: true - title: - type: string - nullable: true - status: - type: integer - format: int32 - nullable: true - detail: - type: string - nullable: true - instance: - type: string - nullable: true - additionalProperties: { } - ProcessElementInfo: - type: object - properties: - flow: - type: integer - format: int32 - nullable: true - started: - type: string - format: date-time - nullable: true - elementId: - type: string - nullable: true - name: - type: string - nullable: true - altinnTaskType: - type: string - nullable: true - ended: - type: string - format: date-time - nullable: true - validated: - $ref: '#/components/schemas/ValidationStatus' - flowType: - type: string - nullable: true - additionalProperties: false - ProcessHistoryItem: - type: object - properties: - eventType: - type: string - nullable: true - elementId: - type: string - nullable: true - occured: - type: string - format: date-time - nullable: true - started: - type: string - format: date-time - nullable: true - ended: - type: string - format: date-time - nullable: true - performedBy: - type: string - nullable: true - additionalProperties: false - ProcessHistoryList: - type: object - properties: - processHistory: - type: array - items: - $ref: '#/components/schemas/ProcessHistoryItem' - nullable: true - additionalProperties: false - ProcessNext: - type: object - properties: - action: - type: string - nullable: true - additionalProperties: false - ProcessState: - type: object - properties: - started: - type: string - format: date-time - nullable: true - startEvent: - type: string - nullable: true - currentTask: - $ref: '#/components/schemas/ProcessElementInfo' - ended: - type: string - format: date-time - nullable: true - endEvent: - type: string - nullable: true - additionalProperties: false - ReadStatus: - enum: - - 0 - - 1 - - 2 - type: integer - format: int32 - Reference: - type: object - properties: - value: - type: string - nullable: true - relation: - $ref: '#/components/schemas/RelationType' - valueType: - $ref: '#/components/schemas/ReferenceType' - additionalProperties: false - ReferenceType: - enum: - - DataElement - - Task - type: string - RelationType: - enum: - - GeneratedFrom - type: string - ResourceLinks: - type: object - properties: - apps: - type: string - nullable: true - platform: - type: string - nullable: true - additionalProperties: false - ShadowFields: - type: object - properties: - prefix: - type: string - nullable: true - saveToDataType: - type: string - nullable: true - additionalProperties: false - SimpleInstance: - type: object - properties: - id: - type: string - nullable: true - presentationTexts: - type: object - additionalProperties: - type: string - nullable: true - dueBefore: - type: string - format: date-time - nullable: true - lastChanged: - type: string - format: date-time - nullable: true - lastChangedBy: - type: string - nullable: true - additionalProperties: false - Substatus: - type: object - properties: - label: - type: string - nullable: true - description: - type: string - nullable: true - additionalProperties: false - TagsList: - type: object - properties: - tags: - type: array - items: - type: string - nullable: true - additionalProperties: false - TextResource: - type: object - properties: - id: - type: string - nullable: true - org: - type: string - nullable: true - language: - type: string - nullable: true - resources: - type: array - items: - $ref: '#/components/schemas/TextResourceElement' - nullable: true - additionalProperties: false - TextResourceElement: - type: object - properties: - id: - type: string - nullable: true - value: - type: string - nullable: true - variables: - type: array - items: - $ref: '#/components/schemas/TextResourceVariable' - nullable: true - additionalProperties: false - TextResourceVariable: - type: object - properties: - key: - type: string - nullable: true - dataSource: - type: string - nullable: true - defaultValue: - type: string - nullable: true - additionalProperties: false - UserAction: - required: - - id - type: object - properties: - id: - type: string - nullable: true - authorized: - type: boolean - type: - $ref: '#/components/schemas/ActionType' - additionalProperties: false - UserActionRequest: - type: object - properties: - action: - type: string - nullable: true - buttonId: - type: string - nullable: true - metadata: - type: object - additionalProperties: - type: string - nullable: true - ignoredValidators: - type: array - items: - type: string - nullable: true - additionalProperties: false - UserActionResponse: - required: - - instance - type: object - properties: - instance: - $ref: '#/components/schemas/Instance' - updatedDataModels: - type: object - additionalProperties: { } - nullable: true - updatedValidationIssues: - type: object - additionalProperties: - type: object - additionalProperties: - type: array - items: - $ref: '#/components/schemas/ValidationIssueWithSource' - nullable: true - clientActions: - type: array - items: - $ref: '#/components/schemas/ClientAction' - nullable: true - error: - $ref: '#/components/schemas/ActionError' - redirectUrl: - type: string - format: uri - nullable: true - additionalProperties: false - UserDefinedMetadataDto: - type: object - properties: - userDefinedMetadata: - type: array - items: - $ref: '#/components/schemas/KeyValueEntry' - nullable: true - additionalProperties: false - ValidationIssueSeverity: - enum: - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - type: integer - format: int32 - ValidationIssueWithSource: - required: - - code - - description - - severity - - source - type: object - properties: - severity: - $ref: '#/components/schemas/ValidationIssueSeverity' - dataElementId: - type: string - nullable: true - field: - type: string - nullable: true - code: - type: string - nullable: true - description: - type: string - nullable: true - source: - type: string - nullable: true - noIncrementalUpdates: - type: boolean - customTextKey: - type: string - nullable: true - customTextParams: - type: array - items: - type: string - nullable: true - additionalProperties: false - ValidationSourcePair: - type: object - properties: - source: - type: string - nullable: true - issues: - type: array - items: - $ref: '#/components/schemas/ValidationIssueWithSource' - nullable: true - additionalProperties: false - ValidationStatus: - type: object - properties: - timestamp: - type: string - format: date-time - nullable: true - canCompleteTask: - type: boolean - additionalProperties: false \ No newline at end of file