diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..cd955474 --- /dev/null +++ b/.gitignore @@ -0,0 +1,364 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd +ITALearning/ITALearning/Files/ \ No newline at end of file diff --git a/README.md b/README.md index 99ee2686..2b95da4e 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,29 @@ -# TÍTULO DO PROJETO +# IGESC Conecta -`CURSO` +`Análise e Desenvolvimento de Sistemas` -`DISCIPLINA` +`Projeto: Desenvolvimento de um Sistema Sociotécnico Inovador` -`SEMESTRE` +`5º Semestre` -Descrever resumidamente, em um ou dois parágrafos, o projeto que está sendo desenvolvido. +Este projeto fullstack tem como objetivo modernizar a gestão interna do Instituto Igesc, substituindo o uso de planilhas por uma plataforma integrada. A solução permitirá centralizar informações e organizar os processos de forma mais eficiente, garantindo maior controle e acessibilidade aos dados. ## Integrantes -* Nome completo do aluno 1 -* Nome completo do aluno 2 -* Nome completo do aluno 3 -* Nome completo do aluno 4 -* Nome completo do aluno 5 -* Nome completo do aluno 6 +* Lucas Bebiano Xavier +* Felipe van Oorschot +* Ricardo José Teixeira da Silva Junior +* Pedro Roberto Gomes Da Silva Abadia +* Kenia Aparecida Caires Cardoso +* Joao Victor Oliveira Santos ## Orientador -* Nome completo do professor orientador +* Sandra Maria Silveira ## Instruções de utilização -Assim que a primeira versão do sistema estiver disponível, deverá complementar com as instruções de utilização. Descreva como instalar eventuais dependências e como executar a aplicação. +Assim que a primeira versão do sistema estiver disponível, vamos complementar com as instruções de uso. # Documentação diff --git "a/atas/ADS - Ata de Reuni\303\243o Etapa 1.docx" "b/atas/ADS - Ata de Reuni\303\243o Etapa 1.docx" new file mode 100644 index 00000000..c262eee6 Binary files /dev/null and "b/atas/ADS - Ata de Reuni\303\243o Etapa 1.docx" differ diff --git a/atas/ADS_-_Ata_Acordo_Inicial_v03_assinada.pdf b/atas/ADS_-_Ata_Acordo_Inicial_v03_assinada.pdf new file mode 100644 index 00000000..ab00758e Binary files /dev/null and b/atas/ADS_-_Ata_Acordo_Inicial_v03_assinada.pdf differ diff --git a/atas/PROCURACAO_NIT_PUC_MINAS assinada.pdf b/atas/PROCURACAO_NIT_PUC_MINAS assinada.pdf new file mode 100644 index 00000000..1876fb87 Binary files /dev/null and b/atas/PROCURACAO_NIT_PUC_MINAS assinada.pdf differ diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API.sln b/codigo-fonte/IgescConecta.API/IgescConecta.API.sln new file mode 100644 index 00000000..1e7683b2 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36401.2 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IgescConecta.API", "IgescConecta.API\IgescConecta.API.csproj", "{FCBA626A-D6D3-4E78-AE3E-48FF685A0ADD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IgescConecta.Domain", "IgescConecta.Domain\IgescConecta.Domain.csproj", "{7BDCADC2-09B7-4B95-B04A-E023D59322C1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FCBA626A-D6D3-4E78-AE3E-48FF685A0ADD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FCBA626A-D6D3-4E78-AE3E-48FF685A0ADD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FCBA626A-D6D3-4E78-AE3E-48FF685A0ADD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FCBA626A-D6D3-4E78-AE3E-48FF685A0ADD}.Release|Any CPU.Build.0 = Release|Any CPU + {7BDCADC2-09B7-4B95-B04A-E023D59322C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7BDCADC2-09B7-4B95-B04A-E023D59322C1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7BDCADC2-09B7-4B95-B04A-E023D59322C1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7BDCADC2-09B7-4B95-B04A-E023D59322C1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D12E4E2A-817E-44D1-8F3F-205DA6EC61A3} + EndGlobalSection +EndGlobal diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Extensions/ApiAuthorize.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Extensions/ApiAuthorize.cs new file mode 100644 index 00000000..d6fa45c7 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Extensions/ApiAuthorize.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authentication.JwtBearer; + +namespace IgescConecta.API.Common.Extensions +{ + public class ApiAuthorize : AuthorizeAttribute + { + public ApiAuthorize() + { + AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme; + } + } +} + diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Extensions/DependencyInjection.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Extensions/DependencyInjection.cs new file mode 100644 index 00000000..451458b8 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Extensions/DependencyInjection.cs @@ -0,0 +1,139 @@ +using IgescConecta.API.Common.Options; +using IgescConecta.API.Data; +using IgescConecta.API.Services; +using IgescConecta.Domain.Entities; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.EntityFrameworkCore; +using Microsoft.OpenApi.Models; + +namespace IgescConecta.API.Common.Extensions +{ + public static class DependencyInjection + { + // === DbContext: Azure SQL (DefaultConnection) === + public static IServiceCollection AddDbContextIgesc(this IServiceCollection services, IConfiguration cfg) + { + services.AddHttpContextAccessor(); + + services.AddDbContext(options => + { + var cs = cfg.GetConnectionString("DefaultConnection") + ?? throw new InvalidOperationException( + "Connection string 'DefaultConnection' não encontrada. " + + "Defina em appsettings/ambiente ou nas Connection Strings do App Service."); + + options.UseSqlServer(cs, sql => + { + // resiliente para nuvem + sql.EnableRetryOnFailure(maxRetryCount: 5, + maxRetryDelay: TimeSpan.FromSeconds(10), + errorNumbersToAdd: null); + sql.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName); + }); + }); + + services.AddDatabaseDeveloperPageExceptionFilter(); + return services; + } + + // === Swagger + Bearer JWT === + public static IServiceCollection AddSwaggerDocumentation(this IServiceCollection services) + { + services.AddSwaggerGen(c => + { + // Agrupamento por controller/GroupName + c.TagActionsBy(api => + { + if (api.GroupName != null) return new[] { api.GroupName }; + if (api.ActionDescriptor is ControllerActionDescriptor d) return new[] { d.ControllerName }; + return new[] { "" }; + }); + + c.DocInclusionPredicate((name, api) => true); + c.SupportNonNullableReferenceTypes(); + + // Segurança: Bearer + c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + Name = "Authorization", + Type = SecuritySchemeType.Http, + Scheme = "bearer", + BearerFormat = "JWT", + In = ParameterLocation.Header, + Description = "Informe: Bearer {seu_token}" + }); + + c.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "Bearer" + } + }, + Array.Empty() + } + }); + }); + + return services; + } + + // === Serviços de domínio (Auth/Email) + opções === + public static IServiceCollection AddServices(this IServiceCollection services, IConfiguration cfg) + { + services.AddScoped(); + + // Vincula SmtpOptions à seção "Smtp" (host, port, ssl) + services.Configure(cfg.GetSection("Smtp")); + + // Seleciona o provedor por configuração: Email:Provider = Dev | Smtp + services.AddScoped(sp => + { + var provider = cfg["Email:Provider"] ?? "Dev"; + + if (provider.Equals("Smtp", StringComparison.OrdinalIgnoreCase)) + { + return new SmtpEmailService( + sp.GetRequiredService>(), + sp.GetRequiredService>(), + cfg + ); + } + + // Dev (log/console) + return new ConsoleEmailService(sp.GetRequiredService>()); + }); + + return services; + } + + // === Identity Core + Roles + Tokens === + public static IServiceCollection AddIdentity(this IServiceCollection services) + { + services.AddIdentityCore(op => + { + op.SignIn.RequireConfirmedAccount = false; + op.User.RequireUniqueEmail = true; + + // (opcional) regras de senha customizadas: + // op.Password.RequiredLength = 6; + // op.Password.RequireNonAlphanumeric = false; + // op.Password.RequireUppercase = true; + // op.Password.RequireLowercase = true; + // op.Password.RequireDigit = true; + }) + .AddRoles() + .AddEntityFrameworkStores() + .AddSignInManager() + .AddDefaultTokenProviders() + .AddApiEndpoints(); + + return services; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Extensions/WhereFilters.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Extensions/WhereFilters.cs new file mode 100644 index 00000000..afa898f1 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Extensions/WhereFilters.cs @@ -0,0 +1,220 @@ +using System.ComponentModel.DataAnnotations; +using System.Linq.Expressions; +using System.Reflection; + +namespace IgescConecta.API.Common.Extensions +{ + public enum Op + { + None, + Equals, + NotEquals, + LessThan, + LessThanOrEquals, + GreaterThan, + GreaterThanOrEquals, + Contains, + StartsWith, + EndsWith, + DoesNotContain, + IsNull, + IsEmpty, + IsNotNull, + IsNotEmpty, + Clear + } + + public class Filter + { + public string PropertyName { get; set; } + public Op Operation { get; set; } + public object Value { get; set; } + } + + public static class ExpressionBuilder + { + + private static MethodInfo containsMethod = typeof(string).GetMethod("Contains", new Type[] { typeof(string) }); + private static MethodInfo startsWithMethod = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }); + private static MethodInfo endsWithMethod = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) }); + + public static Expression> GetExpression(IList filters) + { + Expression exp = null; + + ParameterExpression param = Expression.Parameter(typeof(T), "t"); + if (filters.Count == 0) + { + exp = Expression.Equal(Expression.Constant(1), Expression.Constant(1)); + return Expression.Lambda>(exp, param); + } + + + if (filters.Count == 1) + exp = GetExpression(param, filters[0]); + else if (filters.Count == 2) + exp = GetExpression(param, filters[0], filters[1]); + else + { + while (filters.Count > 0) + { + var f1 = filters[0]; + var f2 = filters[1]; + + if (exp == null) + exp = GetExpression(param, filters[0], filters[1]); + else + exp = Expression.AndAlso(exp, GetExpression(param, filters[0], filters[1])); + + filters.Remove(f1); + filters.Remove(f2); + + if (filters.Count == 1) + { + exp = Expression.AndAlso(exp, GetExpression(param, filters[0])); + filters.RemoveAt(0); + } + } + } + + + return Expression.Lambda>(exp, param); + } + + private static MemberExpression GetNestedPropertyExpression(Expression param, string propertyName) + { + string[] parts = propertyName.Split('.'); + Expression body = param; + foreach (var part in parts) + { + body = Expression.PropertyOrField(body, part); + } + return (MemberExpression)body; + } + + private static Expression GetExpression(ParameterExpression param, Filter filter) + { + MemberExpression member = GetNestedPropertyExpression(param, filter.PropertyName); + var value = filter.Value; + + // Caso a propriedade seja enum, converte o valor para enum + if (member.Type.IsEnum) + { + value = value.ToString().GetValueFromName(member.Type); + } + + object convertedValue; + var targetType = member.Type.GetUnderlyingType(); + + // Tratamento especial para JsonElement (quando o valor vem do JSON) + if (value is System.Text.Json.JsonElement je) + { + switch (je.ValueKind) + { + case System.Text.Json.JsonValueKind.String: + if (targetType == typeof(DateTime)) + convertedValue = DateTime.Parse(je.GetString()); + else + convertedValue = je.GetString(); + break; + case System.Text.Json.JsonValueKind.Number: + if (targetType == typeof(int)) + convertedValue = je.GetInt32(); + else if (targetType == typeof(long)) + convertedValue = je.GetInt64(); + else if (targetType == typeof(double)) + convertedValue = je.GetDouble(); + else + convertedValue = je.GetDecimal(); + break; + case System.Text.Json.JsonValueKind.True: + convertedValue = true; + break; + case System.Text.Json.JsonValueKind.False: + convertedValue = false; + break; + case System.Text.Json.JsonValueKind.Null: + convertedValue = null; + break; + default: + convertedValue = je.GetRawText(); + break; + } + } + else if (targetType == typeof(string)) + { + convertedValue = value?.ToString(); + } + else if (targetType == typeof(DateTime) && value is string str) + { + convertedValue = DateTime.Parse(str); + } + else + { + convertedValue = Convert.ChangeType(value, targetType); + } + + ConstantExpression constant = Expression.Constant(convertedValue, targetType); + var convertedMember = Expression.Convert(member, targetType); + + return filter.Operation switch + { + Op.Equals => Expression.Equal(convertedMember, constant), + Op.NotEquals => Expression.NotEqual(convertedMember, constant), + Op.GreaterThan => Expression.GreaterThan(convertedMember, constant), + Op.GreaterThanOrEquals => Expression.GreaterThanOrEqual(convertedMember, constant), + Op.LessThan => Expression.LessThan(convertedMember, constant), + Op.LessThanOrEquals => Expression.LessThanOrEqual(convertedMember, constant), + Op.Contains => Expression.Call(convertedMember, containsMethod, constant), + Op.StartsWith => Expression.Call(convertedMember, startsWithMethod, constant), + Op.EndsWith => Expression.Call(convertedMember, endsWithMethod, constant), + Op.IsNull => Expression.Equal(convertedMember, Expression.Constant(null, targetType)), + _ => null, + }; + } + + private static BinaryExpression GetExpression(ParameterExpression param, Filter filter1, Filter filter2) + { + Expression bin1 = GetExpression(param, filter1); + Expression bin2 = GetExpression(param, filter2); + + return Expression.AndAlso(bin1, bin2); + } + + public static Type GetUnderlyingType(this Type type) + { + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + return Nullable.GetUnderlyingType(type); + return type; + } + + public static bool IsNullableType(this Type type) + { + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + return true; + return false; + } + + public static object GetValueFromName(this string name, Type type) + { + + foreach (var field in type.GetFields()) + { + if (Attribute.GetCustomAttribute(field, typeof(DisplayAttribute)) is DisplayAttribute attribute) + { + if (attribute.Name == name) + { + return field.GetValue(null); + } + } + + if (field.Name == name) + { + return field.GetValue(null); + } + } + + throw new ArgumentOutOfRangeException(nameof(name)); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Options/FrontendOptions.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Options/FrontendOptions.cs new file mode 100644 index 00000000..df713aa1 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Options/FrontendOptions.cs @@ -0,0 +1,8 @@ +namespace IgescConecta.API.Common.Options +{ + public class FrontendOptions + { + public string ResetPasswordUrlTemplate { get; set; } = ""; + } + +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Options/SmtpOptions.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Options/SmtpOptions.cs new file mode 100644 index 00000000..7164e747 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Options/SmtpOptions.cs @@ -0,0 +1,11 @@ +namespace IgescConecta.API.Common.Options +{ + public class SmtpOptions + { + public string Host { get; set; } = ""; + public int Port { get; set; } = 25; + public bool UseSsl { get; set; } = false; + // Segredos via variáveis de ambiente (IIS), não mapeados aqui por segurança: + // User / Password + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Query/PaginationRequest.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Query/PaginationRequest.cs new file mode 100644 index 00000000..17aabdc2 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Query/PaginationRequest.cs @@ -0,0 +1,20 @@ +using IgescConecta.API.Common.Extensions; + +namespace IgescConecta.API.Common.Query +{ + public class PaginationRequest + { + public PaginationRequest(int pageNumber, int pageSize, List filters) + { + PageNumber = pageNumber; + PageSize = pageSize; + Filters = filters; + } + + public int PageNumber { get; set; } = 1; + + public int PageSize { get; set; } = 10; + + public List Filters { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Query/PaginationResponse.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Query/PaginationResponse.cs new file mode 100644 index 00000000..aed94b16 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Query/PaginationResponse.cs @@ -0,0 +1,9 @@ +namespace IgescConecta.API.Common.Query +{ + public class PaginationResponse + { + public int TotalItems { get; set; } + + public IEnumerable Items { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Validation/Result.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Validation/Result.cs new file mode 100644 index 00000000..25fb1545 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Validation/Result.cs @@ -0,0 +1,30 @@ +namespace IgescConecta.API.Common.Validation +{ + public readonly struct Result + { + public TValue Value { get; } + + public TError Error { get; } + + public bool IsSuccess { get; } + + public bool IsFailure => !IsSuccess; + + public Result(TValue value) + { + Value = value; + Error = default!; + IsSuccess = true; + } + + public Result(TError error) + { + Value = default!; + Error = error; + IsSuccess = false; + } + + public static implicit operator Result(TValue value) => new Result(value); + public static implicit operator Result(TError error) => new Result(error); + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Validation/ValidationFailed.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Validation/ValidationFailed.cs new file mode 100644 index 00000000..1ff4b1b8 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Common/Validation/ValidationFailed.cs @@ -0,0 +1,12 @@ +namespace IgescConecta.API.Common.Validation +{ + public class ValidationFailed + { + public string[] Errors { get; set; } + + public ValidationFailed() { } + + public ValidationFailed(string error) => Errors = [error]; + public ValidationFailed(string[] errors) => Errors = errors; + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Data/ApplicationDbContext.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Data/ApplicationDbContext.cs new file mode 100644 index 00000000..4aeb5a82 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Data/ApplicationDbContext.cs @@ -0,0 +1,168 @@ +using IgescConecta.Domain.Entities; +using IgescConecta.Domain.Primitives; +using IgescConecta.Domain.Shared; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using System.Linq.Expressions; +using System.Security.Claims; +using Microsoft.AspNetCore.Http; +using System.Collections.Generic; +using System.Linq; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Data +{ + public class ApplicationDbContext : IdentityDbContext + { + private readonly IHttpContextAccessor _contextAccessor; + + public ApplicationDbContext( + DbContextOptions options, + IHttpContextAccessor contextAccessor) : base(options) + { + _contextAccessor = contextAccessor; + } + + public DbSet Users { get; set; } + public DbSet Roles { get; set; } + public DbSet Teams { get; set; } + + public DbSet Companies { get; set; } + public DbSet Courses { get; set; } + public DbSet Donations { get; set; } + public DbSet OriginBusinessCases { get; set; } + public DbSet Oscs { get; set; } + public DbSet Beneficiaries { get; set; } + public DbSet BusinessCases { get; set; } + public DbSet Persons { get; set; } + public DbSet PersonCompanies { get; set; } + public DbSet PersonOscs { get; set; } + public DbSet PersonTeams { get; set; } + public DbSet ProjectPrograms { get; set; } + public DbSet ProjectDocuments { get; set; } + public DbSet ProjectThemes { get; set; } + public DbSet ProjectTypes { get; set; } + + + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + + + builder.Entity() + .HasOne(u => u.CreatedByUser) + .WithMany() + .HasForeignKey(u => u.CreatedBy) + .OnDelete(DeleteBehavior.Restrict); + + builder.Entity() + .HasOne(u => u.UpdatedByUser) + .WithMany() + .HasForeignKey(u => u.UpdatedBy) + .OnDelete(DeleteBehavior.Restrict); + + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + builder.Entity().HasQueryFilter(e => !e.IsDeleted); + + + + builder.Entity().ToTable("Users"); + builder.Entity().ToTable("Roles"); + builder.Entity>().ToTable("UserClaims"); + builder.Entity>().ToTable("UserLogins"); + builder.Entity>().ToTable("UserRoles"); + builder.Entity>().ToTable("UserTokens"); + builder.Entity>().ToTable("RoleClaims"); + builder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly); + } + + public override int SaveChanges(bool acceptAllChangesOnSuccess) + { + OnBeforeSaving(); + return base.SaveChanges(acceptAllChangesOnSuccess); + } + + public override async Task SaveChangesAsync( + bool acceptAllChangesOnSuccess, + CancellationToken cancellationToken = default) + { + OnBeforeSaving(); + return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); + } + + private void OnBeforeSaving() + { + var entries = ChangeTracker.Entries() + .Where(x => x.Entity is BaseEntity || x.Entity is User) + .ToList(); + + var softDeleteEntries = ChangeTracker + .Entries() + .Where(e => e.State == EntityState.Deleted); + + foreach (var entityEntry in softDeleteEntries) + { + entityEntry.State = EntityState.Modified; + entityEntry.Property(nameof(ISoftDeletable.IsDeleted)).CurrentValue = true; + } + + UpdateTimestamps(entries); + } + + private void UpdateTimestamps(List entries) + { + var filtred = entries.Where(x => + x.State == EntityState.Added || x.State == EntityState.Modified); + + var currentUserIdStr = _contextAccessor?.HttpContext?.User + .FindFirst(ClaimTypes.NameIdentifier)?.Value; + + int.TryParse(currentUserIdStr, out var currentUserId); + + foreach (var entry in filtred) + { + if (entry.Entity is User user) + { + if (entry.State == EntityState.Added) + { + user.CreatedAt = DateTime.UtcNow; + user.CreatedBy = currentUserId; + } + + user.UpdatedAt = DateTime.UtcNow; + user.UpdatedBy = currentUserId; + } + else if (entry.Entity is BaseEntity entity) + { + if (entry.State == EntityState.Added) + { + entity.CreatedAt = DateTime.UtcNow; + entity.CreatedBy = currentUserId; + } + + entity.UpdatedAt = DateTime.UtcNow; + entity.UpdatedBy = currentUserId; + } + } + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Data/ApplicationDbSeed.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Data/ApplicationDbSeed.cs new file mode 100644 index 00000000..eefa9038 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Data/ApplicationDbSeed.cs @@ -0,0 +1,129 @@ +using IgescConecta.Domain.Entities; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Data +{ + public class ApplicationDbSeed + { + private readonly ApplicationDbContext _context; + + public ApplicationDbSeed(ApplicationDbContext context) + { + this._context = context; + } + + public void Seed() + { + if (_context.Users.Any()) + return; + + var pwd = "123@Mudar"; + var passwordHasher = new PasswordHasher(); + + var adminRole = new Role("Admin"); + adminRole.NormalizedName = adminRole.Name!.ToUpper(); + + var editorRole = new Role("Editor"); + editorRole.NormalizedName = editorRole.Name!.ToUpper(); + + var viewerRole = new Role("Viewer"); + viewerRole.NormalizedName = viewerRole.Name!.ToUpper(); + + var roles = new List { adminRole, editorRole, viewerRole }; + + _context.Roles.AddRange(roles); + _context.SaveChanges(); + + User CreateUser(string name, string email, string? phone = null) + { + var user = new User + { + UserName = email, + Email = email, + Name = name, + IsActive = true, + PhoneNumber = phone ?? RandomPhone(), + EmailConfirmed = true, + SecurityStamp = Guid.NewGuid().ToString("D") + }; + + user.NormalizedUserName = user.UserName!.ToUpper(); + user.NormalizedEmail = user.Email!.ToUpper(); + user.PasswordHash = passwordHasher.HashPassword(user, pwd); + + return user; + } + + // Gerador simples de número "aleatório" de 11 dígitos (apenas para seed/dev) + string RandomPhone() + { + var rng = Random.Shared; + // DDD 11–99, seguido de 9 dígitos + var ddd = rng.Next(11, 99); + var rest = rng.NextInt64(1000000000L, 9999999999L); // 10 dígitos + // Monta como string, garantindo 11 dígitos no total (padrão BR sem formatação) + return $"{ddd}{rest}".Substring(0, 11); + } + + // ---- Usuários ------------------------------------------------------ + var users = new List + { + // Administrador padrão + CreateUser("Administrador", "admin@admin.com", "19954213678"), + }; + + _context.Users.AddRange(users); + _context.SaveChanges(); + + // ---- Atribuição de papéis ------------------------------------------ + // Mapa: email -> role + var assignments = new (string Email, string Role)[] + { + ("admin@admin.com", "Admin"), + }; + + var userRoles = new List>(); + + foreach (var (email, roleName) in assignments) + { + var u = users.FirstOrDefault(x => x.Email!.Equals(email, StringComparison.OrdinalIgnoreCase)); + var r = roles.FirstOrDefault(x => x.Name!.Equals(roleName, StringComparison.OrdinalIgnoreCase)); + + if (u != null && r != null) + { + userRoles.Add(new IdentityUserRole + { + UserId = u.Id, + RoleId = r.Id + }); + } + } + + _context.UserRoles.AddRange(userRoles); + _context.SaveChanges(); + } + } + + public static class ApplicationExtensions + { + public static void SeedDatabase(this IApplicationBuilder app, bool isDevelopment) + { + using var scope = app.ApplicationServices.CreateScope(); + var services = scope.ServiceProvider; + try + { + var context = services.GetRequiredService(); + if (!isDevelopment) + context.Database.Migrate(); + var seeder = new ApplicationDbSeed(context); + seeder.Seed(); + } + catch (Exception ex) + { + var logger = services.GetRequiredService>(); + logger.LogError(ex, "An error occurred while migrating or seeding the database."); + } + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ForgotPassword/ForgotPasswordCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ForgotPassword/ForgotPasswordCommand.cs new file mode 100644 index 00000000..fb65226c --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ForgotPassword/ForgotPasswordCommand.cs @@ -0,0 +1,58 @@ +using System.Text; +using IgescConecta.API.Common.Options; +using IgescConecta.API.Services; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.WebUtilities; +using Microsoft.Extensions.Options; + +namespace IgescConecta.API.Features.Auth.ForgotPassword +{ + public class ForgotPasswordCommand : IRequest + { + public string Email { get; set; } = ""; + } + + internal sealed class ForgotPasswordCommandHandler : IRequestHandler + { + private readonly UserManager _userManager; + private readonly IEmailService _email; + private readonly IOptions _frontend; + + public ForgotPasswordCommandHandler( + UserManager userManager, + IEmailService email, + IOptions frontend) + { + _userManager = userManager; + _email = email; + _frontend = frontend; + } + + public async Task Handle(ForgotPasswordCommand request, CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(request.Email)) + return Unit.Value; + + var user = await _userManager.FindByEmailAsync(request.Email); + if (user is null) + { + // Não revelar existência; apenas retornar + return Unit.Value; + } + + var token = await _userManager.GeneratePasswordResetTokenAsync(user); + var tokenUrlSafe = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token)); + + var template = _frontend.Value.ResetPasswordUrlTemplate ?? ""; + // Monta a URL substituindo placeholders + var resetLink = template + .Replace("{uid}", user.Id.ToString()) + .Replace("{token}", tokenUrlSafe); + + await _email.SendPasswordResetLinkAsync(user.Email!, resetLink); + return Unit.Value; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ForgotPassword/ForgotPasswordEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ForgotPassword/ForgotPasswordEndpoint.cs new file mode 100644 index 00000000..159a35dc --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ForgotPassword/ForgotPasswordEndpoint.cs @@ -0,0 +1,36 @@ +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Auth.ForgotPassword +{ + [Route("/api/auth")] + [ApiController] + [ApiExplorerSettings(GroupName = "Auth")] + public class ForgotPasswordEndpoint : ControllerBase + { + private readonly IMediator _mediator; + public ForgotPasswordEndpoint(IMediator mediator) => _mediator = mediator; + + [AllowAnonymous] + [HttpPost("forgot-password", Name = "ForgotPassword")] + public async Task> ForgotPassword([FromBody] ForgotPasswordRequest request) + { + await _mediator.Send(new ForgotPasswordCommand { Email = request.Email }); + return Ok(new ForgotPasswordResponse + { + Message = "Se existir uma conta para este e-mail, enviaremos um link de redefinição." + }); + } + } + + public class ForgotPasswordRequest + { + public string Email { get; set; } = ""; + } + + public class ForgotPasswordResponse + { + public string Message { get; set; } = ""; + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/LoginUserEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/LoginUserEndpoint.cs new file mode 100644 index 00000000..c448921d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/LoginUserEndpoint.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Mvc; +using IgescConecta.API.Services; +using Microsoft.AspNetCore.Identity; +using IgescConecta.Domain.Entities; +using Microsoft.AspNetCore.Authorization; + +namespace IgescConecta.API.Features.Auth +{ + [Route("/api/auth")] + [ApiController] + [ApiExplorerSettings(GroupName = "Auth")] + public class LoginUserEndpoint : ControllerBase + { + private readonly IAuthAuthenticatonService _auth; + private readonly UserManager _userManager; + public LoginUserEndpoint(IAuthAuthenticatonService auth, UserManager userManager) + { + _auth = auth; + _userManager = userManager; + } + + [AllowAnonymous] + [HttpPost("Login", Name = "Login")] + public async Task> LoginUser([FromBody] UserLogin model) + { + var user = await _userManager.FindByEmailAsync(model.Email); + + if(user != null && await _userManager.CheckPasswordAsync(user, model.Password)) + { + return await _auth.BuildToken(user); + } + else + { + ModelState.AddModelError(string.Empty, "Tentativa de login inválida."); + return BadRequest(ModelState); + } + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/RefreshTokenEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/RefreshTokenEndpoint.cs new file mode 100644 index 00000000..cbcdedf0 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/RefreshTokenEndpoint.cs @@ -0,0 +1,63 @@ +using IgescConecta.API.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.IdentityModel.Tokens.Jwt; + +namespace IgescConecta.API.Features.Auth +{ + [Route("/api/auth")] + [ApiController] + [ApiExplorerSettings(GroupName = "Auth")] + public class RefreshTokenEndpoint : ControllerBase + { + private readonly IAuthAuthenticatonService _auth; + + public RefreshTokenEndpoint(IAuthAuthenticatonService auth) + { + _auth = auth; + } + + [AllowAnonymous] + [HttpPost ("RefreshToken", Name = "RefreshToken")] + public async Task RefreshToken(LoginResponse tokenModel) + { + if (tokenModel is null) + { + return BadRequest("Requisição do cliente inválida."); + } + + string? accessToken = tokenModel.AccessToken; + string? refreshToken = tokenModel.RefreshToken; + + var principal = _auth.GetPrincipalFromExpiredToken(accessToken); + + if(principal == null) + { + return BadRequest("Token de acesso ou refresh inválido."); + } + + var newAccessToken = _auth.CreateToken(principal.Claims.ToList()); + var newRefreshToken = _auth.GenerateRefreshToken(); + + tokenModel.RefreshToken = newRefreshToken; + var expiration = DateTime.UtcNow.AddHours(10); + + return new ObjectResult(new + { + accessToken = new JwtSecurityTokenHandler().WriteToken(newAccessToken), + refreshToken = newRefreshToken, + expiresIn = expiration + }); + } + } + + public class LoginResponse + { + public string AccessToken { get; set; } + + public string RefreshToken { get; set; } + + public DateTime ExpiresIn { get; set; } + } + +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ResetPassword/ResetPasswordCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ResetPassword/ResetPasswordCommand.cs new file mode 100644 index 00000000..dbcff574 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ResetPassword/ResetPasswordCommand.cs @@ -0,0 +1,54 @@ +using System.Text; +using IgescConecta.API.Common.Validation; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.WebUtilities; + +namespace IgescConecta.API.Features.Auth.ResetPassword +{ + public class ResetPasswordCommand : IRequest> + { + public int UserId { get; set; } + public string Token { get; set; } = ""; + public string NewPassword { get; set; } = ""; + } + + internal sealed class ResetPasswordCommandHandler : IRequestHandler> + { + private readonly UserManager _userManager; + + public ResetPasswordCommandHandler(UserManager userManager) + { + _userManager = userManager; + } + + public async Task> Handle(ResetPasswordCommand request, CancellationToken cancellationToken) + { + // Buscar usuário + var user = await _userManager.FindByIdAsync(request.UserId.ToString()); + if (user is null) + return new ValidationFailed(new[] { "Token ou usuário inválido." }); + + // Decodificar token URL-safe + string decodedToken; + try + { + var tokenBytes = WebEncoders.Base64UrlDecode(request.Token); + decodedToken = Encoding.UTF8.GetString(tokenBytes); + } + catch + { + return new ValidationFailed(new[] { "Token ou usuário inválido." }); + } + + // Resetar senha + var result = await _userManager.ResetPasswordAsync(user, decodedToken, request.NewPassword); + if (!result.Succeeded) + return new ValidationFailed(result.Errors.Select(e => e.Description).ToArray()); + + return true; + } + } +} + diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ResetPassword/ResetPasswordEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ResetPassword/ResetPasswordEndpoint.cs new file mode 100644 index 00000000..6b785562 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Auth/ResetPassword/ResetPasswordEndpoint.cs @@ -0,0 +1,44 @@ +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Auth.ResetPassword +{ + [Route("/api/auth")] + [ApiController] + [ApiExplorerSettings(GroupName = "Auth")] + public class ResetPasswordEndpoint : ControllerBase + { + private readonly IMediator _mediator; + public ResetPasswordEndpoint(IMediator mediator) => _mediator = mediator; + + [AllowAnonymous] + [HttpPatch("reset-password", Name = "ResetPassword")] + public async Task> ResetPassword([FromBody] ResetPasswordRequest request) + { + var result = await _mediator.Send(new ResetPasswordCommand + { + UserId = request.UserId, + Token = request.Token, + NewPassword = request.NewPassword + }); + + if (!result.IsSuccess) + return BadRequest(result.Error); + + return Ok(new ResetPasswordResponse { Message = "Senha redefinida com sucesso." }); + } + } + + public class ResetPasswordRequest + { + public int UserId { get; set; } + public string Token { get; set; } = ""; + public string NewPassword { get; set; } = ""; + } + + public class ResetPasswordResponse + { + public string Message { get; set; } = ""; + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/CreateBeneficiary/CreateBeneficiaryCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/CreateBeneficiary/CreateBeneficiaryCommand.cs new file mode 100644 index 00000000..e81fccd0 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/CreateBeneficiary/CreateBeneficiaryCommand.cs @@ -0,0 +1,36 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; + +namespace IgescConecta.API.Features.Beneficiares.CreateBeneficiary +{ + public class CreateBeneficiaryCommand : IRequest> + { + public string Name { get; set; } + + public string Notes { get; set; } + } + + internal sealed class CreateBeneficiaryCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + public CreateBeneficiaryCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(CreateBeneficiaryCommand request, CancellationToken cancellationToken) + { + var beneficiary = new Beneficiary + { + Name = request.Name, + Notes = request.Notes + }; + + await _context.Beneficiaries.AddAsync(beneficiary, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + return beneficiary.Id; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/CreateBeneficiary/CreateBeneficiaryEndPoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/CreateBeneficiary/CreateBeneficiaryEndPoint.cs new file mode 100644 index 00000000..68836a79 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/CreateBeneficiary/CreateBeneficiaryEndPoint.cs @@ -0,0 +1,47 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Beneficiares.CreateBeneficiary +{ + [ApiAuthorize] + [Route("/api/beneficiary")] + [ApiController] + [ApiExplorerSettings(GroupName = "Beneficiaries")] + public class CreateBeneficiaryEndPoint : ControllerBase + { + private readonly IMediator _mediator; + + public CreateBeneficiaryEndPoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("CreateBeneficiary", Name = "CreateBeneficiary")] + public async Task> CreateBeneficiary([FromBody] CreateBeneficiaryRequest request) + { + var result = await _mediator.Send(new CreateBeneficiaryCommand + { + Name = request.Name, + Notes = request.Notes + }); + return result.IsSuccess ? Ok(new CreateBeneficiaryResponse(result.Value)) : BadRequest(result.Error); + } + } + + public class CreateBeneficiaryRequest + { + public string Name { get; set; } + + public string Notes { get; set; } + } + + public class CreateBeneficiaryResponse + { + public int BeneficiaryId { get; set; } + public CreateBeneficiaryResponse(int beneficiaryId) + { + BeneficiaryId = beneficiaryId; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/DeleteBeneficiary/DeleteBeneficiaryCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/DeleteBeneficiary/DeleteBeneficiaryCommand.cs new file mode 100644 index 00000000..0f46cb46 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/DeleteBeneficiary/DeleteBeneficiaryCommand.cs @@ -0,0 +1,40 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; + +namespace IgescConecta.API.Features.Beneficiares.DeleteBeneficiary +{ + public class DeleteBeneficiaryCommand : IRequest> + { + public int BeneficiaryId { get; set; } + public DeleteBeneficiaryCommand(int beneficiaryId) + { + BeneficiaryId = beneficiaryId; + } + } + + internal sealed class DeleteBeneficiaryCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public DeleteBeneficiaryCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(DeleteBeneficiaryCommand request, CancellationToken cancellationToken) + { + var beneficiary = await _context.Beneficiaries.FindAsync([request.BeneficiaryId]); + + if(beneficiary == null) + { + return new ValidationFailed(new[] { "Beneficiário não encontrado." }); + } + + _context.Beneficiaries.Remove(beneficiary); + await _context.SaveChangesAsync(cancellationToken); + + return true; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/DeleteBeneficiary/DeleteBeneficiaryEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/DeleteBeneficiary/DeleteBeneficiaryEndpoint.cs new file mode 100644 index 00000000..9de45002 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/DeleteBeneficiary/DeleteBeneficiaryEndpoint.cs @@ -0,0 +1,27 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Beneficiares.DeleteBeneficiary +{ + [ApiAuthorize] + [Route("/api/beneficiary")] + [ApiController] + [ApiExplorerSettings(GroupName = "Beneficiaries")] + public class DeleteBeneficiaryEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public DeleteBeneficiaryEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpDelete("{beneficiaryId}", Name = "DeleteBeneficiary")] + public async Task DeleteBeneficiary(int beneficiaryId) + { + var result = await _mediator.Send(new DeleteBeneficiaryCommand(beneficiaryId)); + return result.IsSuccess ? Ok() : BadRequest(result.Error); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/GetBeneficiary/GetBeneficiaryEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/GetBeneficiary/GetBeneficiaryEndpoint.cs new file mode 100644 index 00000000..628bfaee --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/GetBeneficiary/GetBeneficiaryEndpoint.cs @@ -0,0 +1,61 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Beneficiares.GetBeneficiary +{ + [ApiAuthorize] + [Route("/api/beneficiaries")] + [ApiController] + [ApiExplorerSettings(GroupName = "Beneficiaries")] + public class GetBeneficiaryEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public GetBeneficiaryEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("{beneficiaryId}", Name = "GetBeneficiary")] + public async Task> GetBeneficiary(int beneficiaryId) + { + var result = await _mediator.Send(new GetBeneficiaryQuery(beneficiaryId)); + + var beneficiaryInfo = new GetBeneficiaryResponse + { + BeneficiaryId = beneficiaryId, + Name = result.Value?.Name, + Notes = result.Value?.Notes, + Oscs = result.Value?.Oscs.Select(o => new GetBeneficiaryOscResponse + { + OscId = o.Id, + Name = o.Name, + CorporateName = o.CorporateName + }).ToList() + }; + + return result.IsSuccess ? Ok(beneficiaryInfo) : BadRequest(result.Error); + } + + public class GetBeneficiaryResponse + { + public int BeneficiaryId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + + public List Oscs { get; set; } = new(); + } + + public class GetBeneficiaryOscResponse + { + public int OscId { get; set; } + + public string Name { get; set; } + + public string CorporateName { get; set; } + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/GetBeneficiary/GetBeneficiaryQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/GetBeneficiary/GetBeneficiaryQuery.cs new file mode 100644 index 00000000..582e014d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/GetBeneficiary/GetBeneficiaryQuery.cs @@ -0,0 +1,42 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Beneficiares.GetBeneficiary +{ + public class GetBeneficiaryQuery : IRequest> + { + public int BeneficiaryId { get; set; } + + public GetBeneficiaryQuery(int id) + { + BeneficiaryId = id; + } + } + + internal sealed class GetBenefiaryQueryHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public GetBenefiaryQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(GetBeneficiaryQuery request, CancellationToken cancellationToken) + { + var beneficiary = await _context.Beneficiaries.Where(b => b.Id == request.BeneficiaryId) + .Include(b => b.Oscs) + .FirstOrDefaultAsync(); + + if (beneficiary == null) + { + return new ValidationFailed(new[] { "Beneficiary not Found" }); + } + + return beneficiary; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/ListBeneficiaries/ListBeneficiaryEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/ListBeneficiaries/ListBeneficiaryEndpoint.cs new file mode 100644 index 00000000..84fc444c --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/ListBeneficiaries/ListBeneficiaryEndpoint.cs @@ -0,0 +1,34 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Beneficiares.ListBeneficiaries +{ + [ApiAuthorize] + [Route("/api/beneficiary")] + [ApiController] + [ApiExplorerSettings(GroupName = "Beneficiaries")] + public class ListBeneficiaryEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListBeneficiaryEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("ListBeneficiary", Name = "ListBeneficiary")] + public async Task> ListBeneficiaries(ListBeneficiaryRequest request) + { + var result = await _mediator.Send(new ListBeneficiaryQuery(request.PageNumber, request.PageSize, request.Filters)); + return Ok(result); + } + } + + public class ListBeneficiaryRequest + { + public int PageNumber { get; set; } + public int PageSize { get; set; } + public List Filters { get; set; } = new(); + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/ListBeneficiaries/ListBeneficiaryQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/ListBeneficiaries/ListBeneficiaryQuery.cs new file mode 100644 index 00000000..12fda6bd --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/ListBeneficiaries/ListBeneficiaryQuery.cs @@ -0,0 +1,67 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Beneficiares.ListBeneficiaries +{ + public class ListBeneficiaryViewModel : PaginationResponse + { + } + + public class BeneficiaryViewModel + { + public int BeneficiaryId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + + public int OscsCount { get; set; } + } + + public class ListBeneficiaryQuery : PaginationRequest, IRequest + { + public ListBeneficiaryQuery(int pageNumber, int pageSize, List filters) : base(pageNumber, pageSize, filters) + { + } + } + + internal sealed class ListBeneficiaryQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public ListBeneficiaryQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(ListBeneficiaryQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + var query = _context.Beneficiaries.AsQueryable(); + var result = await query.Where(expr).Select(beneficiary => new BeneficiaryViewModel + { + BeneficiaryId = beneficiary.Id, + Name = beneficiary.Name, + Notes = beneficiary.Notes, + OscsCount = _context.Oscs + .Count(osc => osc.Beneficiaries.Any(b => b.Id == beneficiary.Id)), + }) + .OrderBy(x => x.BeneficiaryId) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToListAsync(cancellationToken); + + var totalRecords = await _context.Beneficiaries.CountAsync(expr, cancellationToken); + + return new ListBeneficiaryViewModel + { + Items = result, + TotalItems = totalRecords + }; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/UpdateBeneficiary/UpdateBeneficiaryCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/UpdateBeneficiary/UpdateBeneficiaryCommand.cs new file mode 100644 index 00000000..ee2027bf --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/UpdateBeneficiary/UpdateBeneficiaryCommand.cs @@ -0,0 +1,43 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; + +namespace IgescConecta.API.Features.Beneficiares.UpdateBeneficiary +{ + public class UpdateBeneficiaryCommand : IRequest> + { + public int BeneficiaryId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + } + + internal sealed class UpdateBeneficiaryCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public UpdateBeneficiaryCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(UpdateBeneficiaryCommand request, CancellationToken cancellationToken) + { + var beneficiary = await _context.Beneficiaries.FindAsync([request.BeneficiaryId], cancellationToken: cancellationToken); + + if(beneficiary == null) + { + return new ValidationFailed(new[] {"Publico beneficiário não encontrado."}); + } + + beneficiary.Name = string.IsNullOrEmpty(request.Name) ? beneficiary.Name : request.Name; + beneficiary.Notes = string.IsNullOrEmpty(request.Notes) ? beneficiary.Notes : request.Notes; + + await _context.SaveChangesAsync(cancellationToken); + + return beneficiary; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/UpdateBeneficiary/UpdateBeneficiaryEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/UpdateBeneficiary/UpdateBeneficiaryEndpoint.cs new file mode 100644 index 00000000..d9611c60 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Beneficiares/UpdateBeneficiary/UpdateBeneficiaryEndpoint.cs @@ -0,0 +1,56 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Beneficiares.UpdateBeneficiary +{ + [ApiAuthorize] + [Route("/api/beneficiaries")] + [ApiController] + [ApiExplorerSettings(GroupName = "Beneficiaries")] + public class UpdateBeneficiaryEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public UpdateBeneficiaryEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{beneficiaryId}", Name = "UpdateBeneficiary")] + public async Task> UpdateBeneficiary(int beneficiaryId, [FromBody] UpdateBeneficiaryRequest request) + { + var result = await _mediator.Send(new UpdateBeneficiaryCommand + { + BeneficiaryId = beneficiaryId, + Name = request.Name, + Notes = request.Notes + }); + + var updateResponse = new UpdateBeneficiaryResponse + { + BeneficiaryId = beneficiaryId, + Name = result.Value.Name, + Notes = result.Value.Notes + }; + + return result.IsSuccess ? Ok(updateResponse) : BadRequest(result.Error); + } + } + + public class UpdateBeneficiaryRequest + { + public string Name { get; set; } + + public string Notes { get; set; } + } + + public class UpdateBeneficiaryResponse + { + public int BeneficiaryId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/CreateBusinessCase/CreateBusinessCaseCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/CreateBusinessCase/CreateBusinessCaseCommand.cs new file mode 100644 index 00000000..90367df1 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/CreateBusinessCase/CreateBusinessCaseCommand.cs @@ -0,0 +1,46 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.BusinessCases.CreateBusinessCase +{ + public class CreateBusinessCaseCommand : IRequest> + { + public string Name { get; set; } + + public List OriginsBusinessCasesIds { get; set; } = []; + } + + internal sealed class CreateBusinessCaseCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public CreateBusinessCaseCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(CreateBusinessCaseCommand request, CancellationToken cancellationToken) + { + var businessCase = new BusinessCase + { + Name = request.Name, + }; + + if (request.OriginsBusinessCasesIds.Any()) + { + var originBusinessCase = await _context.OriginBusinessCases + .Where(obc => request.OriginsBusinessCasesIds.Contains(obc.Id)) + .ToListAsync(); + + businessCase.Origins = originBusinessCase; + } + + await _context.BusinessCases.AddAsync(businessCase); + await _context.SaveChangesAsync(cancellationToken); + return businessCase.Id; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/CreateBusinessCase/CreateBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/CreateBusinessCase/CreateBusinessCaseEndpoint.cs new file mode 100644 index 00000000..24455690 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/CreateBusinessCase/CreateBusinessCaseEndpoint.cs @@ -0,0 +1,48 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.BusinessCases.CreateBusinessCase +{ + [ApiAuthorize] + [Route("/api/businesscase")] + [ApiController] + [ApiExplorerSettings(GroupName = "BusinessCases")] + public class CreateBusinessCaseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public CreateBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("CreateBusinessCase", Name = "CreateBusinessCase")] + public async Task> CreateBusinessCase([FromBody] CreateBusinessCaseRequest request) + { + var result = await _mediator.Send(new CreateBusinessCaseCommand + { + Name = request.Name, + OriginsBusinessCasesIds = request.OriginsBusinessCasesIds + }); + return result.IsSuccess ? Ok(new CreateBusinessCaseResponse(result.Value)) : BadRequest(result.Error); + } + } + + public class CreateBusinessCaseRequest + { + public string Name { get; set; } + + public List OriginsBusinessCasesIds { get; set; } = []; + } + + public class CreateBusinessCaseResponse + { + public int BusinessCaseId { get; set; } + + public CreateBusinessCaseResponse(int businessCaseId) + { + BusinessCaseId = businessCaseId; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/DeleteBusinessCase/DeleteBusinessCaseCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/DeleteBusinessCase/DeleteBusinessCaseCommand.cs new file mode 100644 index 00000000..37dbac8f --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/DeleteBusinessCase/DeleteBusinessCaseCommand.cs @@ -0,0 +1,48 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.BusinessCases.DeleteBusinessCase +{ + public class DeleteBusinessCaseCommand : IRequest> + { + public int BusinessCaseId { get; set; } + public DeleteBusinessCaseCommand(int businessCaseId) + { + BusinessCaseId = businessCaseId; + } + } + + internal sealed class DeleteBusinessCaseCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public DeleteBusinessCaseCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(DeleteBusinessCaseCommand request, CancellationToken cancellationToken) + { + var businessCase = await _context.BusinessCases.FindAsync(request.BusinessCaseId); + + if (businessCase == null) + { + return new ValidationFailed(new[] { "Business Case não encontrado." }); + } + + var hasRelatedOrigins = await _context.OriginBusinessCases + .AnyAsync(obc => obc.BusinessCaseId == businessCase.Id && !obc.IsDeleted, cancellationToken); + + if (hasRelatedOrigins) + { + return new ValidationFailed(new[] { "Não é possível deletar o Grupo de Causas pois existem Causas relacionadas." }); + } + + _context.BusinessCases.Remove(businessCase); + await _context.SaveChangesAsync(cancellationToken); + return true; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/DeleteBusinessCase/DeleteBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/DeleteBusinessCase/DeleteBusinessCaseEndpoint.cs new file mode 100644 index 00000000..58c36f54 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/DeleteBusinessCase/DeleteBusinessCaseEndpoint.cs @@ -0,0 +1,26 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.BusinessCases.DeleteBusinessCase +{ + [ApiAuthorize] + [Route("/api/businesscase")] + [ApiController] + [ApiExplorerSettings(GroupName = "BusinessCases")] + public class DeleteBusinessCaseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + public DeleteBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpDelete("{businessCaseId}", Name = "DeleteBusinessCase")] + public async Task DeleteBusinessCase(int businessCaseId) + { + var result = await _mediator.Send(new DeleteBusinessCaseCommand(businessCaseId)); + return result.IsSuccess ? Ok() : BadRequest(result.Error); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/GetBusinessCase/GetBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/GetBusinessCase/GetBusinessCaseEndpoint.cs new file mode 100644 index 00000000..9ea0c4f9 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/GetBusinessCase/GetBusinessCaseEndpoint.cs @@ -0,0 +1,54 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.BusinessCases.GetBusinessCase +{ + [ApiAuthorize] + [Route("/api/businesscases")] + [ApiController] + [ApiExplorerSettings(GroupName = "BusinessCases")] + public class GetBusinessCaseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public GetBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("{businessCaseId}", Name = "GetBusinessCase")] + public async Task> GetBusinessCase(int businessCaseId) + { + var result = await _mediator.Send(new GetBusinessCaseQuery(businessCaseId)); + + var businessCaseInfo = new GetBusinessCaseResponse + { + BusinessCaseId = businessCaseId, + Name = result.Value.Name, + Origins = result.Value?.Origins.Select(o => new GetBusinessCaseOriginResponse + { + OriginBusinessCaseId = o.Id, + Name = o.Name + }).ToList() + }; + + return result.IsSuccess ? Ok(businessCaseInfo) : BadRequest(result.Error); + } + } + + public class GetBusinessCaseResponse + { + public int BusinessCaseId { get; set; } + + public string Name { get; set; } + + public List Origins { get; set; } = []; + } + + public class GetBusinessCaseOriginResponse + { + public int OriginBusinessCaseId { get; set; } + public string Name { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/GetBusinessCase/GetBusinessCaseQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/GetBusinessCase/GetBusinessCaseQuery.cs new file mode 100644 index 00000000..bc14783c --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/GetBusinessCase/GetBusinessCaseQuery.cs @@ -0,0 +1,41 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.BusinessCases.GetBusinessCase +{ + public class GetBusinessCaseQuery : IRequest> + { + public int BusinessCaseId { get; set; } + + public GetBusinessCaseQuery(int id) + { + BusinessCaseId = id; + } + } + + internal sealed class GetBusinessCaseQueryHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public GetBusinessCaseQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(GetBusinessCaseQuery request, CancellationToken cancellationToken) + { + var businessCase = await _context.BusinessCases + .Where(bc => bc.Id == request.BusinessCaseId) + .Include(bc => bc.Origins) + .FirstOrDefaultAsync(); + + if (businessCase == null) + return new ValidationFailed(new[] { "Business Case not Found" }); + + return businessCase; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/ListBusinessCases/ListBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/ListBusinessCases/ListBusinessCaseEndpoint.cs new file mode 100644 index 00000000..66be871d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/ListBusinessCases/ListBusinessCaseEndpoint.cs @@ -0,0 +1,34 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.BusinessCases.ListBusinessCases +{ + [ApiAuthorize] + [Route("/api/businesscase")] + [ApiController] + [ApiExplorerSettings(GroupName = "BusinessCases")] + public class ListBusinessCaseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("ListBusinessCase", Name = "ListBusinessCase")] + public async Task> ListBusinessCases(ListBusinessCaseRequest request) + { + var result = await _mediator.Send(new ListBusinessCaseQuery(request.PageNumber, request.PageSize, request.Filters)); + return Ok(result); + } + } + + public class ListBusinessCaseRequest + { + public int PageNumber { get; set; } + public int PageSize { get; set; } + public List Filters { get; set; } = new(); + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/ListBusinessCases/ListBusinessCaseQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/ListBusinessCases/ListBusinessCaseQuery.cs new file mode 100644 index 00000000..ea85db6a --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/ListBusinessCases/ListBusinessCaseQuery.cs @@ -0,0 +1,64 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.BusinessCases.ListBusinessCases +{ + public class ListBusinessCaseViewModel : PaginationResponse + { + } + + public class BusinessCaseViewModel + { + public int BusinessCaseId { get; set; } + + public string Name { get; set; } + + public int OriginsBusinessCases { get; set; } + } + + public class ListBusinessCaseQuery : PaginationRequest, IRequest + { + public ListBusinessCaseQuery(int pageNumber, int pageSize, List filters) : base(pageNumber, pageSize, filters) + { + } + } + + internal sealed class ListBusinessCaseQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public ListBusinessCaseQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(ListBusinessCaseQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + var query = _context.BusinessCases.AsQueryable(); + var result = await query.Where(expr).Select(bc => new BusinessCaseViewModel + { + BusinessCaseId = bc.Id, + Name = bc.Name, + OriginsBusinessCases = _context.OriginBusinessCases + .Count(obc => obc.BusinessCaseId == bc.Id) + }) + .OrderBy(bc => bc.BusinessCaseId) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToListAsync(cancellationToken); + + var totalRecords = await _context.BusinessCases.CountAsync(expr, cancellationToken); + + return new ListBusinessCaseViewModel + { + Items = result, + TotalItems = totalRecords, + }; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/UpdateBusinessCase/UpdateBusinessCaseCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/UpdateBusinessCase/UpdateBusinessCaseCommand.cs new file mode 100644 index 00000000..8f6a6365 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/UpdateBusinessCase/UpdateBusinessCaseCommand.cs @@ -0,0 +1,53 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.BusinessCases.UpdateBusinessCase +{ + public class UpdateBusinessCaseCommand : IRequest> + { + public int BusinessCaseId { get; set; } + + public string? Name { get; set; } + + public List OriginsBusinessCasesIds { get; set; } = []; + } + + internal sealed class UpdateBusinessCaseCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public UpdateBusinessCaseCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(UpdateBusinessCaseCommand request, CancellationToken cancellationToken) + { + var businessCase = await _context.BusinessCases + .Where(bc => bc.Id == request.BusinessCaseId) + .Include(bc => bc.Origins) + .FirstOrDefaultAsync(cancellationToken); + + if (businessCase == null) + return new ValidationFailed(new[] { "Business Case not Found" }); + + businessCase.Name = string.IsNullOrEmpty(request.Name) ? businessCase.Name : request.Name; + + if(!request.OriginsBusinessCasesIds.OrderBy(x => x) + .SequenceEqual(businessCase.Origins.Select(o => o.Id).OrderBy(x => x))) + { + var origins = await _context.OriginBusinessCases + .Where(obc => request.OriginsBusinessCasesIds.Contains(obc.Id)) + .ToListAsync(cancellationToken); + + businessCase.Origins = origins; + } + + await _context.SaveChangesAsync(cancellationToken); + return businessCase; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/UpdateBusinessCase/UpdateBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/UpdateBusinessCase/UpdateBusinessCaseEndpoint.cs new file mode 100644 index 00000000..cb45af04 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/BusinessCases/UpdateBusinessCase/UpdateBusinessCaseEndpoint.cs @@ -0,0 +1,67 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.BusinessCases.UpdateBusinessCase +{ + [ApiAuthorize] + [Route("/api/businesscases")] + [ApiController] + [ApiExplorerSettings(GroupName = "BusinessCases")] + public class UpdateBusinessCaseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public UpdateBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{businessCaseId}", Name = "UpdateBusinessCase")] + public async Task> UpdateBusinessCase(int businessCaseId, [FromBody] UpdateBusinessCaseRequest request) + { + var result = await _mediator.Send(new UpdateBusinessCaseCommand + { + BusinessCaseId = businessCaseId, + Name = request.Name, + OriginsBusinessCasesIds = request.OriginsBusinessCasesIds + }); + + var updateResponse = new UpdateBusinessCaseResponse + { + BusinessCaseId = businessCaseId, + Name = result.Value.Name, + OriginsBusinessCases = result.Value.Origins?.Select(o => new UpdateOriginBusinessCaseInBusinessCaseResponse + { + OriginBusinessCaseId = o.Id, + Name = o.Name + }).ToList() + }; + + return result.IsSuccess ? Ok(updateResponse) : BadRequest(result.Error); + } + } + + public class UpdateBusinessCaseRequest + { + public string? Name { get; set; } + + public List OriginsBusinessCasesIds { get; set; } = []; + } + + public class UpdateBusinessCaseResponse + { + public int BusinessCaseId { get; set; } + + public string Name { get; set; } + + public List? OriginsBusinessCases { get; set; } + } + + public class UpdateOriginBusinessCaseInBusinessCaseResponse + { + public int OriginBusinessCaseId { get; set; } + + public string Name { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/CreateCompany/CreateCompanyCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/CreateCompany/CreateCompanyCommand.cs new file mode 100644 index 00000000..9cfd31e5 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/CreateCompany/CreateCompanyCommand.cs @@ -0,0 +1,87 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Features.Companies.CreateCompany +{ + public class CreateCompanyCommand : IRequest> + { + public string CNPJ { get; set; } = string.Empty; + public string CompanyName { get; set; } = string.Empty; + public string? CorporateReason { get; set; } + public string? FieldOfActivity { get; set; } + public string? ZipCode { get; set; } + public string? Address { get; set; } + public string? Neighborhood { get; set; } + public string? City { get; set; } + public string? State { get; set; } + public string? PhoneNumber { get; set; } + public string? Website { get; set; } + public string? SocialMedia { get; set; } + public bool IsActive { get; set; } = true; + } + + internal sealed class CreateCompanyCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public CreateCompanyCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(CreateCompanyCommand request, CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(request.CNPJ) || request.CNPJ.Length != 14 || !request.CNPJ.All(char.IsDigit)) + { + return new ValidationFailed("O CNPJ deve conter exatamente 14 dgitos numricos."); + } + + if (string.IsNullOrWhiteSpace(request.CompanyName)) + { + return new ValidationFailed("O nome da empresa (CompanyName) obrigatrio."); + } + + if (string.IsNullOrWhiteSpace(request.CorporateReason)) + { + return new ValidationFailed("A razo social (CorporateReason) obrigatria."); + } + + var existingCompany = await _context.Companies + .IgnoreQueryFilters() + .FirstOrDefaultAsync(c => c.CNPJ == request.CNPJ, cancellationToken); + + if (existingCompany != null) + { + return new ValidationFailed("Uma empresa com este CNPJ j est cadastrada (seja ela ativa ou inativa)."); + } + + var company = new Company + { + CNPJ = request.CNPJ, + CompanyName = request.CompanyName, + CorporateReason = request.CorporateReason, + FieldOfActivity = request.FieldOfActivity, + ZipCode = request.ZipCode, + Address = request.Address, + Neighborhood = request.Neighborhood, + City = request.City, + State = request.State, + PhoneNumber = request.PhoneNumber, + Website = request.Website, + SocialMedia = request.SocialMedia, + IsDeleted = !request.IsActive + }; + + await _context.Companies.AddAsync(company, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + + return company.CNPJ; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/CreateCompany/CreateCompanyEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/CreateCompany/CreateCompanyEndpoint.cs new file mode 100644 index 00000000..41c18ba6 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/CreateCompany/CreateCompanyEndpoint.cs @@ -0,0 +1,31 @@ +using IgescConecta.API.Features.Companies.CreateCompany; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Companies.CreateCompany +{ + [ApiController] + [Route("api/companies")] + public class CreateCompanyEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public CreateCompanyEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost] + public async Task Post([FromBody] CreateCompanyCommand request) + { + var result = await _mediator.Send(request); + + if (result.IsSuccess) + { + return CreatedAtRoute("GetCompanyByCnpj", new { cnpj = result.Value }, result.Value); + } + + return BadRequest(result.Error); + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/InactivateCompany/InactivateCompanyCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/InactivateCompany/InactivateCompanyCommand.cs new file mode 100644 index 00000000..718c64e8 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/InactivateCompany/InactivateCompanyCommand.cs @@ -0,0 +1,47 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Features.Companies.InactivateCompany +{ + public class InactivateCompanyCommand : IRequest> + { + public string CNPJ { get; set; } = string.Empty; + } + + internal sealed class InactivateCompanyCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public InactivateCompanyCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(InactivateCompanyCommand request, CancellationToken cancellationToken) + { + var company = await _context.Companies + .IgnoreQueryFilters() + .FirstOrDefaultAsync(c => c.CNPJ == request.CNPJ, cancellationToken); + + if (company is null) + { + return new ValidationFailed($"Empresa com CNPJ {request.CNPJ} no encontrada."); + } + + if (company.IsDeleted) + { + return new ValidationFailed($"Empresa com CNPJ {request.CNPJ} j est inativa."); + } + + company.IsDeleted = true; + + await _context.SaveChangesAsync(cancellationToken); + + return Unit.Value; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/InactivateCompany/InactivateCompanyEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/InactivateCompany/InactivateCompanyEndpoint.cs new file mode 100644 index 00000000..3013a302 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/InactivateCompany/InactivateCompanyEndpoint.cs @@ -0,0 +1,32 @@ +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Companies.InactivateCompany +{ + [ApiController] + [Route("api/companies")] + public class InactivateCompanyEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public InactivateCompanyEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpDelete("{cnpj}")] + public async Task Delete(string cnpj) + { + var request = new InactivateCompanyCommand { CNPJ = cnpj }; + + var result = await _mediator.Send(request); + + if (result.IsSuccess) + { + return NoContent(); + } + + return BadRequest(result.Error); + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompanies/ListCompaniesEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompanies/ListCompaniesEndpoint.cs new file mode 100644 index 00000000..06aea080 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompanies/ListCompaniesEndpoint.cs @@ -0,0 +1,33 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Companies.ListCompanies +{ + [ApiController] + [Route("api/companies")] + public class ListCompaniesEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListCompaniesEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("search")] + public async Task> Search(ListCompaniesRequest request) + { + var query = new ListCompaniesQuery(request.PageNumber, request.PageSize, request.Filters); + var result = await _mediator.Send(query); + return Ok(result); + } + } + + public class ListCompaniesRequest + { + public int PageNumber { get; set; } + public int PageSize { get; set; } + public List Filters { get; set; } = new(); + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompanies/ListCompaniesQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompanies/ListCompaniesQuery.cs new file mode 100644 index 00000000..f54c6291 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompanies/ListCompaniesQuery.cs @@ -0,0 +1,99 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System.Linq; + +namespace IgescConecta.API.Features.Companies.ListCompanies +{ + public class ListCompaniesViewModel : PaginationResponse + { + } + + public class CompanyViewModel + { + public int Id { get; set; } + public string CNPJ { get; set; } = string.Empty; + public string Nome { get; set; } = string.Empty; + public string RazaoSocial { get; set; } = string.Empty; + public string? Telefone { get; set; } + public bool Ativa { get; set; } + } + + public class ListCompaniesQuery : PaginationRequest, IRequest + { + public ListCompaniesQuery(int pageNumber, int pageSize, List filters) + : base(pageNumber, pageSize, filters) + { + } + } + + internal sealed class ListCompaniesQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public ListCompaniesQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(ListCompaniesQuery request, CancellationToken cancellationToken) + { + var query = _context.Companies.AsQueryable(); + var filters = request.Filters ?? new List(); + + var statusFilter = filters.FirstOrDefault(f => f.PropertyName.Equals("IsActive", StringComparison.OrdinalIgnoreCase)); + + if (statusFilter != null) + { + if (bool.TryParse(statusFilter.Value.ToString(), out bool isActive)) + { + if (!isActive) + { + query = query.IgnoreQueryFilters().Where(c => c.IsDeleted); + } + else + { + query = query.Where(c => !c.IsDeleted); + } + } + filters.Remove(statusFilter); + } + else + { + query = query.IgnoreQueryFilters(); + } + + if (filters.Any()) + { + var expr = ExpressionBuilder.GetExpression(filters); + query = query.Where(expr); + } + + var totalRecords = await query.CountAsync(cancellationToken); + + var items = await query + .Select(company => new CompanyViewModel + { + Id = company.Id, + CNPJ = company.CNPJ, + Nome = company.CompanyName, + RazaoSocial = company.CorporateReason ?? string.Empty, + Telefone = company.PhoneNumber, + Ativa = !company.IsDeleted + }) + .OrderBy(c => c.Nome) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToListAsync(cancellationToken); + + return new ListCompaniesViewModel + { + Items = items, + TotalItems = totalRecords + }; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompany/ListCompanyEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompany/ListCompanyEndpoint.cs new file mode 100644 index 00000000..e6697b2f --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompany/ListCompanyEndpoint.cs @@ -0,0 +1,30 @@ +using IgescConecta.API.Features.Companies.ListCompany; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Companies.ListCompany +{ + [ApiController] + [Route("api/companies")] + public class ListCompanyEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListCompanyEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("{cnpj}", Name = "GetCompanyByCnpj")] + public async Task Get(string cnpj) + { + var query = new ListCompanyQuery { CNPJ = cnpj }; + var result = await _mediator.Send(query); + if (result.IsSuccess) + { + return Ok(result.Value); + } + return NotFound(result.Error); + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompany/ListCompanyQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompany/ListCompanyQuery.cs new file mode 100644 index 00000000..c45f8e2e --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ListCompany/ListCompanyQuery.cs @@ -0,0 +1,73 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Features.Companies.ListCompany +{ + public class CompanyDto + { + public string CNPJ { get; set; } = string.Empty; + public string Nome { get; set; } = string.Empty; + public string RazaoSocial { get; set; } = string.Empty; + public string? AreaAtuacao { get; set; } + public string? CEP { get; set; } + public string? Endereco { get; set; } + public string? Bairro { get; set; } + public string? Cidade { get; set; } + public string? UF { get; set; } + public string? Telefone { get; set; } + public string? Email { get; set; } + public string? Site { get; set; } + public string? RedesSociais { get; set; } + public bool Ativa { get; set; } + } + + public class ListCompanyQuery : IRequest> + { + public string CNPJ { get; set; } = string.Empty; + } + + internal sealed class ListCompanyQueryHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public ListCompanyQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(ListCompanyQuery request, CancellationToken cancellationToken) + { + var company = await _context.Companies + .AsNoTracking() + .FirstOrDefaultAsync(c => c.CNPJ == request.CNPJ, cancellationToken); + + if (company is null) + { + return new ValidationFailed($"Empresa com CNPJ {request.CNPJ} no encontrada."); + } + + var companyDto = new CompanyDto + { + CNPJ = company.CNPJ, + Nome = company.CompanyName, + RazaoSocial = company.CorporateReason ?? string.Empty, + AreaAtuacao = company.FieldOfActivity, + CEP = company.ZipCode, + Endereco = company.Address, + Bairro = company.Neighborhood, + Cidade = company.City, + UF = company.State, + Telefone = company.PhoneNumber, + Site = company.Website, + RedesSociais = company.SocialMedia, + Ativa = !company.IsDeleted + }; + + return companyDto; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ReactiveCompany/ReactivateCompanyCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ReactiveCompany/ReactivateCompanyCommand.cs new file mode 100644 index 00000000..eb304cfa --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ReactiveCompany/ReactivateCompanyCommand.cs @@ -0,0 +1,47 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Features.Companies.ReactivateCompany +{ + public class ReactivateCompanyCommand : IRequest> + { + public string CNPJ { get; set; } = string.Empty; + } + + internal sealed class ReactivateCompanyCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public ReactivateCompanyCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(ReactivateCompanyCommand request, CancellationToken cancellationToken) + { + var company = await _context.Companies + .IgnoreQueryFilters() + .FirstOrDefaultAsync(c => c.CNPJ == request.CNPJ, cancellationToken); + + if (company is null) + { + return new ValidationFailed($"Empresa com CNPJ {request.CNPJ} não encontrada."); + } + + if (!company.IsDeleted) + { + return new ValidationFailed($"A empresa com CNPJ {request.CNPJ} já está ativa."); + } + + company.IsDeleted = false; + + await _context.SaveChangesAsync(cancellationToken); + + return Unit.Value; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ReactiveCompany/ReactivateCompanyEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ReactiveCompany/ReactivateCompanyEndpoint.cs new file mode 100644 index 00000000..9bc46939 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/ReactiveCompany/ReactivateCompanyEndpoint.cs @@ -0,0 +1,32 @@ +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Companies.ReactivateCompany +{ + [ApiController] + [Route("api/companies")] + public class ReactivateCompanyEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ReactivateCompanyEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPatch("{cnpj}/activate")] + public async Task Reactivate(string cnpj) + { + var command = new ReactivateCompanyCommand { CNPJ = cnpj }; + + var result = await _mediator.Send(command); + + if (result.IsSuccess) + { + return NoContent(); + } + + return BadRequest(result.Error); + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/UpdateEmpresa/UpdateCompanyCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/UpdateEmpresa/UpdateCompanyCommand.cs new file mode 100644 index 00000000..812f0345 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/UpdateEmpresa/UpdateCompanyCommand.cs @@ -0,0 +1,69 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Features.Companies.UpdateCompany +{ + public class UpdateCompanyCommand : IRequest> + { + // O CNPJ vir da rota do endpoint, mas o inclumos aqui para consistncia. + public string CNPJ { get; set; } = string.Empty; + + // Propriedades traduzidas para o ingls + public string CompanyName { get; set; } = string.Empty; + public string? CorporateReason { get; set; } + public string? FieldOfActivity { get; set; } + public string? ZipCode { get; set; } + public string? Address { get; set; } + public string? Neighborhood { get; set; } + public string? City { get; set; } + public string? State { get; set; } + public string? PhoneNumber { get; set; } + public string? Website { get; set; } + public string? SocialMedia { get; set; } + } + + internal sealed class UpdateCompanyCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public UpdateCompanyCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(UpdateCompanyCommand request, CancellationToken cancellationToken) + { + // 1. Encontra a empresa existente no banco pelo CNPJ + var company = await _context.Companies + .FirstOrDefaultAsync(c => c.CNPJ == request.CNPJ, cancellationToken); + + if (company is null) + { + return new ValidationFailed($"Empresa com CNPJ {request.CNPJ} no encontrada."); + } + + // 2. Atualiza todas as propriedades da entidade com os dados do command + company.CompanyName = request.CompanyName; + company.CorporateReason = request.CorporateReason; + company.FieldOfActivity = request.FieldOfActivity; + company.ZipCode = request.ZipCode; + company.Address = request.Address; + company.Neighborhood = request.Neighborhood; + company.City = request.City; + company.State = request.State; + company.PhoneNumber = request.PhoneNumber; + company.Website = request.Website; + company.SocialMedia = request.SocialMedia; + + // 3. O Entity Framework j sabe que a entidade foi modificada, basta salvar. + await _context.SaveChangesAsync(cancellationToken); + + return company.CNPJ; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/UpdateEmpresa/UpdateCompanyEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/UpdateEmpresa/UpdateCompanyEndpoint.cs new file mode 100644 index 00000000..2d78a49b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Company/UpdateEmpresa/UpdateCompanyEndpoint.cs @@ -0,0 +1,32 @@ +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Companies.UpdateCompany +{ + [ApiController] + [Route("api/companies")] + public class UpdateCompanyEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public UpdateCompanyEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{cnpj}")] + public async Task Put([FromRoute] string cnpj, [FromBody] UpdateCompanyCommand request) + { + request.CNPJ = cnpj; + + var result = await _mediator.Send(request); + + if (result.IsSuccess) + { + return Ok(new { cnpj = result.Value, message = "Company updated successfully." }); + } + + return BadRequest(result.Error); + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Create/CreateCourseCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Create/CreateCourseCommand.cs new file mode 100644 index 00000000..de124a89 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Create/CreateCourseCommand.cs @@ -0,0 +1,40 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; + +namespace IgescConecta.API.Features.Courses.CreateCourse +{ + public class CreateCourseCommand : IRequest> + { + public string Name { get; set; } + } + + internal sealed class CreateCourseCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public CreateCourseCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(CreateCourseCommand request, CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(request.Name)) + { + return new ValidationFailed(new[] { "O nome do Programa é obrigatório." }); + } + + var course = new Course + { + Name = request.Name, + }; + + await _context.Courses.AddAsync(course, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + + return course.Id; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Create/CreateCourseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Create/CreateCourseEndpoint.cs new file mode 100644 index 00000000..238b31ea --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Create/CreateCourseEndpoint.cs @@ -0,0 +1,48 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Courses.CreateCourse +{ + [ApiAuthorize] + [Route("/api/courses")] + [ApiController] + [ApiExplorerSettings(GroupName = "Courses")] + public class CreateCourseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public CreateCourseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost(Name = "CreateCourse")] + public async Task> CreateCourse([FromBody] CreateCourseRequest request) + { + var result = await _mediator.Send(new CreateCourseCommand + { + Name = request.Name + }); + + return result.IsSuccess + ? Ok(new CreateCourseResponse(result.Value)) + : BadRequest(result.Error); + } + } + + public class CreateCourseRequest + { + public string Name { get; set; } + } + + public class CreateCourseResponse + { + public int CourseId { get; set; } + + public CreateCourseResponse(int courseId) + { + CourseId = courseId; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Delete/DeleteCourseCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Delete/DeleteCourseCommand.cs new file mode 100644 index 00000000..d7fbade7 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Delete/DeleteCourseCommand.cs @@ -0,0 +1,45 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Courses.DeleteCourse +{ + public class DeleteCourseCommand : IRequest> + { + public int CourseId { get; set; } + } + + internal sealed class DeleteCourseCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public DeleteCourseCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(DeleteCourseCommand request, CancellationToken cancellationToken) + { + var course = await _context.Courses.FindAsync(request.CourseId); + + if (course == null) + { + return new ValidationFailed(new[] { "Programa não encontrado ou já está excluído." }); + } + + var hasTeams = await _context.Teams + .AnyAsync(t => t.CourseId == request.CourseId, cancellationToken); + + if (hasTeams) + { + return new ValidationFailed(new[] { "Desvincule as Turmas desse Programa antes de excluí-lo." }); + } + + _context.Courses.Remove(course); + await _context.SaveChangesAsync(cancellationToken); + + return course.Id; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Delete/DeleteCourseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Delete/DeleteCourseEndpoint.cs new file mode 100644 index 00000000..657f254b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Delete/DeleteCourseEndpoint.cs @@ -0,0 +1,43 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Courses.DeleteCourse +{ + [ApiAuthorize] + [Route("/api/courses")] + [ApiController] + [ApiExplorerSettings(GroupName = "Courses")] + public class DeleteCourseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public DeleteCourseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpDelete("{courseId}", Name = "DeleteCourse")] + public async Task> DeleteCourse(int courseId) + { + var result = await _mediator.Send(new DeleteCourseCommand + { + CourseId = courseId + }); + + return result.IsSuccess + ? Ok(new DeleteCourseResponse(result.Value)) + : BadRequest(result.Error); + } + } + + public class DeleteCourseResponse + { + public int CourseId { get; set; } + + public DeleteCourseResponse(int courseId) + { + CourseId = courseId; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Edit/EditCourseCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Edit/EditCourseCommand.cs new file mode 100644 index 00000000..b9617026 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Edit/EditCourseCommand.cs @@ -0,0 +1,46 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Courses.EditCourse +{ + public class EditCourseCommand : IRequest> + { + public int CourseId { get; set; } + public string Name { get; set; } + } + + internal sealed class EditCourseCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public EditCourseCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(EditCourseCommand request, CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(request.Name)) + { + return new ValidationFailed(new[] { "O nome do Programa é obrigatório." }); + } + + var course = await _context.Courses + .Where(c => c.Id == request.CourseId) + .FirstOrDefaultAsync(cancellationToken); + + if (course == null) + { + return new ValidationFailed(new[] { "Programa não encontrado." }); + } + + course.Name = request.Name; + + await _context.SaveChangesAsync(cancellationToken); + + return course.Id; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Edit/EditCourseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Edit/EditCourseEndpoint.cs new file mode 100644 index 00000000..bb80ef12 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/Edit/EditCourseEndpoint.cs @@ -0,0 +1,51 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Courses.EditCourse +{ + [ApiAuthorize] + [Route("/api/courses")] + [ApiController] + [ApiExplorerSettings(GroupName = "Courses")] + public class EditCourseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public EditCourseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{courseId}", Name = "EditCourse")] + public async Task> EditCourse(int courseId, [FromBody] EditCourseRequest request) + { + var result = await _mediator.Send(new EditCourseCommand + { + CourseId = courseId, + Name = request.Name + }); + + var updateResponse = new EditCourseResponse(result.Value); + + return result.IsSuccess + ? Ok(updateResponse) + : BadRequest(result.Error); + } + } + + public class EditCourseRequest + { + public string Name { get; set; } + } + + public class EditCourseResponse + { + public int CourseId { get; set; } + + public EditCourseResponse(int courseId) + { + CourseId = courseId; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/List/ListCourseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/List/ListCourseEndpoint.cs new file mode 100644 index 00000000..b49a4c31 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/List/ListCourseEndpoint.cs @@ -0,0 +1,47 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Courses.ListCourse +{ + [ApiAuthorize] + [Route("/api/courses")] + [ApiController] + [ApiExplorerSettings(GroupName = "Courses")] + public class ListCourseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListCourseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("search", Name = "ListCourse")] + public async Task> ListCourse([FromBody] ListCourseRequest request) + { + var result = await _mediator.Send(new ListCourseQuery(request.PageNumber, request.PageSize, request.Filters)); + return Ok(result); + } + + [HttpGet("{id:int}", Name = "GetCourseById")] + public async Task> GetCourseById([FromRoute] int id) + { + var result = await _mediator.Send(new GetCourseByIdQuery(id)); + + if (result == null) + { + return NotFound(); + } + + return Ok(result); + } + } + + public class ListCourseRequest + { + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 10; + public List Filters { get; set; } = new(); + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/List/ListCourseQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/List/ListCourseQuery.cs new file mode 100644 index 00000000..3fe3464d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Course/List/ListCourseQuery.cs @@ -0,0 +1,137 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Courses.ListCourse +{ + public class ListCourseViewModel : PaginationResponse + { + } + + public class CourseViewModel + { + public int CourseId { get; set; } + public string? Name { get; set; } + public int TeamsCount { get; set; } + } + + public class GetCourseByIdViewModel + { + public int CourseId { get; set; } + public string? Name { get; set; } + public bool IsDeleted { get; set; } + public int? TeamsCount { get; set; } + public int CreatedBy { get; set; } + public DateTime CreatedAt { get; set; } + public int UpdatedBy { get; set; } + public DateTime UpdatedAt { get; set; } + + public List Teams { get; set; } = new List(); + } + + public class TeamViewModel + { + public int Id { get; set; } + public string? Name { get; set; } + public string? LessonTime { get; set; } + public DateTime? Start { get; set; } + public DateTime? Finish { get; set; } + } + + public class GetCourseByIdQuery : IRequest + { + public int Id { get; } + + public GetCourseByIdQuery(int id) + { + Id = id; + } + } + + public class ListCourseQuery : PaginationRequest, IRequest + { + public ListCourseQuery(int pageNumber, int pageSize, List filters) + : base(pageNumber, pageSize, filters) + { + } + } + + internal sealed class ListCourseQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public ListCourseQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(ListCourseQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + + var query = _context.Courses.AsQueryable(); + + var result = await query + .Where(expr) + .Select(c => new CourseViewModel + { + CourseId = c.Id, + Name = c.Name, + TeamsCount = c.Teams.Count + }) + .OrderBy(x => x.CourseId) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToListAsync(cancellationToken); + + var totalRecords = await _context.Courses.CountAsync(expr, cancellationToken); + + return new ListCourseViewModel + { + Items = result, + TotalItems = totalRecords, + }; + } + } + + internal sealed class GetCourseByIdQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public GetCourseByIdQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(GetCourseByIdQuery request, CancellationToken cancellationToken) + { + var course = await _context.Courses + .Where(c => c.Id == request.Id) + .Select(c => new GetCourseByIdViewModel + { + CourseId = c.Id, + Name = c.Name, + IsDeleted = c.IsDeleted, + CreatedBy = c.CreatedBy, + CreatedAt = c.CreatedAt, + UpdatedBy = c.UpdatedBy, + UpdatedAt = c.UpdatedAt, + TeamsCount = c.Teams.Count(), + Teams = c.Teams.Select(t => new TeamViewModel + { + Id = t.Id, + Name = t.Name, + LessonTime = t.LessonTime, + Start = t.Start, + Finish = t.Finish + }).ToList() + }) + .FirstOrDefaultAsync(cancellationToken); + + return course; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/CreateDonation/CreateDonationCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/CreateDonation/CreateDonationCommand.cs new file mode 100644 index 00000000..0dca270d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/CreateDonation/CreateDonationCommand.cs @@ -0,0 +1,77 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Features.Donations.CreateDonation +{ + public class CreateDonationCommand : IRequest> + { + public decimal Value { get; set; } + public DateTime DonationDate { get; set; } + public int? PersonId { get; set; } + public int? CompanyId { get; set; } + public int? OscId { get; set; } + public int? CourseId { get; set; } + public int? TeamId { get; set; } + } + + internal sealed class CreateDonationCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public CreateDonationCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(CreateDonationCommand request, CancellationToken cancellationToken) + { + if (request.Value <= 0) + { + return new ValidationFailed("O valor da doa��o deve ser maior que zero."); + } + + if (request.PersonId.HasValue == request.CompanyId.HasValue) + { + return new ValidationFailed("A doa��o deve ter exatamente um doador: ou uma Pessoa (PersonId) ou uma Empresa (CompanyId)."); + } + + if (request.OscId.HasValue && request.CourseId.HasValue) + { + return new ValidationFailed("A doa��o pode ser destinada para uma OSC ou para um Curso/Turma, mas n�o para ambos ao mesmo tempo."); + } + + if (request.TeamId.HasValue && !request.CourseId.HasValue) + { + return new ValidationFailed("Uma doa��o para uma Turma (TeamId) tamb�m deve especificar o Curso (CourseId)."); + } + + if (request.CourseId.HasValue && !request.TeamId.HasValue) + { + return new ValidationFailed("Uma doa��o para um Curso deve especificar uma Turma (TeamId). A doa��o n�o pode ser para um curso em geral."); + } + + var finalDonationDate = request.DonationDate.Date + DateTime.UtcNow.TimeOfDay; + + var donation = new Donation + { + Value = request.Value, + DonationDate = finalDonationDate, + PersonId = request.PersonId, + CompanyId = request.CompanyId, + OscId = request.OscId, + CourseId = request.CourseId, + TeamId = request.TeamId + }; + + await _context.Donations.AddAsync(donation, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + + return donation.Id; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/CreateDonation/CreateDonationEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/CreateDonation/CreateDonationEndpoint.cs new file mode 100644 index 00000000..4af1a857 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/CreateDonation/CreateDonationEndpoint.cs @@ -0,0 +1,31 @@ +using IgescConecta.API.Features.Donations.CreateDonation; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Donations.CreateDonation +{ + [ApiController] + [Route("api/donations")] + public class CreateDonationEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public CreateDonationEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost] + public async Task Post([FromBody] CreateDonationCommand request) + { + var result = await _mediator.Send(request); + + if (result.IsSuccess) + { + return CreatedAtRoute("GetDonationById", new { id = result.Value }, result.Value); + } + + return BadRequest(result.Error); + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/DeleteDonation/DeleteDonationCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/DeleteDonation/DeleteDonationCommand.cs new file mode 100644 index 00000000..b5c18924 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/DeleteDonation/DeleteDonationCommand.cs @@ -0,0 +1,46 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Features.Donations.DeleteDonation +{ + public class DeleteDonationCommand : IRequest> + { + public int Id { get; set; } + } + + internal sealed class DeleteDonationCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public DeleteDonationCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(DeleteDonationCommand request, CancellationToken cancellationToken) + { + var donation = await _context.Donations + .FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken); + + if (donation is null) + { + return new ValidationFailed($"Doação com ID {request.Id} não encontrada."); + } + + if (donation.IsDeleted) + { + return new ValidationFailed($"Doação com ID {request.Id} já está inativa/deletada."); + } + + donation.IsDeleted = true; + + await _context.SaveChangesAsync(cancellationToken); + + return Unit.Value; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/DeleteDonation/DeleteDonationEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/DeleteDonation/DeleteDonationEndpoint.cs new file mode 100644 index 00000000..bb73f2b0 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/DeleteDonation/DeleteDonationEndpoint.cs @@ -0,0 +1,32 @@ +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Donations.DeleteDonation +{ + [ApiController] + [Route("api/donations")] + public class DeleteDonationEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public DeleteDonationEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpDelete("{id:int}")] + public async Task Delete(int id) + { + var request = new DeleteDonationCommand { Id = id }; + + var result = await _mediator.Send(request); + + if (result.IsSuccess) + { + return NoContent(); + } + + return BadRequest(result.Error); + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonation/ListDonationEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonation/ListDonationEndpoint.cs new file mode 100644 index 00000000..8bd7bd85 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonation/ListDonationEndpoint.cs @@ -0,0 +1,30 @@ +using IgescConecta.API.Features.Donations.ListDonation; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Donations.ListDonation +{ + [ApiController] + [Route("api/donations")] + public class ListDonationEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListDonationEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("{id:int}", Name = "GetDonationById")] + public async Task Get(int id) + { + var query = new ListDonationQuery { Id = id }; + var result = await _mediator.Send(query); + if (result.IsSuccess) + { + return Ok(result.Value); + } + return NotFound(result.Error); + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonation/ListDonationQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonation/ListDonationQuery.cs new file mode 100644 index 00000000..d915bce2 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonation/ListDonationQuery.cs @@ -0,0 +1,61 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Features.Donations.ListDonation +{ + public class DonationDto + { + public int Id { get; set; } + public decimal Valor { get; set; } + public DateTime Data { get; set; } + public int? PersonId { get; set; } + public int? CompanyId { get; set; } + public int? OscId { get; set; } + public int? TeamId { get; set; } + } + + public class ListDonationQuery : IRequest> + { + public int Id { get; set; } + } + + internal sealed class ListDonationQueryHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public ListDonationQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(ListDonationQuery request, CancellationToken cancellationToken) + { + var donation = await _context.Donations + .AsNoTracking() + .FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken); + + if (donation is null) + { + return new ValidationFailed($"Doao com ID {request.Id} no encontrada."); + } + + var donationDto = new DonationDto + { + Id = donation.Id, + Valor = donation.Value, + Data = donation.DonationDate, + PersonId = donation.PersonId, + CompanyId = donation.CompanyId, + OscId = donation.OscId, + TeamId = donation.TeamId + }; + + return donationDto; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonations/ListDonationsEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonations/ListDonationsEndpoint.cs new file mode 100644 index 00000000..2cc2b577 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonations/ListDonationsEndpoint.cs @@ -0,0 +1,33 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Donations.ListDonations +{ + [ApiController] + [Route("api/donations")] + public class ListDonationsEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListDonationsEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("search")] + public async Task> Search(ListDonationsRequest request) + { + var query = new ListDonationsQuery(request.PageNumber, request.PageSize, request.Filters); + var result = await _mediator.Send(query); + return Ok(result); + } + } + + public class ListDonationsRequest + { + public int PageNumber { get; set; } + public int PageSize { get; set; } + public List Filters { get; set; } = new(); + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonations/ListDonationsQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonations/ListDonationsQuery.cs new file mode 100644 index 00000000..c888d47a --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/ListDonations/ListDonationsQuery.cs @@ -0,0 +1,75 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System.Linq; + +namespace IgescConecta.API.Features.Donations.ListDonations +{ + public class ListDonationsViewModel : PaginationResponse + { + } + + public class DonationViewModel + { + public int Id { get; set; } + public decimal Value { get; set; } + public DateTime DonationDate { get; set; } + public string DoadorNome { get; set; } = string.Empty; + public string DestinoNome { get; set; } = string.Empty; + } + + public class ListDonationsQuery : PaginationRequest, IRequest + { + public ListDonationsQuery(int pageNumber, int pageSize, List filters) + : base(pageNumber, pageSize, filters) + { + } + } + + internal sealed class ListDonationsQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public ListDonationsQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(ListDonationsQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + + var query = _context.Donations.AsNoTracking() + .Include(d => d.Person) + .Include(d => d.Company) + .Include(d => d.Osc) + .Include(d => d.Team); + + var totalRecords = await query.Where(expr).CountAsync(cancellationToken); + + var items = await query + .Where(expr) + .OrderByDescending(d => d.DonationDate) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .Select(donation => new DonationViewModel + { + Id = donation.Id, + Value = donation.Value, + DonationDate = donation.DonationDate, + DoadorNome = donation.Person != null ? donation.Person.Name : (donation.Company != null ? donation.Company.CompanyName : "N/A"), + DestinoNome = donation.Osc != null ? donation.Osc.Name : (donation.Team != null ? donation.Team.Name : "IGESC (Geral)") + }) + .ToListAsync(cancellationToken); + + return new ListDonationsViewModel + { + Items = items, + TotalItems = totalRecords + }; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/UpdateDonation/UpdateDonationCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/UpdateDonation/UpdateDonationCommand.cs new file mode 100644 index 00000000..89a55de6 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/UpdateDonation/UpdateDonationCommand.cs @@ -0,0 +1,74 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace IgescConecta.API.Features.Donations.UpdateDonation +{ + public class UpdateDonationCommand : IRequest> + { + public int Id { get; set; } + public decimal Value { get; set; } + public DateTime DonationDate { get; set; } + + public int? OscId { get; set; } + public int? CourseId { get; set; } + public int? TeamId { get; set; } + } + + internal sealed class UpdateDonationCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public UpdateDonationCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(UpdateDonationCommand request, CancellationToken cancellationToken) + { + var donation = await _context.Donations + .FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken); + + if (donation is null) + { + return new ValidationFailed($"Doao com ID {request.Id} no encontrada."); + } + + if (request.Value <= 0) + { + return new ValidationFailed("O valor da doao deve ser maior que zero."); + } + + if (request.OscId.HasValue && request.CourseId.HasValue) + { + return new ValidationFailed("A doao pode ser destinada para uma OSC ou para um Curso/Turma, mas no para ambos ao mesmo tempo."); + } + + if (request.TeamId.HasValue && !request.CourseId.HasValue) + { + return new ValidationFailed("Uma doao para uma Turma (TeamId) tambm deve especificar o Curso (CourseId)."); + } + + if (request.CourseId.HasValue && !request.TeamId.HasValue) + { + return new ValidationFailed("Uma doao para um Curso deve especificar uma Turma (TeamId)."); + } + + donation.Value = request.Value; + donation.DonationDate = request.DonationDate; + donation.OscId = request.OscId; + donation.CourseId = request.CourseId; + donation.TeamId = request.TeamId; + + + await _context.SaveChangesAsync(cancellationToken); + + return donation.Id; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/UpdateDonation/UpdateDonationEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/UpdateDonation/UpdateDonationEndpoint.cs new file mode 100644 index 00000000..f508423e --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Donations/UpdateDonation/UpdateDonationEndpoint.cs @@ -0,0 +1,32 @@ +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Donations.UpdateDonation +{ + [ApiController] + [Route("api/donations")] + public class UpdateDonationEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public UpdateDonationEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{id:int}")] + public async Task Put([FromRoute] int id, [FromBody] UpdateDonationCommand request) + { + request.Id = id; + + var result = await _mediator.Send(request); + + if (result.IsSuccess) + { + return Ok(new { id = result.Value, message = "Donation updated successfully." }); + } + + return BadRequest(result.Error); + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/CreateOriginBusinessCase/CreateOriginBusinessCaseCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/CreateOriginBusinessCase/CreateOriginBusinessCaseCommand.cs new file mode 100644 index 00000000..b0b0628d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/CreateOriginBusinessCase/CreateOriginBusinessCaseCommand.cs @@ -0,0 +1,40 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; + +namespace IgescConecta.API.Features.OriginsBusinessCases.CreateOriginBusinessCase +{ + public class CreateOriginBusinessCaseCommand : IRequest> + { + public string Name { get; set; } + + public string Notes { get; set; } + + public int BusinessCaseId { get; set; } + } + + internal sealed class CreateOriginBusinessCaseCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public CreateOriginBusinessCaseCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(CreateOriginBusinessCaseCommand request, CancellationToken cancellationToken) + { + var originBusinessCase = new OriginBusinessCase + { + Name = request.Name, + Notes = request.Notes, + BusinessCaseId = request.BusinessCaseId + }; + + await _context.OriginBusinessCases.AddAsync(originBusinessCase); + await _context.SaveChangesAsync(cancellationToken); + return originBusinessCase.Id; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/CreateOriginBusinessCase/CreateOriginBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/CreateOriginBusinessCase/CreateOriginBusinessCaseEndpoint.cs new file mode 100644 index 00000000..b593f49d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/CreateOriginBusinessCase/CreateOriginBusinessCaseEndpoint.cs @@ -0,0 +1,51 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.OriginsBusinessCases.CreateOriginBusinessCase +{ + [ApiAuthorize] + [Route("/api/origins-business-cases")] + [ApiController] + [ApiExplorerSettings(GroupName = "OriginsBusinessCases")] + public class CreateOriginBusinessCaseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public CreateOriginBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("CreateOriginBusinessCase", Name = "CreateOriginBusinessCase")] + public async Task> CreateOriginBusinessCase([FromBody] CreateOriginBusinessCaseRequest request) + { + var result = await _mediator.Send(new CreateOriginBusinessCaseCommand + { + Name = request.Name, + Notes = request.Notes, + BusinessCaseId = request.BusinessCaseId + }); + + return result.IsSuccess ? Ok(new CreateOriginBusinessCaseResponse(result.Value)) : BadRequest(result.Error); + } + } + + public class CreateOriginBusinessCaseRequest + { + public string Name { get; set; } + + public string Notes { get; set; } + + public int BusinessCaseId { get; set; } + } + + public class CreateOriginBusinessCaseResponse + { + public int OriginBusinessCaseId { get; set; } + public CreateOriginBusinessCaseResponse(int originBusinessCaseId) + { + OriginBusinessCaseId = originBusinessCaseId; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/DeleteOriginBusinessCase/DeleteOriginBusinessCaseCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/DeleteOriginBusinessCase/DeleteOriginBusinessCaseCommand.cs new file mode 100644 index 00000000..5b9b5061 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/DeleteOriginBusinessCase/DeleteOriginBusinessCaseCommand.cs @@ -0,0 +1,41 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; + +namespace IgescConecta.API.Features.OriginsBusinessCases.DeleteOriginBusinessCase +{ + public class DeleteOriginBusinessCaseCommand : IRequest> + { + public int OriginBusinessCaseId { get; set; } + + public DeleteOriginBusinessCaseCommand(int originBusinessCaseId) + { + OriginBusinessCaseId = originBusinessCaseId; + } + } + + internal sealed class DeleteOriginBusinessCaseCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public DeleteOriginBusinessCaseCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(DeleteOriginBusinessCaseCommand request, CancellationToken cancellationToken) + { + var originBusinessCase = await _context.OriginBusinessCases.FindAsync(request.OriginBusinessCaseId); + + if (originBusinessCase == null) + { + return new ValidationFailed(new[] { "Origin Business Cases not found." }); + } + + _context.OriginBusinessCases.Remove(originBusinessCase); + await _context.SaveChangesAsync(cancellationToken); + + return true; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/DeleteOriginBusinessCase/DeleteOriginBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/DeleteOriginBusinessCase/DeleteOriginBusinessCaseEndpoint.cs new file mode 100644 index 00000000..04c9cbea --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/DeleteOriginBusinessCase/DeleteOriginBusinessCaseEndpoint.cs @@ -0,0 +1,27 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.OriginsBusinessCases.DeleteOriginBusinessCase +{ + [ApiAuthorize] + [Route("/api/origins-business-cases")] + [ApiController] + [ApiExplorerSettings(GroupName = "OriginsBusinessCases")] + public class DeleteOriginBusinessCaseEndpoint: ControllerBase + { + private readonly IMediator _mediator; + + public DeleteOriginBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpDelete("{originBusinessCaseId}", Name = "DeleteOriginBusinessCase")] + public async Task DeleteOriginBusinessCase(int originBusinessCaseId) + { + var result = await _mediator.Send(new DeleteOriginBusinessCaseCommand(originBusinessCaseId)); + return result.IsSuccess ? Ok() : BadRequest(result.Error); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/GetOriginBusinessCase/GetOriginBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/GetOriginBusinessCase/GetOriginBusinessCaseEndpoint.cs new file mode 100644 index 00000000..f3ee15f3 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/GetOriginBusinessCase/GetOriginBusinessCaseEndpoint.cs @@ -0,0 +1,67 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Validation; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.OriginsBusinessCases.GetOriginBusinessCase +{ + [ApiAuthorize] + [Route("/api/origins-business-cases")] + [ApiController] + [ApiExplorerSettings(GroupName = "OriginsBusinessCases")] + public class GetOriginBusinessCaseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public GetOriginBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("{originBusinessCaseId}", Name = "GetOriginBusinessCase")] + public async Task> GetOriginBusinessCase(int originBusinessCaseId) + { + var result = await _mediator.Send(new GetOriginBusinessCaseQuery(originBusinessCaseId)); + + if (result.IsSuccess) + { + var originBusinessCaseInfo = new GetOriginBusinessCaseResponse + { + OriginBusinessCaseId = originBusinessCaseId, + Name = result.Value.Name, + Notes = result.Value.Notes, + Oscs = result.Value?.Oscs?.Select(o => new GetOriginBusinessCaseOscResponse + { + OscId = o.Id, + Name = o.Name + }).ToList() + }; + return Ok(originBusinessCaseInfo); + } + + return BadRequest(result.Error); + } + } + + public class GetOriginBusinessCaseResponse + { + public int OriginBusinessCaseId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + + public List? Oscs { get; set; } + } + + public class GetOriginBusinessCaseOscResponse + { + public int OscId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/GetOriginBusinessCase/GetOriginBusinessCaseQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/GetOriginBusinessCase/GetOriginBusinessCaseQuery.cs new file mode 100644 index 00000000..c10e2e2f --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/GetOriginBusinessCase/GetOriginBusinessCaseQuery.cs @@ -0,0 +1,41 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.OriginsBusinessCases.GetOriginBusinessCase +{ + public class GetOriginBusinessCaseQuery : IRequest> + { + public int OriginBusinessCaseId { get; set; } + + public GetOriginBusinessCaseQuery(int id) + { + OriginBusinessCaseId = id; + } + } + + internal sealed class GetOriginBusinessCaseQueryHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public GetOriginBusinessCaseQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(GetOriginBusinessCaseQuery request, CancellationToken cancellationToken) + { + var originBusinessCase = await _context.OriginBusinessCases + .Where(obc => obc.Id == request.OriginBusinessCaseId) + .Include(obc => obc.Oscs) + .FirstOrDefaultAsync(cancellationToken); + + if (originBusinessCase == null) + return new ValidationFailed(new[] { "Origin Business Case not Found" }); + + return originBusinessCase; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginBusinessCaseEndpoint.cs new file mode 100644 index 00000000..eb9131a7 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginBusinessCaseEndpoint.cs @@ -0,0 +1,37 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.OriginsBusinessCases.ListOriginsBusinessCases +{ + [ApiAuthorize] + [Route("/api/origins-business-cases")] + [ApiController] + [ApiExplorerSettings(GroupName = "OriginsBusinessCases")] + public class ListOriginBusinessCaseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListOriginBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("ListOriginBusinessCase", Name = "ListOriginBusinessCase")] + public async Task> ListOriginBusinessCase(ListOriginBusinessCaseRequest request) + { + var result = await _mediator.Send(new ListOriginBusinessCaseQuery(request.PageNumber, request.PageSize, request.Filters)); + return Ok(result); + } + } + + public class ListOriginBusinessCaseRequest + { + public int PageNumber { get; set; } + + public int PageSize { get; set; } + + public List Filters { get; set; } = []; + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginBusinessCaseQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginBusinessCaseQuery.cs new file mode 100644 index 00000000..81447cac --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginBusinessCaseQuery.cs @@ -0,0 +1,64 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.OriginsBusinessCases.ListOriginsBusinessCases +{ + public class ListOriginBusinessCaseViewModel : PaginationResponse + { + } + + public class OriginBusinessCaseViewModel + { + public int OriginBusinessCaseId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + } + + public class ListOriginBusinessCaseQuery : PaginationRequest, IRequest + { + public ListOriginBusinessCaseQuery(int pageNumber, int pageSize, List filters) : base(pageNumber, pageSize, filters) + { + } + } + + internal sealed class ListOriginBusinessCaseHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public ListOriginBusinessCaseHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(ListOriginBusinessCaseQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + var query = _context.OriginBusinessCases + .AsQueryable(); + var result = await query.Where(expr).Select(Osc => new OriginBusinessCaseViewModel + { + Name = Osc.Name, + Notes = Osc.Notes, + OriginBusinessCaseId = Osc.Id, + }) + .OrderBy(x => x.OriginBusinessCaseId) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToListAsync(cancellationToken); + + var totalRecords = await _context.OriginBusinessCases.CountAsync(expr, cancellationToken); + + return new ListOriginBusinessCaseViewModel + { + Items = result, + TotalItems = totalRecords, + }; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginsBusinessCaseByBusinessCaseIdEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginsBusinessCaseByBusinessCaseIdEndpoint.cs new file mode 100644 index 00000000..8fdb2f8e --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginsBusinessCaseByBusinessCaseIdEndpoint.cs @@ -0,0 +1,39 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.OriginsBusinessCases.ListOriginsBusinessCases +{ + [ApiAuthorize] + [Route("/api/origins-business-cases")] + [ApiController] + [ApiExplorerSettings(GroupName = "OriginsBusinessCases")] + public class ListOriginsBusinessCaseByBusinessCaseIdEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListOriginsBusinessCaseByBusinessCaseIdEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("ListOriginsBusinessCaseByBusinessCaseId", Name = "ListOriginsBusinessCaseByBusinessCaseId")] + public async Task> ListOriginsBusinessCaseByBusinessCaseId(ListOriginsBusinessCaseByBusinessCaseIdRequest request) + { + var result = await _mediator.Send(new ListOriginsBusinessCaseByBusinessCaseIdQuery(request.PageNumber, request.PageSize, request.Filters, request.BusinessCaseId)); + return Ok(result); + } + } + + public class ListOriginsBusinessCaseByBusinessCaseIdRequest + { + public int PageNumber { get; set; } + + public int PageSize { get; set; } + + public List Filters { get; set; } = []; + + public int BusinessCaseId { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginsBusinessCaseByBusinessCaseIdQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginsBusinessCaseByBusinessCaseIdQuery.cs new file mode 100644 index 00000000..63f53159 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/ListOriginsBusinessCases/ListOriginsBusinessCaseByBusinessCaseIdQuery.cs @@ -0,0 +1,72 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.OriginsBusinessCases.ListOriginsBusinessCases +{ + public class ListOriginsBusinessCaseByBusinessCaseIdViewModel : PaginationResponse + { + } + + public class OriginBusinessCaseByBusinessCaseIdViewModel + { + public int OriginBusinessCaseId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + + public int BusinessCaseId { get; set; } + } + + public class ListOriginsBusinessCaseByBusinessCaseIdQuery : PaginationRequest, IRequest + { + public int BusinessCaseId { get; set; } + + public ListOriginsBusinessCaseByBusinessCaseIdQuery(int pageNumber, int pageSize, List filters, int businessCaseId) : base(pageNumber, pageSize, filters) + { + BusinessCaseId = businessCaseId; + } + } + + internal sealed class ListOriginsBusinessCaseByBusinessCaseIdHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public ListOriginsBusinessCaseByBusinessCaseIdHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(ListOriginsBusinessCaseByBusinessCaseIdQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + var query = _context.OriginBusinessCases + .AsQueryable() + .Where(obc => obc.BusinessCaseId == request.BusinessCaseId) + .Where(expr); + var result = await query.Where(expr).Select(osc => new OriginBusinessCaseByBusinessCaseIdViewModel + { + Name = osc.Name, + Notes = osc.Notes, + OriginBusinessCaseId = osc.Id, + BusinessCaseId = osc.BusinessCaseId, + }) + .OrderBy(x => x.OriginBusinessCaseId) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToListAsync(cancellationToken); + + var totalRecords = await query.CountAsync(expr, cancellationToken); + + return new ListOriginsBusinessCaseByBusinessCaseIdViewModel + { + Items = result, + TotalItems = totalRecords, + }; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/UpdateOriginBusinessCase/UpdateOriginBusinessCaseCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/UpdateOriginBusinessCase/UpdateOriginBusinessCaseCommand.cs new file mode 100644 index 00000000..96f71a9e --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/UpdateOriginBusinessCase/UpdateOriginBusinessCaseCommand.cs @@ -0,0 +1,42 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; + +namespace IgescConecta.API.Features.OriginsBusinessCases.UpdateOriginBusinessCase +{ + public class UpdateOriginBusinessCaseCommand : IRequest> + { + public int OriginBusinessCaseId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + } + + internal sealed class UpdateOriginBusinessCaseCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public UpdateOriginBusinessCaseCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(UpdateOriginBusinessCaseCommand request, CancellationToken cancellationToken) + { + var originBusinessCase = await _context.OriginBusinessCases.FindAsync(request.OriginBusinessCaseId); + + if (originBusinessCase == null) + { + return new ValidationFailed(new[] { "Origin Business Case not Found" }); + } + + originBusinessCase.Name = string.IsNullOrEmpty(request.Name) ? originBusinessCase.Name : request.Name; + originBusinessCase.Notes = string.IsNullOrEmpty(request.Notes) ? originBusinessCase.Notes : request.Notes; + + await _context.SaveChangesAsync(cancellationToken); + return originBusinessCase; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/UpdateOriginBusinessCase/UpdateOriginBusinessCaseEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/UpdateOriginBusinessCase/UpdateOriginBusinessCaseEndpoint.cs new file mode 100644 index 00000000..e4206b61 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/OriginsBusinessCases/UpdateOriginBusinessCase/UpdateOriginBusinessCaseEndpoint.cs @@ -0,0 +1,56 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.OriginsBusinessCases.UpdateOriginBusinessCase +{ + [ApiAuthorize] + [Route("/api/origins-business-cases")] + [ApiController] + [ApiExplorerSettings(GroupName = "OriginsBusinessCases")] + public class UpdateOriginBusinessCaseEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public UpdateOriginBusinessCaseEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{originBusinessCaseId}", Name = "UpdateOriginBusinessCase")] + public async Task> UpdateOriginBusinessCase(int originBusinessCaseId, [FromBody] UpdateOriginBusinessCaseRequest request) + { + var result = await _mediator.Send(new UpdateOriginBusinessCaseCommand + { + OriginBusinessCaseId = originBusinessCaseId, + Name = request.Name, + Notes = request.Notes + }); + + var updateResponse = new UpdateOriginBusinessCaseResponse + { + OriginBusinessCaseId = originBusinessCaseId, + Name = result.Value.Name, + Notes = result.Value.Notes + }; + + return result.IsSuccess ? Ok(updateResponse) : BadRequest(result.Error); + } + } + + public class UpdateOriginBusinessCaseRequest + { + public string Name { get; set; } + + public string Notes { get; set; } + } + + public class UpdateOriginBusinessCaseResponse + { + public int OriginBusinessCaseId { get; set; } + + public string Name { get; set; } + + public string Notes { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/CreateOsc/CreateOscCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/CreateOsc/CreateOscCommand.cs new file mode 100644 index 00000000..1b53f60f --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/CreateOsc/CreateOscCommand.cs @@ -0,0 +1,94 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.API.Features.Beneficiares; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Oscs.CreateOsc +{ + public class CreateOscCommand : IRequest> + { + public string Name { get; set; } + + public string Objective { get; set; } + + public string CorporateName { get; set; } + + public string Address { get; set; } + + public string ZipCode { get; set; } + + public string Neighborhood { get; set; } + + public string City { get; set; } + + public string State { get; set; } + + public string PhoneNumber { get; set; } + + public string Email { get; set; } + + public string WebUrl { get; set; } + + public string SocialMedia { get; set; } + + public string? OscPrimaryDocumment { get; set; } + + public List BeneficiariesIds { get; set; } = []; + + public List OriginsBusinessCasesIds { get; set; } = []; + } + + internal sealed class CreateOscCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public CreateOscCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(CreateOscCommand request, CancellationToken cancellationToken) + { + var osc = new Osc + { + Name = request.Name, + OscPrimaryDocumment = request.OscPrimaryDocumment, + Address = request.Address, + Neighborhood = request.Neighborhood, + City = request.City, + State = request.State, + PhoneNumber = request.PhoneNumber, + Email = request.Email, + WebUrl = request.WebUrl, + SocialMedia = request.SocialMedia, + CorporateName = request.CorporateName, + Objective = request.Objective, + ZipCode = request.ZipCode, + }; + + if (request.BeneficiariesIds.Any()) + { + var beneficiares = await _context.Beneficiaries + .Where(b => request.BeneficiariesIds.Contains(b.Id)) + .ToListAsync(); + + osc.Beneficiaries = beneficiares; + } + + if (request.OriginsBusinessCasesIds.Any()) + { + var orginnsBusinessCases = await _context.OriginBusinessCases + .Where(o => request.OriginsBusinessCasesIds.Contains(o.Id)) + .ToListAsync(); + + osc.OriginsBusinessCases = orginnsBusinessCases; + } + + await _context.Oscs.AddAsync(osc, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + return osc.Id; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/CreateOsc/CreateOscEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/CreateOsc/CreateOscEndpoint.cs new file mode 100644 index 00000000..46508c88 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/CreateOsc/CreateOscEndpoint.cs @@ -0,0 +1,87 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Oscs.CreateOsc +{ + [ApiAuthorize] + [Route("/api/osc")] + [ApiController] + [ApiExplorerSettings(GroupName = "Oscs")] + public class CreateOscEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public CreateOscEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("CreateOsc", Name = "CreateOsc")] + public async Task> CreateOsc([FromBody] CreateOscRequest request) + { + var result = await _mediator.Send(new CreateOscCommand + { + Name = request.Name, + OscPrimaryDocumment = request.OscPrimaryDocumment, + Address = request.Address, + Neighborhood = request.Neighborhood, + City = request.City, + State = request.State, + PhoneNumber = request.PhoneNumber, + Email = request.Email, + WebUrl = request.WebUrl, + SocialMedia = request.SocialMedia, + CorporateName = request.CorporateName, + Objective = request.Objective, + ZipCode = request.ZipCode, + OriginsBusinessCasesIds = request.OriginsBusinessCasesIds, + BeneficiariesIds = request.BeneficiariesIds + }); + return result.IsSuccess ? Ok(new CreateOscResponse(result.Value)) : BadRequest(result.Error); + } + } + + public class CreateOscRequest + { + public string Name { get; set; } + + public string Objective { get; set; } + + public string CorporateName { get; set; } + + public string Address { get; set; } + + public string Neighborhood { get; set; } + + public string City { get; set; } + + public string State { get; set; } + + public string PhoneNumber { get; set; } + + public string Email { get; set; } + + public string WebUrl { get; set; } + + public string SocialMedia { get; set; } + + public string ZipCode { get; set; } + + public string? OscPrimaryDocumment { get; set; } + + public List BeneficiariesIds { get; set; } = []; + + public List OriginsBusinessCasesIds { get; set; } = []; + } + + public class CreateOscResponse + { + public int OscId { get; set; } + + public CreateOscResponse(int oscId) + { + OscId = oscId; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/DeleteOsc/DeleteOscCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/DeleteOsc/DeleteOscCommand.cs new file mode 100644 index 00000000..0a146ceb --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/DeleteOsc/DeleteOscCommand.cs @@ -0,0 +1,40 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; + +namespace IgescConecta.API.Features.Oscs.DeleteOsc +{ + public class DeleteOscCommand : IRequest> + { + public int OscId { get; set; } + + public DeleteOscCommand(int oscId) + { + OscId = oscId; + } + } + + internal sealed class DeleteOscCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public DeleteOscCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(DeleteOscCommand request, CancellationToken cancellationToken) + { + var osc = await _context.Oscs.FindAsync(request.OscId); + if (osc == null) + { + return new ValidationFailed(new[] { "OSC não encontrada." }); + } + + _context.Oscs.Remove(osc); + await _context.SaveChangesAsync(cancellationToken); + + return true; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/DeleteOsc/DeleteOscEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/DeleteOsc/DeleteOscEndpoint.cs new file mode 100644 index 00000000..83db2135 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/DeleteOsc/DeleteOscEndpoint.cs @@ -0,0 +1,27 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Oscs.DeleteOsc +{ + [ApiAuthorize] + [Route("/api/osc")] + [ApiController] + [ApiExplorerSettings(GroupName = "Oscs")] + public class DeleteOscEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public DeleteOscEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpDelete("{oscId}", Name = "DeleteOsc")] + public async Task DeleteOsc(int oscId) + { + var result = await _mediator.Send(new DeleteOscCommand(oscId)); + return result.IsSuccess ? Ok() : BadRequest(result.Error); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/GetOsc/GetOscEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/GetOsc/GetOscEndpoint.cs new file mode 100644 index 00000000..2ae60783 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/GetOsc/GetOscEndpoint.cs @@ -0,0 +1,106 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Oscs.GetOsc +{ + [ApiAuthorize] + [Route("/api/oscs")] + [ApiController] + [ApiExplorerSettings(GroupName = "Oscs")] + public class GetOscEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public GetOscEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("{oscId}", Name = "GetOsc")] + public async Task> GetOsc(int oscId) + { + var result = await _mediator.Send(new GetOscQuery(oscId)); + var oscInfo = new GetOscResponse + { + OscId = oscId, + Name = result.Value.Name, + CorporateName = result.Value.CorporateName, + Objective = result.Value.Objective, + Address = result.Value.Address, + Neighborhood = result.Value.Neighborhood, + City = result.Value.City, + State = result.Value.State, + PhoneNumber = result.Value.PhoneNumber, + Email = result.Value.Email, + WebUrl = result.Value.WebUrl, + SocialMedia = result.Value.SocialMedia, + OscPrimaryDocumment = result.Value?.OscPrimaryDocumment, + ZipCode = result.Value.ZipCode, + + Beneficiaries = result.Value?.Beneficiaries.Select(b => new GetOscBeneficiaryResponse + { + BeneficiaryId = b.Id, + Name = b.Name + }).ToList(), + + OriginsBusinessCases = result.Value?.OriginsBusinessCases.Select(o => new GetOscOriginBusinessCaseResponse + { + OriginBusinessCaseId = o.Id, + Name = o.Name + }).ToList() + }; + return result.IsSuccess ? Ok(oscInfo) : BadRequest(result.Error); + } + } + + public class GetOscResponse + { + public int OscId { get; set; } + + public string Name { get; set; } + + public string CorporateName { get; set; } + + public string Objective { get; set; } + + public string Address { get; set; } + + public string Neighborhood { get; set; } + + public string City { get; set; } + + public string State { get; set; } + + public string PhoneNumber { get; set; } + + public string Email { get; set; } + + public string WebUrl { get; set; } + + public string SocialMedia { get; set; } + + public string ZipCode { get; set; } + + public string? OscPrimaryDocumment { get; set; } + + public List Beneficiaries { get; set; } = []; + + public List OriginsBusinessCases { get; set; } = []; + } + + public class GetOscBeneficiaryResponse + { + public int BeneficiaryId { get; set; } + + public string Name { get; set; } + } + + public class GetOscOriginBusinessCaseResponse + { + public int OriginBusinessCaseId { get; set; } + + public string Name { get; set; } + } + +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/GetOsc/GetOscQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/GetOsc/GetOscQuery.cs new file mode 100644 index 00000000..e38dfbaf --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/GetOsc/GetOscQuery.cs @@ -0,0 +1,43 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Oscs.GetOsc +{ + public class GetOscQuery : IRequest> + { + public int OscId { get; set; } + public GetOscQuery(int id) + { + OscId = id; + } + } + + internal sealed class GetOscQueryHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public GetOscQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(GetOscQuery request, CancellationToken cancellationToken) + { + var osc = await _context.Oscs + .Where(osc => osc.Id == request.OscId) + .Include(osc => osc.Beneficiaries) + .Include(osc => osc.OriginsBusinessCases) + .FirstOrDefaultAsync(); + + if (osc == null) + { + return new ValidationFailed(new[] { "OSC not Found" }); + } + + return osc; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/ListOscs/ListOscEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/ListOscs/ListOscEndpoint.cs new file mode 100644 index 00000000..59b72fb8 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/ListOscs/ListOscEndpoint.cs @@ -0,0 +1,34 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Oscs.ListOscs +{ + [ApiAuthorize] + [Route("/api/osc")] + [ApiController] + [ApiExplorerSettings(GroupName = "Oscs")] + public class ListOscEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListOscEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("ListOsc", Name = "ListOsc")] + public async Task> ListOscs(ListOscRequest request) + { + var result = await _mediator.Send(new ListOscQuery(request.PageNumber, request.PageSize, request.Filters)); + return Ok(result); + } + } + + public class ListOscRequest + { + public int PageNumber { get; set; } + public int PageSize { get; set; } + public List Filters { get; set; } = new(); + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/ListOscs/ListOscQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/ListOscs/ListOscQuery.cs new file mode 100644 index 00000000..bbfed96d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/ListOscs/ListOscQuery.cs @@ -0,0 +1,100 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Oscs.ListOscs +{ + public class ListOscViewModel : PaginationResponse + { + } + + public class OscViewModel + { + public int OscId { get; set; } + + public string Name { get; set; } + + public string Objective { get; set; } + + public string CorporateName { get; set; } + + public string Address { get; set; } + + public string Neighborhood { get; set; } + + public string City { get; set; } + + public string State { get; set; } + + public string PhoneNumber { get; set; } + + public string Email { get; set; } + + public string WebUrl { get; set; } + + public string SocialMedia { get; set; } + + public string ZipCode { get; set; } + + public string OscPrimaryDocumment { get; set; } + + public int BeneficiariesCount { get; set; } + } + + public class ListOscQuery : PaginationRequest, IRequest + { + public ListOscQuery(int pageNumber, int pageSize, List filters) : base(pageNumber, pageSize, filters) + { + } + } + + internal sealed class ListOscQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public ListOscQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(ListOscQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + var query = _context.Oscs.AsQueryable(); + var result = await query.Where(expr).Select(osc => new OscViewModel + { + OscId = osc.Id, + Name = osc.Name, + Objective = osc.Objective, + CorporateName = osc.CorporateName, + Address = osc.Address, + Neighborhood = osc.Neighborhood, + City = osc.City, + State = osc.State, + PhoneNumber = osc.PhoneNumber, + Email = osc.Email, + WebUrl = osc.WebUrl, + SocialMedia = osc.SocialMedia, + ZipCode = osc.ZipCode, + OscPrimaryDocumment = osc.OscPrimaryDocumment, + BeneficiariesCount = _context.Beneficiaries + .Count(b => b.Oscs.Any(o => o.Id == osc.Id)) + }) + .OrderBy(x => x.OscId) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToListAsync(cancellationToken); + + var totalRecords = await _context.Oscs.CountAsync(expr, cancellationToken); + + return new ListOscViewModel + { + Items = result, + TotalItems = totalRecords + }; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/UpdateOsc/UpdateOscCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/UpdateOsc/UpdateOscCommand.cs new file mode 100644 index 00000000..a9e370fc --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/UpdateOsc/UpdateOscCommand.cs @@ -0,0 +1,103 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Oscs.UpdateOsc +{ + public class UpdateOscCommand : IRequest> + { + public int OscId { get; set; } + + public string? Name { get; set; } + + public string? CorporateName { get; set; } + + public string? Objective { get; set; } + + public string? Address { get; set; } + + public string? Neighborhood { get; set; } + + public string? City { get; set; } + + public string? State { get; set; } + + public string? PhoneNumber { get; set; } + + public string? Email { get; set; } + + public string? WebUrl { get; set; } + + public string? SocialMedia { get; set; } + + public string? ZipCode { get; set; } + + public string? OscPrimaryDocumment { get; set; } + + public List? BeneficiaryIds { get; set; } + + public List? OriginBusinessCaseIds { get; set; } + } + + internal sealed class UpdateOscEndpointHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public UpdateOscEndpointHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(UpdateOscCommand request, CancellationToken cancellationToken) + { + var osc = await _context.Oscs.Where(osc => osc.Id == request.OscId) + .Include(o => o.Beneficiaries) + .Include(o => o.OriginsBusinessCases) + .FirstOrDefaultAsync(); + + if (osc == null) + { + return new ValidationFailed(new[] { "OSC not Found" }); + } + + osc.Name = string.IsNullOrEmpty(request.Name) ? osc.Name : request.Name; + osc.CorporateName = string.IsNullOrEmpty(request.CorporateName) ? osc.CorporateName : request.CorporateName; + osc.Objective = string.IsNullOrEmpty(request.Objective) ? osc.Objective : request.Objective; + osc.Address = string.IsNullOrEmpty(request.Address) ? osc.Address : request.Address; + osc.Neighborhood = string.IsNullOrEmpty(request.Neighborhood) ? osc.Neighborhood : request.Neighborhood; + osc.City = string.IsNullOrEmpty(request.City) ? osc.City : request.City; + osc.State = string.IsNullOrEmpty(request.State) ? osc.State : request.State; + osc.PhoneNumber = string.IsNullOrEmpty(request.PhoneNumber) ? osc.PhoneNumber : request.PhoneNumber; + osc.Email = string.IsNullOrEmpty(request.Email) ? osc.Email : request.Email; + osc.WebUrl = string.IsNullOrEmpty(request.WebUrl) ? osc.WebUrl : request.WebUrl; + osc.SocialMedia = string.IsNullOrEmpty(request.SocialMedia) ? osc.SocialMedia : request.SocialMedia; + osc.ZipCode = string.IsNullOrEmpty(request.ZipCode) ? osc.ZipCode : request.ZipCode; + osc.OscPrimaryDocumment = string.IsNullOrEmpty(request.OscPrimaryDocumment) ? osc.OscPrimaryDocumment : request.OscPrimaryDocumment; + + if (!request.BeneficiaryIds.OrderBy(x => x) + .SequenceEqual(osc.Beneficiaries.Select(b => b.Id).OrderBy(x => x))) + { + var beneficiaries = await _context.Beneficiaries + .Where(b => request.BeneficiaryIds.Contains(b.Id)) + .ToListAsync(cancellationToken); + + osc.Beneficiaries = beneficiaries; + } + + if (!request.OriginBusinessCaseIds.OrderBy(x => x) + .SequenceEqual(osc.OriginsBusinessCases.Select(obc => obc.Id).OrderBy(x => x))) + { + var originsBusinessCases = await _context.OriginBusinessCases + .Where(o => request.OriginBusinessCaseIds.Contains(o.Id)) + .ToListAsync(cancellationToken); + + osc.OriginsBusinessCases = originsBusinessCases; + } + + await _context.SaveChangesAsync(cancellationToken); + return osc; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/UpdateOsc/UpdateOscEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/UpdateOsc/UpdateOscEndpoint.cs new file mode 100644 index 00000000..f57397e5 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Oscs/UpdateOsc/UpdateOscEndpoint.cs @@ -0,0 +1,127 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Oscs.UpdateOsc +{ + [ApiAuthorize] + [Route("/api/oscs")] + [ApiController] + [ApiExplorerSettings(GroupName = "Oscs")] + public class UpdateOscEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public UpdateOscEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{oscId}", Name = "UpdateOsc")] + public async Task> UpdateOsc(int oscId, [FromBody] UpdateOscRequest request) + { + var result = await _mediator.Send(new UpdateOscCommand + { + OscId = oscId, + Name = request.Name, + CorporateName = request.CorporateName, + Objective = request.Objective, + Address = request.Address, + Neighborhood = request.Neighborhood, + City = request.City, + State = request.State, + PhoneNumber = request.PhoneNumber, + Email = request.Email, + WebUrl = request.WebUrl, + SocialMedia = request.SocialMedia, + ZipCode = request.ZipCode, + OscPrimaryDocumment = request.OscPrimaryDocumment, + BeneficiaryIds = request.BeneficiaryIds, + OriginBusinessCaseIds = request.OriginBusinessCaseIds + }); + + var updateResponse = new UpdateOscResponse + { + OscId = oscId, + Name = result.Value.Name, + CorporateName = result.Value.CorporateName, + Objective = result.Value.Objective, + Address = result.Value.Address, + Neighborhood = result.Value.Neighborhood, + City = result.Value.City, + State = result.Value.State, + PhoneNumber = result.Value.PhoneNumber, + Email = result.Value.Email, + WebUrl = result.Value.WebUrl, + SocialMedia = result.Value.SocialMedia, + ZipCode = result.Value.ZipCode, + OscPrimaryDocumment = result.Value.OscPrimaryDocumment, + Beneficiaries = result.Value.Beneficiaries?.Select(b => new UpdateBeneficiaryInOscResponse + { + BeneficiaryId = b.Id, + Name = b.Name + }).ToList(), + OriginsBusinessCases = result.Value.OriginsBusinessCases?.Select(o => new UpdateOriginBusinessCaseInOscResponse + { + OriginBusinessCaseId = o.Id, + Name = o.Name + }).ToList() + }; + + return result.IsSuccess ? Ok(updateResponse) : BadRequest(result.Error); + } + } + + public class UpdateOscRequest + { + public string? Name { get; set; } + public string? CorporateName { get; set; } + public string? Objective { get; set; } + public string? Address { get; set; } + public string? Neighborhood { get; set; } + public string? City { get; set; } + public string? State { get; set; } + public string? PhoneNumber { get; set; } + public string? Email { get; set; } + public string? WebUrl { get; set; } + public string? SocialMedia { get; set; } + public string? ZipCode { get; set; } + public string? OscPrimaryDocumment { get; set; } + public List? BeneficiaryIds { get; set; } + public List? OriginBusinessCaseIds { get; set; } + } + + public class UpdateOscResponse + { + public int OscId { get; set; } + public string Name { get; set; } + public string CorporateName { get; set; } + public string Objective { get; set; } + public string Address { get; set; } + public string? Neighborhood { get; set; } + public string? City { get; set; } + public string? State { get; set; } + public string? PhoneNumber { get; set; } + public string? Email { get; set; } + public string? WebUrl { get; set; } + public string? SocialMedia { get; set; } + public string ZipCode { get; set; } + public string? OscPrimaryDocumment { get; set; } + public List? Beneficiaries { get; set; } + public List? OriginsBusinessCases { get; set; } + } + + public class UpdateBeneficiaryInOscResponse + { + public int BeneficiaryId { get; set; } + + public string? Name { get; set; } + } + + public class UpdateOriginBusinessCaseInOscResponse + { + public int OriginBusinessCaseId { get; set; } + + public string? Name { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/CreatePerson/CreatePersonCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/CreatePerson/CreatePersonCommand.cs new file mode 100644 index 00000000..d52a3ab0 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/CreatePerson/CreatePersonCommand.cs @@ -0,0 +1,58 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Persons.CreatePerson +{ + public class CreatePersonCommand : IRequest> + { + public string Name { get; set; } + public string Email { get; set; } + public string PersonalDocumment { get; set; } + public string? SecondaryEmail { get; set; } + public string? PrimaryPhone { get; set; } + public string? SecondaryPhone { get; set; } + public string? Education1 { get; set; } + public string? Education2 { get; set; } + public string? ProfessionalActivity { get; set; } + public bool IsActive { get; set; } = true; + } + + internal sealed class CreatePersonCommandHandler + : IRequestHandler> + { + private readonly ApplicationDbContext _db; + + public CreatePersonCommandHandler(ApplicationDbContext db) + { + _db = db; + } + + public async Task> Handle(CreatePersonCommand request, CancellationToken ct) + { + // Regra básica: doc único + if (await _db.Persons.AnyAsync(p => p.PersonalDocumment == request.PersonalDocumment, ct)) + return new ValidationFailed(new[] { "CPF Já está sendo usado por outra pessoa." }); + + var person = new Person + { + Name = request.Name, + Email = request.Email, + PersonalDocumment = request.PersonalDocumment, + SecondaryEmail = request.SecondaryEmail, + PrimaryPhone = request.PrimaryPhone, + SecondaryPhone = request.SecondaryPhone, + Education1 = request.Education1, + Education2 = request.Education2, + ProfessionalActivity = request.ProfessionalActivity, + IsActive = request.IsActive + }; + + _db.Persons.Add(person); + await _db.SaveChangesAsync(ct); + return person; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/CreatePerson/CreatePersonEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/CreatePerson/CreatePersonEndpoint.cs new file mode 100644 index 00000000..02b6c565 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/CreatePerson/CreatePersonEndpoint.cs @@ -0,0 +1,87 @@ +using IgescConecta.API.Features.Persons.UpdatePerson; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Persons.CreatePerson +{ + [Route("api/persons")] + [ApiController] + [ApiExplorerSettings(GroupName = "Persons")] + public class CreatePersonEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public CreatePersonEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost(Name = "CreatePerson")] + public async Task> CreatePerson([FromBody] CreatePersonRequest request) + { + var result = await _mediator.Send(new CreatePersonCommand + { + Name = request.Name, + Email = request.Email, + PersonalDocumment = request.PersonalDocumment, + SecondaryEmail = request.SecondaryEmail, + PrimaryPhone = request.PrimaryPhone, + SecondaryPhone = request.SecondaryPhone, + Education1 = request.Education1, + Education2 = request.Education2, + ProfessionalActivity = request.ProfessionalActivity, + IsActive = request.IsActive + }); + + if (result.IsFailure) + return BadRequest(result.Error); + + var p = result.Value; + var resp = new CreatePersonResponse + { + PersonId = p.Id, + Name = p.Name, + Email = p.Email, + PersonalDocumment = p.PersonalDocumment, + SecondaryEmail = p.SecondaryEmail, + PrimaryPhone = p.PrimaryPhone, + SecondaryPhone = p.SecondaryPhone, + Education1 = p.Education1, + Education2 = p.Education2, + ProfessionalActivity = p.ProfessionalActivity, + IsActive = p.IsActive + }; + + return Ok(resp); + } + } + + public class CreatePersonRequest + { + public string Name { get; set; } + public string Email { get; set; } + public string PersonalDocumment { get; set; } + public string? SecondaryEmail { get; set; } + public string? PrimaryPhone { get; set; } + public string? SecondaryPhone { get; set; } + public string? Education1 { get; set; } + public string? Education2 { get; set; } + public string? ProfessionalActivity { get; set; } + public bool IsActive { get; set; } = true; + } + + public class CreatePersonResponse + { + public int PersonId { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string PersonalDocumment { get; set; } + public string? SecondaryEmail { get; set; } + public string? PrimaryPhone { get; set; } + public string? SecondaryPhone { get; set; } + public string? Education1 { get; set; } + public string? Education2 { get; set; } + public string? ProfessionalActivity { get; set; } + public bool IsActive { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/DeletePerson/DeletePersonCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/DeletePerson/DeletePersonCommand.cs new file mode 100644 index 00000000..c5be8392 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/DeletePerson/DeletePersonCommand.cs @@ -0,0 +1,31 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Persons.DeletePerson +{ + public class DeletePersonCommand : IRequest> + { + public int PersonId { get; } + public DeletePersonCommand(int personId) => PersonId = personId; + } + + internal sealed class DeletePersonCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _ctx; + public DeletePersonCommandHandler(ApplicationDbContext ctx) => _ctx = ctx; + + public async Task> Handle(DeletePersonCommand r, CancellationToken ct) + { + var p = await _ctx.Persons.FirstOrDefaultAsync(x => x.Id == r.PersonId, ct); + if (p is null) return new ValidationFailed("Person not found"); + + // Soft delete: o DbContext intercepta State=Deleted e seta IsDeleted=true + _ctx.Persons.Remove(p); + await _ctx.SaveChangesAsync(ct); + return true; + } + } +} + diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/DeletePerson/DeletePersonEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/DeletePerson/DeletePersonEndpoint.cs new file mode 100644 index 00000000..4c32092b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/DeletePerson/DeletePersonEndpoint.cs @@ -0,0 +1,24 @@ +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Persons.DeletePerson +{ + [Route("/api/persons")] + [ApiController] + [ApiExplorerSettings(GroupName = "Persons")] + [Authorize(Roles = "Admin,Editor")] + public class DeletePersonEndpoint : ControllerBase + { + private readonly IMediator _mediator; + public DeletePersonEndpoint(IMediator mediator) => _mediator = mediator; + + [HttpDelete("{personId:int}", Name = "DeletePerson")] + public async Task Delete(int personId) + { + var result = await _mediator.Send(new DeletePersonCommand(personId)); + return result.IsSuccess ? Ok() : BadRequest(result.Error); + } + } +} + diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/GetPerson/GetPersonEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/GetPerson/GetPersonEndpoint.cs new file mode 100644 index 00000000..ea818e31 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/GetPerson/GetPersonEndpoint.cs @@ -0,0 +1,38 @@ +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Persons.GetPerson +{ + [Route("/api/persons")] + [ApiController] + [ApiExplorerSettings(GroupName = "Persons")] + [Authorize(Roles = "Admin,Editor")] + public class GetPersonEndpoint : ControllerBase + { + private readonly IMediator _mediator; + public GetPersonEndpoint(IMediator mediator) => _mediator = mediator; + + [HttpGet("{personId:int}", Name = "GetPerson")] + public async Task> Get(int personId) + { + var vm = await _mediator.Send(new GetPersonQuery(personId)); + return vm is null ? NotFound() : Ok(vm); + } + } + + public class PersonViewModel + { + public int PersonId { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string PersonalDocumment { get; set; } + public string? PrimaryPhone { get; set; } + public string? SecondaryPhone { get; set; } + public string? SecondaryEmail { get; set; } + public string? Education1 { get; set; } + public string? Education2 { get; set; } + public string? ProfessionalActivity { get; set; } + public bool IsActive { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/GetPerson/GetPersonQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/GetPerson/GetPersonQuery.cs new file mode 100644 index 00000000..2dea2e3f --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/GetPerson/GetPersonQuery.cs @@ -0,0 +1,35 @@ +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Persons.GetPerson +{ + public record GetPersonQuery(int PersonId) : IRequest; + + internal sealed class GetPersonQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _ctx; + public GetPersonQueryHandler(ApplicationDbContext ctx) => _ctx = ctx; + + public async Task Handle(GetPersonQuery r, CancellationToken ct) + { + var p = await _ctx.Persons.AsNoTracking().FirstOrDefaultAsync(x => x.Id == r.PersonId, ct); + if (p is null) return null; + + return new PersonViewModel + { + PersonId = p.Id, + Name = p.Name, + Email = p.Email, + PersonalDocumment = p.PersonalDocumment, + PrimaryPhone = p.PrimaryPhone, + SecondaryPhone = p.SecondaryPhone, + SecondaryEmail = p.SecondaryEmail, + Education1 = p.Education1, + Education2 = p.Education2, + ProfessionalActivity = p.ProfessionalActivity, + IsActive = p.IsActive + }; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/ListPerson/ListPersonEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/ListPerson/ListPersonEndpoint.cs new file mode 100644 index 00000000..fd40ec59 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/ListPerson/ListPersonEndpoint.cs @@ -0,0 +1,41 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Features.Users.ListUser; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Persons.ListPerson +{ + + [ApiAuthorize] + [Route("/api/persons")] + [ApiController] + [ApiExplorerSettings(GroupName = "Persons")] + public class ListPersonEndpoint : ControllerBase + { + + private readonly IMediator _mediator; + + public ListPersonEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("ListPerson", Name = "ListPerson")] + public async Task> ListPerson(ListPersonRequest request) + { + var result = await _mediator.Send(new ListPersonQuery(request.PageNumber, request.PageSize, request.Filters)); + return Ok(result); + } + + + + } + + public class ListPersonRequest + { + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 10; + public List Filters { get; set; } = new(); + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/ListPerson/ListPersonQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/ListPerson/ListPersonQuery.cs new file mode 100644 index 00000000..dddccd57 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/ListPerson/ListPersonQuery.cs @@ -0,0 +1,62 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.API.Features.Persons.GetPerson; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Persons.ListPerson +{ + public class ListPersonViewModel : PaginationResponse { } + + public class PersonListItemViewModel + { + public int PersonId { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string PersonalDocumment { get; set; } + public string? PrimaryPhone { get; set; } + public bool IsActive { get; set; } + } + + public class ListPersonQuery : PaginationRequest, IRequest + { + public ListPersonQuery(int pageNumber, int pageSize, List filters) : base(pageNumber, pageSize, filters) { } + } + + internal sealed class ListPersonQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _ctx; + public ListPersonQueryHandler(ApplicationDbContext ctx) => _ctx = ctx; + + public async Task Handle(ListPersonQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + var query = _ctx.Persons.AsQueryable().Where(expr); + + var total = await query.CountAsync(cancellationToken); + + var items = await query + .OrderByDescending(x => x.Id) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .Select(p => new PersonListItemViewModel + { + PersonId = p.Id, + Name = p.Name, + Email = p.Email, + PersonalDocumment = p.PersonalDocumment, + PrimaryPhone = p.PrimaryPhone, + IsActive = p.IsActive + }) + .ToListAsync(cancellationToken); + + return new ListPersonViewModel + { + TotalItems = total, + Items = items + }; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/UpdatePerson/UpdatePersonCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/UpdatePerson/UpdatePersonCommand.cs new file mode 100644 index 00000000..113cf8a3 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/UpdatePerson/UpdatePersonCommand.cs @@ -0,0 +1,70 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Persons.UpdatePerson +{ + public class UpdatePersonCommand : IRequest> + { + public int PersonId { get; set; } + public string? Name { get; set; } + public string? Email { get; set; } + public string? PersonalDocumment { get; set; } + public string? SecondaryEmail { get; set; } + public string? PrimaryPhone { get; set; } + public string? SecondaryPhone { get; set; } + public string? Education1 { get; set; } + public string? Education2 { get; set; } + public string? ProfessionalActivity { get; set; } + public bool? IsActive { get; set; } + } + + internal sealed class UpdatePersonCommandHandler + : IRequestHandler> + { + private readonly ApplicationDbContext _db; + + public UpdatePersonCommandHandler(ApplicationDbContext db) + { + _db = db; + } + + public async Task> Handle(UpdatePersonCommand request, CancellationToken ct) + { + + var person = await _db.Persons + .FirstOrDefaultAsync(p => p.Id == request.PersonId, ct); + + if (person == null) + return new ValidationFailed(new[] { "Pessoa não encontrada" }); + + if (!string.IsNullOrWhiteSpace(request.PersonalDocumment) && + !string.Equals(request.PersonalDocumment, person.PersonalDocumment, StringComparison.OrdinalIgnoreCase)) + { + var exists = await _db.Persons + .AnyAsync(p => p.PersonalDocumment == request.PersonalDocumment && p.Id != person.Id, ct); + if (exists) + return new ValidationFailed(new[] { "CPF Sendo usado por outra pessoa." }); + + person.PersonalDocumment = request.PersonalDocumment; + } + + person.Name = string.IsNullOrWhiteSpace(request.Name) ? person.Name : request.Name; + person.Email = string.IsNullOrWhiteSpace(request.Email) ? person.Email : request.Email; + person.SecondaryEmail = request.SecondaryEmail ?? person.SecondaryEmail; + person.PrimaryPhone = request.PrimaryPhone ?? person.PrimaryPhone; + person.SecondaryPhone = request.SecondaryPhone ?? person.SecondaryPhone; + person.Education1 = request.Education1 ?? person.Education1; + person.Education2 = request.Education2 ?? person.Education2; + person.ProfessionalActivity = request.ProfessionalActivity ?? person.ProfessionalActivity; + + if (request.IsActive.HasValue) + person.IsActive = request.IsActive.Value; + + await _db.SaveChangesAsync(ct); + return person; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/UpdatePerson/UpdatePersonEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/UpdatePerson/UpdatePersonEndpoint.cs new file mode 100644 index 00000000..36581dcc --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Persons/UpdatePerson/UpdatePersonEndpoint.cs @@ -0,0 +1,89 @@ +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Persons.UpdatePerson +{ + [Route("api/persons")] + [ApiController] + [ApiExplorerSettings(GroupName = "Persons")] + public class UpdatePersonEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public UpdatePersonEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{personId}", Name = "UpdatePerson")] + public async Task> UpdatePerson( + int personId, + [FromBody] UpdatePersonRequest request) + { + var result = await _mediator.Send(new UpdatePersonCommand + { + PersonId = personId, + Name = request.Name, + Email = request.Email, + PersonalDocumment = request.PersonalDocumment, + SecondaryEmail = request.SecondaryEmail, + PrimaryPhone = request.PrimaryPhone, + SecondaryPhone = request.SecondaryPhone, + Education1 = request.Education1, + Education2 = request.Education2, + ProfessionalActivity = request.ProfessionalActivity, + IsActive = request.IsActive + }); + + if (result.IsFailure) + return BadRequest(result.Error); + + var p = result.Value; + var resp = new UpdatePersonResponse + { + PersonId = p.Id, + Name = p.Name, + Email = p.Email, + PersonalDocumment = p.PersonalDocumment, + SecondaryEmail = p.SecondaryEmail, + PrimaryPhone = p.PrimaryPhone, + SecondaryPhone = p.SecondaryPhone, + Education1 = p.Education1, + Education2 = p.Education2, + ProfessionalActivity = p.ProfessionalActivity, + IsActive = p.IsActive + }; + + return Ok(resp); + } + } + + public class UpdatePersonRequest + { + public string? Name { get; set; } + public string? Email { get; set; } + public string? PersonalDocumment { get; set; } + public string? SecondaryEmail { get; set; } + public string? PrimaryPhone { get; set; } + public string? SecondaryPhone { get; set; } + public string? Education1 { get; set; } + public string? Education2 { get; set; } + public string? ProfessionalActivity { get; set; } + public bool? IsActive { get; set; } + } + + public class UpdatePersonResponse + { + public int PersonId { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string PersonalDocumment { get; set; } + public string? SecondaryEmail { get; set; } + public string? PrimaryPhone { get; set; } + public string? SecondaryPhone { get; set; } + public string? Education1 { get; set; } + public string? Education2 { get; set; } + public string? ProfessionalActivity { get; set; } + public bool IsActive { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Create/CreateTeamCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Create/CreateTeamCommand.cs new file mode 100644 index 00000000..677dffee --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Create/CreateTeamCommand.cs @@ -0,0 +1,109 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Teams.CreateTeam +{ + public class CreateTeamCommand : IRequest> + { + public string? Name { get; set; } + + public string? LessonTime { get; set; } + + public DateTime? Start { get; set; } + + public DateTime? Finish { get; set; } + + public List PersonTeamsIds { get; set; } = []; + public int? ProjectProgramId { get; set; } + public int CourseId { get; set; } + } + + internal sealed class CreateTeamCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public CreateTeamCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(CreateTeamCommand request, CancellationToken cancellationToken) + { + var courseExists = await _context.Courses + .AnyAsync(c => c.Id == request.CourseId, cancellationToken); + + if (!courseExists) + return new ValidationFailed(new[] { $"Curso com ID {request.CourseId} não encontrado." }); + + if (request.Start >= request.Finish) + { + return new ValidationFailed(new[] { "A data de início deve ser anterior à data de término." }); + } + + if (request.ProjectProgramId.HasValue) + { + var programExists = await _context.ProjectPrograms + .AnyAsync(p => p.Id == request.ProjectProgramId, cancellationToken); + + if (!programExists) + return new ValidationFailed(new[] { $"Programa com ID {request.ProjectProgramId} não encontrado." }); + } + + if (request.PersonTeamsIds.Any()) + { + var personsExist = await _context.Persons + .Where(p => request.PersonTeamsIds.Contains(p.Id)) + .Select(p => p.Id) + .ToListAsync(cancellationToken); + + var invalidIds = request.PersonTeamsIds.Except(personsExist).ToList(); + + if (invalidIds.Any()) + { + return new ValidationFailed(new[] { $"Pessoas com IDs {string.Join(", ", invalidIds)} não encontradas." }); + } + } + + var team = new Team + { + Name = request.Name, + LessonTime = request.LessonTime, + Start = request.Start, + Finish = request.Finish, + ProjectProgramId = request.ProjectProgramId, + CourseId = request.CourseId + }; + + try + { + // Salva o Team primeiro para gerar o Id + await _context.Teams.AddAsync(team, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + + //Adiciona os PersonTeams com TeamId garantido + if (request.PersonTeamsIds.Any()) + { + foreach (var personId in request.PersonTeamsIds) + { + team.PersonTeams.Add(new PersonTeam + { + TeamId = team.Id, + PersonId = personId + }); + } + + await _context.SaveChangesAsync(cancellationToken); + } + + return team.Id; + } + catch (DbUpdateException ex) + { + return new ValidationFailed(new[] { "Erro ao salvar a turma no banco de dados." }); + } + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Create/CreateTeamEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Create/CreateTeamEndpoint.cs new file mode 100644 index 00000000..8fc18b4e --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Create/CreateTeamEndpoint.cs @@ -0,0 +1,66 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using IgescConecta.Domain.Entities; +using System.ComponentModel.DataAnnotations; + +namespace IgescConecta.API.Features.Teams.CreateTeam +{ + [ApiAuthorize] + [Route("/api/teams")] + [ApiController] + [ApiExplorerSettings(GroupName = "Teams")] + public class CreateTeamEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public CreateTeamEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("CreateTeam", Name = "CreateTeam")] + public async Task> CreateTeam([FromBody] CreateTeamRequest request) + { + var result = await _mediator.Send(new CreateTeamCommand + { + Name = request.Name, + LessonTime = request.LessonTime, + Start = request.Start, + Finish = request.Finish, + PersonTeamsIds = request.PersonTeamsIds, + ProjectProgramId = request.ProjectProgramId, + CourseId = request.CourseId + }); + + return result.IsSuccess + ? Ok(new CreateTeamResponse(result.Value)) + : BadRequest(result.Error); + } + } + + public class CreateTeamRequest + { + public string? Name { get; set; } + + public string? LessonTime { get; set; } + + public DateTime? Start { get; set; } + + public DateTime? Finish { get; set; } + + public List PersonTeamsIds { get; set; } = []; + public int? ProjectProgramId { get; set; } + public int CourseId { get; set; } + } + + public class CreateTeamResponse + { + public int TeamId { get; set; } + + public CreateTeamResponse(int teamId) + { + TeamId = teamId; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Delete/DeleteTeamCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Delete/DeleteTeamCommand.cs new file mode 100644 index 00000000..eaf5e4b7 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Delete/DeleteTeamCommand.cs @@ -0,0 +1,38 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Teams.DeleteTeam +{ + public class DeleteTeamCommand : IRequest> + { + public int TeamId { get; set; } + } + + internal sealed class DeleteTeamCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public DeleteTeamCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(DeleteTeamCommand request, CancellationToken cancellationToken) + { + var team = await _context.Teams.FindAsync(request.TeamId); + + if (team == null) + { + return new ValidationFailed(new[] { "Turma não encontrado ou já excluída." }); + } + + _context.Teams.Remove(team); + + await _context.SaveChangesAsync(cancellationToken); + + return team.Id; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Delete/DeleteTeamEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Delete/DeleteTeamEndpoint.cs new file mode 100644 index 00000000..6ae7308d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Delete/DeleteTeamEndpoint.cs @@ -0,0 +1,43 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Teams.DeleteTeam +{ + [ApiAuthorize] + [Route("/api/teams")] + [ApiController] + [ApiExplorerSettings(GroupName = "Teams")] + public class DeleteTeamEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public DeleteTeamEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpDelete("{teamId}", Name = "DeleteTeam")] + public async Task> DeleteTeam(int teamId) + { + var result = await _mediator.Send(new DeleteTeamCommand + { + TeamId = teamId + }); + + return result.IsSuccess + ? Ok(new DeleteTeamResponse(result.Value)) + : BadRequest(result.Error); + } + } + + public class DeleteTeamResponse + { + public int TeamId { get; set; } + + public DeleteTeamResponse(int teamId) + { + TeamId = teamId; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Edit/EditTeamCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Edit/EditTeamCommand.cs new file mode 100644 index 00000000..23c972c0 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Edit/EditTeamCommand.cs @@ -0,0 +1,113 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Teams.EditTeam +{ + public class EditTeamCommand : IRequest> + { + public int TeamId { get; set; } + public string? Name { get; set; } + public string? LessonTime { get; set; } + public DateTime? Start { get; set; } + public DateTime? Finish { get; set; } + public List? PersonTeamsIds { get; set; } + public int? ProjectProgramId { get; set; } + public int? CourseId { get; set; } + } + + internal sealed class EditTeamCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public EditTeamCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(EditTeamCommand request, CancellationToken cancellationToken) + { + var team = await _context.Teams + .Where(t => t.Id == request.TeamId) + .Include(p => p.ProjectProgram) + .Include(c => c.Course) + .Include(pt => pt.PersonTeams) + .FirstOrDefaultAsync(cancellationToken); + + if (team == null) + { + return new ValidationFailed(new[] { "Turma não encontrado ou excluída." }); + } + + var startDate = request.Start ?? team.Start; + var finishDate = request.Finish ?? team.Finish; + + if (startDate >= finishDate) + { + return new ValidationFailed(new[] { "A data de início deve ser anterior à data de término." }); + } + + if (request.ProjectProgramId.HasValue) + { + var programExists = await _context.ProjectPrograms + .AnyAsync(p => p.Id == request.ProjectProgramId, cancellationToken); + + if (!programExists) + return new ValidationFailed(new[] { $"Projeto com ID {request.ProjectProgramId} não encontrado." }); + } + + if (request.CourseId.HasValue) + { + var courseExists = await _context.Courses + .AnyAsync(c => c.Id == request.CourseId, cancellationToken); + + if (!courseExists) + return new ValidationFailed(new[] { $"Projeto com ID {request.CourseId} não encontrado." }); + } + + if (request.PersonTeamsIds != null && request.PersonTeamsIds.Any()) + { + var personsExist = await _context.Persons + .Where(p => request.PersonTeamsIds.Contains(p.Id)) + .Select(p => p.Id) + .ToListAsync(cancellationToken); + + var invalidIds = request.PersonTeamsIds.Except(personsExist).ToList(); + + if (invalidIds.Any()) + { + return new ValidationFailed(new[] { $"Pessoas com IDs {string.Join(", ", invalidIds)} não encontradas." }); + } + } + + team.Name = request.Name ?? team.Name; + team.LessonTime = request.LessonTime ?? team.LessonTime; + team.Start = request.Start ?? team.Start; + team.Finish = request.Finish ?? team.Finish; + team.ProjectProgramId = request.ProjectProgramId ?? team.ProjectProgramId; + team.CourseId = request.CourseId ?? team.CourseId; + + if (request.PersonTeamsIds != null && + !request.PersonTeamsIds.OrderBy(x => x) + .SequenceEqual(team.PersonTeams.Select(pt => pt.PersonId).OrderBy(x => x))) + { + team.PersonTeams.Clear(); + + foreach (var personId in request.PersonTeamsIds) + { + team.PersonTeams.Add(new PersonTeam + { + TeamId = team.Id, + PersonId = personId + }); + } + } + + await _context.SaveChangesAsync(cancellationToken); + + return team; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Edit/EditTeamEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Edit/EditTeamEndpoint.cs new file mode 100644 index 00000000..a395619e --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/Edit/EditTeamEndpoint.cs @@ -0,0 +1,64 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Teams.EditTeam +{ + [ApiAuthorize] + [Route("/api/teams")] + [ApiController] + [ApiExplorerSettings(GroupName = "Teams")] + public class EditTeamEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public EditTeamEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{teamId}", Name = "EditTeam")] + public async Task> EditTeam(int teamId, [FromBody] EditTeamRequest request) + { + var result = await _mediator.Send(new EditTeamCommand + { + TeamId = teamId, + Name = request.Name, + LessonTime = request.LessonTime, + Start = request.Start, + Finish = request.Finish, + PersonTeamsIds = request.PersonTeamsIds, + ProjectProgramId = request.ProjectProgramId, + CourseId = request.CourseId + }); + + if (!result.IsSuccess) + return BadRequest(result.Error); + + var editResponse = new EditTeamResponse + { + TeamId = teamId, + Name = result.Value.Name + }; + + return Ok(editResponse); + } + } + + public class EditTeamRequest + { + public string? Name { get; set; } + public string? LessonTime { get; set; } + public DateTime? Start { get; set; } + public DateTime? Finish { get; set; } + public List? PersonTeamsIds { get; set; } + public int? ProjectProgramId { get; set; } + public int? CourseId { get; set; } + } + + public class EditTeamResponse + { + public int TeamId { get; set; } + public string? Name { get; set; } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/GetId/GetTeamByIdEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/GetId/GetTeamByIdEndpoint.cs new file mode 100644 index 00000000..6c8ee557 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/GetId/GetTeamByIdEndpoint.cs @@ -0,0 +1,62 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Teams.GetTeamById +{ + [ApiAuthorize] + [Route("/api/teams")] + [ApiController] + [ApiExplorerSettings(GroupName = "Teams")] + public class GetTeamByIdEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public GetTeamByIdEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("{teamId}", Name = "GetTeamById")] + public async Task> GetTeamById(int teamId) + { + var result = await _mediator.Send(new GetTeamQuery(teamId)); + + var teamInfo = new GetTeamByIdResponse + { + TeamId = teamId, + Name = result.Value.Name, + LessonTime = result.Value.LessonTime, + Start = result.Value.Start, + Finish = result.Value.Finish, + CourseId = result.Value.CourseId, + CourseName = result.Value.Course?.Name, + ProjectProgramId = result.Value.ProjectProgramId, + ProjectProgramName = result.Value.ProjectProgram?.Name, + PersonTeamsCount = result.Value.PersonTeams.Count, + IsDeleted = result.Value.IsDeleted, + CreatedAt = result.Value.CreatedAt + }; + + return result.IsSuccess + ? Ok(teamInfo) + : NotFound(result.Error); + } + } + + public class GetTeamByIdResponse + { + public int TeamId { get; set; } + public string? Name { get; set; } + public string? LessonTime { get; set; } + public DateTime? Start { get; set; } + public DateTime? Finish { get; set; } + public int? CourseId { get; set; } + public string? CourseName { get; set; } + public int? ProjectProgramId { get; set; } + public string? ProjectProgramName { get; set; } + public int PersonTeamsCount { get; set; } + public bool IsDeleted { get; set; } + public DateTime CreatedAt { get; set; } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/GetId/GetTeamByIdQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/GetId/GetTeamByIdQuery.cs new file mode 100644 index 00000000..4b4012d1 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/GetId/GetTeamByIdQuery.cs @@ -0,0 +1,45 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Teams.GetTeamById +{ + public class GetTeamQuery : IRequest> + { + public int TeamId { get; set; } + + public GetTeamQuery(int id) + { + TeamId = id; + } + } + + internal sealed class GetTeamByIdQueryHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public GetTeamByIdQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(GetTeamQuery request, CancellationToken cancellationToken) + { + var team = await _context.Teams + .Where(team => team.Id == request.TeamId) + .Include(team => team.PersonTeams) + .Include(team => team.ProjectProgram) + .Include(team => team.Course) + .FirstOrDefaultAsync(cancellationToken); + + if (team == null) + { + return new ValidationFailed(new[] { $"Turma com ID {request.TeamId} não encontrado ou está inativo." }); + } + + return team; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/List/ListTeamEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/List/ListTeamEndpoint.cs new file mode 100644 index 00000000..3a90795d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/List/ListTeamEndpoint.cs @@ -0,0 +1,34 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Teams.ListTeams +{ + [ApiAuthorize] + [Route("/api/teams")] + [ApiController] + [ApiExplorerSettings(GroupName = "Teams")] + public class ListTeamEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListTeamEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("search", Name = "ListTeam")] + public async Task> ListTeams([FromBody] ListTeamRequest request) + { + var result = await _mediator.Send(new ListTeamQuery(request.PageNumber, request.PageSize, request.Filters)); + return Ok(result); + } + } + + public class ListTeamRequest + { + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 10; + public List Filters { get; set; } = new(); + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/List/ListTeamQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/List/ListTeamQuery.cs new file mode 100644 index 00000000..149dcb45 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Team/List/ListTeamQuery.cs @@ -0,0 +1,82 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Teams.ListTeams +{ + public class ListTeamViewModel : PaginationResponse + { + } + + public class ListTeamItemViewModel + { + public int TeamId { get; set; } + public string? Name { get; set; } + public string? LessonTime { get; set; } + public DateTime? Start { get; set; } + public DateTime? Finish { get; set; } + public int? ProjectProgramId { get; set; } + public string? ProjectProgramName { get; set; } + public int? CourseId { get; set; } + public string? CourseName { get; set; } + public int PersonTeamsCount { get; set; } + public bool IsDeleted { get; set; } + } + + public class ListTeamQuery : PaginationRequest, IRequest + { + public ListTeamQuery(int pageNumber, int pageSize, List filters) + : base(pageNumber, pageSize, filters) + { + } + } + + internal sealed class ListTeamQueryHandler : IRequestHandler + { + private readonly ApplicationDbContext _context; + + public ListTeamQueryHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task Handle(ListTeamQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + + var query = _context.Teams.AsQueryable(); + + var result = await query + .Where(expr) + .Select(team => new ListTeamItemViewModel + { + TeamId = team.Id, + Name = team.Name, + LessonTime = team.LessonTime, + Start = team.Start, + Finish = team.Finish, + ProjectProgramId = team.ProjectProgramId, + ProjectProgramName = team.ProjectProgram != null ? team.ProjectProgram.Name : "", + CourseId = team.CourseId, + CourseName = team.Course != null ? team.Course.Name : "", + PersonTeamsCount = team.PersonTeams.Count, + IsDeleted = team.IsDeleted + }) + .OrderBy(x => x.CourseId) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToListAsync(cancellationToken); + + var totalRecords = await _context.Teams.CountAsync(expr, cancellationToken); + + return new ListTeamViewModel + { + Items = result, + TotalItems = totalRecords + }; + } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/CreateUser/CreateUserCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/CreateUser/CreateUserCommand.cs new file mode 100644 index 00000000..635c9007 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/CreateUser/CreateUserCommand.cs @@ -0,0 +1,61 @@ +using MediatR; +using IgescConecta.API.Common.Validation; +using Microsoft.AspNetCore.Identity; +using IgescConecta.Domain.Entities; +using Microsoft.VisualBasic; + +namespace IgescConecta.API.Features.Users.CreateUser +{ + + + + public class CreateUserCommand : IRequest> + { + public string Name { get; set; } + public string Password { get; set; } + public string Email { get; set; } + public string PhoneNumber { get; set; } + public string Role { get; set; } + } + + + + internal sealed class CreateUserCommandHandler : IRequestHandler> + { + private readonly UserManager _userManager; + + public CreateUserCommandHandler(UserManager userManager) + { + _userManager = userManager; + } + + + public async Task> Handle(CreateUserCommand request, CancellationToken cancellationToken) + { + + var user = new User + { + UserName = request.Email, + Email = request.Email, + Name = request.Name, + PhoneNumber = request.PhoneNumber, + IsActive = true + }; + + + var result = await _userManager.CreateAsync(user, request.Password); + + if (result.Succeeded) + { + + await _userManager.AddToRoleAsync(user, request.Role.ToUpper()); + + + return user.Id; + } + + + return new ValidationFailed(result.Errors.Select(e => e.Description).ToArray()); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/CreateUser/CreateUserEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/CreateUser/CreateUserEndpoint.cs new file mode 100644 index 00000000..0c3ff703 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/CreateUser/CreateUserEndpoint.cs @@ -0,0 +1,66 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Users.CreateUser +{ + + [ApiAuthorize] + [Route("/api/users")] + [ApiController] + [ApiExplorerSettings(GroupName = "Users")] + [Authorize(Roles = "Admin,Editor")] + public class CreateUserEndPoint : ControllerBase + { + private readonly IMediator _mediator; + + + public CreateUserEndPoint(IMediator mediator) + { + _mediator = mediator; + } + + + [HttpPost("CreateUser", Name = "CreateUser")] + public async Task> CreateUser([FromBody] CreateUserRequest request) + { + + var result = await _mediator.Send(new CreateUserCommand + { + Name = request.Name, + Password = request.Password, + Email = request.Email, + PhoneNumber = request.PhoneNumber, + Role = request.Role + }); + + + + return result.IsSuccess + ? Ok(new CreateUserResponse(result.Value)) + : BadRequest(result.Error); + } + } + + + public class CreateUserRequest + { + public string Name { get; set; } + public string Password { get; set; } + public string Email { get; set; } + public string PhoneNumber { get; set; } + public string Role { get; set; } + } + + + public class CreateUserResponse + { + public int UserId { get; set; } + + public CreateUserResponse(int userId) + { + UserId = userId; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/DeleteUser/DeleteUserCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/DeleteUser/DeleteUserCommand.cs new file mode 100644 index 00000000..8cd7f625 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/DeleteUser/DeleteUserCommand.cs @@ -0,0 +1,41 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; + +namespace IgescConecta.API.Features.Users.DeleteUser +{ + public class DeleteUserCommand : IRequest> + { + public int UserId { get; set; } + + public DeleteUserCommand(int userId) + { + UserId = userId; + } + + } + + internal sealed class DeleteUserCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + + public DeleteUserCommandHandler(ApplicationDbContext context) + { + _context = context; + } + + public async Task> Handle(DeleteUserCommand request, CancellationToken cancellationToken) + { + var user = await _context.Users.FindAsync([request.UserId]); + if (user == null) + { + return new ValidationFailed(new[] { "Usuário não encontrado." }); + } + _context.Users.Remove(user); + await _context.SaveChangesAsync(cancellationToken); + + return true; + } + } + +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/DeleteUser/DeleteUserEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/DeleteUser/DeleteUserEndpoint.cs new file mode 100644 index 00000000..282beae9 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/DeleteUser/DeleteUserEndpoint.cs @@ -0,0 +1,32 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Diagnostics; + +namespace IgescConecta.API.Features.Users.DeleteUser +{ + [ApiAuthorize] + [Route("api/users")] + [ApiController] + [ApiExplorerSettings(GroupName = "Users")] + [Authorize(Roles = "Admin,Editor")] + public class DeleteUserEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public DeleteUserEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpDelete("{userId}", Name = "DeleteUser")] + public async Task DeleteUser(int userId) + { + var result = await _mediator.Send(new DeleteUserCommand(userId)); + return result.IsSuccess ? Ok() : BadRequest(result.Error); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/GetId/GetUserByIdEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/GetId/GetUserByIdEndpoint.cs new file mode 100644 index 00000000..c6147189 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/GetId/GetUserByIdEndpoint.cs @@ -0,0 +1,33 @@ +using IgescConecta.API.Features.Users.ListUser; // UserViewModel +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Users.GetId +{ + [Route("/api/users")] + [ApiController] + [ApiExplorerSettings(GroupName = "Users")] + [Authorize(Roles = "Admin,Editor")] + public class GetUserByIdEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public GetUserByIdEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet("{userId:int}", Name = "GetUserById")] + [ProducesResponseType(typeof(UserViewModel), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task> GetUserById([FromRoute] int userId) + { + var vm = await _mediator.Send(new GetUserByIdQuery(userId)); + if (vm is null) return NotFound(); + return Ok(vm); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/GetId/GetUserByIdQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/GetId/GetUserByIdQuery.cs new file mode 100644 index 00000000..b87e3328 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/GetId/GetUserByIdQuery.cs @@ -0,0 +1,41 @@ +using IgescConecta.API.Features.Users.ListUser; // para reutilizar UserViewModel +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Users.GetId +{ + public record GetUserByIdQuery(int UserId) : IRequest; + + internal sealed class GetUserByIdQueryHandler : IRequestHandler + { + private readonly UserManager _userManager; + + public GetUserByIdQueryHandler(UserManager userManager) + { + _userManager = userManager; + } + + public async Task Handle(GetUserByIdQuery request, CancellationToken cancellationToken) + { + var user = await _userManager.Users + .AsNoTracking() + .FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken); + + if (user is null) return null; + + var role = (await _userManager.GetRolesAsync(user)).FirstOrDefault() ?? string.Empty; + + return new UserViewModel + { + UserId = user.Id, + Name = user.Name, + Email = user.Email ?? string.Empty, + PhoneNumber = user.PhoneNumber ?? string.Empty, + IsActive = user.IsActive, + Role = role + }; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/ListUser/ListUserEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/ListUser/ListUserEndpoint.cs new file mode 100644 index 00000000..4a6b4890 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/ListUser/ListUserEndpoint.cs @@ -0,0 +1,34 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Users.ListUser +{ + [ApiAuthorize] + [Route("/api/users")] + [ApiController] + [ApiExplorerSettings(GroupName = "Users")] + public class ListUserEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public ListUserEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPost("ListUser", Name = "ListUser")] + public async Task> ListUser(ListUserRequest request) + { + var result = await _mediator.Send(new ListUserQuery(request.PageNumber, request.PageSize, request.Filters)); + return Ok(result); + } + } + + public class ListUserRequest + { + public int PageNumber { get; set; } + public int PageSize { get; set; } + public List Filters { get; set; } = new(); + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/ListUser/ListUserQuery.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/ListUser/ListUserQuery.cs new file mode 100644 index 00000000..5b0cf558 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/ListUser/ListUserQuery.cs @@ -0,0 +1,79 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Query; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; + +namespace IgescConecta.API.Features.Users.ListUser +{ + public class ListUserViewModel : PaginationResponse + { + } + + public class UserViewModel + { + public int UserId { get; set; } + + public string Name { get; set; } + + public string Email { get; set; } + + public string Role { get; set; } + + public string PhoneNumber { get; set; } + + public bool IsActive { get; set; } + } + + public class ListUserQuery : PaginationRequest, IRequest + { + public ListUserQuery(int pageNumber, int pageSize, List filters) : base(pageNumber, pageSize, filters) + { + } + } + + internal sealed class ListUserQueryHandler : IRequestHandler + { + private readonly UserManager _userManager; + + public ListUserQueryHandler(UserManager userManager) + { + _userManager = userManager; + } + + public async Task Handle(ListUserQuery request, CancellationToken cancellationToken) + { + var expr = ExpressionBuilder.GetExpression(request.Filters); + var query = _userManager.Users.AsQueryable(); + var result = await query.Where(expr) + .OrderByDescending(x => x.Id) + .Skip((request.PageNumber - 1) * request.PageSize) + .Take(request.PageSize) + .ToListAsync(cancellationToken); + + var users = new List(); + foreach(var item in result) + { + var user = new UserViewModel + { + UserId = item.Id, + Name = item.Name, + Email = item.Email, + PhoneNumber = item.PhoneNumber, + IsActive = item.IsActive + }; + user.Role = (await _userManager.GetRolesAsync(item)).FirstOrDefault() ?? string.Empty; + users.Add(user); + } + + var totalRecords = await _userManager.Users.CountAsync(expr, cancellationToken); + + return new ListUserViewModel + { + Items = users, + TotalItems = totalRecords, + }; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/UpdateUser/UpdateUserCommand.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/UpdateUser/UpdateUserCommand.cs new file mode 100644 index 00000000..2a2067f4 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/UpdateUser/UpdateUserCommand.cs @@ -0,0 +1,67 @@ +using IgescConecta.API.Common.Validation; +using IgescConecta.API.Data; +using IgescConecta.Domain.Entities; +using MediatR; +using Microsoft.AspNetCore.Identity; + +namespace IgescConecta.API.Features.Users.UpdateUser +{ + public class UpdateUserCommand : IRequest> + { + public int UserId { get; set; } + + public string? Name { get; set; } + + public string? Password { get; set; } + + public string? Email { get; set; } + + public string? PhoneNumber { get; set; } + + public bool IsActive { get; set; } + + public string? Role { get; set; } + } + + internal sealed class UpdateUserCommandHandler : IRequestHandler> + { + private readonly ApplicationDbContext _context; + private readonly UserManager _userManager; + + public UpdateUserCommandHandler(ApplicationDbContext context, UserManager userManager) + { + _context = context; + _userManager = userManager; + } + + public async Task> Handle(UpdateUserCommand request, CancellationToken cancellationToken) + { + var user = await _context.Users.FindAsync([request.UserId], cancellationToken: cancellationToken); + + if(user == null) + { + return new ValidationFailed(["Usuário não encontrado."]); + } + + user.Name = string.IsNullOrEmpty(request.Name) ? user.Name : request.Name; + user.Email = string.IsNullOrEmpty(request.Email) ? user.Email : request.Email; + user.PhoneNumber = string.IsNullOrEmpty(request.PhoneNumber) ? user.PhoneNumber : request.PhoneNumber; + user.IsActive = request.IsActive; + + if(request.Role != null) + { + await _userManager.RemoveFromRolesAsync(user, await _userManager.GetRolesAsync(user)); + await _userManager.AddToRoleAsync(user, request.Role.ToUpper()); + } + await _userManager.UpdateAsync(user); + + if(!string.IsNullOrEmpty(request.Password)) + { + await _userManager.RemovePasswordAsync(user); + await _userManager.AddPasswordAsync(user, request.Password); + } + + return user; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/UpdateUser/UpdateUserEndpoint.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/UpdateUser/UpdateUserEndpoint.cs new file mode 100644 index 00000000..7c84b60a --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Features/Users/UpdateUser/UpdateUserEndpoint.cs @@ -0,0 +1,67 @@ +using IgescConecta.API.Common.Extensions; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace IgescConecta.API.Features.Users.UpdateUser +{ + [ApiAuthorize] + [Route("/api/users")] + [ApiController] + [ApiExplorerSettings(GroupName = "Users")] + public class UpdateUserEndpoint : ControllerBase + { + private readonly IMediator _mediator; + + public UpdateUserEndpoint(IMediator mediator) + { + _mediator = mediator; + } + + [HttpPut("{userId}", Name = "UpdateUser")] + public async Task> UpdateUser(int userId, [FromBody] UpdateUserRequest request) + { + var result = await _mediator.Send(new UpdateUserCommand + { + UserId = request.UserId, + Name = request.Name, + Password = request.Password, + Email = request.Email, + PhoneNumber = request.PhoneNumber, + IsActive = request.IsActive, + Role = request.Role + }); + + var updateResponse = new UpdateUserResponse + { + Name = result.Value.Name, + Email = result.Value.Email, + PhoneNumber = result.Value.PhoneNumber, + IsActive = result.Value.IsActive, + Role = request.Role ?? "" + }; + + return result.IsSuccess ? Ok(updateResponse) : BadRequest(result.Error); + } + } + + public class UpdateUserRequest + { + public int UserId { get; set; } + public string? Name { get; set; } + public string? Password { get; set; } + public string? Email { get; set; } + public string? PhoneNumber { get; set; } + public bool IsActive { get; set; } + public string? Role { get; set; } + } + + public class UpdateUserResponse + { + public int UserId { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string PhoneNumber { get; set; } + public bool IsActive { get; set; } + public string Role { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/IgescConecta.API.csproj b/codigo-fonte/IgescConecta.API/IgescConecta.API/IgescConecta.API.csproj new file mode 100644 index 00000000..0acec838 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/IgescConecta.API.csproj @@ -0,0 +1,40 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + Always + + + + diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/IgescConecta.API.http b/codigo-fonte/IgescConecta.API/IgescConecta.API/IgescConecta.API.http new file mode 100644 index 00000000..313b9581 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/IgescConecta.API.http @@ -0,0 +1,6 @@ +@IgescConecta.API_HostAddress = http://localhost:5249 + +GET {{IgescConecta.API_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002000141_InitialIdentity.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002000141_InitialIdentity.Designer.cs new file mode 100644 index 00000000..b3f7a98a --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002000141_InitialIdentity.Designer.cs @@ -0,0 +1,1185 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251002000141_InitialIdentity")] + partial class InitialIdentity + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CNPJ") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("projectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany("Projects") + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Navigation("Projects"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002000141_InitialIdentity.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002000141_InitialIdentity.cs new file mode 100644 index 00000000..a73086d1 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002000141_InitialIdentity.cs @@ -0,0 +1,887 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + /// + public partial class InitialIdentity : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Beneficiaries", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Beneficiaries", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "BusinessCases", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BusinessCases", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Companies", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CompanyName = table.Column(type: "nvarchar(max)", nullable: false), + CorporateReason = table.Column(type: "nvarchar(max)", nullable: true), + CNPJ = table.Column(type: "nvarchar(max)", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Companies", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Courses", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Courses", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Oscs", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + Objective = table.Column(type: "nvarchar(max)", nullable: false), + CorporateName = table.Column(type: "nvarchar(max)", nullable: false), + Address = table.Column(type: "nvarchar(max)", nullable: false), + ZipCode = table.Column(type: "nvarchar(max)", nullable: false), + OscPrimaryDocumment = table.Column(type: "nvarchar(max)", nullable: true), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Oscs", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Persons", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + Email = table.Column(type: "nvarchar(max)", nullable: false), + PersonalDocumment = table.Column(type: "nvarchar(max)", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Persons", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ProjectDocuments", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectDocuments", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "projectThemes", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_projectThemes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ProjectTypes", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Roles", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Roles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + IsActive = table.Column(type: "bit", nullable: false), + UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "bit", nullable: false), + PasswordHash = table.Column(type: "nvarchar(max)", nullable: true), + SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), + TwoFactorEnabled = table.Column(type: "bit", nullable: false), + LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), + LockoutEnabled = table.Column(type: "bit", nullable: false), + AccessFailedCount = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "OriginBusinessCases", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + BusinessCaseId = table.Column(type: "int", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OriginBusinessCases", x => x.Id); + table.ForeignKey( + name: "FK_OriginBusinessCases_BusinessCases_BusinessCaseId", + column: x => x.BusinessCaseId, + principalTable: "BusinessCases", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "BeneficiaryOsc", + columns: table => new + { + BeneficiariesId = table.Column(type: "int", nullable: false), + OscsId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BeneficiaryOsc", x => new { x.BeneficiariesId, x.OscsId }); + table.ForeignKey( + name: "FK_BeneficiaryOsc_Beneficiaries_BeneficiariesId", + column: x => x.BeneficiariesId, + principalTable: "Beneficiaries", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_BeneficiaryOsc_Oscs_OscsId", + column: x => x.OscsId, + principalTable: "Oscs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PersonCompanies", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + PersonId = table.Column(type: "int", nullable: false), + CompanyId = table.Column(type: "int", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersonCompanies", x => x.Id); + table.ForeignKey( + name: "FK_PersonCompanies_Companies_CompanyId", + column: x => x.CompanyId, + principalTable: "Companies", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PersonCompanies_Persons_PersonId", + column: x => x.PersonId, + principalTable: "Persons", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "RoleClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RoleId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_RoleClaims_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserClaims", x => x.Id); + table.ForeignKey( + name: "FK_UserClaims_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), + ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), + UserId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_UserLogins_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserRoles", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false), + RoleId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_UserRoles_Roles_RoleId", + column: x => x.RoleId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_UserRoles_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "UserTokens", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false), + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false), + Value = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_UserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_UserTokens_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "OriginBusinessCaseOsc", + columns: table => new + { + OriginsBusinessCasesId = table.Column(type: "int", nullable: false), + OscsId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OriginBusinessCaseOsc", x => new { x.OriginsBusinessCasesId, x.OscsId }); + table.ForeignKey( + name: "FK_OriginBusinessCaseOsc_OriginBusinessCases_OriginsBusinessCasesId", + column: x => x.OriginsBusinessCasesId, + principalTable: "OriginBusinessCases", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_OriginBusinessCaseOsc_Oscs_OscsId", + column: x => x.OscsId, + principalTable: "Oscs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Donations", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + DonationDate = table.Column(type: "datetime2", nullable: false), + Value = table.Column(type: "decimal(18,2)", nullable: false), + PersonId = table.Column(type: "int", nullable: true), + CompanyId = table.Column(type: "int", nullable: true), + OscId = table.Column(type: "int", nullable: true), + TeamId = table.Column(type: "int", nullable: true), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Donations", x => x.Id); + table.ForeignKey( + name: "FK_Donations_Companies_CompanyId", + column: x => x.CompanyId, + principalTable: "Companies", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Donations_Oscs_OscId", + column: x => x.OscId, + principalTable: "Oscs", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Donations_Persons_PersonId", + column: x => x.PersonId, + principalTable: "Persons", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "PersonOscs", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + PersonId = table.Column(type: "int", nullable: false), + OscId = table.Column(type: "int", nullable: false), + TeamId = table.Column(type: "int", nullable: true), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersonOscs", x => x.Id); + table.ForeignKey( + name: "FK_PersonOscs_Oscs_OscId", + column: x => x.OscId, + principalTable: "Oscs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PersonOscs_Persons_PersonId", + column: x => x.PersonId, + principalTable: "Persons", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PersonTeams", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + MemberTypes = table.Column(type: "nvarchar(max)", nullable: false), + PersonId = table.Column(type: "int", nullable: false), + TeamId = table.Column(type: "int", nullable: false), + OscId = table.Column(type: "int", nullable: true), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersonTeams", x => x.Id); + table.ForeignKey( + name: "FK_PersonTeams_Oscs_OscId", + column: x => x.OscId, + principalTable: "Oscs", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_PersonTeams_Persons_PersonId", + column: x => x.PersonId, + principalTable: "Persons", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ProjectPrograms", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + OdsTypes = table.Column(type: "nvarchar(max)", nullable: false), + Decision = table.Column(type: "int", nullable: false), + ProjectThemeId = table.Column(type: "int", nullable: false), + ProjectTypeId = table.Column(type: "int", nullable: false), + TeamId = table.Column(type: "int", nullable: false), + OscId = table.Column(type: "int", nullable: false), + ProjectDocumentId = table.Column(type: "int", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectPrograms", x => x.Id); + table.ForeignKey( + name: "FK_ProjectPrograms_Oscs_OscId", + column: x => x.OscId, + principalTable: "Oscs", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ProjectPrograms_ProjectDocuments_ProjectDocumentId", + column: x => x.ProjectDocumentId, + principalTable: "ProjectDocuments", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ProjectPrograms_ProjectTypes_ProjectThemeId", + column: x => x.ProjectThemeId, + principalTable: "ProjectTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ProjectPrograms_projectThemes_ProjectTypeId", + column: x => x.ProjectTypeId, + principalTable: "projectThemes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Team", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Start = table.Column(type: "datetime2", nullable: false), + Finish = table.Column(type: "datetime2", nullable: false), + ProjectProgramId = table.Column(type: "int", nullable: true), + CourseId = table.Column(type: "int", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Team", x => x.Id); + table.ForeignKey( + name: "FK_Team_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Team_ProjectPrograms_ProjectProgramId", + column: x => x.ProjectProgramId, + principalTable: "ProjectPrograms", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_BeneficiaryOsc_OscsId", + table: "BeneficiaryOsc", + column: "OscsId"); + + migrationBuilder.CreateIndex( + name: "IX_Donations_CompanyId", + table: "Donations", + column: "CompanyId"); + + migrationBuilder.CreateIndex( + name: "IX_Donations_OscId", + table: "Donations", + column: "OscId"); + + migrationBuilder.CreateIndex( + name: "IX_Donations_PersonId", + table: "Donations", + column: "PersonId"); + + migrationBuilder.CreateIndex( + name: "IX_Donations_TeamId", + table: "Donations", + column: "TeamId"); + + migrationBuilder.CreateIndex( + name: "IX_OriginBusinessCaseOsc_OscsId", + table: "OriginBusinessCaseOsc", + column: "OscsId"); + + migrationBuilder.CreateIndex( + name: "IX_OriginBusinessCases_BusinessCaseId", + table: "OriginBusinessCases", + column: "BusinessCaseId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonCompanies_CompanyId", + table: "PersonCompanies", + column: "CompanyId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonCompanies_PersonId", + table: "PersonCompanies", + column: "PersonId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonOscs_OscId", + table: "PersonOscs", + column: "OscId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonOscs_PersonId", + table: "PersonOscs", + column: "PersonId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonOscs_TeamId", + table: "PersonOscs", + column: "TeamId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonTeams_OscId", + table: "PersonTeams", + column: "OscId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonTeams_PersonId", + table: "PersonTeams", + column: "PersonId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonTeams_TeamId", + table: "PersonTeams", + column: "TeamId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectPrograms_OscId", + table: "ProjectPrograms", + column: "OscId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectPrograms_ProjectDocumentId", + table: "ProjectPrograms", + column: "ProjectDocumentId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectPrograms_ProjectThemeId", + table: "ProjectPrograms", + column: "ProjectThemeId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectPrograms_ProjectTypeId", + table: "ProjectPrograms", + column: "ProjectTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_ProjectPrograms_TeamId", + table: "ProjectPrograms", + column: "TeamId"); + + migrationBuilder.CreateIndex( + name: "IX_RoleClaims_RoleId", + table: "RoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "Roles", + column: "NormalizedName", + unique: true, + filter: "[NormalizedName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_Team_CourseId", + table: "Team", + column: "CourseId"); + + migrationBuilder.CreateIndex( + name: "IX_Team_ProjectProgramId", + table: "Team", + column: "ProjectProgramId"); + + migrationBuilder.CreateIndex( + name: "IX_UserClaims_UserId", + table: "UserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserLogins_UserId", + table: "UserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_UserRoles_RoleId", + table: "UserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "Users", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "Users", + column: "NormalizedUserName", + unique: true, + filter: "[NormalizedUserName] IS NOT NULL"); + + migrationBuilder.AddForeignKey( + name: "FK_Donations_Team_TeamId", + table: "Donations", + column: "TeamId", + principalTable: "Team", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_PersonOscs_Team_TeamId", + table: "PersonOscs", + column: "TeamId", + principalTable: "Team", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_PersonTeams_Team_TeamId", + table: "PersonTeams", + column: "TeamId", + principalTable: "Team", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectPrograms_Team_TeamId", + table: "ProjectPrograms", + column: "TeamId", + principalTable: "Team", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ProjectPrograms_Oscs_OscId", + table: "ProjectPrograms"); + + migrationBuilder.DropForeignKey( + name: "FK_ProjectPrograms_Team_TeamId", + table: "ProjectPrograms"); + + migrationBuilder.DropTable( + name: "BeneficiaryOsc"); + + migrationBuilder.DropTable( + name: "Donations"); + + migrationBuilder.DropTable( + name: "OriginBusinessCaseOsc"); + + migrationBuilder.DropTable( + name: "PersonCompanies"); + + migrationBuilder.DropTable( + name: "PersonOscs"); + + migrationBuilder.DropTable( + name: "PersonTeams"); + + migrationBuilder.DropTable( + name: "RoleClaims"); + + migrationBuilder.DropTable( + name: "UserClaims"); + + migrationBuilder.DropTable( + name: "UserLogins"); + + migrationBuilder.DropTable( + name: "UserRoles"); + + migrationBuilder.DropTable( + name: "UserTokens"); + + migrationBuilder.DropTable( + name: "Beneficiaries"); + + migrationBuilder.DropTable( + name: "OriginBusinessCases"); + + migrationBuilder.DropTable( + name: "Companies"); + + migrationBuilder.DropTable( + name: "Persons"); + + migrationBuilder.DropTable( + name: "Roles"); + + migrationBuilder.DropTable( + name: "Users"); + + migrationBuilder.DropTable( + name: "BusinessCases"); + + migrationBuilder.DropTable( + name: "Oscs"); + + migrationBuilder.DropTable( + name: "Team"); + + migrationBuilder.DropTable( + name: "Courses"); + + migrationBuilder.DropTable( + name: "ProjectPrograms"); + + migrationBuilder.DropTable( + name: "ProjectDocuments"); + + migrationBuilder.DropTable( + name: "ProjectTypes"); + + migrationBuilder.DropTable( + name: "projectThemes"); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002021148_FixUserSelfFks_NoCascade.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002021148_FixUserSelfFks_NoCascade.Designer.cs new file mode 100644 index 00000000..6c96ddd0 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002021148_FixUserSelfFks_NoCascade.Designer.cs @@ -0,0 +1,1220 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251002021148_FixUserSelfFks_NoCascade")] + partial class FixUserSelfFks_NoCascade + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CNPJ") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("projectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany("Projects") + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Navigation("Projects"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002021148_FixUserSelfFks_NoCascade.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002021148_FixUserSelfFks_NoCascade.cs new file mode 100644 index 00000000..4101e057 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251002021148_FixUserSelfFks_NoCascade.cs @@ -0,0 +1,104 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + public partial class FixUserSelfFks_NoCascade : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + // timestamps: pode manter como NOT NULL com default "min" + migrationBuilder.AddColumn( + name: "CreatedAt", + table: "Users", + type: "datetime2", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "Users", + type: "datetime2", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + // ✅ chaves: AGORA SÃO NULLABLE e SEM DEFAULT 0 + migrationBuilder.AddColumn( + name: "CreatedBy", + table: "Users", + type: "int", + nullable: true); + + migrationBuilder.AddColumn( + name: "UpdatedBy", + table: "Users", + type: "int", + nullable: true); + + // índices + migrationBuilder.CreateIndex( + name: "IX_Users_CreatedBy", + table: "Users", + column: "CreatedBy"); + + migrationBuilder.CreateIndex( + name: "IX_Users_UpdatedBy", + table: "Users", + column: "UpdatedBy"); + + // FKs self-reference SEM CASCADE (NoAction/Restrict) + migrationBuilder.AddForeignKey( + name: "FK_Users_Users_CreatedBy", + table: "Users", + column: "CreatedBy", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.NoAction); + + migrationBuilder.AddForeignKey( + name: "FK_Users_Users_UpdatedBy", + table: "Users", + column: "UpdatedBy", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.NoAction); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Users_Users_CreatedBy", + table: "Users"); + + migrationBuilder.DropForeignKey( + name: "FK_Users_Users_UpdatedBy", + table: "Users"); + + migrationBuilder.DropIndex( + name: "IX_Users_CreatedBy", + table: "Users"); + + migrationBuilder.DropIndex( + name: "IX_Users_UpdatedBy", + table: "Users"); + + migrationBuilder.DropColumn( + name: "CreatedAt", + table: "Users"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "Users"); + + migrationBuilder.DropColumn( + name: "CreatedBy", + table: "Users"); + + migrationBuilder.DropColumn( + name: "UpdatedBy", + table: "Users"); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251005174241_FixTeamAndCurseEntities.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251005174241_FixTeamAndCurseEntities.Designer.cs new file mode 100644 index 00000000..fb3525e2 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251005174241_FixTeamAndCurseEntities.Designer.cs @@ -0,0 +1,1228 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251005174241_FixTeamAndCurseEntities")] + partial class FixTeamAndCurseEntities + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CNPJ") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("projectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LessonTime") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany("Projects") + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany("Teams") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Navigation("Projects"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251005174241_FixTeamAndCurseEntities.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251005174241_FixTeamAndCurseEntities.cs new file mode 100644 index 00000000..599d0e81 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251005174241_FixTeamAndCurseEntities.cs @@ -0,0 +1,313 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + /// + public partial class FixTeamAndCurseEntities : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Donations_Team_TeamId", + table: "Donations"); + + migrationBuilder.DropForeignKey( + name: "FK_PersonOscs_Team_TeamId", + table: "PersonOscs"); + + migrationBuilder.DropForeignKey( + name: "FK_PersonTeams_Team_TeamId", + table: "PersonTeams"); + + migrationBuilder.DropForeignKey( + name: "FK_ProjectPrograms_Team_TeamId", + table: "ProjectPrograms"); + + migrationBuilder.DropForeignKey( + name: "FK_Team_Courses_CourseId", + table: "Team"); + + migrationBuilder.DropForeignKey( + name: "FK_Team_ProjectPrograms_ProjectProgramId", + table: "Team"); + + migrationBuilder.DropPrimaryKey( + name: "PK_Team", + table: "Team"); + + migrationBuilder.RenameTable( + name: "Team", + newName: "Teams"); + + migrationBuilder.RenameIndex( + name: "IX_Team_ProjectProgramId", + table: "Teams", + newName: "IX_Teams_ProjectProgramId"); + + migrationBuilder.RenameIndex( + name: "IX_Team_CourseId", + table: "Teams", + newName: "IX_Teams_CourseId"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "Users", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "int"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "Users", + type: "int", + nullable: true, + oldClrType: typeof(int), + oldType: "int"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Courses", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + + migrationBuilder.AlterColumn( + name: "Start", + table: "Teams", + type: "datetime2", + nullable: true, + oldClrType: typeof(DateTime), + oldType: "datetime2"); + + migrationBuilder.AlterColumn( + name: "Finish", + table: "Teams", + type: "datetime2", + nullable: true, + oldClrType: typeof(DateTime), + oldType: "datetime2"); + + migrationBuilder.AddColumn( + name: "LessonTime", + table: "Teams", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "Name", + table: "Teams", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddPrimaryKey( + name: "PK_Teams", + table: "Teams", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Donations_Teams_TeamId", + table: "Donations", + column: "TeamId", + principalTable: "Teams", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_PersonOscs_Teams_TeamId", + table: "PersonOscs", + column: "TeamId", + principalTable: "Teams", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_PersonTeams_Teams_TeamId", + table: "PersonTeams", + column: "TeamId", + principalTable: "Teams", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectPrograms_Teams_TeamId", + table: "ProjectPrograms", + column: "TeamId", + principalTable: "Teams", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Teams_Courses_CourseId", + table: "Teams", + column: "CourseId", + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Teams_ProjectPrograms_ProjectProgramId", + table: "Teams", + column: "ProjectProgramId", + principalTable: "ProjectPrograms", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Donations_Teams_TeamId", + table: "Donations"); + + migrationBuilder.DropForeignKey( + name: "FK_PersonOscs_Teams_TeamId", + table: "PersonOscs"); + + migrationBuilder.DropForeignKey( + name: "FK_PersonTeams_Teams_TeamId", + table: "PersonTeams"); + + migrationBuilder.DropForeignKey( + name: "FK_ProjectPrograms_Teams_TeamId", + table: "ProjectPrograms"); + + migrationBuilder.DropForeignKey( + name: "FK_Teams_Courses_CourseId", + table: "Teams"); + + migrationBuilder.DropForeignKey( + name: "FK_Teams_ProjectPrograms_ProjectProgramId", + table: "Teams"); + + migrationBuilder.DropPrimaryKey( + name: "PK_Teams", + table: "Teams"); + + migrationBuilder.DropColumn( + name: "LessonTime", + table: "Teams"); + + migrationBuilder.DropColumn( + name: "Name", + table: "Teams"); + + migrationBuilder.RenameTable( + name: "Teams", + newName: "Team"); + + migrationBuilder.RenameIndex( + name: "IX_Teams_ProjectProgramId", + table: "Team", + newName: "IX_Team_ProjectProgramId"); + + migrationBuilder.RenameIndex( + name: "IX_Teams_CourseId", + table: "Team", + newName: "IX_Team_CourseId"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "Users", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "Users", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(int), + oldType: "int", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "Courses", + type: "nvarchar(max)", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Start", + table: "Team", + type: "datetime2", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + oldClrType: typeof(DateTime), + oldType: "datetime2", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Finish", + table: "Team", + type: "datetime2", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + oldClrType: typeof(DateTime), + oldType: "datetime2", + oldNullable: true); + + migrationBuilder.AddPrimaryKey( + name: "PK_Team", + table: "Team", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Donations_Team_TeamId", + table: "Donations", + column: "TeamId", + principalTable: "Team", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_PersonOscs_Team_TeamId", + table: "PersonOscs", + column: "TeamId", + principalTable: "Team", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_PersonTeams_Team_TeamId", + table: "PersonTeams", + column: "TeamId", + principalTable: "Team", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectPrograms_Team_TeamId", + table: "ProjectPrograms", + column: "TeamId", + principalTable: "Team", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Team_Courses_CourseId", + table: "Team", + column: "CourseId", + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Team_ProjectPrograms_ProjectProgramId", + table: "Team", + column: "ProjectProgramId", + principalTable: "ProjectPrograms", + principalColumn: "Id"); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012181707_AddedNewFieldsToEntities.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012181707_AddedNewFieldsToEntities.Designer.cs new file mode 100644 index 00000000..8a40c79b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012181707_AddedNewFieldsToEntities.Designer.cs @@ -0,0 +1,1383 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251012181707_AddedNewFieldsToEntities")] + partial class AddedNewFieldsToEntities + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CNPJ") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Doacao", b => + { + b.Property("IDDoacao") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Data") + .HasColumnType("datetime2"); + + b.Property("DestinoOSCCodigo") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("DestinoTipo") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("DestinoTurmaId") + .HasColumnType("uniqueidentifier"); + + b.Property("DoadorEmpresaCNPJ") + .HasMaxLength(14) + .HasColumnType("CHAR(14)"); + + b.Property("DoadorPessoaCPF") + .HasMaxLength(11) + .HasColumnType("CHAR(11)"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Valor") + .HasColumnType("decimal(10,2)"); + + b.HasKey("IDDoacao"); + + b.HasIndex("DoadorEmpresaCNPJ"); + + b.ToTable("Doacao", null, t => + { + t.HasCheckConstraint("CHK_Doacao_DestinoExclusivo", "(IIF(DestinoTurmaId IS NULL, 0, 1) + IIF(DestinoOSCCodigo IS NULL, 0, 1)) <= 1"); + + t.HasCheckConstraint("CHK_Doacao_DoadorExclusivo", "(IIF(DoadorPessoaCPF IS NULL, 0, 1) + IIF(DoadorEmpresaCNPJ IS NULL, 0, 1)) = 1"); + }); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Empresa", b => + { + b.Property("CNPJ") + .HasColumnType("CHAR(14)"); + + b.Property("Ativa") + .HasColumnType("bit"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Endereco") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Nome") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("Telefone") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("CNPJ"); + + b.ToTable("Empresa", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("City") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Neighborhood") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SocialMedia") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("WebUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LessonTime") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Doacao", b => + { + b.HasOne("IgescConecta.Domain.Entities.Empresa", "DoadorEmpresa") + .WithMany("DoacoesRealizadas") + .HasForeignKey("DoadorEmpresaCNPJ"); + + b.Navigation("DoadorEmpresa"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany("Teams") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Empresa", b => + { + b.Navigation("DoacoesRealizadas"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012181707_AddedNewFieldsToEntities.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012181707_AddedNewFieldsToEntities.cs new file mode 100644 index 00000000..dc2837b1 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012181707_AddedNewFieldsToEntities.cs @@ -0,0 +1,250 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + /// + public partial class AddedNewFieldsToEntities : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ProjectPrograms_projectThemes_ProjectTypeId", + table: "ProjectPrograms"); + + migrationBuilder.DropPrimaryKey( + name: "PK_projectThemes", + table: "projectThemes"); + + migrationBuilder.RenameTable( + name: "projectThemes", + newName: "ProjectThemes"); + + migrationBuilder.AlterColumn( + name: "OscPrimaryDocumment", + table: "Oscs", + type: "nvarchar(max)", + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AddColumn( + name: "City", + table: "Oscs", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Email", + table: "Oscs", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Neighborhood", + table: "Oscs", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "PhoneNumber", + table: "Oscs", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "SocialMedia", + table: "Oscs", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "State", + table: "Oscs", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "WebUrl", + table: "Oscs", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Notes", + table: "OriginBusinessCases", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Notes", + table: "Beneficiaries", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddPrimaryKey( + name: "PK_ProjectThemes", + table: "ProjectThemes", + column: "Id"); + + migrationBuilder.CreateTable( + name: "Empresa", + columns: table => new + { + CNPJ = table.Column(type: "CHAR(14)", nullable: false), + Nome = table.Column(type: "nvarchar(120)", maxLength: 120, nullable: false), + Endereco = table.Column(type: "nvarchar(max)", nullable: false), + Telefone = table.Column(type: "nvarchar(max)", nullable: false), + Email = table.Column(type: "nvarchar(max)", nullable: false), + Ativa = table.Column(type: "bit", nullable: false), + Id = table.Column(type: "int", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Empresa", x => x.CNPJ); + }); + + migrationBuilder.CreateTable( + name: "Doacao", + columns: table => new + { + IDDoacao = table.Column(type: "uniqueidentifier", nullable: false), + Data = table.Column(type: "datetime2", nullable: false), + Valor = table.Column(type: "decimal(10,2)", nullable: false), + DoadorPessoaCPF = table.Column(type: "CHAR(11)", maxLength: 11, nullable: true), + DoadorEmpresaCNPJ = table.Column(type: "CHAR(14)", maxLength: 14, nullable: true), + DestinoTipo = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: true), + DestinoTurmaId = table.Column(type: "uniqueidentifier", nullable: true), + DestinoOSCCodigo = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: true), + Id = table.Column(type: "int", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Doacao", x => x.IDDoacao); + table.CheckConstraint("CHK_Doacao_DestinoExclusivo", "(IIF(DestinoTurmaId IS NULL, 0, 1) + IIF(DestinoOSCCodigo IS NULL, 0, 1)) <= 1"); + table.CheckConstraint("CHK_Doacao_DoadorExclusivo", "(IIF(DoadorPessoaCPF IS NULL, 0, 1) + IIF(DoadorEmpresaCNPJ IS NULL, 0, 1)) = 1"); + table.ForeignKey( + name: "FK_Doacao_Empresa_DoadorEmpresaCNPJ", + column: x => x.DoadorEmpresaCNPJ, + principalTable: "Empresa", + principalColumn: "CNPJ"); + }); + + migrationBuilder.CreateIndex( + name: "IX_Doacao_DoadorEmpresaCNPJ", + table: "Doacao", + column: "DoadorEmpresaCNPJ"); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectPrograms_ProjectThemes_ProjectTypeId", + table: "ProjectPrograms", + column: "ProjectTypeId", + principalTable: "ProjectThemes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ProjectPrograms_ProjectThemes_ProjectTypeId", + table: "ProjectPrograms"); + + migrationBuilder.DropTable( + name: "Doacao"); + + migrationBuilder.DropTable( + name: "Empresa"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ProjectThemes", + table: "ProjectThemes"); + + migrationBuilder.DropColumn( + name: "City", + table: "Oscs"); + + migrationBuilder.DropColumn( + name: "Email", + table: "Oscs"); + + migrationBuilder.DropColumn( + name: "Neighborhood", + table: "Oscs"); + + migrationBuilder.DropColumn( + name: "PhoneNumber", + table: "Oscs"); + + migrationBuilder.DropColumn( + name: "SocialMedia", + table: "Oscs"); + + migrationBuilder.DropColumn( + name: "State", + table: "Oscs"); + + migrationBuilder.DropColumn( + name: "WebUrl", + table: "Oscs"); + + migrationBuilder.DropColumn( + name: "Notes", + table: "OriginBusinessCases"); + + migrationBuilder.DropColumn( + name: "Notes", + table: "Beneficiaries"); + + migrationBuilder.RenameTable( + name: "ProjectThemes", + newName: "projectThemes"); + + migrationBuilder.AlterColumn( + name: "OscPrimaryDocumment", + table: "Oscs", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + + migrationBuilder.AddPrimaryKey( + name: "PK_projectThemes", + table: "projectThemes", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_ProjectPrograms_projectThemes_ProjectTypeId", + table: "ProjectPrograms", + column: "ProjectTypeId", + principalTable: "projectThemes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012190640_BaselineExisting.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012190640_BaselineExisting.Designer.cs new file mode 100644 index 00000000..6a1f9e7b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012190640_BaselineExisting.Designer.cs @@ -0,0 +1,1369 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251012190640_BaselineExisting")] + partial class BaselineExisting + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CNPJ") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Doacao", b => + { + b.Property("IDDoacao") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Data") + .HasColumnType("datetime2"); + + b.Property("DestinoOSCCodigo") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("DestinoTipo") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("DestinoTurmaId") + .HasColumnType("uniqueidentifier"); + + b.Property("DoadorEmpresaCNPJ") + .HasMaxLength(14) + .HasColumnType("CHAR(14)"); + + b.Property("DoadorPessoaCPF") + .HasMaxLength(11) + .HasColumnType("CHAR(11)"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Valor") + .HasColumnType("decimal(10,2)"); + + b.HasKey("IDDoacao"); + + b.HasIndex("DoadorEmpresaCNPJ"); + + b.ToTable("Doacao", null, t => + { + t.HasCheckConstraint("CHK_Doacao_DestinoExclusivo", "(IIF(DestinoTurmaId IS NULL, 0, 1) + IIF(DestinoOSCCodigo IS NULL, 0, 1)) <= 1"); + + t.HasCheckConstraint("CHK_Doacao_DoadorExclusivo", "(IIF(DoadorPessoaCPF IS NULL, 0, 1) + IIF(DoadorEmpresaCNPJ IS NULL, 0, 1)) = 1"); + }); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Empresa", b => + { + b.Property("CNPJ") + .HasColumnType("CHAR(14)"); + + b.Property("Ativa") + .HasColumnType("bit"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Endereco") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Nome") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("Telefone") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("CNPJ"); + + b.ToTable("Empresa", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Education1") + .HasColumnType("nvarchar(max)"); + + b.Property("Education2") + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PrimaryPhone") + .HasColumnType("nvarchar(max)"); + + b.Property("ProfessionalActivity") + .HasColumnType("nvarchar(max)"); + + b.Property("SecondaryEmail") + .HasColumnType("nvarchar(max)"); + + b.Property("SecondaryPhone") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LessonTime") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Doacao", b => + { + b.HasOne("IgescConecta.Domain.Entities.Empresa", "DoadorEmpresa") + .WithMany("DoacoesRealizadas") + .HasForeignKey("DoadorEmpresaCNPJ"); + + b.Navigation("DoadorEmpresa"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany("Projects") + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany("Teams") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Empresa", b => + { + b.Navigation("DoacoesRealizadas"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Navigation("Projects"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012190640_BaselineExisting.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012190640_BaselineExisting.cs new file mode 100644 index 00000000..9c4ec61c --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012190640_BaselineExisting.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + /// + public partial class BaselineExisting : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + // Baseline vazio: não cria/renomeia/altera nada no banco. + // Motivo: já existem objetos criados por outra pessoa/migration manual no DB + // (ex.: Empresa, Doacao, etc.). Esta migration serve apenas para “alinhar” + // o histórico do EF com o estado atual do banco. + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + // Intencionalmente vazio pelo mesmo motivo do Up(). + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012192221_AddPersonExtraFieldsOnly.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012192221_AddPersonExtraFieldsOnly.Designer.cs new file mode 100644 index 00000000..20f72885 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012192221_AddPersonExtraFieldsOnly.Designer.cs @@ -0,0 +1,1369 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251012192221_AddPersonExtraFieldsOnly")] + partial class AddPersonExtraFieldsOnly + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CNPJ") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Doacao", b => + { + b.Property("IDDoacao") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Data") + .HasColumnType("datetime2"); + + b.Property("DestinoOSCCodigo") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("DestinoTipo") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("DestinoTurmaId") + .HasColumnType("uniqueidentifier"); + + b.Property("DoadorEmpresaCNPJ") + .HasMaxLength(14) + .HasColumnType("CHAR(14)"); + + b.Property("DoadorPessoaCPF") + .HasMaxLength(11) + .HasColumnType("CHAR(11)"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Valor") + .HasColumnType("decimal(10,2)"); + + b.HasKey("IDDoacao"); + + b.HasIndex("DoadorEmpresaCNPJ"); + + b.ToTable("Doacao", null, t => + { + t.HasCheckConstraint("CHK_Doacao_DestinoExclusivo", "(IIF(DestinoTurmaId IS NULL, 0, 1) + IIF(DestinoOSCCodigo IS NULL, 0, 1)) <= 1"); + + t.HasCheckConstraint("CHK_Doacao_DoadorExclusivo", "(IIF(DoadorPessoaCPF IS NULL, 0, 1) + IIF(DoadorEmpresaCNPJ IS NULL, 0, 1)) = 1"); + }); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Empresa", b => + { + b.Property("CNPJ") + .HasColumnType("CHAR(14)"); + + b.Property("Ativa") + .HasColumnType("bit"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Endereco") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Nome") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("Telefone") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("CNPJ"); + + b.ToTable("Empresa", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Education1") + .HasColumnType("nvarchar(max)"); + + b.Property("Education2") + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PrimaryPhone") + .HasColumnType("nvarchar(max)"); + + b.Property("ProfessionalActivity") + .HasColumnType("nvarchar(max)"); + + b.Property("SecondaryEmail") + .HasColumnType("nvarchar(max)"); + + b.Property("SecondaryPhone") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LessonTime") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Doacao", b => + { + b.HasOne("IgescConecta.Domain.Entities.Empresa", "DoadorEmpresa") + .WithMany("DoacoesRealizadas") + .HasForeignKey("DoadorEmpresaCNPJ"); + + b.Navigation("DoadorEmpresa"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany("Projects") + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany("Teams") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Empresa", b => + { + b.Navigation("DoacoesRealizadas"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Navigation("Projects"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012192221_AddPersonExtraFieldsOnly.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012192221_AddPersonExtraFieldsOnly.cs new file mode 100644 index 00000000..298944a3 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012192221_AddPersonExtraFieldsOnly.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + + public partial class AddPersonExtraFieldsOnly : Migration + { + + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn("PrimaryPhone", "Persons", type: "nvarchar(max)", nullable: true); + migrationBuilder.AddColumn("SecondaryPhone", "Persons", type: "nvarchar(max)", nullable: true); + migrationBuilder.AddColumn("SecondaryEmail", "Persons", type: "nvarchar(max)", nullable: true); + migrationBuilder.AddColumn("Education1", "Persons", type: "nvarchar(max)", nullable: true); + migrationBuilder.AddColumn("Education2", "Persons", type: "nvarchar(max)", nullable: true); + migrationBuilder.AddColumn("ProfessionalActivity", "Persons", type: "nvarchar(max)", nullable: true); + } + + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn("PrimaryPhone", "Persons"); + migrationBuilder.DropColumn("SecondaryPhone", "Persons"); + migrationBuilder.DropColumn("SecondaryEmail", "Persons"); + migrationBuilder.DropColumn("Education1", "Persons"); + migrationBuilder.DropColumn("Education2", "Persons"); + migrationBuilder.DropColumn("ProfessionalActivity", "Persons"); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012194857_AddPersonIsActive.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012194857_AddPersonIsActive.Designer.cs new file mode 100644 index 00000000..abbb39d6 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012194857_AddPersonIsActive.Designer.cs @@ -0,0 +1,1372 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251012194857_AddPersonIsActive")] + partial class AddPersonIsActive + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CNPJ") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CompanyName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Doacao", b => + { + b.Property("IDDoacao") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Data") + .HasColumnType("datetime2"); + + b.Property("DestinoOSCCodigo") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("DestinoTipo") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("DestinoTurmaId") + .HasColumnType("uniqueidentifier"); + + b.Property("DoadorEmpresaCNPJ") + .HasMaxLength(14) + .HasColumnType("CHAR(14)"); + + b.Property("DoadorPessoaCPF") + .HasMaxLength(11) + .HasColumnType("CHAR(11)"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Valor") + .HasColumnType("decimal(10,2)"); + + b.HasKey("IDDoacao"); + + b.HasIndex("DoadorEmpresaCNPJ"); + + b.ToTable("Doacao", null, t => + { + t.HasCheckConstraint("CHK_Doacao_DestinoExclusivo", "(IIF(DestinoTurmaId IS NULL, 0, 1) + IIF(DestinoOSCCodigo IS NULL, 0, 1)) <= 1"); + + t.HasCheckConstraint("CHK_Doacao_DoadorExclusivo", "(IIF(DoadorPessoaCPF IS NULL, 0, 1) + IIF(DoadorEmpresaCNPJ IS NULL, 0, 1)) = 1"); + }); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Empresa", b => + { + b.Property("CNPJ") + .HasColumnType("CHAR(14)"); + + b.Property("Ativa") + .HasColumnType("bit"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Endereco") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Nome") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("Telefone") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("CNPJ"); + + b.ToTable("Empresa", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Education1") + .HasColumnType("nvarchar(max)"); + + b.Property("Education2") + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PrimaryPhone") + .HasColumnType("nvarchar(max)"); + + b.Property("ProfessionalActivity") + .HasColumnType("nvarchar(max)"); + + b.Property("SecondaryEmail") + .HasColumnType("nvarchar(max)"); + + b.Property("SecondaryPhone") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LessonTime") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Doacao", b => + { + b.HasOne("IgescConecta.Domain.Entities.Empresa", "DoadorEmpresa") + .WithMany("DoacoesRealizadas") + .HasForeignKey("DoadorEmpresaCNPJ"); + + b.Navigation("DoadorEmpresa"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany("Projects") + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany("Teams") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Empresa", b => + { + b.Navigation("DoacoesRealizadas"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Navigation("Projects"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012194857_AddPersonIsActive.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012194857_AddPersonIsActive.cs new file mode 100644 index 00000000..836b2722 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012194857_AddPersonIsActive.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + /// + public partial class AddPersonIsActive : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "IsActive", + table: "Persons", + type: "bit", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "IsActive", + table: "Persons"); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012232930_RevertDuplicatedEntities.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012232930_RevertDuplicatedEntities.Designer.cs new file mode 100644 index 00000000..6cb72324 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012232930_RevertDuplicatedEntities.Designer.cs @@ -0,0 +1,1307 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251012232930_RevertDuplicatedEntities")] + partial class RevertDuplicatedEntities + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CNPJ") + .IsRequired() + .HasMaxLength(14) + .HasColumnType("nvarchar(14)"); + + b.Property("City") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("CompanyName") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CorporateReason") + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("FieldOfActivity") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Neighborhood") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("SocialMedia") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("State") + .HasMaxLength(2) + .HasColumnType("nvarchar(2)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Website") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("ZipCode") + .HasMaxLength(8) + .HasColumnType("nvarchar(8)"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("City") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Neighborhood") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SocialMedia") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("WebUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LessonTime") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany("Donations") + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany("Teams") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Navigation("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012232930_RevertDuplicatedEntities.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012232930_RevertDuplicatedEntities.cs new file mode 100644 index 00000000..1356ed27 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251012232930_RevertDuplicatedEntities.cs @@ -0,0 +1,249 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + /// + public partial class RevertDuplicatedEntities : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Doacao"); + + migrationBuilder.DropTable( + name: "Empresa"); + + migrationBuilder.AlterColumn( + name: "CorporateReason", + table: "Companies", + type: "nvarchar(120)", + maxLength: 120, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CompanyName", + table: "Companies", + type: "nvarchar(120)", + maxLength: 120, + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + + migrationBuilder.AlterColumn( + name: "CNPJ", + table: "Companies", + type: "nvarchar(14)", + maxLength: 14, + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + + migrationBuilder.AddColumn( + name: "Address", + table: "Companies", + type: "nvarchar(200)", + maxLength: 200, + nullable: true); + + migrationBuilder.AddColumn( + name: "City", + table: "Companies", + type: "nvarchar(100)", + maxLength: 100, + nullable: true); + + migrationBuilder.AddColumn( + name: "FieldOfActivity", + table: "Companies", + type: "nvarchar(100)", + maxLength: 100, + nullable: true); + + migrationBuilder.AddColumn( + name: "IsActive", + table: "Companies", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Neighborhood", + table: "Companies", + type: "nvarchar(100)", + maxLength: 100, + nullable: true); + + migrationBuilder.AddColumn( + name: "PhoneNumber", + table: "Companies", + type: "nvarchar(20)", + maxLength: 20, + nullable: true); + + migrationBuilder.AddColumn( + name: "SocialMedia", + table: "Companies", + type: "nvarchar(255)", + maxLength: 255, + nullable: true); + + migrationBuilder.AddColumn( + name: "State", + table: "Companies", + type: "nvarchar(2)", + maxLength: 2, + nullable: true); + + migrationBuilder.AddColumn( + name: "Website", + table: "Companies", + type: "nvarchar(255)", + maxLength: 255, + nullable: true); + + migrationBuilder.AddColumn( + name: "ZipCode", + table: "Companies", + type: "nvarchar(8)", + maxLength: 8, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Address", + table: "Companies"); + + migrationBuilder.DropColumn( + name: "City", + table: "Companies"); + + migrationBuilder.DropColumn( + name: "FieldOfActivity", + table: "Companies"); + + migrationBuilder.DropColumn( + name: "IsActive", + table: "Companies"); + + migrationBuilder.DropColumn( + name: "Neighborhood", + table: "Companies"); + + migrationBuilder.DropColumn( + name: "PhoneNumber", + table: "Companies"); + + migrationBuilder.DropColumn( + name: "SocialMedia", + table: "Companies"); + + migrationBuilder.DropColumn( + name: "State", + table: "Companies"); + + migrationBuilder.DropColumn( + name: "Website", + table: "Companies"); + + migrationBuilder.DropColumn( + name: "ZipCode", + table: "Companies"); + + migrationBuilder.AlterColumn( + name: "CorporateReason", + table: "Companies", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(120)", + oldMaxLength: 120, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CompanyName", + table: "Companies", + type: "nvarchar(max)", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(120)", + oldMaxLength: 120); + + migrationBuilder.AlterColumn( + name: "CNPJ", + table: "Companies", + type: "nvarchar(max)", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(14)", + oldMaxLength: 14); + + migrationBuilder.CreateTable( + name: "Empresa", + columns: table => new + { + CNPJ = table.Column(type: "CHAR(14)", nullable: false), + Ativa = table.Column(type: "bit", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + Email = table.Column(type: "nvarchar(max)", nullable: false), + Endereco = table.Column(type: "nvarchar(max)", nullable: false), + Id = table.Column(type: "int", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false), + Nome = table.Column(type: "nvarchar(120)", maxLength: 120, nullable: false), + Telefone = table.Column(type: "nvarchar(max)", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Empresa", x => x.CNPJ); + }); + + migrationBuilder.CreateTable( + name: "Doacao", + columns: table => new + { + IDDoacao = table.Column(type: "uniqueidentifier", nullable: false), + DoadorEmpresaCNPJ = table.Column(type: "CHAR(14)", maxLength: 14, nullable: true), + CreatedAt = table.Column(type: "datetime2", nullable: false), + CreatedBy = table.Column(type: "int", nullable: false), + Data = table.Column(type: "datetime2", nullable: false), + DestinoOSCCodigo = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: true), + DestinoTipo = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: true), + DestinoTurmaId = table.Column(type: "uniqueidentifier", nullable: true), + DoadorPessoaCPF = table.Column(type: "CHAR(11)", maxLength: 11, nullable: true), + Id = table.Column(type: "int", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedBy = table.Column(type: "int", nullable: false), + Valor = table.Column(type: "decimal(10,2)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Doacao", x => x.IDDoacao); + table.CheckConstraint("CHK_Doacao_DestinoExclusivo", "(IIF(DestinoTurmaId IS NULL, 0, 1) + IIF(DestinoOSCCodigo IS NULL, 0, 1)) <= 1"); + table.CheckConstraint("CHK_Doacao_DoadorExclusivo", "(IIF(DoadorPessoaCPF IS NULL, 0, 1) + IIF(DoadorEmpresaCNPJ IS NULL, 0, 1)) = 1"); + table.ForeignKey( + name: "FK_Doacao_Empresa_DoadorEmpresaCNPJ", + column: x => x.DoadorEmpresaCNPJ, + principalTable: "Empresa", + principalColumn: "CNPJ"); + }); + + migrationBuilder.CreateIndex( + name: "IX_Doacao_DoadorEmpresaCNPJ", + table: "Doacao", + column: "DoadorEmpresaCNPJ"); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013213927_AddProjectProgramToDonation.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013213927_AddProjectProgramToDonation.Designer.cs new file mode 100644 index 00000000..490b2ac4 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013213927_AddProjectProgramToDonation.Designer.cs @@ -0,0 +1,1318 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251013213927_AddProjectProgramToDonation")] + partial class AddProjectProgramToDonation + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CNPJ") + .IsRequired() + .HasMaxLength(14) + .HasColumnType("nvarchar(14)"); + + b.Property("City") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("CompanyName") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CorporateReason") + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("FieldOfActivity") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Neighborhood") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("SocialMedia") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("State") + .HasMaxLength(2) + .HasColumnType("nvarchar(2)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Website") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("ZipCode") + .HasMaxLength(8) + .HasColumnType("nvarchar(8)"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("ProjectProgramId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("City") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Neighborhood") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SocialMedia") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("WebUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LessonTime") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany("Donations") + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("ProjectProgram"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany("Teams") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Navigation("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013213927_AddProjectProgramToDonation.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013213927_AddProjectProgramToDonation.cs new file mode 100644 index 00000000..a008d071 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013213927_AddProjectProgramToDonation.cs @@ -0,0 +1,45 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + public partial class AddProjectProgramToDonation : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ProjectProgramId", + table: "Donations", + type: "int", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Donations_ProjectProgramId", + table: "Donations", + column: "ProjectProgramId"); + + migrationBuilder.AddForeignKey( + name: "FK_Donations_ProjectPrograms_ProjectProgramId", + table: "Donations", + column: "ProjectProgramId", + principalTable: "ProjectPrograms", + principalColumn: "Id"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Donations_ProjectPrograms_ProjectProgramId", + table: "Donations"); + + migrationBuilder.DropIndex( + name: "IX_Donations_ProjectProgramId", + table: "Donations"); + + migrationBuilder.DropColumn( + name: "ProjectProgramId", + table: "Donations"); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013221439_UpdateDonationWithCourseFK.Designer.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013221439_UpdateDonationWithCourseFK.Designer.cs new file mode 100644 index 00000000..8bdbd956 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013221439_UpdateDonationWithCourseFK.Designer.cs @@ -0,0 +1,1318 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251013221439_UpdateDonationWithCourseFK")] + partial class UpdateDonationWithCourseFK + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CNPJ") + .IsRequired() + .HasMaxLength(14) + .HasColumnType("nvarchar(14)"); + + b.Property("City") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("CompanyName") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CorporateReason") + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("FieldOfActivity") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Neighborhood") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("SocialMedia") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("State") + .HasMaxLength(2) + .HasColumnType("nvarchar(2)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Website") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("ZipCode") + .HasMaxLength(8) + .HasColumnType("nvarchar(8)"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("CourseId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("City") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Neighborhood") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SocialMedia") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("WebUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LessonTime") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany("Donations") + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Course"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany("Teams") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Navigation("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013221439_UpdateDonationWithCourseFK.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013221439_UpdateDonationWithCourseFK.cs new file mode 100644 index 00000000..4cd4ef56 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/20251013221439_UpdateDonationWithCourseFK.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + /// + public partial class UpdateDonationWithCourseFK : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/ApplicationDbContextModelSnapshot.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/ApplicationDbContextModelSnapshot.cs new file mode 100644 index 00000000..02e9bf62 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Migrations/ApplicationDbContextModelSnapshot.cs @@ -0,0 +1,1336 @@ +// +using System; +using IgescConecta.API.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace IgescConecta.API.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + partial class ApplicationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.Property("BeneficiariesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("BeneficiariesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("BeneficiaryOsc"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Beneficiary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Beneficiaries"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CNPJ") + .IsRequired() + .HasMaxLength(14) + .HasColumnType("nvarchar(14)"); + + b.Property("City") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("CompanyName") + .IsRequired() + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CorporateReason") + .HasMaxLength(120) + .HasColumnType("nvarchar(120)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("FieldOfActivity") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Neighborhood") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("SocialMedia") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("State") + .HasMaxLength(2) + .HasColumnType("nvarchar(2)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Website") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("ZipCode") + .HasMaxLength(8) + .HasColumnType("nvarchar(8)"); + + b.HasKey("Id"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("DonationDate") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("CourseId"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BusinessCaseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessCaseId"); + + b.ToTable("OriginBusinessCases"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Osc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("City") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CorporateName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Neighborhood") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Objective") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscPrimaryDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SocialMedia") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("State") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("WebUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Oscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Education1") + .HasColumnType("nvarchar(max)"); + + b.Property("Education2") + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PersonalDocumment") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PrimaryPhone") + .HasColumnType("nvarchar(max)"); + + b.Property("ProfessionalActivity") + .HasColumnType("nvarchar(max)"); + + b.Property("SecondaryEmail") + .HasColumnType("nvarchar(max)"); + + b.Property("SecondaryPhone") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CompanyId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCompanies"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonOscs"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MemberTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("PersonId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("PersonId"); + + b.HasIndex("TeamId"); + + b.ToTable("PersonTeams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectDocuments"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Decision") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OdsTypes") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("OscId") + .HasColumnType("int"); + + b.Property("ProjectDocumentId") + .HasColumnType("int"); + + b.Property("ProjectThemeId") + .HasColumnType("int"); + + b.Property("ProjectTypeId") + .HasColumnType("int"); + + b.Property("TeamId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OscId"); + + b.HasIndex("ProjectDocumentId"); + + b.HasIndex("ProjectThemeId"); + + b.HasIndex("ProjectTypeId"); + + b.HasIndex("TeamId"); + + b.ToTable("ProjectPrograms"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectTheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectThemes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ProjectTypes"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("Roles", (string)null); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LessonTime") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectProgramId") + .HasColumnType("int"); + + b.Property("Start") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("ProjectProgramId"); + + b.ToTable("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedBy") + .HasColumnType("int"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UpdatedBy") + .HasColumnType("int"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedBy"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("Users", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("UserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("UserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("UserTokens", (string)null); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.Property("OriginsBusinessCasesId") + .HasColumnType("int"); + + b.Property("OscsId") + .HasColumnType("int"); + + b.HasKey("OriginsBusinessCasesId", "OscsId"); + + b.HasIndex("OscsId"); + + b.ToTable("OriginBusinessCaseOsc"); + }); + + modelBuilder.Entity("BeneficiaryOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Beneficiary", null) + .WithMany() + .HasForeignKey("BeneficiariesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Donation", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany("Donations") + .HasForeignKey("CompanyId"); + + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId"); + + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany() + .HasForeignKey("PersonId"); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId"); + + b.Navigation("Company"); + + b.Navigation("Course"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.OriginBusinessCase", b => + { + b.HasOne("IgescConecta.Domain.Entities.BusinessCase", "BusinessCase") + .WithMany("Origins") + .HasForeignKey("BusinessCaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BusinessCase"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonCompany", b => + { + b.HasOne("IgescConecta.Domain.Entities.Company", "Company") + .WithMany() + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Companies") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Oscs") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", null) + .WithMany("PersonOscs") + .HasForeignKey("TeamId"); + + b.Navigation("Osc"); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.PersonTeam", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId"); + + b.HasOne("IgescConecta.Domain.Entities.Person", "Person") + .WithMany("Teams") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany("PersonTeams") + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("Person"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.ProjectProgram", b => + { + b.HasOne("IgescConecta.Domain.Entities.Osc", "Osc") + .WithMany() + .HasForeignKey("OscId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectDocument", "ProjectDocument") + .WithMany() + .HasForeignKey("ProjectDocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectType", "ProjectType") + .WithMany() + .HasForeignKey("ProjectThemeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectTheme", "ProjectTheme") + .WithMany() + .HasForeignKey("ProjectTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Team", "Team") + .WithMany() + .HasForeignKey("TeamId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Osc"); + + b.Navigation("ProjectDocument"); + + b.Navigation("ProjectTheme"); + + b.Navigation("ProjectType"); + + b.Navigation("Team"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.HasOne("IgescConecta.Domain.Entities.Course", "Course") + .WithMany("Teams") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.ProjectProgram", "ProjectProgram") + .WithMany() + .HasForeignKey("ProjectProgramId"); + + b.Navigation("Course"); + + b.Navigation("ProjectProgram"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.User", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", "CreatedByUser") + .WithMany() + .HasForeignKey("CreatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("IgescConecta.Domain.Entities.User", "UpdatedByUser") + .WithMany() + .HasForeignKey("UpdatedBy") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("CreatedByUser"); + + b.Navigation("UpdatedByUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("IgescConecta.Domain.Entities.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("IgescConecta.Domain.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OriginBusinessCaseOsc", b => + { + b.HasOne("IgescConecta.Domain.Entities.OriginBusinessCase", null) + .WithMany() + .HasForeignKey("OriginsBusinessCasesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("IgescConecta.Domain.Entities.Osc", null) + .WithMany() + .HasForeignKey("OscsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.BusinessCase", b => + { + b.Navigation("Origins"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Company", b => + { + b.Navigation("Donations"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Course", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Person", b => + { + b.Navigation("Companies"); + + b.Navigation("Oscs"); + + b.Navigation("Teams"); + }); + + modelBuilder.Entity("IgescConecta.Domain.Entities.Team", b => + { + b.Navigation("PersonOscs"); + + b.Navigation("PersonTeams"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Program.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Program.cs new file mode 100644 index 00000000..40e52bcc --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Program.cs @@ -0,0 +1,94 @@ +using IgescConecta.API.Common.Extensions; +using IgescConecta.API.Common.Options; +using IgescConecta.API.Data; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.IdentityModel.Tokens; +using System.Text; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers(); +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerDocumentation(); + +// DbContext (Azure SQL via DefaultConnection) +builder.Services.AddDbContextIgesc(builder.Configuration); + +builder.Services.AddIdentity(); +builder.Services.AddServices(builder.Configuration); + +builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(AppDomain.CurrentDomain.GetAssemblies())); +builder.Services.AddSingleton(_ => TimeProvider.System); +builder.Services.AddDataProtection(); + + +var jwtSection = builder.Configuration.GetSection("Jwt"); +var jwtIssuer = jwtSection.GetValue("JwtIssuer") + ?? throw new InvalidOperationException("Missing config: Jwt:JwtIssuer"); +var jwtAudience = jwtSection.GetValue("JwtAudience") + ?? throw new InvalidOperationException("Missing config: Jwt:JwtAudience"); +var jwtKeyString = jwtSection.GetValue("JwtSecurityKey") + ?? throw new InvalidOperationException("Missing config: Jwt:JwtSecurityKey"); +var jwtKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKeyString)); + +builder.Services + .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(opt => + { + opt.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidateAudience = true, + ValidIssuer = jwtIssuer, + ValidAudience = jwtAudience, + ValidateIssuerSigningKey = true, + IssuerSigningKey = jwtKey, + ClockSkew = TimeSpan.Zero + }; + }); + +builder.Services.Configure(builder.Configuration.GetSection("Frontend")); + +// ---------- CORS ---------- +builder.Services.AddCors(options => +{ + options.AddPolicy("Frontend", p => + p.WithOrigins( + "http://localhost:3000", + "http://localhost:5173" + ) + .AllowAnyHeader() + .AllowAnyMethod() + // .AllowCredentials() // só se usar cookies + ); +}); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseMigrationsEndPoint(); +} + +// ---------- Swagger com feature flag ---------- +var enableSwagger = app.Configuration.GetValue("Swagger:Enabled", true); +if (enableSwagger) +{ + app.UseSwagger(); + app.UseSwaggerUI(c => + { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "IGESC API v1"); + }); +} + +app.UseHttpsRedirection(); +app.UseCors("Frontend"); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.MapControllers(); + +app.SeedDatabase(app.Environment.IsDevelopment()); + +app.Run(); diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Properties/ServiceDependencies/IGESC - Zip Deploy/profile.arm.json b/codigo-fonte/IgescConecta.API/IgescConecta.API/Properties/ServiceDependencies/IGESC - Zip Deploy/profile.arm.json new file mode 100644 index 00000000..bd01b205 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Properties/ServiceDependencies/IGESC - Zip Deploy/profile.arm.json @@ -0,0 +1,173 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_dependencyType": "compute.function.linux.appService" + }, + "parameters": { + "resourceGroupName": { + "type": "string", + "defaultValue": "IGESC", + "metadata": { + "description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking." + } + }, + "resourceGroupLocation": { + "type": "string", + "defaultValue": "brazilsouth", + "metadata": { + "description": "Location of the resource group. Resource groups could have different location than resources, however by default we use API versions from latest hybrid profile which support all locations for resource types we support." + } + }, + "resourceName": { + "type": "string", + "defaultValue": "IGESC", + "metadata": { + "description": "Name of the main resource to be created by this template." + } + }, + "resourceLocation": { + "type": "string", + "defaultValue": "[parameters('resourceGroupLocation')]", + "metadata": { + "description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there." + } + } + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('resourceGroupLocation')]", + "apiVersion": "2019-10-01" + }, + { + "type": "Microsoft.Resources/deployments", + "name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "apiVersion": "2019-10-01", + "dependsOn": [ + "[parameters('resourceGroupName')]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "parameters": { + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "resourceGroupLocation": { + "value": "[parameters('resourceGroupLocation')]" + }, + "resourceName": { + "value": "[parameters('resourceName')]" + }, + "resourceLocation": { + "value": "[parameters('resourceLocation')]" + } + }, + "template": { + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string" + }, + "resourceGroupLocation": { + "type": "string" + }, + "resourceName": { + "type": "string" + }, + "resourceLocation": { + "type": "string" + } + }, + "variables": { + "storage_name": "[toLower(concat('storage', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId))))]", + "appServicePlan_name": "[concat('Plan', uniqueString(concat(parameters('resourceName'), subscription().subscriptionId)))]", + "storage_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Storage/storageAccounts/', variables('storage_name'))]", + "appServicePlan_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/serverFarms/', variables('appServicePlan_name'))]", + "function_ResourceId": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('resourceGroupName'), '/providers/Microsoft.Web/sites/', parameters('resourceName'))]" + }, + "resources": [ + { + "location": "[parameters('resourceLocation')]", + "name": "[parameters('resourceName')]", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "tags": { + "[concat('hidden-related:', variables('appServicePlan_ResourceId'))]": "empty" + }, + "dependsOn": [ + "[variables('appServicePlan_ResourceId')]", + "[variables('storage_ResourceId')]" + ], + "kind": "functionapp", + "properties": { + "name": "[parameters('resourceName')]", + "kind": "functionapp", + "httpsOnly": true, + "reserved": false, + "serverFarmId": "[variables('appServicePlan_ResourceId')]", + "siteConfig": { + "alwaysOn": true, + "linuxFxVersion": "dotnet|3.1" + } + }, + "identity": { + "type": "SystemAssigned" + }, + "resources": [ + { + "name": "appsettings", + "type": "config", + "apiVersion": "2015-08-01", + "dependsOn": [ + "[variables('function_ResourceId')]" + ], + "properties": { + "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storage_name'), ';AccountKey=', listKeys(variables('storage_ResourceId'), '2017-10-01').keys[0].value, ';EndpointSuffix=', 'core.windows.net')]", + "FUNCTIONS_EXTENSION_VERSION": "~3", + "FUNCTIONS_WORKER_RUNTIME": "dotnet" + } + } + ] + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('storage_name')]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2017-10-01", + "tags": { + "[concat('hidden-related:', concat('/providers/Microsoft.Web/sites/', parameters('resourceName')))]": "empty" + }, + "properties": { + "supportsHttpsTrafficOnly": true + }, + "sku": { + "name": "Standard_LRS" + }, + "kind": "Storage" + }, + { + "location": "[parameters('resourceGroupLocation')]", + "name": "[variables('appServicePlan_name')]", + "type": "Microsoft.Web/serverFarms", + "apiVersion": "2015-02-01", + "kind": "linux", + "properties": { + "name": "[variables('appServicePlan_name')]", + "sku": "Standard", + "workerSizeId": "0", + "reserved": true + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Properties/launchSettings.json b/codigo-fonte/IgescConecta.API/IgescConecta.API/Properties/launchSettings.json new file mode 100644 index 00000000..20fc7b67 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:15149", + "sslPort": 44323 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5249", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7201;http://localhost:5249", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/AuthAuthenticatonService.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/AuthAuthenticatonService.cs new file mode 100644 index 00000000..eaf1f524 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/AuthAuthenticatonService.cs @@ -0,0 +1,120 @@ +using IgescConecta.Domain.Entities; +using Microsoft.AspNetCore.Identity; +using Microsoft.IdentityModel.Tokens; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; + +namespace IgescConecta.API.Services +{ + public class AuthAuthenticatonService : IAuthAuthenticatonService + { + private readonly UserManager _userManager; + private readonly IConfiguration _configuration; + + public AuthAuthenticatonService(UserManager userManager, IConfiguration configuration) + { + _userManager = userManager; + _configuration = configuration; + } + + public async Task BuildToken(User user) + { + var roles = await _userManager.GetRolesAsync(user); + var role = roles.FirstOrDefault(); + + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier,user.Id.ToString()), + new Claim(ClaimTypes.Email, user.Email!), + new Claim(ClaimTypes.Role, role ?? string.Empty), + new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) + }; + + var keyStr = _configuration.GetValue("Jwt:JwtSecurityKey") + ?? throw new InvalidOperationException("Missing Jwt:JwtSecurityKey"); + var issuer = _configuration.GetValue("Jwt:JwtIssuer") + ?? throw new InvalidOperationException("Missing Jwt:JwtIssuer"); + var audience = _configuration.GetValue("Jwt:JwtAudience") + ?? throw new InvalidOperationException("Missing Jwt:JwtAudience"); + var minutes = _configuration.GetValue("Jwt:ExpiryMinutes") ?? 600; + + var creds = new SigningCredentials( + new SymmetricSecurityKey(Encoding.UTF8.GetBytes(keyStr)), + SecurityAlgorithms.HmacSha256); + + var expiration = DateTime.UtcNow.AddMinutes(minutes); + + var token = new JwtSecurityToken( + issuer: issuer, + audience: audience, + claims: claims, + expires: expiration, + signingCredentials: creds + ); + + var refreshToken = GenerateRefreshToken(); + + return new UserToken + { + AccessToken = new JwtSecurityTokenHandler().WriteToken(token), + RefresfToken = refreshToken, + ExpiresIn = expiration + }; + } + + + public ClaimsPrincipal? GetPrincipalFromExpiredToken(string? token) + { + var tokenValidationParameters = new TokenValidationParameters + { + ValidateAudience = false, + ValidateIssuer = false, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:JwtSecurityKey"])), + ValidateLifetime = false + }; + + var tokenHandler = new JwtSecurityTokenHandler(); + + var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken securityToken); + + if(securityToken is not JwtSecurityToken jwtSecurityToken || + !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) + throw new SecurityTokenArgumentException("Token inválido"); + + return principal; + } + + public JwtSecurityToken CreateToken(List authClaims) + { + var keyStr = _configuration.GetValue("Jwt:JwtSecurityKey") + ?? throw new InvalidOperationException("Missing Jwt:JwtSecurityKey"); + var issuer = _configuration.GetValue("Jwt:JwtIssuer") + ?? throw new InvalidOperationException("Missing Jwt:JwtIssuer"); + var audience = _configuration.GetValue("Jwt:JwtAudience") + ?? throw new InvalidOperationException("Missing Jwt:JwtAudience"); + var minutes = _configuration.GetValue("Jwt:ExpiryMinutes") ?? 600; + + var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(keyStr)); + + return new JwtSecurityToken( + issuer: issuer, + audience: audience, + expires: DateTime.UtcNow.AddMinutes(minutes), + claims: authClaims, + signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256) + ); + } + + + public string GenerateRefreshToken() + { + var randomNumber = new byte[64]; + using var rng = RandomNumberGenerator.Create(); + rng.GetBytes(randomNumber); + return Convert.ToBase64String(randomNumber); + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/ConsoleEmailService.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/ConsoleEmailService.cs new file mode 100644 index 00000000..5ce9ef74 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/ConsoleEmailService.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Logging; +using System.Threading.Tasks; + +namespace IgescConecta.API.Services +{ + // Implementação simples: registra no log o link de redefinição + public class ConsoleEmailService : IEmailService + { + private readonly ILogger _logger; + public ConsoleEmailService(ILogger logger) => _logger = logger; + + public Task SendPasswordResetLinkAsync(string toEmail, string resetLink) + { + _logger.LogInformation("Link de redefinição de senha para {Email}: {Link}", toEmail, resetLink); + return Task.CompletedTask; + } + } +} + diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/IAuthAuthenticatonService.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/IAuthAuthenticatonService.cs new file mode 100644 index 00000000..ab4de63b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/IAuthAuthenticatonService.cs @@ -0,0 +1,14 @@ +using IgescConecta.Domain.Entities; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; + +namespace IgescConecta.API.Services +{ + public interface IAuthAuthenticatonService + { + Task BuildToken(User user); + ClaimsPrincipal? GetPrincipalFromExpiredToken(string? token); + JwtSecurityToken CreateToken(List authClaims); + string GenerateRefreshToken(); + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/IEmailService.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/IEmailService.cs new file mode 100644 index 00000000..054bcf43 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/IEmailService.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace IgescConecta.API.Services +{ + public interface IEmailService + { + Task SendPasswordResetLinkAsync(string toEmail, string resetLink); + } +} + diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/SmtpEmailService.cs b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/SmtpEmailService.cs new file mode 100644 index 00000000..80cfa884 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/Services/SmtpEmailService.cs @@ -0,0 +1,194 @@ +using System.Net; +using System.Net.Mail; +using System.Net.Mime; +using System.Text; +using IgescConecta.API.Common.Options; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace IgescConecta.API.Services +{ + public class SmtpEmailService : IEmailService + { + private readonly IOptions _smtpOpt; + private readonly ILogger _logger; + private readonly IConfiguration _cfg; // para ler Smtp:User/Password de variável de ambiente + + public SmtpEmailService( + IOptions smtpOpt, + ILogger logger, + IConfiguration cfg) + { + _smtpOpt = smtpOpt; + _logger = logger; + _cfg = cfg; + } + + public async Task SendPasswordResetLinkAsync(string toEmail, string resetLink) + { + var o = _smtpOpt.Value; + + // Lê segredos de ambiente (IIS/Windows), não do appsettings.json + var user = _cfg["Smtp:User"] ?? _cfg["Smtp__User"]; + var pass = _cfg["Smtp:Password"] ?? _cfg["Smtp__Password"]; + + using var client = new SmtpClient(o.Host, o.Port) + { + EnableSsl = o.UseSsl, + Credentials = (string.IsNullOrWhiteSpace(user) || string.IsNullOrWhiteSpace(pass)) + ? CredentialCache.DefaultNetworkCredentials + : new NetworkCredential(user, pass) + }; + + var fromName = _cfg["Email:FromName"] ?? "IGESC Conecta"; + var fromEmail = _cfg["Email:FromEmail"] ?? "no-reply@igesc.org"; + var subject = "IGESC Conecta – Redefinição de senha"; + + // Paleta IGESC + const string AzulClaro = "#1E4EC4"; + const string AzulEscuro = "#264197"; + const string VerdeAcao = "#21AD53"; + const string CinzaClaro = "#F6F6F7"; + const string CinzaEscuro = "#656D77"; + + // Corpo texto (fallback) + var plainText = $@"Olá, + +Recebemos uma solicitação para redefinir sua senha no IGESC Conecta. +Para continuar, acesse o link abaixo (ou copie e cole no navegador): + +{resetLink} + +Se você não fez essa solicitação, pode ignorar este e-mail. + +Atenciosamente, +Equipe IGESC Conecta"; + + // Logo via CID (Content-ID) + var logoCid = "logo_igesc"; + + // HTML com identidade visual + var html = $@" + + + + + {subject} + + + + + + +
+ +
+ + + + + +
+ + + + + + + + + + +
+

Redefinição de senha

+

+ Recebemos uma solicitação para redefinir sua senha no IGESC Conecta. +

+
+

+ Para continuar, clique no botão abaixo: +

+

+ + Redefinir senha + +

+

+ Se o botão não funcionar, copie e cole este link no navegador: +

+

+ {resetLink} +

+

+ Se você não fez essa solicitação, pode ignorar este e-mail. +

+
+ Atenciosamente,
Equipe IGESC Conecta +
+

+ Este é um e-mail automático, por favor não responda. +

+
+ +"; + + // Monta a mensagem com HTML + texto + using var msg = new MailMessage + { + From = new MailAddress(fromEmail, fromName), + Subject = subject, + SubjectEncoding = Encoding.UTF8, + BodyEncoding = Encoding.UTF8, + HeadersEncoding = Encoding.UTF8, + IsBodyHtml = true + }; + msg.To.Add(toEmail); + + // Alternate views (text/plain + text/html) + msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(plainText, Encoding.UTF8, "text/plain")); + + var htmlView = AlternateView.CreateAlternateViewFromString(html, Encoding.UTF8, MediaTypeNames.Text.Html); + + // Anexa a logo como LinkedResource (CID) + var logoPathCfg = _cfg["Email:LogoPath"]; // wwwroot/email/logo-igesc.png + string? logoPath = null; + if (!string.IsNullOrWhiteSpace(logoPathCfg)) + { + logoPath = Path.IsPathRooted(logoPathCfg) + ? logoPathCfg + : Path.Combine(AppContext.BaseDirectory, logoPathCfg); + } + + // (Opcional) log para diagnosticar caminho e existência + _logger.LogInformation("Email logo path resolvido: {Path} (existe? {Exists})", + logoPath, !string.IsNullOrWhiteSpace(logoPath) && File.Exists(logoPath)); + + + if (!string.IsNullOrWhiteSpace(logoPath) && File.Exists(logoPath)) + { + var logo = new LinkedResource(logoPath, "image/png") + { + ContentId = logoCid, + TransferEncoding = TransferEncoding.Base64, + }; + htmlView.LinkedResources.Add(logo); + } + + msg.AlternateViews.Add(htmlView); + + + try + { + await client.SendMailAsync(msg); + _logger.LogInformation("E-mail de redefinição enviado para {Email}", toEmail); + } + catch (SmtpException ex) + { + _logger.LogError(ex, "Falha ao enviar e-mail de redefinição para {Email}", toEmail); + throw; + } + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/appsettings.Development.json b/codigo-fonte/IgescConecta.API/IgescConecta.API/appsettings.Development.json new file mode 100644 index 00000000..0c208ae9 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/appsettings.json b/codigo-fonte/IgescConecta.API/IgescConecta.API/appsettings.json new file mode 100644 index 00000000..51acbbae --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.API/appsettings.json @@ -0,0 +1,33 @@ +{ + "Jwt": { + "JwtSecurityKey": "xbe)<(:WvWk\\%X.+Nz73],Xi£Zc>J'9f>", + "JwtIssuer": "https://localhost/", + "JwtAudience": "https://localhost/", + "ExpiryMinutes": 600 + }, + "ConnectionStrings": { + "DefaultConnection": "Server=tcp:sqlserver-ricardo.database.windows.net,1433;Initial Catalog=igesc;Persist Security Info=False;User ID=rjtsjr;Password=Nmh@132725;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" + }, + "Frontend": { + "ResetPasswordUrlTemplate": "http://localhost:3000/reset-password?uid={uid}&token={token}" + }, + "Email": { + "Provider": "Smtp", // Dev | Smtp + "FromName": "IGESC Conecta", + "FromEmail": "igescconecta@gmail.com", + "LogoPath": "wwwroot/email/logo-gesc.png" + }, + "Smtp": { + "Host": "smtp.gmail.com", // Dev: smtp4dev/Papercut • Prod: smtp.seuprovedor.com + "Port": 587, // Dev: 2525 • Prod: 587 + "UseSsl": true // Dev: false • Prod: true + // Variáveis que precisam ser criadas em variáveis de ambiente no IIS (produção) ou no Windows (dev): Smtp__User ou Smtp__Password + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.API/wwwroot/email/logo-gesc.png b/codigo-fonte/IgescConecta.API/IgescConecta.API/wwwroot/email/logo-gesc.png new file mode 100644 index 00000000..31ace48b Binary files /dev/null and b/codigo-fonte/IgescConecta.API/IgescConecta.API/wwwroot/email/logo-gesc.png differ diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Beneficiary.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Beneficiary.cs new file mode 100644 index 00000000..9c313c5d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Beneficiary.cs @@ -0,0 +1,19 @@ +using IgescConecta.Domain.Enums; +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class Beneficiary : BaseEntity + { + public string Name { get; set; } + + public string Notes { get; set; } + + public ICollection? Oscs { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/BusinessCase.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/BusinessCase.cs new file mode 100644 index 00000000..809382ac --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/BusinessCase.cs @@ -0,0 +1,16 @@ +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class BusinessCase : BaseEntity + { + public string Name { get; set; } + + public ICollection? Origins { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Company.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Company.cs new file mode 100644 index 00000000..fff49f40 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Company.cs @@ -0,0 +1,53 @@ +using IgescConecta.Domain.Shared; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace IgescConecta.Domain.Entities +{ + public class Company : BaseEntity + { + [Required] + [StringLength(120)] + public string CompanyName { get; set; } = string.Empty; + + [StringLength(120)] + public string? CorporateReason { get; set; } + + [Required] + [StringLength(14)] + public string CNPJ { get; set; } = string.Empty; + + + [StringLength(100)] + public string? FieldOfActivity { get; set; } + + [StringLength(8)] + public string? ZipCode { get; set; } + + [StringLength(200)] + public string? Address { get; set; } + + [StringLength(100)] + public string? Neighborhood { get; set; } + + [StringLength(100)] + public string? City { get; set; } + + [StringLength(2)] + public string? State { get; set; } + + [StringLength(20)] + public string? PhoneNumber { get; set; } + + [StringLength(255)] + public string? Website { get; set; } + + [StringLength(255)] + public string? SocialMedia { get; set; } + + public bool IsActive { get; set; } = true; + + + public ICollection Donations { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Course.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Course.cs new file mode 100644 index 00000000..37ed730a --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Course.cs @@ -0,0 +1,16 @@ +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class Course : BaseEntity + { + public string? Name { get; set; } + public ICollection Teams { get; set; } = new List(); + + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Donation.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Donation.cs new file mode 100644 index 00000000..1e35cebd --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Donation.cs @@ -0,0 +1,33 @@ +using IgescConecta.Domain.Shared; +using System.ComponentModel.DataAnnotations.Schema; + +namespace IgescConecta.Domain.Entities +{ + public class Donation : BaseEntity + { + public decimal Value { get; set; } + public DateTime DonationDate { get; set; } + + public int? PersonId { get; set; } + public int? CompanyId { get; set; } + + public int? OscId { get; set; } + public int? CourseId { get; set; } + public int? TeamId { get; set; } + + [ForeignKey("PersonId")] + public Person? Person { get; set; } + + [ForeignKey("CompanyId")] + public Company? Company { get; set; } + + [ForeignKey("OscId")] + public Osc? Osc { get; set; } + + [ForeignKey("CourseId")] + public Course? Course { get; set; } + + [ForeignKey("TeamId")] + public Team? Team { get; set; } + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Empresa.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Empresa.cs new file mode 100644 index 00000000..932499fb --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Empresa.cs @@ -0,0 +1,41 @@ +// Arquivo: IgescConecta.Domain/Entities/Empresa.cs +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using IgescConecta.Domain.Shared; + +namespace IgescConecta.Domain.Entities +{ + [Table("Empresa")] + public class Empresa : BaseEntity + { + // Chave de Negcio (CNPJ - Deve ser nico) + [Key] + [Column(TypeName = "CHAR(14)")] + public string CNPJ { get; set; } = string.Empty; + + // CAMPOS DO CLIENTE: + [Required] + [StringLength(120)] + public string Nome { get; set; } = string.Empty; + + [Required] + [StringLength(120)] + public string RazaoSocial { get; set; } = string.Empty; + + public string AreaAtuacao { get; set; } = string.Empty; + public string CEP { get; set; } = string.Empty; + public string Endereco { get; set; } = string.Empty; + public string Bairro { get; set; } = string.Empty; + public string Cidade { get; set; } = string.Empty; + public string UF { get; set; } = string.Empty; + public string Telefone { get; set; } = string.Empty; + public string Site { get; set; } = string.Empty; + public string RedesSociais { get; set; } = string.Empty; + + public bool Ativa { get; set; } = true; + + public ICollection DoacoesRealizadas { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/OriginBusinessCase.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/OriginBusinessCase.cs new file mode 100644 index 00000000..2a0c9cef --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/OriginBusinessCase.cs @@ -0,0 +1,24 @@ +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class OriginBusinessCase : BaseEntity + { + public string Name { get; set; } + + public string Notes { get; set; } + + public int BusinessCaseId { get; set; } + + public ICollection? Oscs { get; set; } + + [ForeignKey("BusinessCaseId")] + public BusinessCase BusinessCase { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Osc.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Osc.cs new file mode 100644 index 00000000..9925ca5b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Osc.cs @@ -0,0 +1,44 @@ +using IgescConecta.Domain.Primitives; +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class Osc : BaseEntity + { + public string Name { get; set; } + + public string Objective { get; set; } + + public string CorporateName { get; set; } + + public string Address { get; set; } + + public string Neighborhood { get; set; } + + public string City { get; set; } + + public string State { get; set; } + + public string PhoneNumber { get; set; } + + public string Email { get; set; } + + public string WebUrl { get; set; } + + public string SocialMedia { get; set; } + + public string ZipCode { get; set; } + + public string OscPrimaryDocumment { get; set; } + + public ICollection? OriginsBusinessCases { get; set; } + + public ICollection? Beneficiaries { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Person.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Person.cs new file mode 100644 index 00000000..e681a446 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Person.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using IgescConecta.Domain.Shared; + +namespace IgescConecta.Domain.Entities +{ + public class Person : BaseEntity + { + public string Name { get; set; } + + public string Email { get; set; } + + public string PersonalDocumment { get; set; } + + public string? SecondaryEmail { get; set; } + public string? PrimaryPhone { get; set; } + public string? SecondaryPhone { get; set; } + public string? Education1 { get; set; } + public string? Education2 { get; set; } + public string? ProfessionalActivity { get; set; } + public bool IsActive { get; set; } = true; + + public ICollection? Teams { get; set; } + public ICollection? Oscs { get; set; } + public ICollection? Companies { get; set; } + + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PersonCompany.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PersonCompany.cs new file mode 100644 index 00000000..6516073b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PersonCompany.cs @@ -0,0 +1,23 @@ +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class PersonCompany : BaseEntity + { + public int PersonId { get; set; } + + public int CompanyId { get; set; } + + [ForeignKey("PersonId")] + public Person Person { get; set; } + + [ForeignKey("CompanyId")] + public Company Company { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PersonOsc.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PersonOsc.cs new file mode 100644 index 00000000..5c1ab7d3 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PersonOsc.cs @@ -0,0 +1,24 @@ +using IgescConecta.Domain.Enums; +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class PersonOsc : BaseEntity + { + public int PersonId { get; set; } + + public int OscId { get; set; } + + [ForeignKey("PersonId")] + public Person Person { get; set; } + + [ForeignKey("OscId")] + public Osc Osc { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PersonTeam.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PersonTeam.cs new file mode 100644 index 00000000..a13bc45e --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PersonTeam.cs @@ -0,0 +1,30 @@ +using IgescConecta.Domain.Enums; +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class PersonTeam : BaseEntity + { + public IList MemberTypes { get; set; } = new List(); + public int PersonId { get; set; } + + public int TeamId { get; set; } + + public int? OscId { get; set; } + + [ForeignKey("PersonId")] + public Person Person { get; set; } + + [ForeignKey("TeamId")] + public Team Team { get; set; } + + [ForeignKey("OscId")] + public Osc? Osc { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PessoaEmpresa.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PessoaEmpresa.cs new file mode 100644 index 00000000..74e477f2 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/PessoaEmpresa.cs @@ -0,0 +1,29 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace IgescConecta.Domain.Entities +{ + [Table("PessoaEmpresa")] + public class PessoaEmpresa + { + // Chave Estrangeira 1 (FK) - CPF da Pessoa (Representante) + [Column(TypeName = "CHAR(11)")] + [Required] + public string PessoaCPF { get; set; } = string.Empty; + + // Chave Estrangeira 2 (FK) - CNPJ da Empresa + [Column(TypeName = "CHAR(14)")] + [Required] + public string EmpresaCNPJ { get; set; } = string.Empty; + + // Atributo que complementa a chave composta (Restrição 11 e 13) + [StringLength(20)] + [Required] + public string Papel { get; set; } = string.Empty; + + // Propriedades de navegação: + + // public Pessoa Pessoa { get; set; } = null!; // Depende da classe Pessoa + public Empresa Empresa { get; set; } = null!; + } +} \ No newline at end of file diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectDocument.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectDocument.cs new file mode 100644 index 00000000..33473d19 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectDocument.cs @@ -0,0 +1,16 @@ +using IgescConecta.Domain.Enums; +using IgescConecta.Domain.Shared; +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class ProjectDocument : BaseEntity + { + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectProgram.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectProgram.cs new file mode 100644 index 00000000..d5af698b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectProgram.cs @@ -0,0 +1,46 @@ +using IgescConecta.Domain.Enums; +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class ProjectProgram : BaseEntity + { + public string Name { get; set; } + + public IList OdsTypes { get; set; } = new List(); + + public ProjectDecisionType Decision { get; set; } + + public int ProjectThemeId { get; set; } + + public int ProjectTypeId { get; set; } + + public int TeamId { get; set; } + + public int OscId { get; set; } + + public int ProjectDocumentId { get; set; } + + [ForeignKey("ProjectTypeId")] + public ProjectTheme ProjectTheme { get; set; } + + [ForeignKey("ProjectThemeId")] + public ProjectType ProjectType { get; set; } + + [ForeignKey("TeamId")] + public Team Team { get; set; } + + [ForeignKey("OscId")] + public Osc Osc { get; set; } + + [ForeignKey("ProjectDocumentId")] + public ProjectDocument ProjectDocument { get; set; } + + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectTheme.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectTheme.cs new file mode 100644 index 00000000..6177268f --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectTheme.cs @@ -0,0 +1,14 @@ +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class ProjectTheme : BaseEntity + { + public string Name { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectType.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectType.cs new file mode 100644 index 00000000..072fe05b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/ProjectType.cs @@ -0,0 +1,14 @@ +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class ProjectType : BaseEntity + { + public string Name { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Role.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Role.cs new file mode 100644 index 00000000..aa2ec139 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Role.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Identity; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class Role : IdentityRole + { + public Role() + { + + } + + public Role(string roleName) + { + this.Name = roleName; + } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Team.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Team.cs new file mode 100644 index 00000000..6ed7c97b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/Team.cs @@ -0,0 +1,36 @@ +using IgescConecta.Domain.Shared; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; + + +namespace IgescConecta.Domain.Entities +{ + public class Team : BaseEntity + { + public string? Name { get; set; } + public string? LessonTime { get; set; } + public DateTime? Start { get; set; } + + public DateTime? Finish { get; set; } + + public ICollection PersonTeams { get; set; } = new List(); + public ICollection PersonOscs { get; set; } = new List(); + + public int? ProjectProgramId { get; set; } + + [ForeignKey("ProjectProgramId")] + public ProjectProgram? ProjectProgram { get; set; } + + [Required] + public int CourseId { get; set; } + + [ForeignKey("CourseId")] + public Course Course { get; set; } = null!; + + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/User.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/User.cs new file mode 100644 index 00000000..d7648dd3 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/User.cs @@ -0,0 +1,33 @@ +using IgescConecta.Domain.Primitives; +using IgescConecta.Domain.Shared; +using Microsoft.AspNetCore.Identity; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class User : IdentityUser + { + public string Name { get; set; } + + public bool IsActive { get; set; } + + public int? CreatedBy { get; set; } + + public DateTime CreatedAt { get; set; } + + public int? UpdatedBy { get; set; } + + public DateTime UpdatedAt { get; set; } + + [ForeignKey(nameof(CreatedBy))] + public User CreatedByUser { get; set; } + + [ForeignKey(nameof(UpdatedBy))] + public User UpdatedByUser { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/UserLogin.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/UserLogin.cs new file mode 100644 index 00000000..37530cca --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/UserLogin.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class UserLogin + { + public string Email { get; set; } + + public string Password { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/UserToken.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/UserToken.cs new file mode 100644 index 00000000..0d46e008 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Entities/UserToken.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Entities +{ + public class UserToken + { + public string AccessToken { get; set; } + + public DateTime ExpiresIn { get; set; } + + public string RefresfToken { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Enums/MemberType.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Enums/MemberType.cs new file mode 100644 index 00000000..db80f1d8 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Enums/MemberType.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Enums +{ + public enum MemberType + { + [Display(Name = "Participante")] + Student, + [Display(Name = "Professor")] + Professor, + [Display(Name = "Coordenador")] + Coordinator, + [Display(Name = "Consultor Social")] + Consultant, + [Display(Name = "Mentor")] + TeamLeader, + [Display(Name = "Coordenador Geral")] + ProgramCoordinator, + [Display(Name = "Palestrante")] + Speaker, + [Display(Name = "Apoio Técnico")] + TechSupport + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Enums/OdsType.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Enums/OdsType.cs new file mode 100644 index 00000000..152b5fd5 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Enums/OdsType.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Enums +{ + public enum OdsType + { + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Enums/ProjectDecisionType.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Enums/ProjectDecisionType.cs new file mode 100644 index 00000000..d19b6fcc --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Enums/ProjectDecisionType.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Enums +{ + public enum ProjectDecisionType + { + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/IgescConecta.Domain.csproj b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/IgescConecta.Domain.csproj new file mode 100644 index 00000000..87f5719b --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/IgescConecta.Domain.csproj @@ -0,0 +1,20 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Primitives/ISoftDeletable.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Primitives/ISoftDeletable.cs new file mode 100644 index 00000000..f987de60 --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Primitives/ISoftDeletable.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Primitives +{ + public interface ISoftDeletable + { + public bool IsDeleted { get; } + } +} diff --git a/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Shared/BaseEntity.cs b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Shared/BaseEntity.cs new file mode 100644 index 00000000..79e8354d --- /dev/null +++ b/codigo-fonte/IgescConecta.API/IgescConecta.Domain/Shared/BaseEntity.cs @@ -0,0 +1,24 @@ +using IgescConecta.Domain.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IgescConecta.Domain.Shared +{ + public class BaseEntity : ISoftDeletable + { + public int Id { get; set; } + + public int CreatedBy { get; set; } + + public DateTime CreatedAt { get; set; } + + public int UpdatedBy { get; set; } + + public DateTime UpdatedAt { get; set; } + + public bool IsDeleted { get; set; } + } +} diff --git a/codigo-fonte/IgescConecta.API/package-lock.json b/codigo-fonte/IgescConecta.API/package-lock.json new file mode 100644 index 00000000..149d94fc --- /dev/null +++ b/codigo-fonte/IgescConecta.API/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "IgescConecta.API", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/codigo-fonte/frontend/.gitignore b/codigo-fonte/frontend/.gitignore new file mode 100644 index 00000000..a547bf36 --- /dev/null +++ b/codigo-fonte/frontend/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/codigo-fonte/frontend/.prettierrc b/codigo-fonte/frontend/.prettierrc new file mode 100644 index 00000000..848bbfd2 --- /dev/null +++ b/codigo-fonte/frontend/.prettierrc @@ -0,0 +1 @@ +{ "semi": true, "singleQuote": true, "printWidth": 100, "trailingComma": "es5" } diff --git a/codigo-fonte/frontend/README.md b/codigo-fonte/frontend/README.md new file mode 100644 index 00000000..252e3af8 --- /dev/null +++ b/codigo-fonte/frontend/README.md @@ -0,0 +1,103 @@ +# Frontend Web + +Este é o frontend web do projeto IGESC CONECTA. + +## Tecnologias utilizadas + +React 19 + +TypeScript + +Vite + +React Router DOM + +Axios + +Material UI + +MUI X (Date Pickers / Charts) + +Styled Components + +Bootstrap + +Day.js + +JWT Decode + +React Toastify + +OpenApiTools + +## Como executar + +Clone o repositório: + +``` +git clone +cd +``` + +Instale as dependências: + +``` +npm install +``` + +Execute o projeto: + +``` +npm run dev +``` + +Acesse no navegador: +http://localhost:5173 + +## Scripts disponíveis + +npm run dev → inicia o servidor de desenvolvimento + +npm run build → gera a versão de produção + +npm run preview → pré-visualiza a build de produção + +npm run lint → roda o ESLint + +npm run typecheck → verifica tipos com TypeScript + +npm run test → executa testes com Vitest + +npm run format → formata o código com Prettier + +npm run generate-api -> gera integração com backend + +## Estrutura do projeto +``` +src/ +├── api/ # Endpoints prontos para uso, gerado pelo openapitools +├── assets/ # Arquivos estáticos (imagens,fontes,ícones) +├── components/ # Componentes reutilizáveis +├── hooks/ # Custom hooks +├── pages/ # Páginas da aplicação +├── routes/ # Configuração de rotas +├── services/ # Regras Api +├── store/ # Estado global (Context/Redux/Zustand) +├── styles/ # Estilos globais e temas +├── types/ # Types/interfaces em TypeScript +├── utils/ # Funções utilitárias +├── App.tsx # Componente principal +└── main.tsx # Ponto de entrada da aplicação +``` + +## Qualidade e boas práticas + +ESLint + Prettier para linting e formatação + +TypeScript com strict mode + +Vitest + Testing Library para testes unitários + +Aliases configurados (@ → src) no Vite/TS + +CI/CD (opcional) com GitHub Actions \ No newline at end of file diff --git a/codigo-fonte/frontend/eslint.config.js b/codigo-fonte/frontend/eslint.config.js new file mode 100644 index 00000000..0d4d611e --- /dev/null +++ b/codigo-fonte/frontend/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { globalIgnores } from 'eslint/config' + +export default tseslint.config([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', // Permite any explícito + '@typescript-eslint/no-implicit-any': 'off', // Permite any implícito + '@typescript-eslint/no-unused-vars': 'warn', // Alerta sobre variáveis não usadas + }, + }, +]) diff --git a/codigo-fonte/frontend/index.html b/codigo-fonte/frontend/index.html new file mode 100644 index 00000000..e4b78eae --- /dev/null +++ b/codigo-fonte/frontend/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/codigo-fonte/frontend/openapitools.json b/codigo-fonte/frontend/openapitools.json new file mode 100644 index 00000000..5c50d6a2 --- /dev/null +++ b/codigo-fonte/frontend/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.6.0" + } +} diff --git a/codigo-fonte/frontend/package-lock.json b/codigo-fonte/frontend/package-lock.json new file mode 100644 index 00000000..79f202a3 --- /dev/null +++ b/codigo-fonte/frontend/package-lock.json @@ -0,0 +1,7655 @@ +{ + "name": "frontend", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.0.0", + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.3.2", + "@mui/material": "^7.3.2", + "@mui/x-charts": "^8.11.2", + "@mui/x-date-pickers": "^8.12.0", + "axios": "^1.11.0", + "bootstrap": "^5.3.8", + "dayjs": "^1.11.18", + "jwt-decode": "^4.0.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-number-format": "^5.4.4", + "react-router-dom": "^7.8.2", + "react-toastify": "^11.0.5", + "remask": "^1.2.2", + "styled-components": "^6.1.19" + }, + "devDependencies": { + "@eslint/js": "^9.33.0", + "@openapitools/openapi-generator-cli": "^2.25.0", + "@testing-library/jest-dom": "^6.8.0", + "@testing-library/react": "^16.3.0", + "@types/node": "^24.3.1", + "@types/react": "^19.1.12", + "@types/react-dom": "^19.1.9", + "@types/styled-components": "^5.1.34", + "@vitejs/plugin-react": "^5.0.2", + "eslint": "^9.35.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.3.0", + "prettier": "^3.6.2", + "typescript": "~5.8.3", + "typescript-eslint": "^8.39.1", + "vite": "^7.1.2", + "vitest": "^3.2.4" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@borewit/text-codec": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.1.1.tgz", + "integrity": "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/is-prop-valid/node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "license": "MIT" + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/styled/node_modules/@emotion/is-prop-valid": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", + "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", + "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", + "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", + "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", + "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", + "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", + "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", + "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", + "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", + "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", + "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", + "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", + "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", + "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", + "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", + "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", + "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", + "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", + "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", + "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", + "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", + "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", + "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", + "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", + "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", + "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.35.0.tgz", + "integrity": "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", + "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.0", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lukeed/csprng": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", + "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.2.tgz", + "integrity": "sha512-AOyfHjyDKVPGJJFtxOlept3EYEdLoar/RvssBTWVAvDJGIE676dLi2oT/Kx+FoVXFoA/JdV7DEMq/BVWV3KHRw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.2.tgz", + "integrity": "sha512-TZWazBjWXBjR6iGcNkbKklnwodcwj0SrChCNHc9BhD9rBgET22J1eFhHsEmvSvru9+opDy3umqAimQjokhfJlQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^7.3.2", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.2.tgz", + "integrity": "sha512-qXvbnawQhqUVfH1LMgMaiytP+ZpGoYhnGl7yYq2x57GYzcFL/iPzSZ3L30tlbwEjSVKNYcbiKO8tANR1tadjUg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.3", + "@mui/core-downloads-tracker": "^7.3.2", + "@mui/system": "^7.3.2", + "@mui/types": "^7.4.6", + "@mui/utils": "^7.3.2", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.1.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^7.3.2", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.2.tgz", + "integrity": "sha512-ha7mFoOyZGJr75xeiO9lugS3joRROjc8tG1u4P50dH0KR7bwhHznVMcYg7MouochUy0OxooJm/OOSpJ7gKcMvg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.3", + "@mui/utils": "^7.3.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.2.tgz", + "integrity": "sha512-PkJzW+mTaek4e0nPYZ6qLnW5RGa0KN+eRTf5FA2nc7cFZTeM+qebmGibaTLrgQBy3UpcpemaqfzToBNkzuxqew==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.3", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.2.tgz", + "integrity": "sha512-9d8JEvZW+H6cVkaZ+FK56R53vkJe3HsTpcjMUtH8v1xK6Y1TjzHdZ7Jck02mGXJsE6MQGWVs3ogRHTQmS9Q/rA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.3", + "@mui/private-theming": "^7.3.2", + "@mui/styled-engine": "^7.3.2", + "@mui/types": "^7.4.6", + "@mui/utils": "^7.3.2", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.6.tgz", + "integrity": "sha512-NVBbIw+4CDMMppNamVxyTccNv0WxtDb7motWDlMeSC8Oy95saj1TIZMGynPpFLePt3yOD8TskzumeqORCgRGWw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.3" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.2.tgz", + "integrity": "sha512-4DMWQGenOdLnM3y/SdFQFwKsCLM+mqxzvoWp9+x2XdEzXapkznauHLiXtSohHs/mc0+5/9UACt1GdugCX2te5g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.3", + "@mui/types": "^7.4.6", + "@types/prop-types": "^15.7.15", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.1.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-charts": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-8.11.2.tgz", + "integrity": "sha512-wsJqwg4ycUpn7ZWIaIddjwsbc4BsvxUHT4OyxoJIOedRn0P86vTvyxdi4hqIEwiZMVxkCTgvQRQnhALPcoMKvQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.2", + "@mui/utils": "^7.3.2", + "@mui/x-charts-vendor": "8.11.0", + "@mui/x-internal-gestures": "0.2.5", + "@mui/x-internals": "8.11.2", + "bezier-easing": "^2.1.0", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "reselect": "^5.1.1", + "use-sync-external-store": "^1.5.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0", + "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-charts-vendor": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@mui/x-charts-vendor/-/x-charts-vendor-8.11.0.tgz", + "integrity": "sha512-DcLvkSYjG/C7CMHzmC/qQHBQb8QcgGNtRF3d0KifpyOjTEe1J1H2sjQFNjXEJRyAY8eqEK2b5ApxF295XxxTHg==", + "license": "MIT AND ISC", + "dependencies": { + "@babel/runtime": "^7.28.2", + "@types/d3-color": "^3.1.3", + "@types/d3-delaunay": "^6.0.4", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-sankey": "^0.12.4", + "@types/d3-scale": "^4.0.9", + "@types/d3-shape": "^3.1.7", + "@types/d3-time": "^3.0.4", + "@types/d3-timer": "^3.0.2", + "d3-color": "^3.1.0", + "d3-delaunay": "^6.0.4", + "d3-interpolate": "^3.0.1", + "d3-sankey": "^0.12.3", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "d3-time": "^3.1.0", + "d3-timer": "^3.0.1", + "delaunator": "^5.0.1", + "robust-predicates": "^3.0.2" + } + }, + "node_modules/@mui/x-date-pickers": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-8.12.0.tgz", + "integrity": "sha512-CDcjdBNwMcTy3flZTCKZqSUS6deBFGKLqy3Vl6bgr5KTo8Vky2v+S+zNi56fv23Qs+P47GwpILcm3QZt/0BP0A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.2", + "@mui/utils": "^7.3.2", + "@mui/x-internals": "8.12.0", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0", + "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0", + "date-fns": "^2.25.0 || ^3.2.0 || ^4.0.0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0 || ^4.0.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2 || ^3.0.0", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers/node_modules/@mui/x-internals": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.12.0.tgz", + "integrity": "sha512-KCZgFHwuPg0v8I2gpjeC6k3eDRXPPX8RIGSNDXe8zSZ8dAw+p6Q2pzT9kKvctqCXSFK8ct/5YQwqx8Quhs8Ndg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.2", + "@mui/utils": "^7.3.2", + "reselect": "^5.1.1", + "use-sync-external-store": "^1.5.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@mui/x-internal-gestures": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@mui/x-internal-gestures/-/x-internal-gestures-0.2.5.tgz", + "integrity": "sha512-5W6qy9N3zqe0DBcgLrVS5GCkY/XCOYnCqcW6RVGPKSXVBCqNCLPJgIk7+ZKYkInjz5DAG4BHPgOFgo8vd9thsQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.2" + } + }, + "node_modules/@mui/x-internals": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-8.11.2.tgz", + "integrity": "sha512-3BFZ0Njgih+eWQBzSsdKEkRMlHtKRGFWz+/CGUrSBb5IApO0apkUSvG4v5augNYASsjksqWOXVlds7Wwznd0Lg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.2", + "@mui/utils": "^7.3.2", + "reselect": "^5.1.1", + "use-sync-external-store": "^1.5.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@nestjs/axios": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.1.tgz", + "integrity": "sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "axios": "^1.3.1", + "rxjs": "^7.0.0" + } + }, + "node_modules/@nestjs/common": { + "version": "11.1.6", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.6.tgz", + "integrity": "sha512-krKwLLcFmeuKDqngG2N/RuZHCs2ycsKcxWIDgcm7i1lf3sQ0iG03ci+DsP/r3FcT/eJDFsIHnKtNta2LIi7PzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-type": "21.0.0", + "iterare": "1.2.1", + "load-esm": "1.0.2", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "class-transformer": ">=0.4.1", + "class-validator": ">=0.13.2", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, + "node_modules/@nestjs/common/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@nestjs/core": { + "version": "11.1.6", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.6.tgz", + "integrity": "sha512-siWX7UDgErisW18VTeJA+x+/tpNZrJewjTBsRPF3JVxuWRuAB1kRoiJcxHgln8Lb5UY9NdvklITR84DUEXD0Cg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@nuxt/opencollective": "0.4.1", + "fast-safe-stringify": "2.1.1", + "iterare": "1.2.1", + "path-to-regexp": "8.2.0", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "engines": { + "node": ">= 20" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.0", + "@nestjs/microservices": "^11.0.0", + "@nestjs/platform-express": "^11.0.0", + "@nestjs/websockets": "^11.0.0", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/platform-express": { + "optional": true + }, + "@nestjs/websockets": { + "optional": true + } + } + }, + "node_modules/@nestjs/core/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nuxt/opencollective": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz", + "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + }, + "bin": { + "opencollective": "bin/opencollective.js" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0", + "npm": ">=5.10.0" + } + }, + "node_modules/@nuxtjs/opencollective": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz", + "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "consola": "^2.15.0", + "node-fetch": "^2.6.1" + }, + "bin": { + "opencollective": "bin/opencollective.js" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/@nuxtjs/opencollective/node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openapitools/openapi-generator-cli": { + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.25.0.tgz", + "integrity": "sha512-u/3VAbF8c68AXBgm8nBAdDPLPW/KgrtHz28yemf92zNB0iDZFGdRUX2W80Lzf177g6ctYLz0GIPHCOU0LTJegQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@nestjs/axios": "4.0.1", + "@nestjs/common": "11.1.6", + "@nestjs/core": "11.1.6", + "@nuxtjs/opencollective": "0.3.2", + "axios": "1.12.2", + "chalk": "4.1.2", + "commander": "8.3.0", + "compare-versions": "6.1.1", + "concurrently": "9.2.1", + "console.table": "0.10.0", + "fs-extra": "11.3.2", + "glob": "11.0.3", + "inquirer": "8.2.7", + "proxy-agent": "6.5.0", + "reflect-metadata": "0.2.2", + "rxjs": "7.8.2", + "tslib": "2.8.1" + }, + "bin": { + "openapi-generator-cli": "main.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/openapi_generator" + } + }, + "node_modules/@openapitools/openapi-generator-cli/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.34", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.34.tgz", + "integrity": "sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.1.tgz", + "integrity": "sha512-HJXwzoZN4eYTdD8bVV22DN8gsPCAj3V20NHKOs8ezfXanGpmVPR7kalUHd+Y31IJp9stdB87VKPFbsGY3H/2ag==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.1.tgz", + "integrity": "sha512-PZlsJVcjHfcH53mOImyt3bc97Ep3FJDXRpk9sMdGX0qgLmY0EIWxCag6EigerGhLVuL8lDVYNnSo8qnTElO4xw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.1.tgz", + "integrity": "sha512-xc6i2AuWh++oGi4ylOFPmzJOEeAa2lJeGUGb4MudOtgfyyjr4UPNK+eEWTPLvmPJIY/pgw6ssFIox23SyrkkJw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.1.tgz", + "integrity": "sha512-2ofU89lEpDYhdLAbRdeyz/kX3Y2lpYc6ShRnDjY35bZhd2ipuDMDi6ZTQ9NIag94K28nFMofdnKeHR7BT0CATw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.1.tgz", + "integrity": "sha512-wOsE6H2u6PxsHY/BeFHA4VGQN3KUJFZp7QJBmDYI983fgxq5Th8FDkVuERb2l9vDMs1D5XhOrhBrnqcEY6l8ZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.1.tgz", + "integrity": "sha512-A/xeqaHTlKbQggxCqispFAcNjycpUEHP52mwMQZUNqDUJFFYtPHCXS1VAG29uMlDzIVr+i00tSFWFLivMcoIBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.1.tgz", + "integrity": "sha512-54v4okehwl5TaSIkpp97rAHGp7t3ghinRd/vyC1iXqXMfjYUTm7TfYmCzXDoHUPTTf36L8pr0E7YsD3CfB3ZDg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.1.tgz", + "integrity": "sha512-p/LaFyajPN/0PUHjv8TNyxLiA7RwmDoVY3flXHPSzqrGcIp/c2FjwPPP5++u87DGHtw+5kSH5bCJz0mvXngYxw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.1.tgz", + "integrity": "sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.1.tgz", + "integrity": "sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.50.1.tgz", + "integrity": "sha512-RPhTwWMzpYYrHrJAS7CmpdtHNKtt2Ueo+BlLBjfZEhYBhK00OsEqM08/7f+eohiF6poe0YRDDd8nAvwtE/Y62Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.1.tgz", + "integrity": "sha512-eSGMVQw9iekut62O7eBdbiccRguuDgiPMsw++BVUg+1K7WjZXHOg/YOT9SWMzPZA+w98G+Fa1VqJgHZOHHnY0Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.1.tgz", + "integrity": "sha512-S208ojx8a4ciIPrLgazF6AgdcNJzQE4+S9rsmOmDJkusvctii+ZvEuIC4v/xFqzbuP8yDjn73oBlNDgF6YGSXQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.1.tgz", + "integrity": "sha512-3Ag8Ls1ggqkGUvSZWYcdgFwriy2lWo+0QlYgEFra/5JGtAd6C5Hw59oojx1DeqcA2Wds2ayRgvJ4qxVTzCHgzg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.1.tgz", + "integrity": "sha512-t9YrKfaxCYe7l7ldFERE1BRg/4TATxIg+YieHQ966jwvo7ddHJxPj9cNFWLAzhkVsbBvNA4qTbPVNsZKBO4NSg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.1.tgz", + "integrity": "sha512-MCgtFB2+SVNuQmmjHf+wfI4CMxy3Tk8XjA5Z//A0AKD7QXUYFMQcns91K6dEHBvZPCnhJSyDWLApk40Iq/H3tA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.1.tgz", + "integrity": "sha512-nEvqG+0jeRmqaUMuwzlfMKwcIVffy/9KGbAGyoa26iu6eSngAYQ512bMXuqqPrlTyfqdlB9FVINs93j534UJrg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.1.tgz", + "integrity": "sha512-RDsLm+phmT3MJd9SNxA9MNuEAO/J2fhW8GXk62G/B4G7sLVumNFbRwDL6v5NrESb48k+QMqdGbHgEtfU0LCpbA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.1.tgz", + "integrity": "sha512-hpZB/TImk2FlAFAIsoElM3tLzq57uxnGYwplg6WDyAxbYczSi8O2eQ+H2Lx74504rwKtZ3N2g4bCUkiamzS6TQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.1.tgz", + "integrity": "sha512-SXjv8JlbzKM0fTJidX4eVsH+Wmnp0/WcD8gJxIZyR6Gay5Qcsmdbi9zVtnbkGPG8v2vMR1AD06lGWy5FLMcG7A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.1.tgz", + "integrity": "sha512-StxAO/8ts62KZVRAm4JZYq9+NqNsV7RvimNK+YM7ry//zebEH6meuugqW/P5OFUCjyQgui+9fUxT6d5NShvMvA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.8.0.tgz", + "integrity": "sha512-WgXcWzVM6idy5JaftTVC8Vs83NKRmGJz4Hqs4oyOuO2J4r/y79vvKZsb+CaGyCSEbUPI6OsewfPd0G1A0/TUZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz", + "integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", + "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fflate": "^0.8.2", + "token-types": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-sankey": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@types/d3-sankey/-/d3-sankey-0.12.4.tgz", + "integrity": "sha512-YTicQNwioitIlvuvlfW2GfO6sKxpohzg2cSQttlXAPjFwoBuN+XpGLhUN3kLutG/dI3GCLC+DUorqiJt7Naetw==", + "license": "MIT", + "dependencies": { + "@types/d3-shape": "^1" + } + }, + "node_modules/@types/d3-sankey/node_modules/@types/d3-path": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.11.tgz", + "integrity": "sha512-4pQMp8ldf7UaB/gR8Fvvy69psNHkTpD/pVw3vmEi8iZAB9EPMBruB1JvHO4BIq9QkUUd2lV1F5YXpMNj7JPBpw==", + "license": "MIT" + }, + "node_modules/@types/d3-sankey/node_modules/@types/d3-shape": { + "version": "1.3.12", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.3.12.tgz", + "integrity": "sha512-8oMzcd4+poSLGgV0R1Q1rOlx/xdmozS4Xab7np0eamFFUYq71AU9pOCJEFnkXW2aI/oXdVYJzw6pssbSut7Z9Q==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "^1" + } + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz", + "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/intl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/intl/-/intl-1.2.2.tgz", + "integrity": "sha512-A4g5UEAA9c56JWKhc4LSJ9vzDMztjxVXDAXtVK4EbS3hW1V7Sz05VfcTgDQIvkOYJp1NqH222eg62P72HwltfQ==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz", + "integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.1.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", + "integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.1.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.9.tgz", + "integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/styled-components": { + "version": "5.1.34", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.34.tgz", + "integrity": "sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hoist-non-react-statics": "*", + "@types/react": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/stylis": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", + "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.43.0.tgz", + "integrity": "sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.43.0", + "@typescript-eslint/type-utils": "8.43.0", + "@typescript-eslint/utils": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.43.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.43.0.tgz", + "integrity": "sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/typescript-estree": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.43.0.tgz", + "integrity": "sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.43.0", + "@typescript-eslint/types": "^8.43.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.43.0.tgz", + "integrity": "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.43.0.tgz", + "integrity": "sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.43.0.tgz", + "integrity": "sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/typescript-estree": "8.43.0", + "@typescript-eslint/utils": "8.43.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", + "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.43.0.tgz", + "integrity": "sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.43.0", + "@typescript-eslint/tsconfig-utils": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.43.0.tgz", + "integrity": "sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/typescript-estree": "8.43.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.43.0.tgz", + "integrity": "sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.43.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.2.tgz", + "integrity": "sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.3", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.34", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/bezier-easing": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz", + "integrity": "sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==", + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bootstrap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT", + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.4.tgz", + "integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001737", + "electron-to-chromium": "^1.5.211", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001741", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz", + "integrity": "sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", + "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/console.table": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz", + "integrity": "sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "easy-table": "1.1.0" + }, + "engines": { + "node": "> 0.10" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/dayjs": { + "version": "1.11.18", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", + "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/easy-table": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz", + "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "wcwidth": ">=1.0.1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.216", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.216.tgz", + "integrity": "sha512-uVgsufJ+qIiOsZBmqkM2AGPn3gbqPySHl/SLKXJ70nowhI0VsRX4aog+R9EUL2bOjqPPhfR9pG8j8s4Zk4xq+A==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.35.0.tgz", + "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.1", + "@eslint/core": "^0.15.2", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.35.0", + "@eslint/plugin-kit": "^0.3.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", + "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-type": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.0.0.tgz", + "integrity": "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.2.7", + "strtok3": "^10.2.2", + "token-types": "^6.0.0", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/glob": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", + "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, + "node_modules/ip-address": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iterare": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", + "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=6" + } + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/load-esm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.2.tgz", + "integrity": "sha512-nVAvWk/jeyrWyXEAs84mpQCYccxRqgKY4OznLuJhJCa0XsPSfdOIr2zvBZEj3IHEHbX97jjscKRRV539bW0Gpw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + }, + { + "type": "buymeacoffee", + "url": "https://buymeacoffee.com/borewit" + } + ], + "license": "MIT", + "engines": { + "node": ">=13.2.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.20.tgz", + "integrity": "sha512-7gK6zSXEH6neM212JgfYFXe+GmZQM+fia5SsusuBIUgnPheLFBmIPhtFoAQRj8/7wASYQnbDlHPVwY0BefoFgA==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.1.tgz", + "integrity": "sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", + "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz", + "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.1" + } + }, + "node_modules/react-is": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz", + "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==", + "license": "MIT" + }, + "node_modules/react-number-format": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.4.4.tgz", + "integrity": "sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==", + "license": "MIT", + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.2.tgz", + "integrity": "sha512-7M2fR1JbIZ/jFWqelpvSZx+7vd7UlBTfdZqf6OSdF9g6+sfdqJDAWcak6ervbHph200ePlu+7G8LdoiC3ReyAQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.2.tgz", + "integrity": "sha512-Z4VM5mKDipal2jQ385H6UBhiiEDlnJPx6jyWsTYoZQdl5TrjxEV2a9yl3Fi60NBJxYzOTGTTHXPi0pdizvTwow==", + "license": "MIT", + "dependencies": { + "react-router": "7.8.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-toastify": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz", + "integrity": "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1" + }, + "peerDependencies": { + "react": "^18 || ^19", + "react-dom": "^18 || ^19" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/remask": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/remask/-/remask-1.2.2.tgz", + "integrity": "sha512-zUNAiG1mYewmktEKpkvcmpDeP+04CzlWtoim7C9q/dnk7tgqtHoG9GIHjCH3I9fff7O41BLqOjRuX07s/hzF7w==", + "license": "MIT", + "dependencies": { + "@types/intl": "^1.2.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" + }, + "node_modules/rollup": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.1.tgz", + "integrity": "sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.50.1", + "@rollup/rollup-android-arm64": "4.50.1", + "@rollup/rollup-darwin-arm64": "4.50.1", + "@rollup/rollup-darwin-x64": "4.50.1", + "@rollup/rollup-freebsd-arm64": "4.50.1", + "@rollup/rollup-freebsd-x64": "4.50.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.50.1", + "@rollup/rollup-linux-arm-musleabihf": "4.50.1", + "@rollup/rollup-linux-arm64-gnu": "4.50.1", + "@rollup/rollup-linux-arm64-musl": "4.50.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.50.1", + "@rollup/rollup-linux-ppc64-gnu": "4.50.1", + "@rollup/rollup-linux-riscv64-gnu": "4.50.1", + "@rollup/rollup-linux-riscv64-musl": "4.50.1", + "@rollup/rollup-linux-s390x-gnu": "4.50.1", + "@rollup/rollup-linux-x64-gnu": "4.50.1", + "@rollup/rollup-linux-x64-musl": "4.50.1", + "@rollup/rollup-openharmony-arm64": "4.50.1", + "@rollup/rollup-win32-arm64-msvc": "4.50.1", + "@rollup/rollup-win32-ia32-msvc": "4.50.1", + "@rollup/rollup-win32-x64-msvc": "4.50.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "dev": true, + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/strtok3": { + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", + "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/styled-components": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.19.tgz", + "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==", + "license": "MIT", + "dependencies": { + "@emotion/is-prop-valid": "1.2.2", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.5", + "css-to-react-native": "3.2.0", + "csstype": "3.1.3", + "postcss": "8.4.49", + "shallowequal": "1.1.0", + "stylis": "4.3.2", + "tslib": "2.6.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", + "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-types": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.1.tgz", + "integrity": "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.1.0", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.43.0.tgz", + "integrity": "sha512-FyRGJKUGvcFekRRcBKFBlAhnp4Ng8rhe8tuvvkR9OiU0gfd4vyvTRQHEckO6VDlH57jbeUQem2IpqPq9kLJH+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.43.0", + "@typescript-eslint/parser": "8.43.0", + "@typescript-eslint/typescript-estree": "8.43.0", + "@typescript-eslint/utils": "8.43.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/uid": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", + "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lukeed/csprng": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz", + "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/codigo-fonte/frontend/package.json b/codigo-fonte/frontend/package.json new file mode 100644 index 00000000..e38ba0b3 --- /dev/null +++ b/codigo-fonte/frontend/package.json @@ -0,0 +1,57 @@ +{ + "name": "frontend", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview", + "lint": "eslint 'src/**/*.{ts,tsx}' --max-warnings=0", + "generate-api": "openapi-generator-cli generate -i swagger.json -g typescript-axios -o src/api", + "typecheck": "tsc --noEmit", + "test": "vitest", + "test:watch": "vitest --watch", + "format": "prettier --write ." + }, + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.3.2", + "@mui/material": "^7.3.2", + "@mui/x-charts": "^8.11.2", + "@mui/x-date-pickers": "^8.12.0", + "axios": "^1.11.0", + "bootstrap": "^5.3.8", + "dayjs": "^1.11.18", + "jwt-decode": "^4.0.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-number-format": "^5.4.4", + "react-router-dom": "^7.8.2", + "react-toastify": "^11.0.5", + "remask": "^1.2.2", + "styled-components": "^6.1.19" + }, + "devDependencies": { + "@eslint/js": "^9.33.0", + "@openapitools/openapi-generator-cli": "^2.25.0", + "@testing-library/jest-dom": "^6.8.0", + "@testing-library/react": "^16.3.0", + "@types/node": "^24.3.1", + "@types/react": "^19.1.12", + "@types/react-dom": "^19.1.9", + "@types/styled-components": "^5.1.34", + "@vitejs/plugin-react": "^5.0.2", + "eslint": "^9.35.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", + "globals": "^16.3.0", + "prettier": "^3.6.2", + "typescript": "~5.8.3", + "typescript-eslint": "^8.39.1", + "vite": "^7.1.2", + "vitest": "^3.2.4" + } +} diff --git a/codigo-fonte/frontend/public/vite.svg b/codigo-fonte/frontend/public/vite.svg new file mode 100644 index 00000000..e7b8dfb1 --- /dev/null +++ b/codigo-fonte/frontend/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/codigo-fonte/frontend/src/App.tsx b/codigo-fonte/frontend/src/App.tsx new file mode 100644 index 00000000..613366c0 --- /dev/null +++ b/codigo-fonte/frontend/src/App.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import AppRoutes from './routes/AppRoutes'; +import { ToastContainer } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; + +import { ThemeProvider } from '@mui/material/styles'; +import CssBaseline from '@mui/material/CssBaseline'; +import theme from './utils/theme'; + +export default function App() { + return ( + + + + {/* Toast global */} + + + {/* Rotas */} + + + ); +} diff --git a/codigo-fonte/frontend/src/api/.gitignore b/codigo-fonte/frontend/src/api/.gitignore new file mode 100644 index 00000000..149b5765 --- /dev/null +++ b/codigo-fonte/frontend/src/api/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/codigo-fonte/frontend/src/api/.npmignore b/codigo-fonte/frontend/src/api/.npmignore new file mode 100644 index 00000000..999d88df --- /dev/null +++ b/codigo-fonte/frontend/src/api/.npmignore @@ -0,0 +1 @@ +# empty npmignore to ensure all required files (e.g., in the dist folder) are published by npm \ No newline at end of file diff --git a/codigo-fonte/frontend/src/api/.openapi-generator-ignore b/codigo-fonte/frontend/src/api/.openapi-generator-ignore new file mode 100644 index 00000000..7484ee59 --- /dev/null +++ b/codigo-fonte/frontend/src/api/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/codigo-fonte/frontend/src/api/.openapi-generator/FILES b/codigo-fonte/frontend/src/api/.openapi-generator/FILES new file mode 100644 index 00000000..75248056 --- /dev/null +++ b/codigo-fonte/frontend/src/api/.openapi-generator/FILES @@ -0,0 +1,126 @@ +.gitignore +.npmignore +api.ts +apis/auth-api.ts +apis/beneficiaries-api.ts +apis/business-cases-api.ts +apis/courses-api.ts +apis/create-company-endpoint-api.ts +apis/create-donation-endpoint-api.ts +apis/delete-donation-endpoint-api.ts +apis/inactivate-company-endpoint-api.ts +apis/list-companies-endpoint-api.ts +apis/list-company-endpoint-api.ts +apis/list-donation-endpoint-api.ts +apis/list-donations-endpoint-api.ts +apis/origins-business-cases-api.ts +apis/oscs-api.ts +apis/persons-api.ts +apis/reactivate-company-endpoint-api.ts +apis/teams-api.ts +apis/update-company-endpoint-api.ts +apis/update-donation-endpoint-api.ts +apis/users-api.ts +base.ts +common.ts +configuration.ts +git_push.sh +index.ts +models/beneficiary-view-model.ts +models/business-case-view-model.ts +models/company-view-model.ts +models/course-view-model.ts +models/create-beneficiary-request.ts +models/create-beneficiary-response.ts +models/create-business-case-request.ts +models/create-business-case-response.ts +models/create-company-command.ts +models/create-course-request.ts +models/create-course-response.ts +models/create-donation-command.ts +models/create-origin-business-case-request.ts +models/create-origin-business-case-response.ts +models/create-osc-request.ts +models/create-osc-response.ts +models/create-person-request.ts +models/create-person-response.ts +models/create-team-request.ts +models/create-team-response.ts +models/create-user-request.ts +models/create-user-response.ts +models/delete-course-response.ts +models/delete-team-response.ts +models/donation-view-model.ts +models/edit-course-request.ts +models/edit-course-response.ts +models/edit-team-request.ts +models/edit-team-response.ts +models/filter.ts +models/forgot-password-request.ts +models/forgot-password-response.ts +models/get-beneficiary-osc-response.ts +models/get-beneficiary-response.ts +models/get-business-case-origin-response.ts +models/get-business-case-response.ts +models/get-course-by-id-view-model.ts +models/get-origin-business-case-osc-response.ts +models/get-origin-business-case-response.ts +models/get-osc-beneficiary-response.ts +models/get-osc-origin-business-case-response.ts +models/get-osc-response.ts +models/get-team-by-id-response.ts +models/index.ts +models/list-beneficiary-request.ts +models/list-beneficiary-view-model.ts +models/list-business-case-request.ts +models/list-business-case-view-model.ts +models/list-companies-request.ts +models/list-companies-view-model.ts +models/list-course-request.ts +models/list-course-view-model.ts +models/list-donations-request.ts +models/list-donations-view-model.ts +models/list-origin-business-case-request.ts +models/list-origin-business-case-view-model.ts +models/list-origins-business-case-by-business-case-id-request.ts +models/list-origins-business-case-by-business-case-id-view-model.ts +models/list-osc-request.ts +models/list-osc-view-model.ts +models/list-person-request.ts +models/list-person-view-model.ts +models/list-team-item-view-model.ts +models/list-team-request.ts +models/list-team-view-model.ts +models/list-user-request.ts +models/list-user-view-model.ts +models/login-response.ts +models/op.ts +models/origin-business-case-by-business-case-id-view-model.ts +models/origin-business-case-view-model.ts +models/osc-view-model.ts +models/person-list-item-view-model.ts +models/person-view-model.ts +models/problem-details.ts +models/reset-password-request.ts +models/reset-password-response.ts +models/team-view-model.ts +models/update-beneficiary-in-osc-response.ts +models/update-beneficiary-request.ts +models/update-beneficiary-response.ts +models/update-business-case-request.ts +models/update-business-case-response.ts +models/update-company-command.ts +models/update-donation-command.ts +models/update-origin-business-case-in-business-case-response.ts +models/update-origin-business-case-in-osc-response.ts +models/update-origin-business-case-request.ts +models/update-origin-business-case-response.ts +models/update-osc-request.ts +models/update-osc-response.ts +models/update-person-request.ts +models/update-person-response.ts +models/update-user-request.ts +models/update-user-response.ts +models/user-login.ts +models/user-token.ts +models/user-view-model.ts diff --git a/codigo-fonte/frontend/src/api/.openapi-generator/VERSION b/codigo-fonte/frontend/src/api/.openapi-generator/VERSION new file mode 100644 index 00000000..93c8ddab --- /dev/null +++ b/codigo-fonte/frontend/src/api/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.6.0 diff --git a/codigo-fonte/frontend/src/api/api.ts b/codigo-fonte/frontend/src/api/api.ts new file mode 100644 index 00000000..b097a768 --- /dev/null +++ b/codigo-fonte/frontend/src/api/api.ts @@ -0,0 +1,37 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +export * from './apis/auth-api'; +export * from './apis/beneficiaries-api'; +export * from './apis/business-cases-api'; +export * from './apis/courses-api'; +export * from './apis/create-company-endpoint-api'; +export * from './apis/create-donation-endpoint-api'; +export * from './apis/delete-donation-endpoint-api'; +export * from './apis/inactivate-company-endpoint-api'; +export * from './apis/list-companies-endpoint-api'; +export * from './apis/list-company-endpoint-api'; +export * from './apis/list-donation-endpoint-api'; +export * from './apis/list-donations-endpoint-api'; +export * from './apis/origins-business-cases-api'; +export * from './apis/oscs-api'; +export * from './apis/persons-api'; +export * from './apis/reactivate-company-endpoint-api'; +export * from './apis/teams-api'; +export * from './apis/update-company-endpoint-api'; +export * from './apis/update-donation-endpoint-api'; +export * from './apis/users-api'; + diff --git a/codigo-fonte/frontend/src/api/apis/auth-api.ts b/codigo-fonte/frontend/src/api/apis/auth-api.ts new file mode 100644 index 00000000..ae474ef1 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/auth-api.ts @@ -0,0 +1,350 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { ForgotPasswordRequest } from '../models'; +// @ts-ignore +import type { ForgotPasswordResponse } from '../models'; +// @ts-ignore +import type { LoginResponse } from '../models'; +// @ts-ignore +import type { ResetPasswordRequest } from '../models'; +// @ts-ignore +import type { ResetPasswordResponse } from '../models'; +// @ts-ignore +import type { UserLogin } from '../models'; +// @ts-ignore +import type { UserToken } from '../models'; +/** + * AuthApi - axios parameter creator + * @export + */ +export const AuthApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {ForgotPasswordRequest} [forgotPasswordRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + forgotPassword: async (forgotPasswordRequest?: ForgotPasswordRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/auth/forgot-password`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(forgotPasswordRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {UserLogin} [userLogin] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + login: async (userLogin?: UserLogin, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/auth/Login`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(userLogin, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {LoginResponse} [loginResponse] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + refreshToken: async (loginResponse?: LoginResponse, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/auth/RefreshToken`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(loginResponse, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ResetPasswordRequest} [resetPasswordRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + resetPassword: async (resetPasswordRequest?: ResetPasswordRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/auth/reset-password`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(resetPasswordRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * AuthApi - functional programming interface + * @export + */ +export const AuthApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = AuthApiAxiosParamCreator(configuration) + return { + /** + * + * @param {ForgotPasswordRequest} [forgotPasswordRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async forgotPassword(forgotPasswordRequest?: ForgotPasswordRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.forgotPassword(forgotPasswordRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AuthApi.forgotPassword']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {UserLogin} [userLogin] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async login(userLogin?: UserLogin, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.login(userLogin, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AuthApi.login']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {LoginResponse} [loginResponse] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async refreshToken(loginResponse?: LoginResponse, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.refreshToken(loginResponse, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AuthApi.refreshToken']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ResetPasswordRequest} [resetPasswordRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async resetPassword(resetPasswordRequest?: ResetPasswordRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.resetPassword(resetPasswordRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AuthApi.resetPassword']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * AuthApi - factory interface + * @export + */ +export const AuthApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = AuthApiFp(configuration) + return { + /** + * + * @param {ForgotPasswordRequest} [forgotPasswordRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + forgotPassword(forgotPasswordRequest?: ForgotPasswordRequest, options?: any): AxiosPromise { + return localVarFp.forgotPassword(forgotPasswordRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {UserLogin} [userLogin] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + login(userLogin?: UserLogin, options?: any): AxiosPromise { + return localVarFp.login(userLogin, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {LoginResponse} [loginResponse] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + refreshToken(loginResponse?: LoginResponse, options?: any): AxiosPromise { + return localVarFp.refreshToken(loginResponse, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ResetPasswordRequest} [resetPasswordRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + resetPassword(resetPasswordRequest?: ResetPasswordRequest, options?: any): AxiosPromise { + return localVarFp.resetPassword(resetPasswordRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * AuthApi - object-oriented interface + * @export + * @class AuthApi + * @extends {BaseAPI} + */ +export class AuthApi extends BaseAPI { + /** + * + * @param {ForgotPasswordRequest} [forgotPasswordRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AuthApi + */ + public forgotPassword(forgotPasswordRequest?: ForgotPasswordRequest, options?: RawAxiosRequestConfig) { + return AuthApiFp(this.configuration).forgotPassword(forgotPasswordRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {UserLogin} [userLogin] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AuthApi + */ + public login(userLogin?: UserLogin, options?: RawAxiosRequestConfig) { + return AuthApiFp(this.configuration).login(userLogin, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {LoginResponse} [loginResponse] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AuthApi + */ + public refreshToken(loginResponse?: LoginResponse, options?: RawAxiosRequestConfig) { + return AuthApiFp(this.configuration).refreshToken(loginResponse, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ResetPasswordRequest} [resetPasswordRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof AuthApi + */ + public resetPassword(resetPasswordRequest?: ResetPasswordRequest, options?: RawAxiosRequestConfig) { + return AuthApiFp(this.configuration).resetPassword(resetPasswordRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/beneficiaries-api.ts b/codigo-fonte/frontend/src/api/apis/beneficiaries-api.ts new file mode 100644 index 00000000..7f6b3876 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/beneficiaries-api.ts @@ -0,0 +1,426 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateBeneficiaryRequest } from '../models'; +// @ts-ignore +import type { CreateBeneficiaryResponse } from '../models'; +// @ts-ignore +import type { GetBeneficiaryResponse } from '../models'; +// @ts-ignore +import type { ListBeneficiaryRequest } from '../models'; +// @ts-ignore +import type { ListBeneficiaryViewModel } from '../models'; +// @ts-ignore +import type { UpdateBeneficiaryRequest } from '../models'; +// @ts-ignore +import type { UpdateBeneficiaryResponse } from '../models'; +/** + * BeneficiariesApi - axios parameter creator + * @export + */ +export const BeneficiariesApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateBeneficiaryRequest} [createBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createBeneficiary: async (createBeneficiaryRequest?: CreateBeneficiaryRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/beneficiary/CreateBeneficiary`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createBeneficiaryRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} beneficiaryId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteBeneficiary: async (beneficiaryId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'beneficiaryId' is not null or undefined + assertParamExists('deleteBeneficiary', 'beneficiaryId', beneficiaryId) + const localVarPath = `/api/beneficiary/{beneficiaryId}` + .replace(`{${"beneficiaryId"}}`, encodeURIComponent(String(beneficiaryId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} beneficiaryId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getBeneficiary: async (beneficiaryId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'beneficiaryId' is not null or undefined + assertParamExists('getBeneficiary', 'beneficiaryId', beneficiaryId) + const localVarPath = `/api/beneficiaries/{beneficiaryId}` + .replace(`{${"beneficiaryId"}}`, encodeURIComponent(String(beneficiaryId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ListBeneficiaryRequest} [listBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listBeneficiary: async (listBeneficiaryRequest?: ListBeneficiaryRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/beneficiary/ListBeneficiary`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listBeneficiaryRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} beneficiaryId + * @param {UpdateBeneficiaryRequest} [updateBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateBeneficiary: async (beneficiaryId: number, updateBeneficiaryRequest?: UpdateBeneficiaryRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'beneficiaryId' is not null or undefined + assertParamExists('updateBeneficiary', 'beneficiaryId', beneficiaryId) + const localVarPath = `/api/beneficiaries/{beneficiaryId}` + .replace(`{${"beneficiaryId"}}`, encodeURIComponent(String(beneficiaryId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(updateBeneficiaryRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * BeneficiariesApi - functional programming interface + * @export + */ +export const BeneficiariesApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = BeneficiariesApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateBeneficiaryRequest} [createBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createBeneficiary(createBeneficiaryRequest?: CreateBeneficiaryRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createBeneficiary(createBeneficiaryRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BeneficiariesApi.createBeneficiary']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} beneficiaryId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteBeneficiary(beneficiaryId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteBeneficiary(beneficiaryId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BeneficiariesApi.deleteBeneficiary']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} beneficiaryId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getBeneficiary(beneficiaryId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getBeneficiary(beneficiaryId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BeneficiariesApi.getBeneficiary']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ListBeneficiaryRequest} [listBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listBeneficiary(listBeneficiaryRequest?: ListBeneficiaryRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listBeneficiary(listBeneficiaryRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BeneficiariesApi.listBeneficiary']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} beneficiaryId + * @param {UpdateBeneficiaryRequest} [updateBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateBeneficiary(beneficiaryId: number, updateBeneficiaryRequest?: UpdateBeneficiaryRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateBeneficiary(beneficiaryId, updateBeneficiaryRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BeneficiariesApi.updateBeneficiary']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * BeneficiariesApi - factory interface + * @export + */ +export const BeneficiariesApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = BeneficiariesApiFp(configuration) + return { + /** + * + * @param {CreateBeneficiaryRequest} [createBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createBeneficiary(createBeneficiaryRequest?: CreateBeneficiaryRequest, options?: any): AxiosPromise { + return localVarFp.createBeneficiary(createBeneficiaryRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} beneficiaryId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteBeneficiary(beneficiaryId: number, options?: any): AxiosPromise { + return localVarFp.deleteBeneficiary(beneficiaryId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} beneficiaryId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getBeneficiary(beneficiaryId: number, options?: any): AxiosPromise { + return localVarFp.getBeneficiary(beneficiaryId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ListBeneficiaryRequest} [listBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listBeneficiary(listBeneficiaryRequest?: ListBeneficiaryRequest, options?: any): AxiosPromise { + return localVarFp.listBeneficiary(listBeneficiaryRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} beneficiaryId + * @param {UpdateBeneficiaryRequest} [updateBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateBeneficiary(beneficiaryId: number, updateBeneficiaryRequest?: UpdateBeneficiaryRequest, options?: any): AxiosPromise { + return localVarFp.updateBeneficiary(beneficiaryId, updateBeneficiaryRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * BeneficiariesApi - object-oriented interface + * @export + * @class BeneficiariesApi + * @extends {BaseAPI} + */ +export class BeneficiariesApi extends BaseAPI { + /** + * + * @param {CreateBeneficiaryRequest} [createBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BeneficiariesApi + */ + public createBeneficiary(createBeneficiaryRequest?: CreateBeneficiaryRequest, options?: RawAxiosRequestConfig) { + return BeneficiariesApiFp(this.configuration).createBeneficiary(createBeneficiaryRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} beneficiaryId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BeneficiariesApi + */ + public deleteBeneficiary(beneficiaryId: number, options?: RawAxiosRequestConfig) { + return BeneficiariesApiFp(this.configuration).deleteBeneficiary(beneficiaryId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} beneficiaryId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BeneficiariesApi + */ + public getBeneficiary(beneficiaryId: number, options?: RawAxiosRequestConfig) { + return BeneficiariesApiFp(this.configuration).getBeneficiary(beneficiaryId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ListBeneficiaryRequest} [listBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BeneficiariesApi + */ + public listBeneficiary(listBeneficiaryRequest?: ListBeneficiaryRequest, options?: RawAxiosRequestConfig) { + return BeneficiariesApiFp(this.configuration).listBeneficiary(listBeneficiaryRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} beneficiaryId + * @param {UpdateBeneficiaryRequest} [updateBeneficiaryRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BeneficiariesApi + */ + public updateBeneficiary(beneficiaryId: number, updateBeneficiaryRequest?: UpdateBeneficiaryRequest, options?: RawAxiosRequestConfig) { + return BeneficiariesApiFp(this.configuration).updateBeneficiary(beneficiaryId, updateBeneficiaryRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/business-cases-api.ts b/codigo-fonte/frontend/src/api/apis/business-cases-api.ts new file mode 100644 index 00000000..7d5b34bc --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/business-cases-api.ts @@ -0,0 +1,426 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateBusinessCaseRequest } from '../models'; +// @ts-ignore +import type { CreateBusinessCaseResponse } from '../models'; +// @ts-ignore +import type { GetBusinessCaseResponse } from '../models'; +// @ts-ignore +import type { ListBusinessCaseRequest } from '../models'; +// @ts-ignore +import type { ListBusinessCaseViewModel } from '../models'; +// @ts-ignore +import type { UpdateBusinessCaseRequest } from '../models'; +// @ts-ignore +import type { UpdateBusinessCaseResponse } from '../models'; +/** + * BusinessCasesApi - axios parameter creator + * @export + */ +export const BusinessCasesApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateBusinessCaseRequest} [createBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createBusinessCase: async (createBusinessCaseRequest?: CreateBusinessCaseRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/businesscase/CreateBusinessCase`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createBusinessCaseRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} businessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteBusinessCase: async (businessCaseId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'businessCaseId' is not null or undefined + assertParamExists('deleteBusinessCase', 'businessCaseId', businessCaseId) + const localVarPath = `/api/businesscase/{businessCaseId}` + .replace(`{${"businessCaseId"}}`, encodeURIComponent(String(businessCaseId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} businessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getBusinessCase: async (businessCaseId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'businessCaseId' is not null or undefined + assertParamExists('getBusinessCase', 'businessCaseId', businessCaseId) + const localVarPath = `/api/businesscases/{businessCaseId}` + .replace(`{${"businessCaseId"}}`, encodeURIComponent(String(businessCaseId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ListBusinessCaseRequest} [listBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listBusinessCase: async (listBusinessCaseRequest?: ListBusinessCaseRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/businesscase/ListBusinessCase`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listBusinessCaseRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} businessCaseId + * @param {UpdateBusinessCaseRequest} [updateBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateBusinessCase: async (businessCaseId: number, updateBusinessCaseRequest?: UpdateBusinessCaseRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'businessCaseId' is not null or undefined + assertParamExists('updateBusinessCase', 'businessCaseId', businessCaseId) + const localVarPath = `/api/businesscases/{businessCaseId}` + .replace(`{${"businessCaseId"}}`, encodeURIComponent(String(businessCaseId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(updateBusinessCaseRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * BusinessCasesApi - functional programming interface + * @export + */ +export const BusinessCasesApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = BusinessCasesApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateBusinessCaseRequest} [createBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createBusinessCase(createBusinessCaseRequest?: CreateBusinessCaseRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createBusinessCase(createBusinessCaseRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BusinessCasesApi.createBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} businessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteBusinessCase(businessCaseId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteBusinessCase(businessCaseId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BusinessCasesApi.deleteBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} businessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getBusinessCase(businessCaseId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getBusinessCase(businessCaseId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BusinessCasesApi.getBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ListBusinessCaseRequest} [listBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listBusinessCase(listBusinessCaseRequest?: ListBusinessCaseRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listBusinessCase(listBusinessCaseRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BusinessCasesApi.listBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} businessCaseId + * @param {UpdateBusinessCaseRequest} [updateBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateBusinessCase(businessCaseId: number, updateBusinessCaseRequest?: UpdateBusinessCaseRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateBusinessCase(businessCaseId, updateBusinessCaseRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['BusinessCasesApi.updateBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * BusinessCasesApi - factory interface + * @export + */ +export const BusinessCasesApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = BusinessCasesApiFp(configuration) + return { + /** + * + * @param {CreateBusinessCaseRequest} [createBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createBusinessCase(createBusinessCaseRequest?: CreateBusinessCaseRequest, options?: any): AxiosPromise { + return localVarFp.createBusinessCase(createBusinessCaseRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} businessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteBusinessCase(businessCaseId: number, options?: any): AxiosPromise { + return localVarFp.deleteBusinessCase(businessCaseId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} businessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getBusinessCase(businessCaseId: number, options?: any): AxiosPromise { + return localVarFp.getBusinessCase(businessCaseId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ListBusinessCaseRequest} [listBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listBusinessCase(listBusinessCaseRequest?: ListBusinessCaseRequest, options?: any): AxiosPromise { + return localVarFp.listBusinessCase(listBusinessCaseRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} businessCaseId + * @param {UpdateBusinessCaseRequest} [updateBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateBusinessCase(businessCaseId: number, updateBusinessCaseRequest?: UpdateBusinessCaseRequest, options?: any): AxiosPromise { + return localVarFp.updateBusinessCase(businessCaseId, updateBusinessCaseRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * BusinessCasesApi - object-oriented interface + * @export + * @class BusinessCasesApi + * @extends {BaseAPI} + */ +export class BusinessCasesApi extends BaseAPI { + /** + * + * @param {CreateBusinessCaseRequest} [createBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BusinessCasesApi + */ + public createBusinessCase(createBusinessCaseRequest?: CreateBusinessCaseRequest, options?: RawAxiosRequestConfig) { + return BusinessCasesApiFp(this.configuration).createBusinessCase(createBusinessCaseRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} businessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BusinessCasesApi + */ + public deleteBusinessCase(businessCaseId: number, options?: RawAxiosRequestConfig) { + return BusinessCasesApiFp(this.configuration).deleteBusinessCase(businessCaseId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} businessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BusinessCasesApi + */ + public getBusinessCase(businessCaseId: number, options?: RawAxiosRequestConfig) { + return BusinessCasesApiFp(this.configuration).getBusinessCase(businessCaseId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ListBusinessCaseRequest} [listBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BusinessCasesApi + */ + public listBusinessCase(listBusinessCaseRequest?: ListBusinessCaseRequest, options?: RawAxiosRequestConfig) { + return BusinessCasesApiFp(this.configuration).listBusinessCase(listBusinessCaseRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} businessCaseId + * @param {UpdateBusinessCaseRequest} [updateBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof BusinessCasesApi + */ + public updateBusinessCase(businessCaseId: number, updateBusinessCaseRequest?: UpdateBusinessCaseRequest, options?: RawAxiosRequestConfig) { + return BusinessCasesApiFp(this.configuration).updateBusinessCase(businessCaseId, updateBusinessCaseRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/courses-api.ts b/codigo-fonte/frontend/src/api/apis/courses-api.ts new file mode 100644 index 00000000..32e27af2 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/courses-api.ts @@ -0,0 +1,428 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateCourseRequest } from '../models'; +// @ts-ignore +import type { CreateCourseResponse } from '../models'; +// @ts-ignore +import type { DeleteCourseResponse } from '../models'; +// @ts-ignore +import type { EditCourseRequest } from '../models'; +// @ts-ignore +import type { EditCourseResponse } from '../models'; +// @ts-ignore +import type { GetCourseByIdViewModel } from '../models'; +// @ts-ignore +import type { ListCourseRequest } from '../models'; +// @ts-ignore +import type { ListCourseViewModel } from '../models'; +/** + * CoursesApi - axios parameter creator + * @export + */ +export const CoursesApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateCourseRequest} [createCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createCourse: async (createCourseRequest?: CreateCourseRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/courses`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createCourseRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} courseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteCourse: async (courseId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'courseId' is not null or undefined + assertParamExists('deleteCourse', 'courseId', courseId) + const localVarPath = `/api/courses/{courseId}` + .replace(`{${"courseId"}}`, encodeURIComponent(String(courseId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} courseId + * @param {EditCourseRequest} [editCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + editCourse: async (courseId: number, editCourseRequest?: EditCourseRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'courseId' is not null or undefined + assertParamExists('editCourse', 'courseId', courseId) + const localVarPath = `/api/courses/{courseId}` + .replace(`{${"courseId"}}`, encodeURIComponent(String(courseId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(editCourseRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCourseById: async (id: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getCourseById', 'id', id) + const localVarPath = `/api/courses/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ListCourseRequest} [listCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listCourse: async (listCourseRequest?: ListCourseRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/courses/search`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listCourseRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * CoursesApi - functional programming interface + * @export + */ +export const CoursesApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = CoursesApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateCourseRequest} [createCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createCourse(createCourseRequest?: CreateCourseRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createCourse(createCourseRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CoursesApi.createCourse']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} courseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteCourse(courseId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteCourse(courseId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CoursesApi.deleteCourse']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} courseId + * @param {EditCourseRequest} [editCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async editCourse(courseId: number, editCourseRequest?: EditCourseRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.editCourse(courseId, editCourseRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CoursesApi.editCourse']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getCourseById(id: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getCourseById(id, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CoursesApi.getCourseById']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ListCourseRequest} [listCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listCourse(listCourseRequest?: ListCourseRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listCourse(listCourseRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CoursesApi.listCourse']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * CoursesApi - factory interface + * @export + */ +export const CoursesApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = CoursesApiFp(configuration) + return { + /** + * + * @param {CreateCourseRequest} [createCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createCourse(createCourseRequest?: CreateCourseRequest, options?: any): AxiosPromise { + return localVarFp.createCourse(createCourseRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} courseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteCourse(courseId: number, options?: any): AxiosPromise { + return localVarFp.deleteCourse(courseId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} courseId + * @param {EditCourseRequest} [editCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + editCourse(courseId: number, editCourseRequest?: EditCourseRequest, options?: any): AxiosPromise { + return localVarFp.editCourse(courseId, editCourseRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCourseById(id: number, options?: any): AxiosPromise { + return localVarFp.getCourseById(id, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ListCourseRequest} [listCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listCourse(listCourseRequest?: ListCourseRequest, options?: any): AxiosPromise { + return localVarFp.listCourse(listCourseRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * CoursesApi - object-oriented interface + * @export + * @class CoursesApi + * @extends {BaseAPI} + */ +export class CoursesApi extends BaseAPI { + /** + * + * @param {CreateCourseRequest} [createCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CoursesApi + */ + public createCourse(createCourseRequest?: CreateCourseRequest, options?: RawAxiosRequestConfig) { + return CoursesApiFp(this.configuration).createCourse(createCourseRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} courseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CoursesApi + */ + public deleteCourse(courseId: number, options?: RawAxiosRequestConfig) { + return CoursesApiFp(this.configuration).deleteCourse(courseId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} courseId + * @param {EditCourseRequest} [editCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CoursesApi + */ + public editCourse(courseId: number, editCourseRequest?: EditCourseRequest, options?: RawAxiosRequestConfig) { + return CoursesApiFp(this.configuration).editCourse(courseId, editCourseRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CoursesApi + */ + public getCourseById(id: number, options?: RawAxiosRequestConfig) { + return CoursesApiFp(this.configuration).getCourseById(id, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ListCourseRequest} [listCourseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CoursesApi + */ + public listCourse(listCourseRequest?: ListCourseRequest, options?: RawAxiosRequestConfig) { + return CoursesApiFp(this.configuration).listCourse(listCourseRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/create-company-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/create-company-endpoint-api.ts new file mode 100644 index 00000000..303ad7f3 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/create-company-endpoint-api.ts @@ -0,0 +1,131 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateCompanyCommand } from '../models'; +/** + * CreateCompanyEndpointApi - axios parameter creator + * @export + */ +export const CreateCompanyEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateCompanyCommand} [createCompanyCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesPost: async (createCompanyCommand?: CreateCompanyCommand, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/companies`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createCompanyCommand, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * CreateCompanyEndpointApi - functional programming interface + * @export + */ +export const CreateCompanyEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = CreateCompanyEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateCompanyCommand} [createCompanyCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiCompaniesPost(createCompanyCommand?: CreateCompanyCommand, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.apiCompaniesPost(createCompanyCommand, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CreateCompanyEndpointApi.apiCompaniesPost']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * CreateCompanyEndpointApi - factory interface + * @export + */ +export const CreateCompanyEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = CreateCompanyEndpointApiFp(configuration) + return { + /** + * + * @param {CreateCompanyCommand} [createCompanyCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesPost(createCompanyCommand?: CreateCompanyCommand, options?: any): AxiosPromise { + return localVarFp.apiCompaniesPost(createCompanyCommand, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * CreateCompanyEndpointApi - object-oriented interface + * @export + * @class CreateCompanyEndpointApi + * @extends {BaseAPI} + */ +export class CreateCompanyEndpointApi extends BaseAPI { + /** + * + * @param {CreateCompanyCommand} [createCompanyCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CreateCompanyEndpointApi + */ + public apiCompaniesPost(createCompanyCommand?: CreateCompanyCommand, options?: RawAxiosRequestConfig) { + return CreateCompanyEndpointApiFp(this.configuration).apiCompaniesPost(createCompanyCommand, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/create-donation-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/create-donation-endpoint-api.ts new file mode 100644 index 00000000..41149a4f --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/create-donation-endpoint-api.ts @@ -0,0 +1,131 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateDonationCommand } from '../models'; +/** + * CreateDonationEndpointApi - axios parameter creator + * @export + */ +export const CreateDonationEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateDonationCommand} [createDonationCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiDonationsPost: async (createDonationCommand?: CreateDonationCommand, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/donations`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createDonationCommand, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * CreateDonationEndpointApi - functional programming interface + * @export + */ +export const CreateDonationEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = CreateDonationEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateDonationCommand} [createDonationCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiDonationsPost(createDonationCommand?: CreateDonationCommand, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.apiDonationsPost(createDonationCommand, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['CreateDonationEndpointApi.apiDonationsPost']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * CreateDonationEndpointApi - factory interface + * @export + */ +export const CreateDonationEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = CreateDonationEndpointApiFp(configuration) + return { + /** + * + * @param {CreateDonationCommand} [createDonationCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiDonationsPost(createDonationCommand?: CreateDonationCommand, options?: any): AxiosPromise { + return localVarFp.apiDonationsPost(createDonationCommand, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * CreateDonationEndpointApi - object-oriented interface + * @export + * @class CreateDonationEndpointApi + * @extends {BaseAPI} + */ +export class CreateDonationEndpointApi extends BaseAPI { + /** + * + * @param {CreateDonationCommand} [createDonationCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof CreateDonationEndpointApi + */ + public apiDonationsPost(createDonationCommand?: CreateDonationCommand, options?: RawAxiosRequestConfig) { + return CreateDonationEndpointApiFp(this.configuration).apiDonationsPost(createDonationCommand, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/delete-donation-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/delete-donation-endpoint-api.ts new file mode 100644 index 00000000..fa0f708e --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/delete-donation-endpoint-api.ts @@ -0,0 +1,129 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +/** + * DeleteDonationEndpointApi - axios parameter creator + * @export + */ +export const DeleteDonationEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiDonationsIdDelete: async (id: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('apiDonationsIdDelete', 'id', id) + const localVarPath = `/api/donations/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * DeleteDonationEndpointApi - functional programming interface + * @export + */ +export const DeleteDonationEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = DeleteDonationEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiDonationsIdDelete(id: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.apiDonationsIdDelete(id, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['DeleteDonationEndpointApi.apiDonationsIdDelete']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * DeleteDonationEndpointApi - factory interface + * @export + */ +export const DeleteDonationEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = DeleteDonationEndpointApiFp(configuration) + return { + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiDonationsIdDelete(id: number, options?: any): AxiosPromise { + return localVarFp.apiDonationsIdDelete(id, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * DeleteDonationEndpointApi - object-oriented interface + * @export + * @class DeleteDonationEndpointApi + * @extends {BaseAPI} + */ +export class DeleteDonationEndpointApi extends BaseAPI { + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DeleteDonationEndpointApi + */ + public apiDonationsIdDelete(id: number, options?: RawAxiosRequestConfig) { + return DeleteDonationEndpointApiFp(this.configuration).apiDonationsIdDelete(id, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/inactivate-company-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/inactivate-company-endpoint-api.ts new file mode 100644 index 00000000..ac672e6a --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/inactivate-company-endpoint-api.ts @@ -0,0 +1,129 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +/** + * InactivateCompanyEndpointApi - axios parameter creator + * @export + */ +export const InactivateCompanyEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesCnpjDelete: async (cnpj: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'cnpj' is not null or undefined + assertParamExists('apiCompaniesCnpjDelete', 'cnpj', cnpj) + const localVarPath = `/api/companies/{cnpj}` + .replace(`{${"cnpj"}}`, encodeURIComponent(String(cnpj))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * InactivateCompanyEndpointApi - functional programming interface + * @export + */ +export const InactivateCompanyEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = InactivateCompanyEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiCompaniesCnpjDelete(cnpj: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.apiCompaniesCnpjDelete(cnpj, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['InactivateCompanyEndpointApi.apiCompaniesCnpjDelete']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * InactivateCompanyEndpointApi - factory interface + * @export + */ +export const InactivateCompanyEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = InactivateCompanyEndpointApiFp(configuration) + return { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesCnpjDelete(cnpj: string, options?: any): AxiosPromise { + return localVarFp.apiCompaniesCnpjDelete(cnpj, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * InactivateCompanyEndpointApi - object-oriented interface + * @export + * @class InactivateCompanyEndpointApi + * @extends {BaseAPI} + */ +export class InactivateCompanyEndpointApi extends BaseAPI { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof InactivateCompanyEndpointApi + */ + public apiCompaniesCnpjDelete(cnpj: string, options?: RawAxiosRequestConfig) { + return InactivateCompanyEndpointApiFp(this.configuration).apiCompaniesCnpjDelete(cnpj, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/list-companies-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/list-companies-endpoint-api.ts new file mode 100644 index 00000000..1eb34c22 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/list-companies-endpoint-api.ts @@ -0,0 +1,133 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { ListCompaniesRequest } from '../models'; +// @ts-ignore +import type { ListCompaniesViewModel } from '../models'; +/** + * ListCompaniesEndpointApi - axios parameter creator + * @export + */ +export const ListCompaniesEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {ListCompaniesRequest} [listCompaniesRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesSearchPost: async (listCompaniesRequest?: ListCompaniesRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/companies/search`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listCompaniesRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * ListCompaniesEndpointApi - functional programming interface + * @export + */ +export const ListCompaniesEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = ListCompaniesEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {ListCompaniesRequest} [listCompaniesRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiCompaniesSearchPost(listCompaniesRequest?: ListCompaniesRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.apiCompaniesSearchPost(listCompaniesRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ListCompaniesEndpointApi.apiCompaniesSearchPost']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * ListCompaniesEndpointApi - factory interface + * @export + */ +export const ListCompaniesEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = ListCompaniesEndpointApiFp(configuration) + return { + /** + * + * @param {ListCompaniesRequest} [listCompaniesRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesSearchPost(listCompaniesRequest?: ListCompaniesRequest, options?: any): AxiosPromise { + return localVarFp.apiCompaniesSearchPost(listCompaniesRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * ListCompaniesEndpointApi - object-oriented interface + * @export + * @class ListCompaniesEndpointApi + * @extends {BaseAPI} + */ +export class ListCompaniesEndpointApi extends BaseAPI { + /** + * + * @param {ListCompaniesRequest} [listCompaniesRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ListCompaniesEndpointApi + */ + public apiCompaniesSearchPost(listCompaniesRequest?: ListCompaniesRequest, options?: RawAxiosRequestConfig) { + return ListCompaniesEndpointApiFp(this.configuration).apiCompaniesSearchPost(listCompaniesRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/list-company-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/list-company-endpoint-api.ts new file mode 100644 index 00000000..52c7f403 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/list-company-endpoint-api.ts @@ -0,0 +1,129 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +/** + * ListCompanyEndpointApi - axios parameter creator + * @export + */ +export const ListCompanyEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCompanyByCnpj: async (cnpj: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'cnpj' is not null or undefined + assertParamExists('getCompanyByCnpj', 'cnpj', cnpj) + const localVarPath = `/api/companies/{cnpj}` + .replace(`{${"cnpj"}}`, encodeURIComponent(String(cnpj))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * ListCompanyEndpointApi - functional programming interface + * @export + */ +export const ListCompanyEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = ListCompanyEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getCompanyByCnpj(cnpj: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getCompanyByCnpj(cnpj, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ListCompanyEndpointApi.getCompanyByCnpj']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * ListCompanyEndpointApi - factory interface + * @export + */ +export const ListCompanyEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = ListCompanyEndpointApiFp(configuration) + return { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCompanyByCnpj(cnpj: string, options?: any): AxiosPromise { + return localVarFp.getCompanyByCnpj(cnpj, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * ListCompanyEndpointApi - object-oriented interface + * @export + * @class ListCompanyEndpointApi + * @extends {BaseAPI} + */ +export class ListCompanyEndpointApi extends BaseAPI { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ListCompanyEndpointApi + */ + public getCompanyByCnpj(cnpj: string, options?: RawAxiosRequestConfig) { + return ListCompanyEndpointApiFp(this.configuration).getCompanyByCnpj(cnpj, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/list-donation-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/list-donation-endpoint-api.ts new file mode 100644 index 00000000..484f4499 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/list-donation-endpoint-api.ts @@ -0,0 +1,129 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +/** + * ListDonationEndpointApi - axios parameter creator + * @export + */ +export const ListDonationEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getDonationById: async (id: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('getDonationById', 'id', id) + const localVarPath = `/api/donations/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * ListDonationEndpointApi - functional programming interface + * @export + */ +export const ListDonationEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = ListDonationEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getDonationById(id: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getDonationById(id, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ListDonationEndpointApi.getDonationById']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * ListDonationEndpointApi - factory interface + * @export + */ +export const ListDonationEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = ListDonationEndpointApiFp(configuration) + return { + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getDonationById(id: number, options?: any): AxiosPromise { + return localVarFp.getDonationById(id, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * ListDonationEndpointApi - object-oriented interface + * @export + * @class ListDonationEndpointApi + * @extends {BaseAPI} + */ +export class ListDonationEndpointApi extends BaseAPI { + /** + * + * @param {number} id + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ListDonationEndpointApi + */ + public getDonationById(id: number, options?: RawAxiosRequestConfig) { + return ListDonationEndpointApiFp(this.configuration).getDonationById(id, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/list-donations-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/list-donations-endpoint-api.ts new file mode 100644 index 00000000..d2b0179c --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/list-donations-endpoint-api.ts @@ -0,0 +1,133 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { ListDonationsRequest } from '../models'; +// @ts-ignore +import type { ListDonationsViewModel } from '../models'; +/** + * ListDonationsEndpointApi - axios parameter creator + * @export + */ +export const ListDonationsEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {ListDonationsRequest} [listDonationsRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiDonationsSearchPost: async (listDonationsRequest?: ListDonationsRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/donations/search`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listDonationsRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * ListDonationsEndpointApi - functional programming interface + * @export + */ +export const ListDonationsEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = ListDonationsEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {ListDonationsRequest} [listDonationsRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiDonationsSearchPost(listDonationsRequest?: ListDonationsRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.apiDonationsSearchPost(listDonationsRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ListDonationsEndpointApi.apiDonationsSearchPost']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * ListDonationsEndpointApi - factory interface + * @export + */ +export const ListDonationsEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = ListDonationsEndpointApiFp(configuration) + return { + /** + * + * @param {ListDonationsRequest} [listDonationsRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiDonationsSearchPost(listDonationsRequest?: ListDonationsRequest, options?: any): AxiosPromise { + return localVarFp.apiDonationsSearchPost(listDonationsRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * ListDonationsEndpointApi - object-oriented interface + * @export + * @class ListDonationsEndpointApi + * @extends {BaseAPI} + */ +export class ListDonationsEndpointApi extends BaseAPI { + /** + * + * @param {ListDonationsRequest} [listDonationsRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ListDonationsEndpointApi + */ + public apiDonationsSearchPost(listDonationsRequest?: ListDonationsRequest, options?: RawAxiosRequestConfig) { + return ListDonationsEndpointApiFp(this.configuration).apiDonationsSearchPost(listDonationsRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/origins-business-cases-api.ts b/codigo-fonte/frontend/src/api/apis/origins-business-cases-api.ts new file mode 100644 index 00000000..10a8c20e --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/origins-business-cases-api.ts @@ -0,0 +1,499 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateOriginBusinessCaseRequest } from '../models'; +// @ts-ignore +import type { CreateOriginBusinessCaseResponse } from '../models'; +// @ts-ignore +import type { GetOriginBusinessCaseResponse } from '../models'; +// @ts-ignore +import type { ListOriginBusinessCaseRequest } from '../models'; +// @ts-ignore +import type { ListOriginBusinessCaseViewModel } from '../models'; +// @ts-ignore +import type { ListOriginsBusinessCaseByBusinessCaseIdRequest } from '../models'; +// @ts-ignore +import type { ListOriginsBusinessCaseByBusinessCaseIdViewModel } from '../models'; +// @ts-ignore +import type { UpdateOriginBusinessCaseRequest } from '../models'; +// @ts-ignore +import type { UpdateOriginBusinessCaseResponse } from '../models'; +/** + * OriginsBusinessCasesApi - axios parameter creator + * @export + */ +export const OriginsBusinessCasesApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateOriginBusinessCaseRequest} [createOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createOriginBusinessCase: async (createOriginBusinessCaseRequest?: CreateOriginBusinessCaseRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/origins-business-cases/CreateOriginBusinessCase`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createOriginBusinessCaseRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} originBusinessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteOriginBusinessCase: async (originBusinessCaseId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'originBusinessCaseId' is not null or undefined + assertParamExists('deleteOriginBusinessCase', 'originBusinessCaseId', originBusinessCaseId) + const localVarPath = `/api/origins-business-cases/{originBusinessCaseId}` + .replace(`{${"originBusinessCaseId"}}`, encodeURIComponent(String(originBusinessCaseId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} originBusinessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getOriginBusinessCase: async (originBusinessCaseId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'originBusinessCaseId' is not null or undefined + assertParamExists('getOriginBusinessCase', 'originBusinessCaseId', originBusinessCaseId) + const localVarPath = `/api/origins-business-cases/{originBusinessCaseId}` + .replace(`{${"originBusinessCaseId"}}`, encodeURIComponent(String(originBusinessCaseId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ListOriginBusinessCaseRequest} [listOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listOriginBusinessCase: async (listOriginBusinessCaseRequest?: ListOriginBusinessCaseRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/origins-business-cases/ListOriginBusinessCase`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listOriginBusinessCaseRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ListOriginsBusinessCaseByBusinessCaseIdRequest} [listOriginsBusinessCaseByBusinessCaseIdRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listOriginsBusinessCaseByBusinessCaseId: async (listOriginsBusinessCaseByBusinessCaseIdRequest?: ListOriginsBusinessCaseByBusinessCaseIdRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/origins-business-cases/ListOriginsBusinessCaseByBusinessCaseId`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listOriginsBusinessCaseByBusinessCaseIdRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} originBusinessCaseId + * @param {UpdateOriginBusinessCaseRequest} [updateOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateOriginBusinessCase: async (originBusinessCaseId: number, updateOriginBusinessCaseRequest?: UpdateOriginBusinessCaseRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'originBusinessCaseId' is not null or undefined + assertParamExists('updateOriginBusinessCase', 'originBusinessCaseId', originBusinessCaseId) + const localVarPath = `/api/origins-business-cases/{originBusinessCaseId}` + .replace(`{${"originBusinessCaseId"}}`, encodeURIComponent(String(originBusinessCaseId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(updateOriginBusinessCaseRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * OriginsBusinessCasesApi - functional programming interface + * @export + */ +export const OriginsBusinessCasesApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = OriginsBusinessCasesApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateOriginBusinessCaseRequest} [createOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createOriginBusinessCase(createOriginBusinessCaseRequest?: CreateOriginBusinessCaseRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createOriginBusinessCase(createOriginBusinessCaseRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OriginsBusinessCasesApi.createOriginBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} originBusinessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteOriginBusinessCase(originBusinessCaseId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteOriginBusinessCase(originBusinessCaseId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OriginsBusinessCasesApi.deleteOriginBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} originBusinessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getOriginBusinessCase(originBusinessCaseId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getOriginBusinessCase(originBusinessCaseId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OriginsBusinessCasesApi.getOriginBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ListOriginBusinessCaseRequest} [listOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listOriginBusinessCase(listOriginBusinessCaseRequest?: ListOriginBusinessCaseRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listOriginBusinessCase(listOriginBusinessCaseRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OriginsBusinessCasesApi.listOriginBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ListOriginsBusinessCaseByBusinessCaseIdRequest} [listOriginsBusinessCaseByBusinessCaseIdRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listOriginsBusinessCaseByBusinessCaseId(listOriginsBusinessCaseByBusinessCaseIdRequest?: ListOriginsBusinessCaseByBusinessCaseIdRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listOriginsBusinessCaseByBusinessCaseId(listOriginsBusinessCaseByBusinessCaseIdRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OriginsBusinessCasesApi.listOriginsBusinessCaseByBusinessCaseId']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} originBusinessCaseId + * @param {UpdateOriginBusinessCaseRequest} [updateOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateOriginBusinessCase(originBusinessCaseId: number, updateOriginBusinessCaseRequest?: UpdateOriginBusinessCaseRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateOriginBusinessCase(originBusinessCaseId, updateOriginBusinessCaseRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OriginsBusinessCasesApi.updateOriginBusinessCase']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * OriginsBusinessCasesApi - factory interface + * @export + */ +export const OriginsBusinessCasesApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = OriginsBusinessCasesApiFp(configuration) + return { + /** + * + * @param {CreateOriginBusinessCaseRequest} [createOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createOriginBusinessCase(createOriginBusinessCaseRequest?: CreateOriginBusinessCaseRequest, options?: any): AxiosPromise { + return localVarFp.createOriginBusinessCase(createOriginBusinessCaseRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} originBusinessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteOriginBusinessCase(originBusinessCaseId: number, options?: any): AxiosPromise { + return localVarFp.deleteOriginBusinessCase(originBusinessCaseId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} originBusinessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getOriginBusinessCase(originBusinessCaseId: number, options?: any): AxiosPromise { + return localVarFp.getOriginBusinessCase(originBusinessCaseId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ListOriginBusinessCaseRequest} [listOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listOriginBusinessCase(listOriginBusinessCaseRequest?: ListOriginBusinessCaseRequest, options?: any): AxiosPromise { + return localVarFp.listOriginBusinessCase(listOriginBusinessCaseRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ListOriginsBusinessCaseByBusinessCaseIdRequest} [listOriginsBusinessCaseByBusinessCaseIdRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listOriginsBusinessCaseByBusinessCaseId(listOriginsBusinessCaseByBusinessCaseIdRequest?: ListOriginsBusinessCaseByBusinessCaseIdRequest, options?: any): AxiosPromise { + return localVarFp.listOriginsBusinessCaseByBusinessCaseId(listOriginsBusinessCaseByBusinessCaseIdRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} originBusinessCaseId + * @param {UpdateOriginBusinessCaseRequest} [updateOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateOriginBusinessCase(originBusinessCaseId: number, updateOriginBusinessCaseRequest?: UpdateOriginBusinessCaseRequest, options?: any): AxiosPromise { + return localVarFp.updateOriginBusinessCase(originBusinessCaseId, updateOriginBusinessCaseRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * OriginsBusinessCasesApi - object-oriented interface + * @export + * @class OriginsBusinessCasesApi + * @extends {BaseAPI} + */ +export class OriginsBusinessCasesApi extends BaseAPI { + /** + * + * @param {CreateOriginBusinessCaseRequest} [createOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OriginsBusinessCasesApi + */ + public createOriginBusinessCase(createOriginBusinessCaseRequest?: CreateOriginBusinessCaseRequest, options?: RawAxiosRequestConfig) { + return OriginsBusinessCasesApiFp(this.configuration).createOriginBusinessCase(createOriginBusinessCaseRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} originBusinessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OriginsBusinessCasesApi + */ + public deleteOriginBusinessCase(originBusinessCaseId: number, options?: RawAxiosRequestConfig) { + return OriginsBusinessCasesApiFp(this.configuration).deleteOriginBusinessCase(originBusinessCaseId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} originBusinessCaseId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OriginsBusinessCasesApi + */ + public getOriginBusinessCase(originBusinessCaseId: number, options?: RawAxiosRequestConfig) { + return OriginsBusinessCasesApiFp(this.configuration).getOriginBusinessCase(originBusinessCaseId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ListOriginBusinessCaseRequest} [listOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OriginsBusinessCasesApi + */ + public listOriginBusinessCase(listOriginBusinessCaseRequest?: ListOriginBusinessCaseRequest, options?: RawAxiosRequestConfig) { + return OriginsBusinessCasesApiFp(this.configuration).listOriginBusinessCase(listOriginBusinessCaseRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ListOriginsBusinessCaseByBusinessCaseIdRequest} [listOriginsBusinessCaseByBusinessCaseIdRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OriginsBusinessCasesApi + */ + public listOriginsBusinessCaseByBusinessCaseId(listOriginsBusinessCaseByBusinessCaseIdRequest?: ListOriginsBusinessCaseByBusinessCaseIdRequest, options?: RawAxiosRequestConfig) { + return OriginsBusinessCasesApiFp(this.configuration).listOriginsBusinessCaseByBusinessCaseId(listOriginsBusinessCaseByBusinessCaseIdRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} originBusinessCaseId + * @param {UpdateOriginBusinessCaseRequest} [updateOriginBusinessCaseRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OriginsBusinessCasesApi + */ + public updateOriginBusinessCase(originBusinessCaseId: number, updateOriginBusinessCaseRequest?: UpdateOriginBusinessCaseRequest, options?: RawAxiosRequestConfig) { + return OriginsBusinessCasesApiFp(this.configuration).updateOriginBusinessCase(originBusinessCaseId, updateOriginBusinessCaseRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/oscs-api.ts b/codigo-fonte/frontend/src/api/apis/oscs-api.ts new file mode 100644 index 00000000..7552077d --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/oscs-api.ts @@ -0,0 +1,426 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateOscRequest } from '../models'; +// @ts-ignore +import type { CreateOscResponse } from '../models'; +// @ts-ignore +import type { GetOscResponse } from '../models'; +// @ts-ignore +import type { ListOscRequest } from '../models'; +// @ts-ignore +import type { ListOscViewModel } from '../models'; +// @ts-ignore +import type { UpdateOscRequest } from '../models'; +// @ts-ignore +import type { UpdateOscResponse } from '../models'; +/** + * OscsApi - axios parameter creator + * @export + */ +export const OscsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateOscRequest} [createOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createOsc: async (createOscRequest?: CreateOscRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/osc/CreateOsc`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createOscRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} oscId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteOsc: async (oscId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'oscId' is not null or undefined + assertParamExists('deleteOsc', 'oscId', oscId) + const localVarPath = `/api/osc/{oscId}` + .replace(`{${"oscId"}}`, encodeURIComponent(String(oscId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} oscId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getOsc: async (oscId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'oscId' is not null or undefined + assertParamExists('getOsc', 'oscId', oscId) + const localVarPath = `/api/oscs/{oscId}` + .replace(`{${"oscId"}}`, encodeURIComponent(String(oscId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ListOscRequest} [listOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listOsc: async (listOscRequest?: ListOscRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/osc/ListOsc`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listOscRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} oscId + * @param {UpdateOscRequest} [updateOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateOsc: async (oscId: number, updateOscRequest?: UpdateOscRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'oscId' is not null or undefined + assertParamExists('updateOsc', 'oscId', oscId) + const localVarPath = `/api/oscs/{oscId}` + .replace(`{${"oscId"}}`, encodeURIComponent(String(oscId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(updateOscRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * OscsApi - functional programming interface + * @export + */ +export const OscsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = OscsApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateOscRequest} [createOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createOsc(createOscRequest?: CreateOscRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createOsc(createOscRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OscsApi.createOsc']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} oscId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteOsc(oscId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteOsc(oscId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OscsApi.deleteOsc']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} oscId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getOsc(oscId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getOsc(oscId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OscsApi.getOsc']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ListOscRequest} [listOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listOsc(listOscRequest?: ListOscRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listOsc(listOscRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OscsApi.listOsc']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} oscId + * @param {UpdateOscRequest} [updateOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateOsc(oscId: number, updateOscRequest?: UpdateOscRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateOsc(oscId, updateOscRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['OscsApi.updateOsc']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * OscsApi - factory interface + * @export + */ +export const OscsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = OscsApiFp(configuration) + return { + /** + * + * @param {CreateOscRequest} [createOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createOsc(createOscRequest?: CreateOscRequest, options?: any): AxiosPromise { + return localVarFp.createOsc(createOscRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} oscId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteOsc(oscId: number, options?: any): AxiosPromise { + return localVarFp.deleteOsc(oscId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} oscId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getOsc(oscId: number, options?: any): AxiosPromise { + return localVarFp.getOsc(oscId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ListOscRequest} [listOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listOsc(listOscRequest?: ListOscRequest, options?: any): AxiosPromise { + return localVarFp.listOsc(listOscRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} oscId + * @param {UpdateOscRequest} [updateOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateOsc(oscId: number, updateOscRequest?: UpdateOscRequest, options?: any): AxiosPromise { + return localVarFp.updateOsc(oscId, updateOscRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * OscsApi - object-oriented interface + * @export + * @class OscsApi + * @extends {BaseAPI} + */ +export class OscsApi extends BaseAPI { + /** + * + * @param {CreateOscRequest} [createOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OscsApi + */ + public createOsc(createOscRequest?: CreateOscRequest, options?: RawAxiosRequestConfig) { + return OscsApiFp(this.configuration).createOsc(createOscRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} oscId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OscsApi + */ + public deleteOsc(oscId: number, options?: RawAxiosRequestConfig) { + return OscsApiFp(this.configuration).deleteOsc(oscId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} oscId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OscsApi + */ + public getOsc(oscId: number, options?: RawAxiosRequestConfig) { + return OscsApiFp(this.configuration).getOsc(oscId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ListOscRequest} [listOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OscsApi + */ + public listOsc(listOscRequest?: ListOscRequest, options?: RawAxiosRequestConfig) { + return OscsApiFp(this.configuration).listOsc(listOscRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} oscId + * @param {UpdateOscRequest} [updateOscRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof OscsApi + */ + public updateOsc(oscId: number, updateOscRequest?: UpdateOscRequest, options?: RawAxiosRequestConfig) { + return OscsApiFp(this.configuration).updateOsc(oscId, updateOscRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/persons-api.ts b/codigo-fonte/frontend/src/api/apis/persons-api.ts new file mode 100644 index 00000000..8fdfc51e --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/persons-api.ts @@ -0,0 +1,426 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreatePersonRequest } from '../models'; +// @ts-ignore +import type { CreatePersonResponse } from '../models'; +// @ts-ignore +import type { ListPersonRequest } from '../models'; +// @ts-ignore +import type { ListPersonViewModel } from '../models'; +// @ts-ignore +import type { PersonViewModel } from '../models'; +// @ts-ignore +import type { UpdatePersonRequest } from '../models'; +// @ts-ignore +import type { UpdatePersonResponse } from '../models'; +/** + * PersonsApi - axios parameter creator + * @export + */ +export const PersonsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreatePersonRequest} [createPersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createPerson: async (createPersonRequest?: CreatePersonRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/persons`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createPersonRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} personId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deletePerson: async (personId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'personId' is not null or undefined + assertParamExists('deletePerson', 'personId', personId) + const localVarPath = `/api/persons/{personId}` + .replace(`{${"personId"}}`, encodeURIComponent(String(personId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} personId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getPerson: async (personId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'personId' is not null or undefined + assertParamExists('getPerson', 'personId', personId) + const localVarPath = `/api/persons/{personId}` + .replace(`{${"personId"}}`, encodeURIComponent(String(personId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ListPersonRequest} [listPersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listPerson: async (listPersonRequest?: ListPersonRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/persons/ListPerson`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listPersonRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} personId + * @param {UpdatePersonRequest} [updatePersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updatePerson: async (personId: number, updatePersonRequest?: UpdatePersonRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'personId' is not null or undefined + assertParamExists('updatePerson', 'personId', personId) + const localVarPath = `/api/persons/{personId}` + .replace(`{${"personId"}}`, encodeURIComponent(String(personId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(updatePersonRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * PersonsApi - functional programming interface + * @export + */ +export const PersonsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = PersonsApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreatePersonRequest} [createPersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createPerson(createPersonRequest?: CreatePersonRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createPerson(createPersonRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['PersonsApi.createPerson']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} personId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deletePerson(personId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deletePerson(personId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['PersonsApi.deletePerson']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} personId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getPerson(personId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getPerson(personId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['PersonsApi.getPerson']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ListPersonRequest} [listPersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listPerson(listPersonRequest?: ListPersonRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listPerson(listPersonRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['PersonsApi.listPerson']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} personId + * @param {UpdatePersonRequest} [updatePersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updatePerson(personId: number, updatePersonRequest?: UpdatePersonRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updatePerson(personId, updatePersonRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['PersonsApi.updatePerson']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * PersonsApi - factory interface + * @export + */ +export const PersonsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = PersonsApiFp(configuration) + return { + /** + * + * @param {CreatePersonRequest} [createPersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createPerson(createPersonRequest?: CreatePersonRequest, options?: any): AxiosPromise { + return localVarFp.createPerson(createPersonRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} personId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deletePerson(personId: number, options?: any): AxiosPromise { + return localVarFp.deletePerson(personId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} personId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getPerson(personId: number, options?: any): AxiosPromise { + return localVarFp.getPerson(personId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ListPersonRequest} [listPersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listPerson(listPersonRequest?: ListPersonRequest, options?: any): AxiosPromise { + return localVarFp.listPerson(listPersonRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} personId + * @param {UpdatePersonRequest} [updatePersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updatePerson(personId: number, updatePersonRequest?: UpdatePersonRequest, options?: any): AxiosPromise { + return localVarFp.updatePerson(personId, updatePersonRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * PersonsApi - object-oriented interface + * @export + * @class PersonsApi + * @extends {BaseAPI} + */ +export class PersonsApi extends BaseAPI { + /** + * + * @param {CreatePersonRequest} [createPersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PersonsApi + */ + public createPerson(createPersonRequest?: CreatePersonRequest, options?: RawAxiosRequestConfig) { + return PersonsApiFp(this.configuration).createPerson(createPersonRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} personId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PersonsApi + */ + public deletePerson(personId: number, options?: RawAxiosRequestConfig) { + return PersonsApiFp(this.configuration).deletePerson(personId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} personId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PersonsApi + */ + public getPerson(personId: number, options?: RawAxiosRequestConfig) { + return PersonsApiFp(this.configuration).getPerson(personId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ListPersonRequest} [listPersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PersonsApi + */ + public listPerson(listPersonRequest?: ListPersonRequest, options?: RawAxiosRequestConfig) { + return PersonsApiFp(this.configuration).listPerson(listPersonRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} personId + * @param {UpdatePersonRequest} [updatePersonRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof PersonsApi + */ + public updatePerson(personId: number, updatePersonRequest?: UpdatePersonRequest, options?: RawAxiosRequestConfig) { + return PersonsApiFp(this.configuration).updatePerson(personId, updatePersonRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/reactivate-company-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/reactivate-company-endpoint-api.ts new file mode 100644 index 00000000..1b6d268c --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/reactivate-company-endpoint-api.ts @@ -0,0 +1,129 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +/** + * ReactivateCompanyEndpointApi - axios parameter creator + * @export + */ +export const ReactivateCompanyEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesCnpjActivatePatch: async (cnpj: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'cnpj' is not null or undefined + assertParamExists('apiCompaniesCnpjActivatePatch', 'cnpj', cnpj) + const localVarPath = `/api/companies/{cnpj}/activate` + .replace(`{${"cnpj"}}`, encodeURIComponent(String(cnpj))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * ReactivateCompanyEndpointApi - functional programming interface + * @export + */ +export const ReactivateCompanyEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = ReactivateCompanyEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiCompaniesCnpjActivatePatch(cnpj: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.apiCompaniesCnpjActivatePatch(cnpj, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ReactivateCompanyEndpointApi.apiCompaniesCnpjActivatePatch']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * ReactivateCompanyEndpointApi - factory interface + * @export + */ +export const ReactivateCompanyEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = ReactivateCompanyEndpointApiFp(configuration) + return { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesCnpjActivatePatch(cnpj: string, options?: any): AxiosPromise { + return localVarFp.apiCompaniesCnpjActivatePatch(cnpj, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * ReactivateCompanyEndpointApi - object-oriented interface + * @export + * @class ReactivateCompanyEndpointApi + * @extends {BaseAPI} + */ +export class ReactivateCompanyEndpointApi extends BaseAPI { + /** + * + * @param {string} cnpj + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof ReactivateCompanyEndpointApi + */ + public apiCompaniesCnpjActivatePatch(cnpj: string, options?: RawAxiosRequestConfig) { + return ReactivateCompanyEndpointApiFp(this.configuration).apiCompaniesCnpjActivatePatch(cnpj, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/teams-api.ts b/codigo-fonte/frontend/src/api/apis/teams-api.ts new file mode 100644 index 00000000..918fb209 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/teams-api.ts @@ -0,0 +1,428 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateTeamRequest } from '../models'; +// @ts-ignore +import type { CreateTeamResponse } from '../models'; +// @ts-ignore +import type { DeleteTeamResponse } from '../models'; +// @ts-ignore +import type { EditTeamRequest } from '../models'; +// @ts-ignore +import type { EditTeamResponse } from '../models'; +// @ts-ignore +import type { GetTeamByIdResponse } from '../models'; +// @ts-ignore +import type { ListTeamRequest } from '../models'; +// @ts-ignore +import type { ListTeamViewModel } from '../models'; +/** + * TeamsApi - axios parameter creator + * @export + */ +export const TeamsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateTeamRequest} [createTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTeam: async (createTeamRequest?: CreateTeamRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/teams/CreateTeam`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createTeamRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} teamId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteTeam: async (teamId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'teamId' is not null or undefined + assertParamExists('deleteTeam', 'teamId', teamId) + const localVarPath = `/api/teams/{teamId}` + .replace(`{${"teamId"}}`, encodeURIComponent(String(teamId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} teamId + * @param {EditTeamRequest} [editTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + editTeam: async (teamId: number, editTeamRequest?: EditTeamRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'teamId' is not null or undefined + assertParamExists('editTeam', 'teamId', teamId) + const localVarPath = `/api/teams/{teamId}` + .replace(`{${"teamId"}}`, encodeURIComponent(String(teamId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(editTeamRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} teamId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTeamById: async (teamId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'teamId' is not null or undefined + assertParamExists('getTeamById', 'teamId', teamId) + const localVarPath = `/api/teams/{teamId}` + .replace(`{${"teamId"}}`, encodeURIComponent(String(teamId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ListTeamRequest} [listTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTeam: async (listTeamRequest?: ListTeamRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/teams/search`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listTeamRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * TeamsApi - functional programming interface + * @export + */ +export const TeamsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = TeamsApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateTeamRequest} [createTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createTeam(createTeamRequest?: CreateTeamRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createTeam(createTeamRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TeamsApi.createTeam']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} teamId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteTeam(teamId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteTeam(teamId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TeamsApi.deleteTeam']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} teamId + * @param {EditTeamRequest} [editTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async editTeam(teamId: number, editTeamRequest?: EditTeamRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.editTeam(teamId, editTeamRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TeamsApi.editTeam']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} teamId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getTeamById(teamId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getTeamById(teamId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TeamsApi.getTeamById']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ListTeamRequest} [listTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listTeam(listTeamRequest?: ListTeamRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listTeam(listTeamRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['TeamsApi.listTeam']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * TeamsApi - factory interface + * @export + */ +export const TeamsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = TeamsApiFp(configuration) + return { + /** + * + * @param {CreateTeamRequest} [createTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createTeam(createTeamRequest?: CreateTeamRequest, options?: any): AxiosPromise { + return localVarFp.createTeam(createTeamRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} teamId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteTeam(teamId: number, options?: any): AxiosPromise { + return localVarFp.deleteTeam(teamId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} teamId + * @param {EditTeamRequest} [editTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + editTeam(teamId: number, editTeamRequest?: EditTeamRequest, options?: any): AxiosPromise { + return localVarFp.editTeam(teamId, editTeamRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} teamId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getTeamById(teamId: number, options?: any): AxiosPromise { + return localVarFp.getTeamById(teamId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ListTeamRequest} [listTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listTeam(listTeamRequest?: ListTeamRequest, options?: any): AxiosPromise { + return localVarFp.listTeam(listTeamRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * TeamsApi - object-oriented interface + * @export + * @class TeamsApi + * @extends {BaseAPI} + */ +export class TeamsApi extends BaseAPI { + /** + * + * @param {CreateTeamRequest} [createTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TeamsApi + */ + public createTeam(createTeamRequest?: CreateTeamRequest, options?: RawAxiosRequestConfig) { + return TeamsApiFp(this.configuration).createTeam(createTeamRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} teamId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TeamsApi + */ + public deleteTeam(teamId: number, options?: RawAxiosRequestConfig) { + return TeamsApiFp(this.configuration).deleteTeam(teamId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} teamId + * @param {EditTeamRequest} [editTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TeamsApi + */ + public editTeam(teamId: number, editTeamRequest?: EditTeamRequest, options?: RawAxiosRequestConfig) { + return TeamsApiFp(this.configuration).editTeam(teamId, editTeamRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} teamId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TeamsApi + */ + public getTeamById(teamId: number, options?: RawAxiosRequestConfig) { + return TeamsApiFp(this.configuration).getTeamById(teamId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ListTeamRequest} [listTeamRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof TeamsApi + */ + public listTeam(listTeamRequest?: ListTeamRequest, options?: RawAxiosRequestConfig) { + return TeamsApiFp(this.configuration).listTeam(listTeamRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/update-company-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/update-company-endpoint-api.ts new file mode 100644 index 00000000..3827d645 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/update-company-endpoint-api.ts @@ -0,0 +1,138 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { UpdateCompanyCommand } from '../models'; +/** + * UpdateCompanyEndpointApi - axios parameter creator + * @export + */ +export const UpdateCompanyEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {string} cnpj + * @param {UpdateCompanyCommand} [updateCompanyCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesCnpjPut: async (cnpj: string, updateCompanyCommand?: UpdateCompanyCommand, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'cnpj' is not null or undefined + assertParamExists('apiCompaniesCnpjPut', 'cnpj', cnpj) + const localVarPath = `/api/companies/{cnpj}` + .replace(`{${"cnpj"}}`, encodeURIComponent(String(cnpj))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(updateCompanyCommand, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * UpdateCompanyEndpointApi - functional programming interface + * @export + */ +export const UpdateCompanyEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = UpdateCompanyEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {string} cnpj + * @param {UpdateCompanyCommand} [updateCompanyCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiCompaniesCnpjPut(cnpj: string, updateCompanyCommand?: UpdateCompanyCommand, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.apiCompaniesCnpjPut(cnpj, updateCompanyCommand, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['UpdateCompanyEndpointApi.apiCompaniesCnpjPut']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * UpdateCompanyEndpointApi - factory interface + * @export + */ +export const UpdateCompanyEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = UpdateCompanyEndpointApiFp(configuration) + return { + /** + * + * @param {string} cnpj + * @param {UpdateCompanyCommand} [updateCompanyCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiCompaniesCnpjPut(cnpj: string, updateCompanyCommand?: UpdateCompanyCommand, options?: any): AxiosPromise { + return localVarFp.apiCompaniesCnpjPut(cnpj, updateCompanyCommand, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * UpdateCompanyEndpointApi - object-oriented interface + * @export + * @class UpdateCompanyEndpointApi + * @extends {BaseAPI} + */ +export class UpdateCompanyEndpointApi extends BaseAPI { + /** + * + * @param {string} cnpj + * @param {UpdateCompanyCommand} [updateCompanyCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UpdateCompanyEndpointApi + */ + public apiCompaniesCnpjPut(cnpj: string, updateCompanyCommand?: UpdateCompanyCommand, options?: RawAxiosRequestConfig) { + return UpdateCompanyEndpointApiFp(this.configuration).apiCompaniesCnpjPut(cnpj, updateCompanyCommand, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/update-donation-endpoint-api.ts b/codigo-fonte/frontend/src/api/apis/update-donation-endpoint-api.ts new file mode 100644 index 00000000..0337718b --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/update-donation-endpoint-api.ts @@ -0,0 +1,138 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { UpdateDonationCommand } from '../models'; +/** + * UpdateDonationEndpointApi - axios parameter creator + * @export + */ +export const UpdateDonationEndpointApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {number} id + * @param {UpdateDonationCommand} [updateDonationCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiDonationsIdPut: async (id: number, updateDonationCommand?: UpdateDonationCommand, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'id' is not null or undefined + assertParamExists('apiDonationsIdPut', 'id', id) + const localVarPath = `/api/donations/{id}` + .replace(`{${"id"}}`, encodeURIComponent(String(id))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(updateDonationCommand, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * UpdateDonationEndpointApi - functional programming interface + * @export + */ +export const UpdateDonationEndpointApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = UpdateDonationEndpointApiAxiosParamCreator(configuration) + return { + /** + * + * @param {number} id + * @param {UpdateDonationCommand} [updateDonationCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiDonationsIdPut(id: number, updateDonationCommand?: UpdateDonationCommand, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.apiDonationsIdPut(id, updateDonationCommand, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['UpdateDonationEndpointApi.apiDonationsIdPut']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * UpdateDonationEndpointApi - factory interface + * @export + */ +export const UpdateDonationEndpointApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = UpdateDonationEndpointApiFp(configuration) + return { + /** + * + * @param {number} id + * @param {UpdateDonationCommand} [updateDonationCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiDonationsIdPut(id: number, updateDonationCommand?: UpdateDonationCommand, options?: any): AxiosPromise { + return localVarFp.apiDonationsIdPut(id, updateDonationCommand, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * UpdateDonationEndpointApi - object-oriented interface + * @export + * @class UpdateDonationEndpointApi + * @extends {BaseAPI} + */ +export class UpdateDonationEndpointApi extends BaseAPI { + /** + * + * @param {number} id + * @param {UpdateDonationCommand} [updateDonationCommand] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UpdateDonationEndpointApi + */ + public apiDonationsIdPut(id: number, updateDonationCommand?: UpdateDonationCommand, options?: RawAxiosRequestConfig) { + return UpdateDonationEndpointApiFp(this.configuration).apiDonationsIdPut(id, updateDonationCommand, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/apis/users-api.ts b/codigo-fonte/frontend/src/api/apis/users-api.ts new file mode 100644 index 00000000..dfa12621 --- /dev/null +++ b/codigo-fonte/frontend/src/api/apis/users-api.ts @@ -0,0 +1,428 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateUserRequest } from '../models'; +// @ts-ignore +import type { CreateUserResponse } from '../models'; +// @ts-ignore +import type { ListUserRequest } from '../models'; +// @ts-ignore +import type { ListUserViewModel } from '../models'; +// @ts-ignore +import type { ProblemDetails } from '../models'; +// @ts-ignore +import type { UpdateUserRequest } from '../models'; +// @ts-ignore +import type { UpdateUserResponse } from '../models'; +// @ts-ignore +import type { UserViewModel } from '../models'; +/** + * UsersApi - axios parameter creator + * @export + */ +export const UsersApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @param {CreateUserRequest} [createUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createUser: async (createUserRequest?: CreateUserRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/users/CreateUser`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createUserRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteUser: async (userId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'userId' is not null or undefined + assertParamExists('deleteUser', 'userId', userId) + const localVarPath = `/api/users/{userId}` + .replace(`{${"userId"}}`, encodeURIComponent(String(userId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserById: async (userId: number, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'userId' is not null or undefined + assertParamExists('getUserById', 'userId', userId) + const localVarPath = `/api/users/{userId}` + .replace(`{${"userId"}}`, encodeURIComponent(String(userId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {ListUserRequest} [listUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listUser: async (listUserRequest?: ListUserRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/users/ListUser`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(listUserRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @param {number} userId + * @param {UpdateUserRequest} [updateUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateUser: async (userId: number, updateUserRequest?: UpdateUserRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'userId' is not null or undefined + assertParamExists('updateUser', 'userId', userId) + const localVarPath = `/api/users/{userId}` + .replace(`{${"userId"}}`, encodeURIComponent(String(userId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication Bearer required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(updateUserRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * UsersApi - functional programming interface + * @export + */ +export const UsersApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = UsersApiAxiosParamCreator(configuration) + return { + /** + * + * @param {CreateUserRequest} [createUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createUser(createUserRequest?: CreateUserRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createUser(createUserRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['UsersApi.createUser']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deleteUser(userId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deleteUser(userId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['UsersApi.deleteUser']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserById(userId: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserById(userId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['UsersApi.getUserById']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {ListUserRequest} [listUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listUser(listUserRequest?: ListUserRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listUser(listUserRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['UsersApi.listUser']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * + * @param {number} userId + * @param {UpdateUserRequest} [updateUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateUser(userId: number, updateUserRequest?: UpdateUserRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateUser(userId, updateUserRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['UsersApi.updateUser']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * UsersApi - factory interface + * @export + */ +export const UsersApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = UsersApiFp(configuration) + return { + /** + * + * @param {CreateUserRequest} [createUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createUser(createUserRequest?: CreateUserRequest, options?: any): AxiosPromise { + return localVarFp.createUser(createUserRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deleteUser(userId: number, options?: any): AxiosPromise { + return localVarFp.deleteUser(userId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserById(userId: number, options?: any): AxiosPromise { + return localVarFp.getUserById(userId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {ListUserRequest} [listUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listUser(listUserRequest?: ListUserRequest, options?: any): AxiosPromise { + return localVarFp.listUser(listUserRequest, options).then((request) => request(axios, basePath)); + }, + /** + * + * @param {number} userId + * @param {UpdateUserRequest} [updateUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateUser(userId: number, updateUserRequest?: UpdateUserRequest, options?: any): AxiosPromise { + return localVarFp.updateUser(userId, updateUserRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * UsersApi - object-oriented interface + * @export + * @class UsersApi + * @extends {BaseAPI} + */ +export class UsersApi extends BaseAPI { + /** + * + * @param {CreateUserRequest} [createUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public createUser(createUserRequest?: CreateUserRequest, options?: RawAxiosRequestConfig) { + return UsersApiFp(this.configuration).createUser(createUserRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public deleteUser(userId: number, options?: RawAxiosRequestConfig) { + return UsersApiFp(this.configuration).deleteUser(userId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} userId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public getUserById(userId: number, options?: RawAxiosRequestConfig) { + return UsersApiFp(this.configuration).getUserById(userId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {ListUserRequest} [listUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public listUser(listUserRequest?: ListUserRequest, options?: RawAxiosRequestConfig) { + return UsersApiFp(this.configuration).listUser(listUserRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @param {number} userId + * @param {UpdateUserRequest} [updateUserRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UsersApi + */ + public updateUser(userId: number, updateUserRequest?: UpdateUserRequest, options?: RawAxiosRequestConfig) { + return UsersApiFp(this.configuration).updateUser(userId, updateUserRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + diff --git a/codigo-fonte/frontend/src/api/base.ts b/codigo-fonte/frontend/src/api/base.ts new file mode 100644 index 00000000..4222ba97 --- /dev/null +++ b/codigo-fonte/frontend/src/api/base.ts @@ -0,0 +1,86 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from './configuration'; +// Some imports not used depending on template conditions +// @ts-ignore +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; + +export const BASE_PATH = "http://localhost:5249".replace(/\/+$/, ""); + +/** + * + * @export + */ +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +/** + * + * @export + * @interface RequestArgs + */ +export interface RequestArgs { + url: string; + options: RawAxiosRequestConfig; +} + +/** + * + * @export + * @class BaseAPI + */ +export class BaseAPI { + protected configuration: Configuration | undefined; + + constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) { + if (configuration) { + this.configuration = configuration; + this.basePath = configuration.basePath ?? basePath; + } + } +}; + +/** + * + * @export + * @class RequiredError + * @extends {Error} + */ +export class RequiredError extends Error { + constructor(public field: string, msg?: string) { + super(msg); + this.name = "RequiredError" + } +} + +interface ServerMap { + [key: string]: { + url: string, + description: string, + }[]; +} + +/** + * + * @export + */ +export const operationServerMap: ServerMap = { +} diff --git a/codigo-fonte/frontend/src/api/common.ts b/codigo-fonte/frontend/src/api/common.ts new file mode 100644 index 00000000..cf3f454d --- /dev/null +++ b/codigo-fonte/frontend/src/api/common.ts @@ -0,0 +1,150 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from "./configuration"; +import type { RequestArgs } from "./base"; +import type { AxiosInstance, AxiosResponse } from 'axios'; +import { RequiredError } from "./base"; + +/** + * + * @export + */ +export const DUMMY_BASE_URL = 'https://example.com' + +/** + * + * @throws {RequiredError} + * @export + */ +export const assertParamExists = function (functionName: string, paramName: string, paramValue: unknown) { + if (paramValue === null || paramValue === undefined) { + throw new RequiredError(paramName, `Required parameter ${paramName} was null or undefined when calling ${functionName}.`); + } +} + +/** + * + * @export + */ +export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) { + if (configuration && configuration.apiKey) { + const localVarApiKeyValue = typeof configuration.apiKey === 'function' + ? await configuration.apiKey(keyParamName) + : await configuration.apiKey; + object[keyParamName] = localVarApiKeyValue; + } +} + +/** + * + * @export + */ +export const setBasicAuthToObject = function (object: any, configuration?: Configuration) { + if (configuration && (configuration.username || configuration.password)) { + object["auth"] = { username: configuration.username, password: configuration.password }; + } +} + +/** + * + * @export + */ +export const setBearerAuthToObject = async function (object: any, configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const accessToken = typeof configuration.accessToken === 'function' + ? await configuration.accessToken() + : await configuration.accessToken; + object["Authorization"] = "Bearer " + accessToken; + } +} + +/** + * + * @export + */ +export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const localVarAccessTokenValue = typeof configuration.accessToken === 'function' + ? await configuration.accessToken(name, scopes) + : await configuration.accessToken; + object["Authorization"] = "Bearer " + localVarAccessTokenValue; + } +} + +function setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = ""): void { + if (parameter == null) return; + if (typeof parameter === "object") { + if (Array.isArray(parameter)) { + (parameter as any[]).forEach(item => setFlattenedQueryParams(urlSearchParams, item, key)); + } + else { + Object.keys(parameter).forEach(currentKey => + setFlattenedQueryParams(urlSearchParams, parameter[currentKey], `${key}${key !== '' ? '.' : ''}${currentKey}`) + ); + } + } + else { + if (urlSearchParams.has(key)) { + urlSearchParams.append(key, parameter); + } + else { + urlSearchParams.set(key, parameter); + } + } +} + +/** + * + * @export + */ +export const setSearchParams = function (url: URL, ...objects: any[]) { + const searchParams = new URLSearchParams(url.search); + setFlattenedQueryParams(searchParams, objects); + url.search = searchParams.toString(); +} + +/** + * + * @export + */ +export const serializeDataIfNeeded = function (value: any, requestOptions: any, configuration?: Configuration) { + const nonString = typeof value !== 'string'; + const needsSerialization = nonString && configuration && configuration.isJsonMime + ? configuration.isJsonMime(requestOptions.headers['Content-Type']) + : nonString; + return needsSerialization + ? JSON.stringify(value !== undefined ? value : {}) + : (value || ""); +} + +/** + * + * @export + */ +export const toPathString = function (url: URL) { + return url.pathname + url.search + url.hash +} + +/** + * + * @export + */ +export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) { + return >(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs = {...axiosArgs.options, url: (axios.defaults.baseURL ? '' : configuration?.basePath ?? basePath) + axiosArgs.url}; + return axios.request(axiosRequestArgs); + }; +} diff --git a/codigo-fonte/frontend/src/api/configuration.ts b/codigo-fonte/frontend/src/api/configuration.ts new file mode 100644 index 00000000..03221243 --- /dev/null +++ b/codigo-fonte/frontend/src/api/configuration.ts @@ -0,0 +1,110 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export interface ConfigurationParameters { + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + username?: string; + password?: string; + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + basePath?: string; + serverIndex?: number; + baseOptions?: any; + formDataCtor?: new () => any; +} + +export class Configuration { + /** + * parameter for apiKey security + * @param name security name + * @memberof Configuration + */ + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + /** + * parameter for basic security + * + * @type {string} + * @memberof Configuration + */ + username?: string; + /** + * parameter for basic security + * + * @type {string} + * @memberof Configuration + */ + password?: string; + /** + * parameter for oauth2 security + * @param name security name + * @param scopes oauth2 scope + * @memberof Configuration + */ + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + /** + * override base path + * + * @type {string} + * @memberof Configuration + */ + basePath?: string; + /** + * override server index + * + * @type {number} + * @memberof Configuration + */ + serverIndex?: number; + /** + * base options for axios calls + * + * @type {any} + * @memberof Configuration + */ + baseOptions?: any; + /** + * The FormData constructor that will be used to create multipart form data + * requests. You can inject this here so that execution environments that + * do not support the FormData class can still run the generated client. + * + * @type {new () => FormData} + */ + formDataCtor?: new () => any; + + constructor(param: ConfigurationParameters = {}) { + this.apiKey = param.apiKey; + this.username = param.username; + this.password = param.password; + this.accessToken = param.accessToken; + this.basePath = param.basePath; + this.serverIndex = param.serverIndex; + this.baseOptions = param.baseOptions; + this.formDataCtor = param.formDataCtor; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } +} diff --git a/codigo-fonte/frontend/src/api/git_push.sh b/codigo-fonte/frontend/src/api/git_push.sh new file mode 100644 index 00000000..f53a75d4 --- /dev/null +++ b/codigo-fonte/frontend/src/api/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/codigo-fonte/frontend/src/api/index.ts b/codigo-fonte/frontend/src/api/index.ts new file mode 100644 index 00000000..b86e9afe --- /dev/null +++ b/codigo-fonte/frontend/src/api/index.ts @@ -0,0 +1,18 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export * from "./api"; +export * from "./configuration"; +export * from "./models"; diff --git a/codigo-fonte/frontend/src/api/models/beneficiary-view-model.ts b/codigo-fonte/frontend/src/api/models/beneficiary-view-model.ts new file mode 100644 index 00000000..de93e8c1 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/beneficiary-view-model.ts @@ -0,0 +1,48 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface BeneficiaryViewModel + */ +export interface BeneficiaryViewModel { + /** + * + * @type {number} + * @memberof BeneficiaryViewModel + */ + 'beneficiaryId'?: number; + /** + * + * @type {string} + * @memberof BeneficiaryViewModel + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof BeneficiaryViewModel + */ + 'notes'?: string; + /** + * + * @type {number} + * @memberof BeneficiaryViewModel + */ + 'oscsCount'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/business-case-view-model.ts b/codigo-fonte/frontend/src/api/models/business-case-view-model.ts new file mode 100644 index 00000000..fe648c85 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/business-case-view-model.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface BusinessCaseViewModel + */ +export interface BusinessCaseViewModel { + /** + * + * @type {number} + * @memberof BusinessCaseViewModel + */ + 'businessCaseId'?: number; + /** + * + * @type {string} + * @memberof BusinessCaseViewModel + */ + 'name'?: string; + /** + * + * @type {number} + * @memberof BusinessCaseViewModel + */ + 'originsBusinessCases'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/company-view-model.ts b/codigo-fonte/frontend/src/api/models/company-view-model.ts new file mode 100644 index 00000000..e969611a --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/company-view-model.ts @@ -0,0 +1,60 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CompanyViewModel + */ +export interface CompanyViewModel { + /** + * + * @type {number} + * @memberof CompanyViewModel + */ + 'id'?: number; + /** + * + * @type {string} + * @memberof CompanyViewModel + */ + 'cnpj'?: string; + /** + * + * @type {string} + * @memberof CompanyViewModel + */ + 'nome'?: string; + /** + * + * @type {string} + * @memberof CompanyViewModel + */ + 'razaoSocial'?: string; + /** + * + * @type {string} + * @memberof CompanyViewModel + */ + 'telefone'?: string | null; + /** + * + * @type {boolean} + * @memberof CompanyViewModel + */ + 'ativa'?: boolean; +} + diff --git a/codigo-fonte/frontend/src/api/models/course-view-model.ts b/codigo-fonte/frontend/src/api/models/course-view-model.ts new file mode 100644 index 00000000..97851ce2 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/course-view-model.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CourseViewModel + */ +export interface CourseViewModel { + /** + * + * @type {number} + * @memberof CourseViewModel + */ + 'courseId'?: number; + /** + * + * @type {string} + * @memberof CourseViewModel + */ + 'name'?: string | null; + /** + * + * @type {number} + * @memberof CourseViewModel + */ + 'teamsCount'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-beneficiary-request.ts b/codigo-fonte/frontend/src/api/models/create-beneficiary-request.ts new file mode 100644 index 00000000..ad366b08 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-beneficiary-request.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateBeneficiaryRequest + */ +export interface CreateBeneficiaryRequest { + /** + * + * @type {string} + * @memberof CreateBeneficiaryRequest + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof CreateBeneficiaryRequest + */ + 'notes'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-beneficiary-response.ts b/codigo-fonte/frontend/src/api/models/create-beneficiary-response.ts new file mode 100644 index 00000000..2d79e2d0 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-beneficiary-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateBeneficiaryResponse + */ +export interface CreateBeneficiaryResponse { + /** + * + * @type {number} + * @memberof CreateBeneficiaryResponse + */ + 'beneficiaryId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-business-case-request.ts b/codigo-fonte/frontend/src/api/models/create-business-case-request.ts new file mode 100644 index 00000000..2285ec89 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-business-case-request.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateBusinessCaseRequest + */ +export interface CreateBusinessCaseRequest { + /** + * + * @type {string} + * @memberof CreateBusinessCaseRequest + */ + 'name'?: string; + /** + * + * @type {Array} + * @memberof CreateBusinessCaseRequest + */ + 'originsBusinessCasesIds'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-business-case-response.ts b/codigo-fonte/frontend/src/api/models/create-business-case-response.ts new file mode 100644 index 00000000..ed377270 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-business-case-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateBusinessCaseResponse + */ +export interface CreateBusinessCaseResponse { + /** + * + * @type {number} + * @memberof CreateBusinessCaseResponse + */ + 'businessCaseId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-company-command.ts b/codigo-fonte/frontend/src/api/models/create-company-command.ts new file mode 100644 index 00000000..5f4809d0 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-company-command.ts @@ -0,0 +1,102 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateCompanyCommand + */ +export interface CreateCompanyCommand { + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'cnpj'?: string; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'companyName'?: string; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'corporateReason'?: string | null; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'fieldOfActivity'?: string | null; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'zipCode'?: string | null; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'address'?: string | null; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'neighborhood'?: string | null; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'city'?: string | null; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'state'?: string | null; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'phoneNumber'?: string | null; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'website'?: string | null; + /** + * + * @type {string} + * @memberof CreateCompanyCommand + */ + 'socialMedia'?: string | null; + /** + * + * @type {boolean} + * @memberof CreateCompanyCommand + */ + 'isActive'?: boolean; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-course-request.ts b/codigo-fonte/frontend/src/api/models/create-course-request.ts new file mode 100644 index 00000000..7747acb9 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-course-request.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateCourseRequest + */ +export interface CreateCourseRequest { + /** + * + * @type {string} + * @memberof CreateCourseRequest + */ + 'name'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-course-response.ts b/codigo-fonte/frontend/src/api/models/create-course-response.ts new file mode 100644 index 00000000..89fcc980 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-course-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateCourseResponse + */ +export interface CreateCourseResponse { + /** + * + * @type {number} + * @memberof CreateCourseResponse + */ + 'courseId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-donation-command.ts b/codigo-fonte/frontend/src/api/models/create-donation-command.ts new file mode 100644 index 00000000..72bf1879 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-donation-command.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateDonationCommand + */ +export interface CreateDonationCommand { + /** + * + * @type {number} + * @memberof CreateDonationCommand + */ + 'value'?: number; + /** + * + * @type {string} + * @memberof CreateDonationCommand + */ + 'donationDate'?: string; + /** + * + * @type {number} + * @memberof CreateDonationCommand + */ + 'personId'?: number | null; + /** + * + * @type {number} + * @memberof CreateDonationCommand + */ + 'companyId'?: number | null; + /** + * + * @type {number} + * @memberof CreateDonationCommand + */ + 'oscId'?: number | null; + /** + * + * @type {number} + * @memberof CreateDonationCommand + */ + 'courseId'?: number | null; + /** + * + * @type {number} + * @memberof CreateDonationCommand + */ + 'teamId'?: number | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-origin-business-case-request.ts b/codigo-fonte/frontend/src/api/models/create-origin-business-case-request.ts new file mode 100644 index 00000000..98750848 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-origin-business-case-request.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateOriginBusinessCaseRequest + */ +export interface CreateOriginBusinessCaseRequest { + /** + * + * @type {string} + * @memberof CreateOriginBusinessCaseRequest + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof CreateOriginBusinessCaseRequest + */ + 'notes'?: string; + /** + * + * @type {number} + * @memberof CreateOriginBusinessCaseRequest + */ + 'businessCaseId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-origin-business-case-response.ts b/codigo-fonte/frontend/src/api/models/create-origin-business-case-response.ts new file mode 100644 index 00000000..ca8f53be --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-origin-business-case-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateOriginBusinessCaseResponse + */ +export interface CreateOriginBusinessCaseResponse { + /** + * + * @type {number} + * @memberof CreateOriginBusinessCaseResponse + */ + 'originBusinessCaseId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-osc-request.ts b/codigo-fonte/frontend/src/api/models/create-osc-request.ts new file mode 100644 index 00000000..f0a5c388 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-osc-request.ts @@ -0,0 +1,114 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateOscRequest + */ +export interface CreateOscRequest { + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'objective'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'corporateName'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'address'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'neighborhood'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'city'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'state'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'phoneNumber'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'webUrl'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'socialMedia'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'zipCode'?: string; + /** + * + * @type {string} + * @memberof CreateOscRequest + */ + 'oscPrimaryDocumment'?: string | null; + /** + * + * @type {Array} + * @memberof CreateOscRequest + */ + 'beneficiariesIds'?: Array; + /** + * + * @type {Array} + * @memberof CreateOscRequest + */ + 'originsBusinessCasesIds'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-osc-response.ts b/codigo-fonte/frontend/src/api/models/create-osc-response.ts new file mode 100644 index 00000000..a9b37ac8 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-osc-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateOscResponse + */ +export interface CreateOscResponse { + /** + * + * @type {number} + * @memberof CreateOscResponse + */ + 'oscId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-person-request.ts b/codigo-fonte/frontend/src/api/models/create-person-request.ts new file mode 100644 index 00000000..455023bd --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-person-request.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreatePersonRequest + */ +export interface CreatePersonRequest { + /** + * + * @type {string} + * @memberof CreatePersonRequest + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof CreatePersonRequest + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof CreatePersonRequest + */ + 'personalDocumment'?: string; + /** + * + * @type {string} + * @memberof CreatePersonRequest + */ + 'secondaryEmail'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonRequest + */ + 'primaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonRequest + */ + 'secondaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonRequest + */ + 'education1'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonRequest + */ + 'education2'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonRequest + */ + 'professionalActivity'?: string | null; + /** + * + * @type {boolean} + * @memberof CreatePersonRequest + */ + 'isActive'?: boolean; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-person-response.ts b/codigo-fonte/frontend/src/api/models/create-person-response.ts new file mode 100644 index 00000000..0d1de212 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-person-response.ts @@ -0,0 +1,90 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreatePersonResponse + */ +export interface CreatePersonResponse { + /** + * + * @type {number} + * @memberof CreatePersonResponse + */ + 'personId'?: number; + /** + * + * @type {string} + * @memberof CreatePersonResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof CreatePersonResponse + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof CreatePersonResponse + */ + 'personalDocumment'?: string; + /** + * + * @type {string} + * @memberof CreatePersonResponse + */ + 'secondaryEmail'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonResponse + */ + 'primaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonResponse + */ + 'secondaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonResponse + */ + 'education1'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonResponse + */ + 'education2'?: string | null; + /** + * + * @type {string} + * @memberof CreatePersonResponse + */ + 'professionalActivity'?: string | null; + /** + * + * @type {boolean} + * @memberof CreatePersonResponse + */ + 'isActive'?: boolean; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-team-request.ts b/codigo-fonte/frontend/src/api/models/create-team-request.ts new file mode 100644 index 00000000..04a1023c --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-team-request.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateTeamRequest + */ +export interface CreateTeamRequest { + /** + * + * @type {string} + * @memberof CreateTeamRequest + */ + 'name'?: string | null; + /** + * + * @type {string} + * @memberof CreateTeamRequest + */ + 'lessonTime'?: string | null; + /** + * + * @type {string} + * @memberof CreateTeamRequest + */ + 'start'?: string | null; + /** + * + * @type {string} + * @memberof CreateTeamRequest + */ + 'finish'?: string | null; + /** + * + * @type {Array} + * @memberof CreateTeamRequest + */ + 'personTeamsIds'?: Array; + /** + * + * @type {number} + * @memberof CreateTeamRequest + */ + 'projectProgramId'?: number | null; + /** + * + * @type {number} + * @memberof CreateTeamRequest + */ + 'courseId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-team-response.ts b/codigo-fonte/frontend/src/api/models/create-team-response.ts new file mode 100644 index 00000000..306ecfac --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-team-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateTeamResponse + */ +export interface CreateTeamResponse { + /** + * + * @type {number} + * @memberof CreateTeamResponse + */ + 'teamId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-user-request.ts b/codigo-fonte/frontend/src/api/models/create-user-request.ts new file mode 100644 index 00000000..e6b465ad --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-user-request.ts @@ -0,0 +1,54 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateUserRequest + */ +export interface CreateUserRequest { + /** + * + * @type {string} + * @memberof CreateUserRequest + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof CreateUserRequest + */ + 'password'?: string; + /** + * + * @type {string} + * @memberof CreateUserRequest + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof CreateUserRequest + */ + 'phoneNumber'?: string; + /** + * + * @type {string} + * @memberof CreateUserRequest + */ + 'role'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/create-user-response.ts b/codigo-fonte/frontend/src/api/models/create-user-response.ts new file mode 100644 index 00000000..f164d2f3 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/create-user-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface CreateUserResponse + */ +export interface CreateUserResponse { + /** + * + * @type {number} + * @memberof CreateUserResponse + */ + 'userId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/delete-course-response.ts b/codigo-fonte/frontend/src/api/models/delete-course-response.ts new file mode 100644 index 00000000..80e1ff5a --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/delete-course-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface DeleteCourseResponse + */ +export interface DeleteCourseResponse { + /** + * + * @type {number} + * @memberof DeleteCourseResponse + */ + 'courseId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/delete-team-response.ts b/codigo-fonte/frontend/src/api/models/delete-team-response.ts new file mode 100644 index 00000000..0ac08577 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/delete-team-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface DeleteTeamResponse + */ +export interface DeleteTeamResponse { + /** + * + * @type {number} + * @memberof DeleteTeamResponse + */ + 'teamId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/donation-view-model.ts b/codigo-fonte/frontend/src/api/models/donation-view-model.ts new file mode 100644 index 00000000..c545d6f4 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/donation-view-model.ts @@ -0,0 +1,54 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface DonationViewModel + */ +export interface DonationViewModel { + /** + * + * @type {number} + * @memberof DonationViewModel + */ + 'id'?: number; + /** + * + * @type {number} + * @memberof DonationViewModel + */ + 'value'?: number; + /** + * + * @type {string} + * @memberof DonationViewModel + */ + 'donationDate'?: string; + /** + * + * @type {string} + * @memberof DonationViewModel + */ + 'doadorNome'?: string; + /** + * + * @type {string} + * @memberof DonationViewModel + */ + 'destinoNome'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/edit-course-request.ts b/codigo-fonte/frontend/src/api/models/edit-course-request.ts new file mode 100644 index 00000000..efab7b05 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/edit-course-request.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface EditCourseRequest + */ +export interface EditCourseRequest { + /** + * + * @type {string} + * @memberof EditCourseRequest + */ + 'name'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/edit-course-response.ts b/codigo-fonte/frontend/src/api/models/edit-course-response.ts new file mode 100644 index 00000000..f3640383 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/edit-course-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface EditCourseResponse + */ +export interface EditCourseResponse { + /** + * + * @type {number} + * @memberof EditCourseResponse + */ + 'courseId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/edit-team-request.ts b/codigo-fonte/frontend/src/api/models/edit-team-request.ts new file mode 100644 index 00000000..c3fd9d44 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/edit-team-request.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface EditTeamRequest + */ +export interface EditTeamRequest { + /** + * + * @type {string} + * @memberof EditTeamRequest + */ + 'name'?: string | null; + /** + * + * @type {string} + * @memberof EditTeamRequest + */ + 'lessonTime'?: string | null; + /** + * + * @type {string} + * @memberof EditTeamRequest + */ + 'start'?: string | null; + /** + * + * @type {string} + * @memberof EditTeamRequest + */ + 'finish'?: string | null; + /** + * + * @type {Array} + * @memberof EditTeamRequest + */ + 'personTeamsIds'?: Array | null; + /** + * + * @type {number} + * @memberof EditTeamRequest + */ + 'projectProgramId'?: number | null; + /** + * + * @type {number} + * @memberof EditTeamRequest + */ + 'courseId'?: number | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/edit-team-response.ts b/codigo-fonte/frontend/src/api/models/edit-team-response.ts new file mode 100644 index 00000000..cbaa0bff --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/edit-team-response.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface EditTeamResponse + */ +export interface EditTeamResponse { + /** + * + * @type {number} + * @memberof EditTeamResponse + */ + 'teamId'?: number; + /** + * + * @type {string} + * @memberof EditTeamResponse + */ + 'name'?: string | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/filter.ts b/codigo-fonte/frontend/src/api/models/filter.ts new file mode 100644 index 00000000..17c78da2 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/filter.ts @@ -0,0 +1,47 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Op } from './op'; + +/** + * + * @export + * @interface Filter + */ +export interface Filter { + /** + * + * @type {string} + * @memberof Filter + */ + 'propertyName'?: string; + /** + * + * @type {Op} + * @memberof Filter + */ + 'operation'?: Op; + /** + * + * @type {any} + * @memberof Filter + */ + 'value'?: any; +} + + + diff --git a/codigo-fonte/frontend/src/api/models/forgot-password-request.ts b/codigo-fonte/frontend/src/api/models/forgot-password-request.ts new file mode 100644 index 00000000..1f1637fb --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/forgot-password-request.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface ForgotPasswordRequest + */ +export interface ForgotPasswordRequest { + /** + * + * @type {string} + * @memberof ForgotPasswordRequest + */ + 'email'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/forgot-password-response.ts b/codigo-fonte/frontend/src/api/models/forgot-password-response.ts new file mode 100644 index 00000000..330f8c4a --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/forgot-password-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface ForgotPasswordResponse + */ +export interface ForgotPasswordResponse { + /** + * + * @type {string} + * @memberof ForgotPasswordResponse + */ + 'message'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-beneficiary-osc-response.ts b/codigo-fonte/frontend/src/api/models/get-beneficiary-osc-response.ts new file mode 100644 index 00000000..4a42d0c3 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-beneficiary-osc-response.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface GetBeneficiaryOscResponse + */ +export interface GetBeneficiaryOscResponse { + /** + * + * @type {number} + * @memberof GetBeneficiaryOscResponse + */ + 'oscId'?: number; + /** + * + * @type {string} + * @memberof GetBeneficiaryOscResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof GetBeneficiaryOscResponse + */ + 'corporateName'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-beneficiary-response.ts b/codigo-fonte/frontend/src/api/models/get-beneficiary-response.ts new file mode 100644 index 00000000..b9dfe1f3 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-beneficiary-response.ts @@ -0,0 +1,51 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { GetBeneficiaryOscResponse } from './get-beneficiary-osc-response'; + +/** + * + * @export + * @interface GetBeneficiaryResponse + */ +export interface GetBeneficiaryResponse { + /** + * + * @type {number} + * @memberof GetBeneficiaryResponse + */ + 'beneficiaryId'?: number; + /** + * + * @type {string} + * @memberof GetBeneficiaryResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof GetBeneficiaryResponse + */ + 'notes'?: string; + /** + * + * @type {Array} + * @memberof GetBeneficiaryResponse + */ + 'oscs'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-business-case-origin-response.ts b/codigo-fonte/frontend/src/api/models/get-business-case-origin-response.ts new file mode 100644 index 00000000..284296b1 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-business-case-origin-response.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface GetBusinessCaseOriginResponse + */ +export interface GetBusinessCaseOriginResponse { + /** + * + * @type {number} + * @memberof GetBusinessCaseOriginResponse + */ + 'originBusinessCaseId'?: number; + /** + * + * @type {string} + * @memberof GetBusinessCaseOriginResponse + */ + 'name'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-business-case-response.ts b/codigo-fonte/frontend/src/api/models/get-business-case-response.ts new file mode 100644 index 00000000..82c1736b --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-business-case-response.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { GetBusinessCaseOriginResponse } from './get-business-case-origin-response'; + +/** + * + * @export + * @interface GetBusinessCaseResponse + */ +export interface GetBusinessCaseResponse { + /** + * + * @type {number} + * @memberof GetBusinessCaseResponse + */ + 'businessCaseId'?: number; + /** + * + * @type {string} + * @memberof GetBusinessCaseResponse + */ + 'name'?: string; + /** + * + * @type {Array} + * @memberof GetBusinessCaseResponse + */ + 'origins'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-course-by-id-view-model.ts b/codigo-fonte/frontend/src/api/models/get-course-by-id-view-model.ts new file mode 100644 index 00000000..a70a8435 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-course-by-id-view-model.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { TeamViewModel } from './team-view-model'; + +/** + * + * @export + * @interface GetCourseByIdViewModel + */ +export interface GetCourseByIdViewModel { + /** + * + * @type {number} + * @memberof GetCourseByIdViewModel + */ + 'courseId'?: number; + /** + * + * @type {string} + * @memberof GetCourseByIdViewModel + */ + 'name'?: string | null; + /** + * + * @type {boolean} + * @memberof GetCourseByIdViewModel + */ + 'isDeleted'?: boolean; + /** + * + * @type {number} + * @memberof GetCourseByIdViewModel + */ + 'teamsCount'?: number | null; + /** + * + * @type {number} + * @memberof GetCourseByIdViewModel + */ + 'createdBy'?: number; + /** + * + * @type {string} + * @memberof GetCourseByIdViewModel + */ + 'createdAt'?: string; + /** + * + * @type {number} + * @memberof GetCourseByIdViewModel + */ + 'updatedBy'?: number; + /** + * + * @type {string} + * @memberof GetCourseByIdViewModel + */ + 'updatedAt'?: string; + /** + * + * @type {Array} + * @memberof GetCourseByIdViewModel + */ + 'teams'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-origin-business-case-osc-response.ts b/codigo-fonte/frontend/src/api/models/get-origin-business-case-osc-response.ts new file mode 100644 index 00000000..55fa3ef5 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-origin-business-case-osc-response.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface GetOriginBusinessCaseOscResponse + */ +export interface GetOriginBusinessCaseOscResponse { + /** + * + * @type {number} + * @memberof GetOriginBusinessCaseOscResponse + */ + 'oscId'?: number; + /** + * + * @type {string} + * @memberof GetOriginBusinessCaseOscResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof GetOriginBusinessCaseOscResponse + */ + 'notes'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-origin-business-case-response.ts b/codigo-fonte/frontend/src/api/models/get-origin-business-case-response.ts new file mode 100644 index 00000000..e6b3bfc4 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-origin-business-case-response.ts @@ -0,0 +1,51 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { GetOriginBusinessCaseOscResponse } from './get-origin-business-case-osc-response'; + +/** + * + * @export + * @interface GetOriginBusinessCaseResponse + */ +export interface GetOriginBusinessCaseResponse { + /** + * + * @type {number} + * @memberof GetOriginBusinessCaseResponse + */ + 'originBusinessCaseId'?: number; + /** + * + * @type {string} + * @memberof GetOriginBusinessCaseResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof GetOriginBusinessCaseResponse + */ + 'notes'?: string; + /** + * + * @type {Array} + * @memberof GetOriginBusinessCaseResponse + */ + 'oscs'?: Array | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-osc-beneficiary-response.ts b/codigo-fonte/frontend/src/api/models/get-osc-beneficiary-response.ts new file mode 100644 index 00000000..dee33b79 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-osc-beneficiary-response.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface GetOscBeneficiaryResponse + */ +export interface GetOscBeneficiaryResponse { + /** + * + * @type {number} + * @memberof GetOscBeneficiaryResponse + */ + 'beneficiaryId'?: number; + /** + * + * @type {string} + * @memberof GetOscBeneficiaryResponse + */ + 'name'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-osc-origin-business-case-response.ts b/codigo-fonte/frontend/src/api/models/get-osc-origin-business-case-response.ts new file mode 100644 index 00000000..0be03568 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-osc-origin-business-case-response.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface GetOscOriginBusinessCaseResponse + */ +export interface GetOscOriginBusinessCaseResponse { + /** + * + * @type {number} + * @memberof GetOscOriginBusinessCaseResponse + */ + 'originBusinessCaseId'?: number; + /** + * + * @type {string} + * @memberof GetOscOriginBusinessCaseResponse + */ + 'name'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-osc-response.ts b/codigo-fonte/frontend/src/api/models/get-osc-response.ts new file mode 100644 index 00000000..fc10bc8c --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-osc-response.ts @@ -0,0 +1,126 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { GetOscBeneficiaryResponse } from './get-osc-beneficiary-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { GetOscOriginBusinessCaseResponse } from './get-osc-origin-business-case-response'; + +/** + * + * @export + * @interface GetOscResponse + */ +export interface GetOscResponse { + /** + * + * @type {number} + * @memberof GetOscResponse + */ + 'oscId'?: number; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'corporateName'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'objective'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'address'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'neighborhood'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'city'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'state'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'phoneNumber'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'webUrl'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'socialMedia'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'zipCode'?: string; + /** + * + * @type {string} + * @memberof GetOscResponse + */ + 'oscPrimaryDocumment'?: string | null; + /** + * + * @type {Array} + * @memberof GetOscResponse + */ + 'beneficiaries'?: Array; + /** + * + * @type {Array} + * @memberof GetOscResponse + */ + 'originsBusinessCases'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/get-team-by-id-response.ts b/codigo-fonte/frontend/src/api/models/get-team-by-id-response.ts new file mode 100644 index 00000000..d9a96c89 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/get-team-by-id-response.ts @@ -0,0 +1,96 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface GetTeamByIdResponse + */ +export interface GetTeamByIdResponse { + /** + * + * @type {number} + * @memberof GetTeamByIdResponse + */ + 'teamId'?: number; + /** + * + * @type {string} + * @memberof GetTeamByIdResponse + */ + 'name'?: string | null; + /** + * + * @type {string} + * @memberof GetTeamByIdResponse + */ + 'lessonTime'?: string | null; + /** + * + * @type {string} + * @memberof GetTeamByIdResponse + */ + 'start'?: string | null; + /** + * + * @type {string} + * @memberof GetTeamByIdResponse + */ + 'finish'?: string | null; + /** + * + * @type {number} + * @memberof GetTeamByIdResponse + */ + 'courseId'?: number | null; + /** + * + * @type {string} + * @memberof GetTeamByIdResponse + */ + 'courseName'?: string | null; + /** + * + * @type {number} + * @memberof GetTeamByIdResponse + */ + 'projectProgramId'?: number | null; + /** + * + * @type {string} + * @memberof GetTeamByIdResponse + */ + 'projectProgramName'?: string | null; + /** + * + * @type {number} + * @memberof GetTeamByIdResponse + */ + 'personTeamsCount'?: number; + /** + * + * @type {boolean} + * @memberof GetTeamByIdResponse + */ + 'isDeleted'?: boolean; + /** + * + * @type {string} + * @memberof GetTeamByIdResponse + */ + 'createdAt'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/index.ts b/codigo-fonte/frontend/src/api/models/index.ts new file mode 100644 index 00000000..f98530bf --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/index.ts @@ -0,0 +1,97 @@ +export * from './beneficiary-view-model'; +export * from './business-case-view-model'; +export * from './company-view-model'; +export * from './course-view-model'; +export * from './create-beneficiary-request'; +export * from './create-beneficiary-response'; +export * from './create-business-case-request'; +export * from './create-business-case-response'; +export * from './create-company-command'; +export * from './create-course-request'; +export * from './create-course-response'; +export * from './create-donation-command'; +export * from './create-origin-business-case-request'; +export * from './create-origin-business-case-response'; +export * from './create-osc-request'; +export * from './create-osc-response'; +export * from './create-person-request'; +export * from './create-person-response'; +export * from './create-team-request'; +export * from './create-team-response'; +export * from './create-user-request'; +export * from './create-user-response'; +export * from './delete-course-response'; +export * from './delete-team-response'; +export * from './donation-view-model'; +export * from './edit-course-request'; +export * from './edit-course-response'; +export * from './edit-team-request'; +export * from './edit-team-response'; +export * from './filter'; +export * from './forgot-password-request'; +export * from './forgot-password-response'; +export * from './get-beneficiary-osc-response'; +export * from './get-beneficiary-response'; +export * from './get-business-case-origin-response'; +export * from './get-business-case-response'; +export * from './get-course-by-id-view-model'; +export * from './get-origin-business-case-osc-response'; +export * from './get-origin-business-case-response'; +export * from './get-osc-beneficiary-response'; +export * from './get-osc-origin-business-case-response'; +export * from './get-osc-response'; +export * from './get-team-by-id-response'; +export * from './list-beneficiary-request'; +export * from './list-beneficiary-view-model'; +export * from './list-business-case-request'; +export * from './list-business-case-view-model'; +export * from './list-companies-request'; +export * from './list-companies-view-model'; +export * from './list-course-request'; +export * from './list-course-view-model'; +export * from './list-donations-request'; +export * from './list-donations-view-model'; +export * from './list-origin-business-case-request'; +export * from './list-origin-business-case-view-model'; +export * from './list-origins-business-case-by-business-case-id-request'; +export * from './list-origins-business-case-by-business-case-id-view-model'; +export * from './list-osc-request'; +export * from './list-osc-view-model'; +export * from './list-person-request'; +export * from './list-person-view-model'; +export * from './list-team-item-view-model'; +export * from './list-team-request'; +export * from './list-team-view-model'; +export * from './list-user-request'; +export * from './list-user-view-model'; +export * from './login-response'; +export * from './op'; +export * from './origin-business-case-by-business-case-id-view-model'; +export * from './origin-business-case-view-model'; +export * from './osc-view-model'; +export * from './person-list-item-view-model'; +export * from './person-view-model'; +export * from './problem-details'; +export * from './reset-password-request'; +export * from './reset-password-response'; +export * from './team-view-model'; +export * from './update-beneficiary-in-osc-response'; +export * from './update-beneficiary-request'; +export * from './update-beneficiary-response'; +export * from './update-business-case-request'; +export * from './update-business-case-response'; +export * from './update-company-command'; +export * from './update-donation-command'; +export * from './update-origin-business-case-in-business-case-response'; +export * from './update-origin-business-case-in-osc-response'; +export * from './update-origin-business-case-request'; +export * from './update-origin-business-case-response'; +export * from './update-osc-request'; +export * from './update-osc-response'; +export * from './update-person-request'; +export * from './update-person-response'; +export * from './update-user-request'; +export * from './update-user-response'; +export * from './user-login'; +export * from './user-token'; +export * from './user-view-model'; diff --git a/codigo-fonte/frontend/src/api/models/list-beneficiary-request.ts b/codigo-fonte/frontend/src/api/models/list-beneficiary-request.ts new file mode 100644 index 00000000..213a78c5 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-beneficiary-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListBeneficiaryRequest + */ +export interface ListBeneficiaryRequest { + /** + * + * @type {number} + * @memberof ListBeneficiaryRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListBeneficiaryRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListBeneficiaryRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-beneficiary-view-model.ts b/codigo-fonte/frontend/src/api/models/list-beneficiary-view-model.ts new file mode 100644 index 00000000..911b7752 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-beneficiary-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { BeneficiaryViewModel } from './beneficiary-view-model'; + +/** + * + * @export + * @interface ListBeneficiaryViewModel + */ +export interface ListBeneficiaryViewModel { + /** + * + * @type {number} + * @memberof ListBeneficiaryViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListBeneficiaryViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-business-case-request.ts b/codigo-fonte/frontend/src/api/models/list-business-case-request.ts new file mode 100644 index 00000000..c2d32da9 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-business-case-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListBusinessCaseRequest + */ +export interface ListBusinessCaseRequest { + /** + * + * @type {number} + * @memberof ListBusinessCaseRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListBusinessCaseRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListBusinessCaseRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-business-case-view-model.ts b/codigo-fonte/frontend/src/api/models/list-business-case-view-model.ts new file mode 100644 index 00000000..b721e781 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-business-case-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { BusinessCaseViewModel } from './business-case-view-model'; + +/** + * + * @export + * @interface ListBusinessCaseViewModel + */ +export interface ListBusinessCaseViewModel { + /** + * + * @type {number} + * @memberof ListBusinessCaseViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListBusinessCaseViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-companies-request.ts b/codigo-fonte/frontend/src/api/models/list-companies-request.ts new file mode 100644 index 00000000..fe7eaed6 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-companies-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListCompaniesRequest + */ +export interface ListCompaniesRequest { + /** + * + * @type {number} + * @memberof ListCompaniesRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListCompaniesRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListCompaniesRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-companies-view-model.ts b/codigo-fonte/frontend/src/api/models/list-companies-view-model.ts new file mode 100644 index 00000000..9ddae203 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-companies-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { CompanyViewModel } from './company-view-model'; + +/** + * + * @export + * @interface ListCompaniesViewModel + */ +export interface ListCompaniesViewModel { + /** + * + * @type {number} + * @memberof ListCompaniesViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListCompaniesViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-course-request.ts b/codigo-fonte/frontend/src/api/models/list-course-request.ts new file mode 100644 index 00000000..4871d132 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-course-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListCourseRequest + */ +export interface ListCourseRequest { + /** + * + * @type {number} + * @memberof ListCourseRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListCourseRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListCourseRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-course-view-model.ts b/codigo-fonte/frontend/src/api/models/list-course-view-model.ts new file mode 100644 index 00000000..a479e2c9 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-course-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { CourseViewModel } from './course-view-model'; + +/** + * + * @export + * @interface ListCourseViewModel + */ +export interface ListCourseViewModel { + /** + * + * @type {number} + * @memberof ListCourseViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListCourseViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-donations-request.ts b/codigo-fonte/frontend/src/api/models/list-donations-request.ts new file mode 100644 index 00000000..0ba8f47d --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-donations-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListDonationsRequest + */ +export interface ListDonationsRequest { + /** + * + * @type {number} + * @memberof ListDonationsRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListDonationsRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListDonationsRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-donations-view-model.ts b/codigo-fonte/frontend/src/api/models/list-donations-view-model.ts new file mode 100644 index 00000000..3a73f35f --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-donations-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { DonationViewModel } from './donation-view-model'; + +/** + * + * @export + * @interface ListDonationsViewModel + */ +export interface ListDonationsViewModel { + /** + * + * @type {number} + * @memberof ListDonationsViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListDonationsViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-origin-business-case-request.ts b/codigo-fonte/frontend/src/api/models/list-origin-business-case-request.ts new file mode 100644 index 00000000..b5a0ae3d --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-origin-business-case-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListOriginBusinessCaseRequest + */ +export interface ListOriginBusinessCaseRequest { + /** + * + * @type {number} + * @memberof ListOriginBusinessCaseRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListOriginBusinessCaseRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListOriginBusinessCaseRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-origin-business-case-view-model.ts b/codigo-fonte/frontend/src/api/models/list-origin-business-case-view-model.ts new file mode 100644 index 00000000..da6d7980 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-origin-business-case-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { OriginBusinessCaseViewModel } from './origin-business-case-view-model'; + +/** + * + * @export + * @interface ListOriginBusinessCaseViewModel + */ +export interface ListOriginBusinessCaseViewModel { + /** + * + * @type {number} + * @memberof ListOriginBusinessCaseViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListOriginBusinessCaseViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-origins-business-case-by-business-case-id-request.ts b/codigo-fonte/frontend/src/api/models/list-origins-business-case-by-business-case-id-request.ts new file mode 100644 index 00000000..c66b4c9d --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-origins-business-case-by-business-case-id-request.ts @@ -0,0 +1,51 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListOriginsBusinessCaseByBusinessCaseIdRequest + */ +export interface ListOriginsBusinessCaseByBusinessCaseIdRequest { + /** + * + * @type {number} + * @memberof ListOriginsBusinessCaseByBusinessCaseIdRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListOriginsBusinessCaseByBusinessCaseIdRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListOriginsBusinessCaseByBusinessCaseIdRequest + */ + 'filters'?: Array; + /** + * + * @type {number} + * @memberof ListOriginsBusinessCaseByBusinessCaseIdRequest + */ + 'businessCaseId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-origins-business-case-by-business-case-id-view-model.ts b/codigo-fonte/frontend/src/api/models/list-origins-business-case-by-business-case-id-view-model.ts new file mode 100644 index 00000000..66857c59 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-origins-business-case-by-business-case-id-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { OriginBusinessCaseByBusinessCaseIdViewModel } from './origin-business-case-by-business-case-id-view-model'; + +/** + * + * @export + * @interface ListOriginsBusinessCaseByBusinessCaseIdViewModel + */ +export interface ListOriginsBusinessCaseByBusinessCaseIdViewModel { + /** + * + * @type {number} + * @memberof ListOriginsBusinessCaseByBusinessCaseIdViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListOriginsBusinessCaseByBusinessCaseIdViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-osc-request.ts b/codigo-fonte/frontend/src/api/models/list-osc-request.ts new file mode 100644 index 00000000..3e504895 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-osc-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListOscRequest + */ +export interface ListOscRequest { + /** + * + * @type {number} + * @memberof ListOscRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListOscRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListOscRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-osc-view-model.ts b/codigo-fonte/frontend/src/api/models/list-osc-view-model.ts new file mode 100644 index 00000000..006559d8 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-osc-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { OscViewModel } from './osc-view-model'; + +/** + * + * @export + * @interface ListOscViewModel + */ +export interface ListOscViewModel { + /** + * + * @type {number} + * @memberof ListOscViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListOscViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-person-request.ts b/codigo-fonte/frontend/src/api/models/list-person-request.ts new file mode 100644 index 00000000..bae20349 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-person-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListPersonRequest + */ +export interface ListPersonRequest { + /** + * + * @type {number} + * @memberof ListPersonRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListPersonRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListPersonRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-person-view-model.ts b/codigo-fonte/frontend/src/api/models/list-person-view-model.ts new file mode 100644 index 00000000..098b6ae7 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-person-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { PersonListItemViewModel } from './person-list-item-view-model'; + +/** + * + * @export + * @interface ListPersonViewModel + */ +export interface ListPersonViewModel { + /** + * + * @type {number} + * @memberof ListPersonViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListPersonViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-team-item-view-model.ts b/codigo-fonte/frontend/src/api/models/list-team-item-view-model.ts new file mode 100644 index 00000000..a877ea00 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-team-item-view-model.ts @@ -0,0 +1,90 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface ListTeamItemViewModel + */ +export interface ListTeamItemViewModel { + /** + * + * @type {number} + * @memberof ListTeamItemViewModel + */ + 'teamId'?: number; + /** + * + * @type {string} + * @memberof ListTeamItemViewModel + */ + 'name'?: string | null; + /** + * + * @type {string} + * @memberof ListTeamItemViewModel + */ + 'lessonTime'?: string | null; + /** + * + * @type {string} + * @memberof ListTeamItemViewModel + */ + 'start'?: string | null; + /** + * + * @type {string} + * @memberof ListTeamItemViewModel + */ + 'finish'?: string | null; + /** + * + * @type {number} + * @memberof ListTeamItemViewModel + */ + 'projectProgramId'?: number | null; + /** + * + * @type {string} + * @memberof ListTeamItemViewModel + */ + 'projectProgramName'?: string | null; + /** + * + * @type {number} + * @memberof ListTeamItemViewModel + */ + 'courseId'?: number | null; + /** + * + * @type {string} + * @memberof ListTeamItemViewModel + */ + 'courseName'?: string | null; + /** + * + * @type {number} + * @memberof ListTeamItemViewModel + */ + 'personTeamsCount'?: number; + /** + * + * @type {boolean} + * @memberof ListTeamItemViewModel + */ + 'isDeleted'?: boolean; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-team-request.ts b/codigo-fonte/frontend/src/api/models/list-team-request.ts new file mode 100644 index 00000000..e575b7b9 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-team-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListTeamRequest + */ +export interface ListTeamRequest { + /** + * + * @type {number} + * @memberof ListTeamRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListTeamRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListTeamRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-team-view-model.ts b/codigo-fonte/frontend/src/api/models/list-team-view-model.ts new file mode 100644 index 00000000..92958c3e --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-team-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { ListTeamItemViewModel } from './list-team-item-view-model'; + +/** + * + * @export + * @interface ListTeamViewModel + */ +export interface ListTeamViewModel { + /** + * + * @type {number} + * @memberof ListTeamViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListTeamViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-user-request.ts b/codigo-fonte/frontend/src/api/models/list-user-request.ts new file mode 100644 index 00000000..d971e34a --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-user-request.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { Filter } from './filter'; + +/** + * + * @export + * @interface ListUserRequest + */ +export interface ListUserRequest { + /** + * + * @type {number} + * @memberof ListUserRequest + */ + 'pageNumber'?: number; + /** + * + * @type {number} + * @memberof ListUserRequest + */ + 'pageSize'?: number; + /** + * + * @type {Array} + * @memberof ListUserRequest + */ + 'filters'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/list-user-view-model.ts b/codigo-fonte/frontend/src/api/models/list-user-view-model.ts new file mode 100644 index 00000000..fadf7979 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/list-user-view-model.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { UserViewModel } from './user-view-model'; + +/** + * + * @export + * @interface ListUserViewModel + */ +export interface ListUserViewModel { + /** + * + * @type {number} + * @memberof ListUserViewModel + */ + 'totalItems'?: number; + /** + * + * @type {Array} + * @memberof ListUserViewModel + */ + 'items'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/login-response.ts b/codigo-fonte/frontend/src/api/models/login-response.ts new file mode 100644 index 00000000..c93544bf --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/login-response.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface LoginResponse + */ +export interface LoginResponse { + /** + * + * @type {string} + * @memberof LoginResponse + */ + 'accessToken'?: string; + /** + * + * @type {string} + * @memberof LoginResponse + */ + 'refreshToken'?: string; + /** + * + * @type {string} + * @memberof LoginResponse + */ + 'expiresIn'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/op.ts b/codigo-fonte/frontend/src/api/models/op.ts new file mode 100644 index 00000000..4076b1e2 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/op.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @enum {string} + */ + +export const Op = { + NUMBER_0: 0, + NUMBER_1: 1, + NUMBER_2: 2, + NUMBER_3: 3, + NUMBER_4: 4, + NUMBER_5: 5, + NUMBER_6: 6, + NUMBER_7: 7, + NUMBER_8: 8, + NUMBER_9: 9, + NUMBER_10: 10, + NUMBER_11: 11, + NUMBER_12: 12, + NUMBER_13: 13, + NUMBER_14: 14, + NUMBER_15: 15 +} as const; + +export type Op = typeof Op[keyof typeof Op]; + + + diff --git a/codigo-fonte/frontend/src/api/models/origin-business-case-by-business-case-id-view-model.ts b/codigo-fonte/frontend/src/api/models/origin-business-case-by-business-case-id-view-model.ts new file mode 100644 index 00000000..25ca3cd4 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/origin-business-case-by-business-case-id-view-model.ts @@ -0,0 +1,48 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface OriginBusinessCaseByBusinessCaseIdViewModel + */ +export interface OriginBusinessCaseByBusinessCaseIdViewModel { + /** + * + * @type {number} + * @memberof OriginBusinessCaseByBusinessCaseIdViewModel + */ + 'originBusinessCaseId'?: number; + /** + * + * @type {string} + * @memberof OriginBusinessCaseByBusinessCaseIdViewModel + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof OriginBusinessCaseByBusinessCaseIdViewModel + */ + 'notes'?: string; + /** + * + * @type {number} + * @memberof OriginBusinessCaseByBusinessCaseIdViewModel + */ + 'businessCaseId'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/origin-business-case-view-model.ts b/codigo-fonte/frontend/src/api/models/origin-business-case-view-model.ts new file mode 100644 index 00000000..0f5f6ba9 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/origin-business-case-view-model.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface OriginBusinessCaseViewModel + */ +export interface OriginBusinessCaseViewModel { + /** + * + * @type {number} + * @memberof OriginBusinessCaseViewModel + */ + 'originBusinessCaseId'?: number; + /** + * + * @type {string} + * @memberof OriginBusinessCaseViewModel + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof OriginBusinessCaseViewModel + */ + 'notes'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/osc-view-model.ts b/codigo-fonte/frontend/src/api/models/osc-view-model.ts new file mode 100644 index 00000000..c65bfbff --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/osc-view-model.ts @@ -0,0 +1,114 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface OscViewModel + */ +export interface OscViewModel { + /** + * + * @type {number} + * @memberof OscViewModel + */ + 'oscId'?: number; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'objective'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'corporateName'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'address'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'neighborhood'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'city'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'state'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'phoneNumber'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'webUrl'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'socialMedia'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'zipCode'?: string; + /** + * + * @type {string} + * @memberof OscViewModel + */ + 'oscPrimaryDocumment'?: string; + /** + * + * @type {number} + * @memberof OscViewModel + */ + 'beneficiariesCount'?: number; +} + diff --git a/codigo-fonte/frontend/src/api/models/person-list-item-view-model.ts b/codigo-fonte/frontend/src/api/models/person-list-item-view-model.ts new file mode 100644 index 00000000..09568a8e --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/person-list-item-view-model.ts @@ -0,0 +1,60 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface PersonListItemViewModel + */ +export interface PersonListItemViewModel { + /** + * + * @type {number} + * @memberof PersonListItemViewModel + */ + 'personId'?: number; + /** + * + * @type {string} + * @memberof PersonListItemViewModel + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof PersonListItemViewModel + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof PersonListItemViewModel + */ + 'personalDocumment'?: string; + /** + * + * @type {string} + * @memberof PersonListItemViewModel + */ + 'primaryPhone'?: string | null; + /** + * + * @type {boolean} + * @memberof PersonListItemViewModel + */ + 'isActive'?: boolean; +} + diff --git a/codigo-fonte/frontend/src/api/models/person-view-model.ts b/codigo-fonte/frontend/src/api/models/person-view-model.ts new file mode 100644 index 00000000..25909543 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/person-view-model.ts @@ -0,0 +1,90 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface PersonViewModel + */ +export interface PersonViewModel { + /** + * + * @type {number} + * @memberof PersonViewModel + */ + 'personId'?: number; + /** + * + * @type {string} + * @memberof PersonViewModel + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof PersonViewModel + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof PersonViewModel + */ + 'personalDocumment'?: string; + /** + * + * @type {string} + * @memberof PersonViewModel + */ + 'primaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof PersonViewModel + */ + 'secondaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof PersonViewModel + */ + 'secondaryEmail'?: string | null; + /** + * + * @type {string} + * @memberof PersonViewModel + */ + 'education1'?: string | null; + /** + * + * @type {string} + * @memberof PersonViewModel + */ + 'education2'?: string | null; + /** + * + * @type {string} + * @memberof PersonViewModel + */ + 'professionalActivity'?: string | null; + /** + * + * @type {boolean} + * @memberof PersonViewModel + */ + 'isActive'?: boolean; +} + diff --git a/codigo-fonte/frontend/src/api/models/problem-details.ts b/codigo-fonte/frontend/src/api/models/problem-details.ts new file mode 100644 index 00000000..b8aacad5 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/problem-details.ts @@ -0,0 +1,56 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface ProblemDetails + */ +export interface ProblemDetails { + [key: string]: any; + + /** + * + * @type {string} + * @memberof ProblemDetails + */ + 'type'?: string | null; + /** + * + * @type {string} + * @memberof ProblemDetails + */ + 'title'?: string | null; + /** + * + * @type {number} + * @memberof ProblemDetails + */ + 'status'?: number | null; + /** + * + * @type {string} + * @memberof ProblemDetails + */ + 'detail'?: string | null; + /** + * + * @type {string} + * @memberof ProblemDetails + */ + 'instance'?: string | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/reset-password-request.ts b/codigo-fonte/frontend/src/api/models/reset-password-request.ts new file mode 100644 index 00000000..6e7056f1 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/reset-password-request.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface ResetPasswordRequest + */ +export interface ResetPasswordRequest { + /** + * + * @type {number} + * @memberof ResetPasswordRequest + */ + 'userId'?: number; + /** + * + * @type {string} + * @memberof ResetPasswordRequest + */ + 'token'?: string; + /** + * + * @type {string} + * @memberof ResetPasswordRequest + */ + 'newPassword'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/reset-password-response.ts b/codigo-fonte/frontend/src/api/models/reset-password-response.ts new file mode 100644 index 00000000..bf72a7e8 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/reset-password-response.ts @@ -0,0 +1,30 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface ResetPasswordResponse + */ +export interface ResetPasswordResponse { + /** + * + * @type {string} + * @memberof ResetPasswordResponse + */ + 'message'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/team-view-model.ts b/codigo-fonte/frontend/src/api/models/team-view-model.ts new file mode 100644 index 00000000..1e223bac --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/team-view-model.ts @@ -0,0 +1,54 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface TeamViewModel + */ +export interface TeamViewModel { + /** + * + * @type {number} + * @memberof TeamViewModel + */ + 'id'?: number; + /** + * + * @type {string} + * @memberof TeamViewModel + */ + 'name'?: string | null; + /** + * + * @type {string} + * @memberof TeamViewModel + */ + 'lessonTime'?: string | null; + /** + * + * @type {string} + * @memberof TeamViewModel + */ + 'start'?: string | null; + /** + * + * @type {string} + * @memberof TeamViewModel + */ + 'finish'?: string | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-beneficiary-in-osc-response.ts b/codigo-fonte/frontend/src/api/models/update-beneficiary-in-osc-response.ts new file mode 100644 index 00000000..d6d80d39 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-beneficiary-in-osc-response.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateBeneficiaryInOscResponse + */ +export interface UpdateBeneficiaryInOscResponse { + /** + * + * @type {number} + * @memberof UpdateBeneficiaryInOscResponse + */ + 'beneficiaryId'?: number; + /** + * + * @type {string} + * @memberof UpdateBeneficiaryInOscResponse + */ + 'name'?: string | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-beneficiary-request.ts b/codigo-fonte/frontend/src/api/models/update-beneficiary-request.ts new file mode 100644 index 00000000..fe039044 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-beneficiary-request.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateBeneficiaryRequest + */ +export interface UpdateBeneficiaryRequest { + /** + * + * @type {string} + * @memberof UpdateBeneficiaryRequest + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof UpdateBeneficiaryRequest + */ + 'notes'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-beneficiary-response.ts b/codigo-fonte/frontend/src/api/models/update-beneficiary-response.ts new file mode 100644 index 00000000..5170caeb --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-beneficiary-response.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateBeneficiaryResponse + */ +export interface UpdateBeneficiaryResponse { + /** + * + * @type {number} + * @memberof UpdateBeneficiaryResponse + */ + 'beneficiaryId'?: number; + /** + * + * @type {string} + * @memberof UpdateBeneficiaryResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof UpdateBeneficiaryResponse + */ + 'notes'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-business-case-request.ts b/codigo-fonte/frontend/src/api/models/update-business-case-request.ts new file mode 100644 index 00000000..50c47c60 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-business-case-request.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateBusinessCaseRequest + */ +export interface UpdateBusinessCaseRequest { + /** + * + * @type {string} + * @memberof UpdateBusinessCaseRequest + */ + 'name'?: string | null; + /** + * + * @type {Array} + * @memberof UpdateBusinessCaseRequest + */ + 'originsBusinessCasesIds'?: Array; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-business-case-response.ts b/codigo-fonte/frontend/src/api/models/update-business-case-response.ts new file mode 100644 index 00000000..104f095a --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-business-case-response.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { UpdateOriginBusinessCaseInBusinessCaseResponse } from './update-origin-business-case-in-business-case-response'; + +/** + * + * @export + * @interface UpdateBusinessCaseResponse + */ +export interface UpdateBusinessCaseResponse { + /** + * + * @type {number} + * @memberof UpdateBusinessCaseResponse + */ + 'businessCaseId'?: number; + /** + * + * @type {string} + * @memberof UpdateBusinessCaseResponse + */ + 'name'?: string; + /** + * + * @type {Array} + * @memberof UpdateBusinessCaseResponse + */ + 'originsBusinessCases'?: Array | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-company-command.ts b/codigo-fonte/frontend/src/api/models/update-company-command.ts new file mode 100644 index 00000000..8150cf86 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-company-command.ts @@ -0,0 +1,96 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateCompanyCommand + */ +export interface UpdateCompanyCommand { + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'cnpj'?: string; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'companyName'?: string; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'corporateReason'?: string | null; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'fieldOfActivity'?: string | null; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'zipCode'?: string | null; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'address'?: string | null; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'neighborhood'?: string | null; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'city'?: string | null; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'state'?: string | null; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'phoneNumber'?: string | null; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'website'?: string | null; + /** + * + * @type {string} + * @memberof UpdateCompanyCommand + */ + 'socialMedia'?: string | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-donation-command.ts b/codigo-fonte/frontend/src/api/models/update-donation-command.ts new file mode 100644 index 00000000..58b9c024 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-donation-command.ts @@ -0,0 +1,60 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateDonationCommand + */ +export interface UpdateDonationCommand { + /** + * + * @type {number} + * @memberof UpdateDonationCommand + */ + 'id'?: number; + /** + * + * @type {number} + * @memberof UpdateDonationCommand + */ + 'value'?: number; + /** + * + * @type {string} + * @memberof UpdateDonationCommand + */ + 'donationDate'?: string; + /** + * + * @type {number} + * @memberof UpdateDonationCommand + */ + 'oscId'?: number | null; + /** + * + * @type {number} + * @memberof UpdateDonationCommand + */ + 'courseId'?: number | null; + /** + * + * @type {number} + * @memberof UpdateDonationCommand + */ + 'teamId'?: number | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-origin-business-case-in-business-case-response.ts b/codigo-fonte/frontend/src/api/models/update-origin-business-case-in-business-case-response.ts new file mode 100644 index 00000000..179e70ae --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-origin-business-case-in-business-case-response.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateOriginBusinessCaseInBusinessCaseResponse + */ +export interface UpdateOriginBusinessCaseInBusinessCaseResponse { + /** + * + * @type {number} + * @memberof UpdateOriginBusinessCaseInBusinessCaseResponse + */ + 'originBusinessCaseId'?: number; + /** + * + * @type {string} + * @memberof UpdateOriginBusinessCaseInBusinessCaseResponse + */ + 'name'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-origin-business-case-in-osc-response.ts b/codigo-fonte/frontend/src/api/models/update-origin-business-case-in-osc-response.ts new file mode 100644 index 00000000..752a31cc --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-origin-business-case-in-osc-response.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateOriginBusinessCaseInOscResponse + */ +export interface UpdateOriginBusinessCaseInOscResponse { + /** + * + * @type {number} + * @memberof UpdateOriginBusinessCaseInOscResponse + */ + 'originBusinessCaseId'?: number; + /** + * + * @type {string} + * @memberof UpdateOriginBusinessCaseInOscResponse + */ + 'name'?: string | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-origin-business-case-request.ts b/codigo-fonte/frontend/src/api/models/update-origin-business-case-request.ts new file mode 100644 index 00000000..0681b74b --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-origin-business-case-request.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateOriginBusinessCaseRequest + */ +export interface UpdateOriginBusinessCaseRequest { + /** + * + * @type {string} + * @memberof UpdateOriginBusinessCaseRequest + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof UpdateOriginBusinessCaseRequest + */ + 'notes'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-origin-business-case-response.ts b/codigo-fonte/frontend/src/api/models/update-origin-business-case-response.ts new file mode 100644 index 00000000..75da7c55 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-origin-business-case-response.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateOriginBusinessCaseResponse + */ +export interface UpdateOriginBusinessCaseResponse { + /** + * + * @type {number} + * @memberof UpdateOriginBusinessCaseResponse + */ + 'originBusinessCaseId'?: number; + /** + * + * @type {string} + * @memberof UpdateOriginBusinessCaseResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof UpdateOriginBusinessCaseResponse + */ + 'notes'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-osc-request.ts b/codigo-fonte/frontend/src/api/models/update-osc-request.ts new file mode 100644 index 00000000..eb75878c --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-osc-request.ts @@ -0,0 +1,72 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateOscRequest + */ +export interface UpdateOscRequest { + /** + * + * @type {string} + * @memberof UpdateOscRequest + */ + 'name'?: string | null; + /** + * + * @type {string} + * @memberof UpdateOscRequest + */ + 'corporateName'?: string | null; + /** + * + * @type {string} + * @memberof UpdateOscRequest + */ + 'objective'?: string | null; + /** + * + * @type {string} + * @memberof UpdateOscRequest + */ + 'address'?: string | null; + /** + * + * @type {string} + * @memberof UpdateOscRequest + */ + 'zipCode'?: string | null; + /** + * + * @type {string} + * @memberof UpdateOscRequest + */ + 'oscPrimaryDocumment'?: string | null; + /** + * + * @type {Array} + * @memberof UpdateOscRequest + */ + 'beneficiaryIds'?: Array | null; + /** + * + * @type {Array} + * @memberof UpdateOscRequest + */ + 'originBusinessCaseIds'?: Array | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-osc-response.ts b/codigo-fonte/frontend/src/api/models/update-osc-response.ts new file mode 100644 index 00000000..db30d9f7 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-osc-response.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { UpdateBeneficiaryInOscResponse } from './update-beneficiary-in-osc-response'; +// May contain unused imports in some cases +// @ts-ignore +import type { UpdateOriginBusinessCaseInOscResponse } from './update-origin-business-case-in-osc-response'; + +/** + * + * @export + * @interface UpdateOscResponse + */ +export interface UpdateOscResponse { + /** + * + * @type {number} + * @memberof UpdateOscResponse + */ + 'oscId'?: number; + /** + * + * @type {string} + * @memberof UpdateOscResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof UpdateOscResponse + */ + 'corporateName'?: string; + /** + * + * @type {string} + * @memberof UpdateOscResponse + */ + 'objective'?: string; + /** + * + * @type {string} + * @memberof UpdateOscResponse + */ + 'address'?: string; + /** + * + * @type {string} + * @memberof UpdateOscResponse + */ + 'zipCode'?: string; + /** + * + * @type {string} + * @memberof UpdateOscResponse + */ + 'oscPrimaryDocumment'?: string | null; + /** + * + * @type {Array} + * @memberof UpdateOscResponse + */ + 'beneficiaries'?: Array | null; + /** + * + * @type {Array} + * @memberof UpdateOscResponse + */ + 'originsBusinessCases'?: Array | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-person-request.ts b/codigo-fonte/frontend/src/api/models/update-person-request.ts new file mode 100644 index 00000000..31776957 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-person-request.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdatePersonRequest + */ +export interface UpdatePersonRequest { + /** + * + * @type {string} + * @memberof UpdatePersonRequest + */ + 'name'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonRequest + */ + 'email'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonRequest + */ + 'personalDocumment'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonRequest + */ + 'secondaryEmail'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonRequest + */ + 'primaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonRequest + */ + 'secondaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonRequest + */ + 'education1'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonRequest + */ + 'education2'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonRequest + */ + 'professionalActivity'?: string | null; + /** + * + * @type {boolean} + * @memberof UpdatePersonRequest + */ + 'isActive'?: boolean | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-person-response.ts b/codigo-fonte/frontend/src/api/models/update-person-response.ts new file mode 100644 index 00000000..fa00c47a --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-person-response.ts @@ -0,0 +1,90 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdatePersonResponse + */ +export interface UpdatePersonResponse { + /** + * + * @type {number} + * @memberof UpdatePersonResponse + */ + 'personId'?: number; + /** + * + * @type {string} + * @memberof UpdatePersonResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof UpdatePersonResponse + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof UpdatePersonResponse + */ + 'personalDocumment'?: string; + /** + * + * @type {string} + * @memberof UpdatePersonResponse + */ + 'secondaryEmail'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonResponse + */ + 'primaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonResponse + */ + 'secondaryPhone'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonResponse + */ + 'education1'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonResponse + */ + 'education2'?: string | null; + /** + * + * @type {string} + * @memberof UpdatePersonResponse + */ + 'professionalActivity'?: string | null; + /** + * + * @type {boolean} + * @memberof UpdatePersonResponse + */ + 'isActive'?: boolean; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-user-request.ts b/codigo-fonte/frontend/src/api/models/update-user-request.ts new file mode 100644 index 00000000..d3aa836d --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-user-request.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateUserRequest + */ +export interface UpdateUserRequest { + /** + * + * @type {number} + * @memberof UpdateUserRequest + */ + 'userId'?: number; + /** + * + * @type {string} + * @memberof UpdateUserRequest + */ + 'name'?: string | null; + /** + * + * @type {string} + * @memberof UpdateUserRequest + */ + 'password'?: string | null; + /** + * + * @type {string} + * @memberof UpdateUserRequest + */ + 'email'?: string | null; + /** + * + * @type {string} + * @memberof UpdateUserRequest + */ + 'phoneNumber'?: string | null; + /** + * + * @type {boolean} + * @memberof UpdateUserRequest + */ + 'isActive'?: boolean; + /** + * + * @type {string} + * @memberof UpdateUserRequest + */ + 'role'?: string | null; +} + diff --git a/codigo-fonte/frontend/src/api/models/update-user-response.ts b/codigo-fonte/frontend/src/api/models/update-user-response.ts new file mode 100644 index 00000000..28f53a6a --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/update-user-response.ts @@ -0,0 +1,60 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UpdateUserResponse + */ +export interface UpdateUserResponse { + /** + * + * @type {number} + * @memberof UpdateUserResponse + */ + 'userId'?: number; + /** + * + * @type {string} + * @memberof UpdateUserResponse + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof UpdateUserResponse + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof UpdateUserResponse + */ + 'phoneNumber'?: string; + /** + * + * @type {boolean} + * @memberof UpdateUserResponse + */ + 'isActive'?: boolean; + /** + * + * @type {string} + * @memberof UpdateUserResponse + */ + 'role'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/user-login.ts b/codigo-fonte/frontend/src/api/models/user-login.ts new file mode 100644 index 00000000..3269b416 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/user-login.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UserLogin + */ +export interface UserLogin { + /** + * + * @type {string} + * @memberof UserLogin + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof UserLogin + */ + 'password'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/user-token.ts b/codigo-fonte/frontend/src/api/models/user-token.ts new file mode 100644 index 00000000..4f58cc33 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/user-token.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UserToken + */ +export interface UserToken { + /** + * + * @type {string} + * @memberof UserToken + */ + 'accessToken'?: string; + /** + * + * @type {string} + * @memberof UserToken + */ + 'expiresIn'?: string; + /** + * + * @type {string} + * @memberof UserToken + */ + 'refresfToken'?: string; +} + diff --git a/codigo-fonte/frontend/src/api/models/user-view-model.ts b/codigo-fonte/frontend/src/api/models/user-view-model.ts new file mode 100644 index 00000000..c1ff59b7 --- /dev/null +++ b/codigo-fonte/frontend/src/api/models/user-view-model.ts @@ -0,0 +1,60 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * IgescConecta.API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface UserViewModel + */ +export interface UserViewModel { + /** + * + * @type {number} + * @memberof UserViewModel + */ + 'userId'?: number; + /** + * + * @type {string} + * @memberof UserViewModel + */ + 'name'?: string; + /** + * + * @type {string} + * @memberof UserViewModel + */ + 'email'?: string; + /** + * + * @type {string} + * @memberof UserViewModel + */ + 'role'?: string; + /** + * + * @type {string} + * @memberof UserViewModel + */ + 'phoneNumber'?: string; + /** + * + * @type {boolean} + * @memberof UserViewModel + */ + 'isActive'?: boolean; +} + diff --git a/codigo-fonte/frontend/src/assets/logo-gesc.png b/codigo-fonte/frontend/src/assets/logo-gesc.png new file mode 100644 index 00000000..31ace48b Binary files /dev/null and b/codigo-fonte/frontend/src/assets/logo-gesc.png differ diff --git a/codigo-fonte/frontend/src/assets/react.svg b/codigo-fonte/frontend/src/assets/react.svg new file mode 100644 index 00000000..6c87de9b --- /dev/null +++ b/codigo-fonte/frontend/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/codigo-fonte/frontend/src/components/ConfirmDelete.tsx b/codigo-fonte/frontend/src/components/ConfirmDelete.tsx new file mode 100644 index 00000000..0ccf9ea4 --- /dev/null +++ b/codigo-fonte/frontend/src/components/ConfirmDelete.tsx @@ -0,0 +1,130 @@ +import React from 'react'; +import { + Dialog, + DialogTitle, + DialogContent, + DialogActions, + Typography, + Button, +} from '@mui/material'; +import { alpha } from '@mui/material/styles'; + +interface ConfirmDialogProps { + open: boolean; + title?: string; + message: string; + highlightText?: string; + confirmLabel?: string; + cancelLabel?: string; + onClose: () => void; + onConfirm: () => void; + loading?: boolean; + danger?: boolean; +} + +export const ConfirmDialog: React.FC = ({ + open, + title = 'Confirmação', + message, + highlightText, + confirmLabel = 'Confirmar', + cancelLabel = 'Cancelar', + onClose, + onConfirm, + loading = false, + danger = false, +}) => { + return ( + + + + {title} + + + + + + {message} + {highlightText && ( + <> +
+ {highlightText} + + )} +
+
+ + + + + + +
+ ); +}; diff --git a/codigo-fonte/frontend/src/components/SideMenu.tsx b/codigo-fonte/frontend/src/components/SideMenu.tsx new file mode 100644 index 00000000..08716087 --- /dev/null +++ b/codigo-fonte/frontend/src/components/SideMenu.tsx @@ -0,0 +1,318 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { + Box, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Typography, + Divider, + IconButton, +} from '@mui/material'; +import HomeIcon from '@mui/icons-material/Home'; +import SchoolIcon from '@mui/icons-material/School'; +import GroupIcon from '@mui/icons-material/Group'; +import PublicIcon from '@mui/icons-material/Public'; +import GroupsIcon from '@mui/icons-material/Groups'; +import Diversity2Icon from '@mui/icons-material/Diversity2'; +import BusinessIcon from '@mui/icons-material/Business'; +import VolunteerActivismIcon from '@mui/icons-material/VolunteerActivism'; +import PeopleAltIcon from '@mui/icons-material/PeopleAlt'; +import LogoutIcon from '@mui/icons-material/Logout'; +import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; +import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp'; +import { useNavigate, useLocation } from 'react-router-dom'; + +const IGESC_COLORS = { + AZUL_CLARO: '#1E4EC4', + AZUL_ESCURO: '#264197', + CINZA_MEDIO: '#666f77', + CINZA_CLARO: '#e7e7e7', + VERDE_ACAO: '#4CAF50', + BRANCO: '#ffffff', +}; + +const menuItems = [ + { path: '/home', label: 'Início', icon: }, + { path: '/course', label: 'Programas', icon: }, + { path: '/team', label: 'Turmas', icon: }, + { path: '/osc', label: 'OSC', icon: }, + { path: '/beneficiary', label: 'Público', icon: }, + { path: '/business-case', label: 'Grupo de Causas', icon: }, + { path: '/person', label: 'Pessoas', icon: }, + { path: '/company', label: 'Empresa', icon: }, + { path: '/donation', label: 'Doações', icon: }, + { path: '/user', label: 'Usuários', icon: }, +]; + +export default function SideMenu() { + const navigate = useNavigate(); + const location = useLocation(); + + const handleNavigation = (path: string) => { + navigate(path); + }; + + const loginRaw = localStorage.getItem('loginResponse'); + const login = loginRaw ? JSON.parse(loginRaw) : {}; + const firstName = + typeof login?.name === 'string' && login.name.trim() + ? login.name.trim().split(/\s+/)[0] + : ''; + + const handleLogout = () => { + localStorage.removeItem('loginResponse'); + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + navigate('/login'); + }; + + const listRef = useRef(null); + const [canUp, setCanUp] = useState(false); + const [canDown, setCanDown] = useState(false); + const scrollState = useRef<{ timer: any | null }>({ timer: null }); + + const updateArrows = () => { + const el = listRef.current; + if (!el) return; + const up = el.scrollTop > 0; + const down = el.scrollTop + el.clientHeight < el.scrollHeight - 1; + setCanUp(up); + setCanDown(down); + }; + + const startScroll = (dir: 1 | -1) => { + const el = listRef.current; + if (!el) return; + stopScroll(); + scrollState.current.timer = setInterval(() => { + el.scrollBy({ top: dir * 8, behavior: 'auto' }); + updateArrows(); + }, 16); + }; + + const stopScroll = () => { + if (scrollState.current.timer) { + clearInterval(scrollState.current.timer); + scrollState.current.timer = null; + } + }; + + const nudge = (dir: 1 | -1) => { + const el = listRef.current; + if (!el) return; + el.scrollBy({ top: dir * 140, behavior: 'smooth' }); + setTimeout(updateArrows, 220); + }; + + useEffect(() => { + updateArrows(); + const el = listRef.current; + if (!el) return; + const onScroll = () => updateArrows(); + el.addEventListener('scroll', onScroll); + const onResize = () => updateArrows(); + window.addEventListener('resize', onResize); + return () => { + el.removeEventListener('scroll', onScroll); + window.removeEventListener('resize', onResize); + stopScroll(); + }; + }, []); + + return ( + + + + IGESC Conecta + + + + + + {menuItems.map((item) => { + const isSelected = + location.pathname === item.path || location.pathname.startsWith(item.path + '/'); + return ( + + handleNavigation(item.path)} + selected={isSelected} + sx={{ + borderRadius: 1, + color: IGESC_COLORS.BRANCO, + py: { xs: 0.55, md: 0.7 }, + px: { xs: 1.1, md: 1.3 }, + minHeight: { xs: 36, md: 42 }, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.10)' }, + '&.Mui-selected': { + backgroundColor: IGESC_COLORS.VERDE_ACAO, + color: IGESC_COLORS.BRANCO, + fontWeight: 700, + '&:hover': { backgroundColor: IGESC_COLORS.AZUL_ESCURO }, + }, + }} + > + + {item.icon} + + + + + ); + })} + + + + + + + {firstName} + + + + + + + {canUp && ( + startScroll(-1)} + onMouseUp={stopScroll} + onMouseLeave={stopScroll} + onClick={() => nudge(-1)} + sx={{ + position: 'absolute', + top: 8, + right: 8, + width: 32, + height: 32, + borderRadius: 2, + backdropFilter: 'blur(6px)', + background: 'rgba(255,255,255,0.18)', + border: '1px solid rgba(255,255,255,0.35)', + boxShadow: '0 4px 14px rgba(0,0,0,0.18)', + color: '#fff', + '&:hover': { background: 'rgba(255,255,255,0.28)' }, + }} + > + + + )} + + {canDown && ( + startScroll(1)} + onMouseUp={stopScroll} + onMouseLeave={stopScroll} + onClick={() => nudge(1)} + sx={{ + position: 'absolute', + bottom: 8, + right: 8, + width: 32, + height: 32, + borderRadius: 2, + backdropFilter: 'blur(6px)', + background: 'rgba(255,255,255,0.18)', + border: '1px solid rgba(255,255,255,0.35)', + boxShadow: '0 4px 14px rgba(0,0,0,0.18)', + color: '#fff', + '&:hover': { background: 'rgba(255,255,255,0.28)' }, + }} + > + + + )} + + + ); +} diff --git a/codigo-fonte/frontend/src/components/Table.tsx b/codigo-fonte/frontend/src/components/Table.tsx new file mode 100644 index 00000000..180a0b5c --- /dev/null +++ b/codigo-fonte/frontend/src/components/Table.tsx @@ -0,0 +1,419 @@ +import React from 'react'; +import { + Table as MuiTable, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Paper, + TablePagination, + Box, + Typography, + Button, + alpha, + Stack, +} from '@mui/material'; +import VisibilityIcon from '@mui/icons-material/Visibility'; +import EditIcon from '@mui/icons-material/Edit'; +import DeleteIcon from '@mui/icons-material/Delete'; +import TravelExploreIcon from '@mui/icons-material/TravelExplore'; + +/** + * Exemplo de uso da Tabela com ações e paginação backend: + * + * 1️⃣ Defina suas colunas: + * + * const columns: Column[] = [ + * { label: 'ID', field: 'id' }, + * { label: 'Nome', field: 'name' }, + * { label: 'Email', field: 'email' }, + * { label: 'Perfil', field: 'profile' }, + * ]; + * + * 2️⃣ Controle os dados e a paginação via backend: + * + * const [data, setData] = useState([]); + * const [page, setPage] = useState(0); + * const [rowsPerPage, setRowsPerPage] = useState(10); + * const [totalCount, setTotalCount] = useState(0); + * + * * Exemplo de chamada à API: + * + * useEffect(() => { + * fetch(`/api/users?page=${page + 1}&limit=${rowsPerPage}`) + * .then(res => res.json()) + * .then(result => { + * setData(result.items); // items da página atual + * setTotalCount(result.total); // total de registros no backend + * }); + * }, [page, rowsPerPage]); + * + * 3️⃣ Defina funções de ação opcionais: + * + * const handleView = (user: User) => {...}; + * const handleEdit = (user: User) => {...}; + * const handleDelete = (user: User) => {...}; + * + * 4️⃣ Renderize a tabela: + * + * + * columns={columns} + * data={data} + * page={page} + * rowsPerPage={rowsPerPage} + * totalCount={totalCount} + * onPageChange={setPage} + * onRowsPerPageChange={setRowsPerPage} + * onView={handleView} + * onEdit={handleEdit} + * onDelete={handleDelete} + * /> + * + * 🔹 Observações: + * - A coluna "Ações" aparece automaticamente se passar qualquer função de ação. + * - Cada botão recebe a linha correspondente como parâmetro. + * - A tabela suporta paginação backend: apenas os itens da página atual são carregados da API. + */ + +export type Column = { + label: string; + field: keyof T; + align?: 'left' | 'right' | 'center'; + render?: (value: T[keyof T], row: T) => React.ReactNode; +}; + +type TableProps = { + columns: Column[]; + data: T[]; + page: number; + rowsPerPage: number; + totalCount: number; + onPageChange: (newPage: number) => void; + onRowsPerPageChange?: (newRowsPerPage: number) => void; + rowsPerPageOptions?: number[]; + onView?: (row: T) => void; + onEdit?: (row: T) => void; + onDelete?: (row: T) => void; + onOriginBusinessCase?: (row: T) => void; + noDataMessage?: string; +}; + +function Table({ + columns, + data, + page, + rowsPerPage, + totalCount, + onPageChange, + onRowsPerPageChange, + rowsPerPageOptions = [5, 10, 25], + onView, + onEdit, + onDelete, + onOriginBusinessCase, + noDataMessage, +}: TableProps) { + const handleChangePage = (event: React.MouseEvent | null, newPage: number) => { + onPageChange(newPage); + }; + + const pageCount = totalCount / page; + + const handleChangeRowsPerPage = ( + event: React.ChangeEvent + ) => { + onRowsPerPageChange?.(parseInt(event.target.value, 10)); + onPageChange(0); + }; + + const hasActions = onView || onEdit || onDelete || onOriginBusinessCase; + + return ( + + + {/* Total de registros */} + + + Total de registros:{' '} + + {totalCount} + + + + + + + {/* Cabeçalho */} + + + {columns.map((col) => ( + + {col.label} + + ))} + {hasActions && ( + + Ações + + )} + + + + {/* Corpo */} + + {data.map((row, idx) => ( + + {columns.map((col) => ( + + {col.render ? col.render(row[col.field], row) : row[col.field]} + + ))} + + {hasActions && ( + + + {onView && ( + + )} + {onEdit && ( + + )} + {onDelete && ( + + )} + {onOriginBusinessCase && ( + + )} + + + )} + + ))} + + + + + {/* Mensagem de nenhum dado */} + {noDataMessage ? ( + + {noDataMessage} + + ) : ( + <> + )} + + {/* Paginação */} + + + `${from}–${to} de ${count !== -1 ? count : `mais de ${to}`}` + } + sx={{ + '.MuiTablePagination-selectLabel, .MuiTablePagination-displayedRows': { + color: '#1a1a2e', + fontSize: '0.875rem', + fontWeight: 500, + }, + '.MuiSelect-select': { + color: '#1a1a2e', + fontSize: '0.875rem', + fontWeight: 600, + }, + '.MuiTablePagination-actions button': { + color: '#1E4EC4', + '&:hover': { + bgcolor: alpha('#1E4EC4', 0.08), + }, + }, + }} + /> + + + + ); +} + +export default Table; diff --git a/codigo-fonte/frontend/src/components/TitleAndButtons.tsx b/codigo-fonte/frontend/src/components/TitleAndButtons.tsx new file mode 100644 index 00000000..de49bba6 --- /dev/null +++ b/codigo-fonte/frontend/src/components/TitleAndButtons.tsx @@ -0,0 +1,133 @@ +import { Box, Typography, Stack, Button } from '@mui/material'; +import AddIcon from '@mui/icons-material/Add'; +import DownloadIcon from '@mui/icons-material/Download'; +import UploadFileIcon from '@mui/icons-material/UploadFile'; + +interface TitleAndButtonsProps { + title: string; + onAdd?: () => void; + addLabel?: string; + onImportCsv?: () => void; + importLabel?: string; + onExportCsv?: () => void; + exportLabel?: string; +} + +const TitleAndButtons = ({ + title, + onAdd, + addLabel, + onImportCsv, + importLabel, + onExportCsv, + exportLabel, +}: TitleAndButtonsProps) => ( + + + {title} + + + {onAdd && ( + + )} + {onImportCsv && ( + + )} + {onExportCsv && ( + + )} + + +); + +export default TitleAndButtons; diff --git a/codigo-fonte/frontend/src/hooks/.gitkeep b/codigo-fonte/frontend/src/hooks/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/codigo-fonte/frontend/src/index.css b/codigo-fonte/frontend/src/index.css new file mode 100644 index 00000000..7b835b3e --- /dev/null +++ b/codigo-fonte/frontend/src/index.css @@ -0,0 +1,16 @@ +html, body, #root { + height: 100%; + margin: 0; + background-color: #f6f6f7; +} + +body { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + color: #242424; + display: flex; + flex-direction: column; +} + +* { + box-sizing: border-box; +} \ No newline at end of file diff --git a/codigo-fonte/frontend/src/main.tsx b/codigo-fonte/frontend/src/main.tsx new file mode 100644 index 00000000..b83cdeba --- /dev/null +++ b/codigo-fonte/frontend/src/main.tsx @@ -0,0 +1,11 @@ +import React from "react"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter } from "react-router-dom"; +import App from "./App"; +import "./index.css"; + +createRoot(document.getElementById("root")!).render( + + + +); diff --git a/codigo-fonte/frontend/src/pages/Beneficiary.tsx b/codigo-fonte/frontend/src/pages/Beneficiary.tsx new file mode 100644 index 00000000..86e054e8 --- /dev/null +++ b/codigo-fonte/frontend/src/pages/Beneficiary.tsx @@ -0,0 +1,707 @@ +import React, { useState, useEffect, use } from 'react'; +import { + Box, + Container, + Button, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + CircularProgress, + FormControl, + InputLabel, + Select, + MenuItem, + Grid, + SelectChangeEvent, + Typography, + Stack, + Divider, + TextField, + Autocomplete +} from '@mui/material'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import SearchIcon from '@mui/icons-material/Search'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import dayjs, { Dayjs } from 'dayjs'; +import 'dayjs/locale/pt-br'; +import Table, { Column } from '../components/Table'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import { toast } from 'react-toastify'; +import { + OscsApi, + BeneficiariesApi, + CreateBeneficiaryRequest, + UpdateBeneficiaryRequest, + ListBeneficiaryRequest, + Filter, + Op, +} from './../api'; +import { apiConfig } from '../services/auth'; +import { alpha } from '@mui/material/styles'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import ClearIcon from '@mui/icons-material/Clear'; +import { Chip, Paper } from '@mui/material'; +import { ConfirmDialog } from '@/components/ConfirmDelete'; + +dayjs.locale('pt-br'); + +interface Beneficiary { + beneficiaryId?: number; + name?: string; + notes?: string; + oscs?: Osc[]; +} + +interface Osc { + oscId?: number; + name?: string; + corporateName?: string; +} + +const Beneficiary: React.FC = () => { + + const [beneficiary, setBeneficiaries] = useState([]); + const [loading, setLoading] = useState(false); + const [modalLoading, setModalLoading] = useState(false); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [noDataMessage, setNoDataMessage] = useState(''); + const [openModal, setOpenModal] = useState(false); + const [isVisualizing, setIsVisualizing] = useState(false); + const [updateBeneficiary, setUpdateBeneficiary] = useState(null); + const [createBeneficiary, setCreateBeneficiary] = useState(null); + const [selectedBeneficiary, setSelectedBeneficiary] = useState(null); + + const [filterBeneficiaryName, setFilterBeneficiaryName] = useState(''); + + const [openDeleteModal, setOpenDeleteModal] = useState(false); + const [beneficiaryToDelete, setBeneficiaryToDelete] = useState(null); + + const beneficiariesApi = new BeneficiariesApi(apiConfig); + const oscsApi = new OscsApi(apiConfig); + + const dialogTitle = () => { + return isVisualizing ? 'Visualizar Público' : updateBeneficiary ? 'Atualizar Público' : 'Criar Público'; + } + + useEffect(() => { + fetchBeneficiaries(); + }, [page, rowsPerPage]); + + const fetchBeneficiaries = async (customFilters?: Filter[]) => { + try { + setLoading(true); + setBeneficiaries([]); + + const filters: Filter[] = customFilters ? customFilters : []; + + const listBeneficiaryRequest: ListBeneficiaryRequest = { + pageNumber: page + 1, + pageSize: rowsPerPage, + filters: filters.length > 0 ? filters : undefined, + }; + + const { data } = await beneficiariesApi.listBeneficiary(listBeneficiaryRequest); + + if (!data.items || data.items.length === 0) { + setNoDataMessage('Nenhum público encontrado.'); + setBeneficiaries([]); + return; + } + + setBeneficiaries( + (data.items ?? []).map((item) => ({ + ...item, + })) + ); + + setTotalCount(data.totalItems || 0); + setNoDataMessage(''); + } catch (error) { + console.error('Erro ao carregar público:', error); + toast.error('Erro ao carregar público.'); + setBeneficiaries([]); + setTotalCount(0); + } finally { + setLoading(false); + } + } + + const handleSearch = () => { + const filters: Filter[] = []; + + if (filterBeneficiaryName && filterBeneficiaryName.trim() !== '') { + filters.push({ + propertyName: 'name', + operation: 7, + value: filterBeneficiaryName.trim(), + }); + } + setPage(0); + fetchBeneficiaries(filters); + } + + const handleClearFilters = () => { + setPage(0); + setFilterBeneficiaryName(''); + fetchBeneficiaries([]); + } + + const handleAdd = () => { + setCreateBeneficiary({ + name: '', + notes: '', + }); + setIsVisualizing(false); + resetForm(); + setOpenModal(true); + } + + const resetForm = () => { + setUpdateBeneficiary(null); + } + + const handleCloseModal = () => { + setOpenModal(false); + setTimeout(() => { + resetForm(); + setIsVisualizing(false); + setSelectedBeneficiary(null); + }, 300); + } + + const handleUpdateBeneficiary = async (beneficiary: Beneficiary) => { + try { + setModalLoading(true); + + const { data } = await beneficiariesApi.getBeneficiary(beneficiary.beneficiaryId!); + + setUpdateBeneficiary(data); + setIsVisualizing(false); + setOpenModal(true); + } catch (error) { + console.error('Erro ao carregar dados do público:', error); + toast.error('Erro ao carregar dados do público.'); + } finally { + setModalLoading(false); + } + } + + const handleView = async (beneficiary: Beneficiary) => { + try { + const { data } = await beneficiariesApi.getBeneficiary(beneficiary.beneficiaryId!); + setSelectedBeneficiary(data); + setIsVisualizing(true); + setOpenModal(true); + } catch (error) { + console.error('Erro ao carregar dados do público:', error); + toast.error('Erro ao carregar dados do público.'); + } + } + + const handleDelete = async (beneficiary: Beneficiary) => { + setBeneficiaryToDelete(beneficiary); + setOpenDeleteModal(true); + } + + const confirmDelete = async () => { + if (!beneficiaryToDelete) + return; + + try { + await beneficiariesApi.deleteBeneficiary(beneficiaryToDelete.beneficiaryId!); + toast.success('Público deletado com sucesso.'); + fetchBeneficiaries(); + } catch (error) { + console.error('Erro ao deletar público:', error); + toast.error('Erro ao deletar público.'); + } finally { + setOpenDeleteModal(false); + setBeneficiaryToDelete(null); + } + } + + const handleSave = async () => { + const beneficiaryForm = updateBeneficiary || createBeneficiary; + + if (!validateBeneficiaryForm(beneficiaryForm)) + return; + + if (updateBeneficiary) { + try { + const updateBeneficiaryRequest: UpdateBeneficiaryRequest = { + name: updateBeneficiary.name!, + notes: updateBeneficiary.notes!, + }; + + await beneficiariesApi.updateBeneficiary(updateBeneficiary.beneficiaryId!, updateBeneficiaryRequest); + + toast.success('Público atualizado com sucesso.'); + handleCloseModal(); + fetchBeneficiaries(); + } catch (error) { + console.error('Erro ao atualizar público:', error); + toast.error('Erro ao atualizar público.'); + } finally { + setModalLoading(false); + } + } + else { + try { + const createBeneficiaryRequest: CreateBeneficiaryRequest = { + name: createBeneficiary!.name!, + notes: createBeneficiary!.notes!, + }; + + await beneficiariesApi.createBeneficiary(createBeneficiaryRequest); + + toast.success('Público criado com sucesso.'); + handleCloseModal(); + fetchBeneficiaries(); + } catch (error) { + console.error('Erro ao criar público:', error); + toast.error('Erro ao criar público.'); + } finally { + setModalLoading(false); + } + } + } + + const validateBeneficiaryForm = (beneficiary: any): boolean => { + const requiredFields = ['name', 'notes']; + + for (const field of requiredFields) { + if (!beneficiary[field] || beneficiary[field].toString().trim() === '') { + toast.error(`O campo "${formatFieldName(field)}" é obrigatório!`); + return false; + } + } + + return true; + } + + const formatFieldName = (field: string): string => { + const mapping: Record = { + name: 'Nome', + notes: 'Observações', + }; + return mapping[field] || field; + } + + const columns: Column[] = [ + { label: 'ID', field: 'beneficiaryId' }, + { label: 'Nome', field: 'name' }, + { label: 'Observações', field: 'notes' }, + ]; + + return ( + + + + + + + {/* Filtro por nome de Público */} + + + + + Busca de Público + + + {filterBeneficiaryName && ( + + )} + + + + + setFilterBeneficiaryName(e.target.value)} + placeholder="Digite o nome..." + fullWidth + size="small" + sx={{ + '& .MuiOutlinedInput-root': { + borderRadius: 1.5, + backgroundColor: 'white', + '&:hover fieldset': { + borderColor: '#1E4EC4', + }, + '&.Mui-focused fieldset': { + borderColor: '#1E4EC4', + borderWidth: 2, + }, + }, + '& .MuiInputLabel-root.Mui-focused': { + color: '#1E4EC4', + }, + }} + /> + + + + + + + + + + + {/* Tabela */} + + {loading ? ( + + + + ) : ( + + )} + + + {/* Delete Modal */} + setOpenDeleteModal(false)} + onConfirm={confirmDelete} + title='Confirmar exclusão' + message='Deseja realmente excluir este Público?' + highlightText={beneficiaryToDelete?.name} + confirmLabel='Excluir' + cancelLabel='Cancelar' + danger + /> + + {/* Modal */} + + + + {dialogTitle()} + + + + + {isVisualizing && selectedBeneficiary ? ( + + {/* Dados principais */} + + Detalhes da Público + + ID: {selectedBeneficiary.beneficiaryId} + Nome: {selectedBeneficiary.name} + Observações: {selectedBeneficiary.notes} + + + {/* OSC */} + + + OSC + + + {selectedBeneficiary.oscs && selectedBeneficiary.oscs.length > 0 ? ( + + {selectedBeneficiary.oscs.map((b) => ( + + ))} + + ) : ( + Nenhum OSC associado. + )} + + + ) : updateBeneficiary ? ( + + {/* Campos de texto editáveis */} + setUpdateBeneficiary({ ...updateBeneficiary, name: e.target.value })} + fullWidth + /> + setUpdateBeneficiary({ ...updateBeneficiary, notes: e.target.value })} + fullWidth + /> + + {/* Chips de OSC */} + + + OSC + + + + {updateBeneficiary.oscs && updateBeneficiary.oscs.length > 0 ? ( + + {updateBeneficiary.oscs.map((b) => ( + + ))} + + ) : ( + Nenhum OSC. + )} + + + ) : createBeneficiary ? ( + + {/* Campos de texto editáveis */} + setCreateBeneficiary({ ...createBeneficiary, name: e.target.value })} + fullWidth + /> + setCreateBeneficiary({ ...createBeneficiary, notes: e.target.value })} + fullWidth + /> + ) : + ( + Nenhum dado encontrado. + )} + + + + {isVisualizing ? ( + + ) : ( + <> + + + + )} + + + + + + + ); +}; + +export default Beneficiary; \ No newline at end of file diff --git a/codigo-fonte/frontend/src/pages/BusinessCase.tsx b/codigo-fonte/frontend/src/pages/BusinessCase.tsx new file mode 100644 index 00000000..ae163f2f --- /dev/null +++ b/codigo-fonte/frontend/src/pages/BusinessCase.tsx @@ -0,0 +1,699 @@ +import React, { useState, useEffect, use } from 'react'; +import { + Box, + Container, + Button, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + CircularProgress, + FormControl, + InputLabel, + Select, + MenuItem, + Grid, + SelectChangeEvent, + Typography, + Stack, + Divider, + TextField, + Autocomplete +} from '@mui/material'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import SearchIcon from '@mui/icons-material/Search'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import dayjs, { Dayjs } from 'dayjs'; +import 'dayjs/locale/pt-br'; +import Table, { Column } from '../components/Table'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import { toast } from 'react-toastify'; +import { + BusinessCasesApi, + OriginsBusinessCasesApi, + CreateBusinessCaseRequest, + UpdateBusinessCaseRequest, + ListBusinessCaseRequest, + Filter, + Op, +} from './../api'; +import { apiConfig } from '../services/auth'; +import { alpha } from '@mui/material/styles'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import ClearIcon from '@mui/icons-material/Clear'; +import { Chip, Paper } from '@mui/material'; +import { ConfirmDialog } from '@/components/ConfirmDelete'; +import { useNavigate } from 'react-router-dom'; + +dayjs.locale('pt-br'); + +interface BusinessCase { + businessCaseId?: number; + name?: string; + originsBusinessCases?: number; + origins?: OriginBusinessCase[]; +} + +interface OriginBusinessCase { + originBusinessCaseId?: number; + name?: string; +} + +const BusinessCase: React.FC = () => { + const [businessCase, setBusinessCase] = useState([]); + const [loading, setLoading] = useState(false); + const [modalLoading, setModalLoading] = useState(false); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [noDataMessage, setNoDataMessage] = useState(''); + const [openModal, setOpenModal] = useState(false); + const [isVisualizing, setIsVisualizing] = useState(false); + const [updateBusinessCase, setUpdateBusinessCase] = useState(null); + const [createBusinessCase, setCreateBusinessCase] = useState(null); + const [selectedBusinessCase, setSelectedBusinessCase] = useState(null); + + const [filterBusinessCaseName, setFilterBusinessCaseName] = useState(''); + + const [openDeleteModal, setOpenDeleteModal] = useState(false); + const [businessCaseToDelete, setBusinessCaseToDelete] = useState(null); + + const businessCaseApi = new BusinessCasesApi(apiConfig); + const navigate = useNavigate(); + + const handleDirect = (businessCase: BusinessCase) => { + if (!businessCase.businessCaseId) + return; + + navigate(`/business-case/${businessCase.businessCaseId}/origin-business-case`,{ + state: {name: businessCase.name} + }); + }; + + const dialogTitle = () => { + return isVisualizing ? 'Visualizar Grupo de Causas' : selectedBusinessCase ? 'Editar Grupo de Causas' : 'Adicionar Grupo de Causas'; + } + + useEffect(() => { + fetchBusinessCases(); + }, [page, rowsPerPage]); + + const fetchBusinessCases = async (customFilters?: Filter[]) => { + try { + setLoading(true); + setBusinessCase([]); + + const filters: Filter[] = customFilters ? customFilters : []; + + const listBusinessCaseRequest: ListBusinessCaseRequest = { + pageNumber: page + 1, + pageSize: rowsPerPage, + filters: filters.length > 0 ? filters : undefined, + }; + + const { data } = await businessCaseApi.listBusinessCase(listBusinessCaseRequest); + + if (!data.items || data.items.length === 0) { + setNoDataMessage('Nenhum Grupo de Causas encontrado.'); + setBusinessCase([]); + return; + } + + setBusinessCase( + (data.items ?? []).map((item) => ({ + ...item, + })) + ); + + setTotalCount(data.totalItems || 0); + setNoDataMessage(''); + } catch (error) { + console.error('Erro ao carregar Grupo de Causas:', error); + toast.error('Erro ao carregar Grupo de Causas.'); + } finally { + setLoading(false); + } + } + + const handleSearch = () => { + const filters: Filter[] = []; + + if (filterBusinessCaseName && filterBusinessCaseName.trim() !== '') { + filters.push({ + propertyName: 'name', + operation: 7, + value: filterBusinessCaseName.trim(), + }); + } + setPage(0); + fetchBusinessCases(filters); + } + + const handleClearFilters = () => { + setPage(0); + setFilterBusinessCaseName(''); + fetchBusinessCases([]); + } + + const handleAdd = () => { + setCreateBusinessCase({ + name: '', + }); + setIsVisualizing(false); + resetForm(); + setOpenModal(true); + } + + const resetForm = () => { + setUpdateBusinessCase(null); + } + + const handleCloseModal = () => { + setOpenModal(false); + setTimeout(() => { + resetForm(); + setIsVisualizing(false); + setSelectedBusinessCase(null); + }, 300); + } + + const handleUpdateBusinessCase = async (businessCase: BusinessCase) => { + try { + setModalLoading(true); + + const { data } = await businessCaseApi.getBusinessCase(businessCase.businessCaseId!); + + setUpdateBusinessCase(data); + setIsVisualizing(false); + setOpenModal(true); + } catch (error) { + console.error('Erro ao carregar Grupo de Causas:', error); + toast.error('Erro ao carregar Grupo de Causas.'); + } finally { + setModalLoading(false); + } + } + + const handleView = async (businessCase: BusinessCase) => { + try { + const { data } = await businessCaseApi.getBusinessCase(businessCase.businessCaseId!); + setSelectedBusinessCase(data); + setIsVisualizing(true); + setOpenModal(true); + } catch (error) { + console.error('Erro ao carregar Grupo de Causas:', error); + toast.error('Erro ao carregar Grupo de Causas.'); + } + } + + const handleDelete = async (businessCase: BusinessCase) => { + setBusinessCaseToDelete(businessCase); + setOpenDeleteModal(true); + } + + const confirmDelete = async () => { + if (!businessCaseToDelete) + return; + + try { + await businessCaseApi.deleteBusinessCase(businessCaseToDelete.businessCaseId!); + toast.success('Grupo de Causas deletado com sucesso.'); + fetchBusinessCases(); + } catch (error) { + console.error('Erro ao deletar Grupo de Causas:', error); + toast.error(error?.response?.data?.errors?.[0]); + } finally { + setOpenDeleteModal(false); + setBusinessCaseToDelete(null); + } + } + + const handleSave = async () => { + const businessCaseForm = updateBusinessCase || createBusinessCase; + + if (!validateBusinessCaseForm(businessCaseForm)) + return; + + if (updateBusinessCase) { + try { + const updateBusinessCaseRequest: UpdateBusinessCaseRequest = { + name: updateBusinessCase.name!, + }; + + await businessCaseApi.updateBusinessCase(updateBusinessCase.businessCaseId!, updateBusinessCaseRequest); + + toast.success('Grupo de Causas atualizado com sucesso.'); + handleCloseModal(); + fetchBusinessCases(); + } catch (error) { + console.error('Erro ao atualizar Grupo de Causas:', error); + toast.error('Erro ao atualizar Grupo de Causas.'); + } finally { + setModalLoading(false); + } + } + else { + try { + const createBusinessCaseRequest: CreateBusinessCaseRequest = { + name: createBusinessCase!.name!, + }; + + await businessCaseApi.createBusinessCase(createBusinessCaseRequest); + + toast.success('Grupo de Causas criado com sucesso.'); + handleCloseModal(); + fetchBusinessCases(); + } catch (error) { + console.error('Erro ao criar Grupo de Causas:', error); + toast.error('Erro ao criar Grupo de Causas.'); + } finally { + setModalLoading(false); + } + } + } + + const validateBusinessCaseForm = (businessCase: any): boolean => { + const requiredFields = ['name']; + + for (const field of requiredFields) { + if (!businessCase[field] || businessCase[field].toString().trim() === '') { + toast.error(`O campo "${formatFieldName(field)}" é obrigatório!`); + return false; + } + } + + return true; + } + + const formatFieldName = (field: string): string => { + const mapping: Record = { + name: 'Nome', + }; + return mapping[field] || field; + } + + const columns: Column[] = [ + { label: 'ID', field: 'businessCaseId' }, + { label: 'Nome', field: 'name' }, + { label: 'Causas', field: 'originsBusinessCases' }, + ]; + + return ( + + + + + + + {/* Filtro por nome de Grupo de Causas */} + + + + + Busca de Grupo de Causas + + + {filterBusinessCaseName && ( + + )} + + + + + setFilterBusinessCaseName(e.target.value)} + placeholder="Digite o nome..." + fullWidth + size="small" + sx={{ + '& .MuiOutlinedInput-root': { + borderRadius: 1.5, + backgroundColor: 'white', + '&:hover fieldset': { + borderColor: '#1E4EC4', + }, + '&.Mui-focused fieldset': { + borderColor: '#1E4EC4', + borderWidth: 2, + }, + }, + '& .MuiInputLabel-root.Mui-focused': { + color: '#1E4EC4', + }, + }} + /> + + + + + + + + + + + {/* Tabela */} + + {loading ? ( + + + + ) : ( +
+ )} + + + {/* Delete Modal */} + setOpenDeleteModal(false)} + onConfirm={confirmDelete} + title='Confirmar exclusão' + message='Deseja realmente excluir este Público?' + highlightText={businessCaseToDelete?.name} + confirmLabel='Excluir' + cancelLabel='Cancelar' + danger + /> + + {/* Modal */} + + + + {dialogTitle()} + + + + + {isVisualizing && selectedBusinessCase ? ( + + {/* Dados principais */} + + Detalhes de Grupo de Causas + + ID: {selectedBusinessCase.businessCaseId} + Nome: {selectedBusinessCase.name} + + + {/* OriginBusinessCase */} + + + Causas + + + {selectedBusinessCase.origins && selectedBusinessCase.origins.length > 0 ? ( + + {selectedBusinessCase.origins.map((b) => ( + + ))} + + ) : ( + Nenhuma causa associada. + )} + + + ) : updateBusinessCase ? ( + + {/* Campos de texto editáveis */} + setUpdateBusinessCase({ ...updateBusinessCase, name: e.target.value })} + fullWidth + /> + + {/* Chips de OriginBusinessCase */} + + + Causas + + + + {updateBusinessCase.origins && updateBusinessCase.origins.length > 0 ? ( + + {updateBusinessCase.origins.map((b) => ( + + ))} + + ) : ( + Nenhuma Causa. + )} + + + ) : createBusinessCase ? ( + + {/* Campos de texto editáveis */} + setCreateBusinessCase({ ...createBusinessCase, name: e.target.value })} + fullWidth + /> + ) : + ( + Nenhum dado encontrado. + )} + + + + {isVisualizing ? ( + + ) : ( + <> + + + + )} + + + + + + + ); +}; + +export default BusinessCase; \ No newline at end of file diff --git a/codigo-fonte/frontend/src/pages/Company.tsx b/codigo-fonte/frontend/src/pages/Company.tsx new file mode 100644 index 00000000..b7d3538d --- /dev/null +++ b/codigo-fonte/frontend/src/pages/Company.tsx @@ -0,0 +1,614 @@ +import React, { useState, useEffect, useMemo } from 'react'; +import { + Box, Container, Button, Dialog, DialogTitle, DialogContent, DialogActions, + CircularProgress, Grid, Typography, Divider, TextField, Chip, Paper, + alpha, FormControl, FormLabel, RadioGroup, FormControlLabel, Radio, +} from '@mui/material'; +import SearchIcon from '@mui/icons-material/Search'; +import ClearIcon from '@mui/icons-material/Clear'; +import Table, { Column } from '@/components/Table'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import { ConfirmDialog } from '@/components/ConfirmDelete'; +import { toast } from 'react-toastify'; +import { mask } from 'remask'; +import { + CreateCompanyEndpointApi, + ListCompaniesEndpointApi, + ListCompanyEndpointApi, + UpdateCompanyEndpointApi, + InactivateCompanyEndpointApi, + ReactivateCompanyEndpointApi, + type CreateCompanyCommand, + type UpdateCompanyCommand, + type Filter, + type CompanyViewModel, +} from '@/api'; +import { apiConfig } from '@/services/auth'; + +interface CompanyFullDetails { + id?: number; + cnpj?: string; + nome?: string; + razaoSocial?: string; + areaAtuacao?: string; + cep?: string; + endereco?: string; + bairro?: string; + cidade?: string; + uf?: string; + telefone?: string; + email?: string; + site?: string; + redesSociais?: string; + ativa?: boolean; +} + +interface CompanyFormData { + id?: number; + cnpj: string; + nome: string; + razaoSocial: string; + areaAtuacao: string; + cep: string; + endereco: string; + bairro: string; + cidade: string; + uf: string; + telefone: string; + email: string; + site: string; + redesSociais: string; + ativa: boolean; +} + +const formatCnpjMask = (cnpj: string) => mask(cnpj ?? '', ['99.999.999/9999-99']); +const formatCepMask = (cep: string) => mask(cep ?? '', ['99999-999']); +const formatPhoneMask = (phone: string) => mask(phone ?? '', ['(99) 9999-9999', '(99) 99999-9999']); + +const columns: Column[] = [ + { label: 'ID/CNPJ', field: 'cnpj', render: (row) => formatCnpjMask(row.cnpj!) }, + { label: 'Nome', field: 'nome' }, + { label: 'Razão Social', field: 'razaoSocial' }, + { label: 'Telefone', field: 'telefone', render: (row) => formatPhoneMask(row.telefone!) }, + { + label: 'Status', + field: 'ativa', + render: (row) => ( + + ), + }, +]; + +const CompanyPage: React.FC = () => { + const createApi = useMemo(() => new CreateCompanyEndpointApi(apiConfig), []); + const listApi = useMemo(() => new ListCompanyEndpointApi(apiConfig), []); + const listAllApi = useMemo(() => new ListCompaniesEndpointApi(apiConfig), []); + const updateApi = useMemo(() => new UpdateCompanyEndpointApi(apiConfig), []); + const inactivateApi = useMemo(() => new InactivateCompanyEndpointApi(apiConfig), []); + const reactivateApi = useMemo(() => new ReactivateCompanyEndpointApi(apiConfig), []); + + const [companies, setCompanies] = useState([]); + const [editingData, setEditingData] = useState | null>(null); + const [filterText, setFilterText] = useState(''); + const [statusFilter, setStatusFilter] = useState('ativas'); + const [loading, setLoading] = useState(false); + const [modalLoading, setModalLoading] = useState(false); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [openModal, setOpenModal] = useState(false); + const [isVisualizing, setIsVisualizing] = useState(false); + const [openDeleteModal, setOpenDeleteModal] = useState(false); + const [openReactivateModal, setOpenReactivateModal] = useState(false); + const [companyToAction, setCompanyToAction] = useState(null); + + const isCreating = editingData ? !('id' in editingData) : false; + const dialogTitle = isVisualizing ? 'Visualizar Empresa' : isCreating ? 'Nova Empresa' : 'Editar Empresa'; + const isReadOnlyMode = isVisualizing; + + const mapApiDataToFormData = (data: CompanyFullDetails): CompanyFormData => ({ + id: data.id, + cnpj: data.cnpj || '', + nome: data.nome || '', + razaoSocial: data.razaoSocial || '', + areaAtuacao: data.areaAtuacao || '', + cep: data.cep || '', + endereco: data.endereco || '', + bairro: data.bairro || '', + cidade: data.cidade || '', + uf: data.uf || '', + telefone: data.telefone || '', + email: data.email || '', + site: data.site || '', + redesSociais: data.redesSociais || '', + ativa: data.ativa ?? false, + }); + + const fetchCompanies = async () => { + try { + setLoading(true); + const localFilters: Filter[] = []; + if (filterText) { + localFilters.push({ propertyName: 'CompanyName', operation: 7, value: filterText }); + } + if (statusFilter === 'ativas') { + localFilters.push({ propertyName: 'IsActive', operation: 0, value: true }); + } else if (statusFilter === 'inativas') { + localFilters.push({ propertyName: 'IsActive', operation: 0, value: false }); + } + const response = await listAllApi.apiCompaniesSearchPost({ + pageNumber: page + 1, + pageSize: rowsPerPage, + filters: localFilters.length > 0 ? localFilters : null, + }); + setCompanies(response.data.items ?? []); + setTotalCount(response.data.totalItems ?? 0); + } catch (err: any) { + console.error("Erro detalhado da API:", err.response || err); + toast.error('Erro ao buscar empresas.'); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchCompanies(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [page, rowsPerPage, statusFilter]); + + const handleSearch = () => { + setPage(0); + fetchCompanies(); + }; + + const handleClearFilters = () => { + setFilterText(''); + setStatusFilter('ativas'); + if (page !== 0) { + setPage(0); + } else if (filterText || statusFilter !== 'ativas') { + fetchCompanies(); + } + }; + + const handleAdd = () => { + setEditingData({ + cnpj: '', nome: '', razaoSocial: '', areaAtuacao: '', cep: '', endereco: '', bairro: '', + cidade: '', uf: '', telefone: '', email: '', site: '', redesSociais: '', ativa: true, + }); + setIsVisualizing(false); + setOpenModal(true); + }; + + const handleEdit = async (company: CompanyViewModel) => { + if (!company.cnpj) return; + try { + setModalLoading(true); + const response = await listApi.getCompanyByCnpj(company.cnpj); + const companyData = response.data as CompanyFullDetails; + setEditingData(mapApiDataToFormData(companyData)); + setIsVisualizing(false); + setOpenModal(true); + } catch { + toast.error('Erro ao carregar dados para edição.'); + } finally { + setModalLoading(false); + } + }; + + const handleView = async (company: CompanyViewModel) => { + if (!company.cnpj) return; + try { + setModalLoading(true); + const response = await listApi.getCompanyByCnpj(company.cnpj); + const companyData = response.data as CompanyFullDetails; + setEditingData(mapApiDataToFormData(companyData)); + setIsVisualizing(true); + setOpenModal(true); + } catch { + toast.error('Erro ao carregar detalhes da empresa.'); + } finally { + setModalLoading(false); + } + }; + + const handleToggleActive = (company: CompanyViewModel) => { + setCompanyToAction(company); + if (company.ativa) { + setOpenDeleteModal(true); + } else { + setOpenReactivateModal(true); + } + }; + + const confirmInactivate = async () => { + if (!companyToAction?.cnpj) return; + try { + setModalLoading(true); + await inactivateApi.apiCompaniesCnpjDelete(companyToAction.cnpj); + toast.success(`Empresa ${companyToAction.nome} inativada com sucesso!`); + fetchCompanies(); + } catch (err: any) { + toast.error(err?.response?.data?.title || 'Erro ao inativar empresa.'); + } finally { + setModalLoading(false); + setOpenDeleteModal(false); + setCompanyToAction(null); + } + }; + + const confirmReactivate = async () => { + if (!companyToAction?.cnpj) return; + try { + setModalLoading(true); + await reactivateApi.apiCompaniesCnpjActivatePatch(companyToAction.cnpj); + toast.success(`Empresa ${companyToAction.nome} reativada com sucesso!`); + fetchCompanies(); + } catch (err: any) { + toast.error(err?.response?.data?.title || 'Erro ao reativar empresa.'); + } finally { + setModalLoading(false); + setOpenReactivateModal(false); + setCompanyToAction(null); + } + }; + + const handleSave = async () => { + const data = editingData; + if (!data?.cnpj || !data?.nome || !data?.razaoSocial) { + toast.error('CNPJ, Nome Fantasia e Razão Social são obrigatórios!'); + return; + } + + const cnpjDigits = data.cnpj.replace(/\D/g, ''); + const payload = { + cnpj: cnpjDigits, + companyName: data.nome, + corporateReason: data.razaoSocial, + fieldOfActivity: data.areaAtuacao, + zipCode: (data.cep || '').replace(/\D/g, ''), + address: data.endereco, + neighborhood: data.bairro, + city: data.cidade, + state: data.uf, + phoneNumber: (data.telefone || '').replace(/\D/g, ''), + website: data.site, + socialMedia: data.redesSociais, + isActive: data.ativa, + email: data.email, + }; + + try { + setModalLoading(true); + if (isCreating) { + await createApi.apiCompaniesPost(payload as CreateCompanyCommand); + toast.success('Empresa criada com sucesso!'); + } else { + await updateApi.apiCompaniesCnpjPut(cnpjDigits, payload as UpdateCompanyCommand); + toast.success('Empresa atualizada com sucesso!'); + } + handleCloseModal(); + fetchCompanies(); + } catch (err: any) { + toast.error(err?.response?.data?.title || 'Erro ao salvar empresa.'); + } finally { + setModalLoading(false); + } + }; + + const handleCloseModal = () => { + setOpenModal(false); + setEditingData(null); + setIsVisualizing(false); + }; + + const handleValueChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setEditingData((p) => (p ? { ...p, [name]: value } : null)); + }; + + const handleCnpjChange = (e: React.ChangeEvent) => { + if (isCreating) { + const masked = formatCnpjMask(e.target.value); + setEditingData((p) => (p ? { ...p, cnpj: masked } : null)); + } + }; + + const handleCepChange = (e: React.ChangeEvent) => { + const masked = formatCepMask(e.target.value); + setEditingData((p) => (p ? { ...p, cep: masked } : null)); + }; + + const handlePhoneChange = (e: React.ChangeEvent) => { + const masked = formatPhoneMask(e.target.value); + setEditingData((p) => (p ? { ...p, telefone: masked } : null)); + }; + + const handleUfChange = (e: React.ChangeEvent) => { + const value = e.target.value.toUpperCase().slice(0, 2); + setEditingData((p) => (p ? { ...p, uf: value } : null)); + }; + + return ( + + + + + + + + + Busca de Empresa + + + + + setFilterText(e.target.value)} + onKeyDown={(e) => e.key === 'Enter' && handleSearch()} + placeholder="Digite o nome para buscar..." + fullWidth + size="small" + sx={{ '& .MuiOutlinedInput-root': { borderRadius: 1.5, backgroundColor: 'white' } }} + /> + + + + { + setPage(0); + setStatusFilter(e.target.value); + }} + > + } label="Ativas" /> + } label="Inativas" /> + + + + + + + + + + + + {loading ? ( + + ) : ( +
0 ? '' : 'Nenhuma empresa encontrada.'} + /> + )} + + + setOpenDeleteModal(false)} + onConfirm={confirmInactivate} + title="Confirmar Inativação" + message="Deseja realmente INATIVAR esta Empresa?" + highlightText={companyToAction?.nome} + confirmLabel="Inativar" + cancelLabel="Cancelar" + danger + /> + + setOpenReactivateModal(false)} + onConfirm={confirmReactivate} + title="Confirmar Reativação" + message="Deseja realmente REATIVAR esta Empresa?" + highlightText={companyToAction?.nome} + confirmLabel="Reativar" + cancelLabel="Cancelar" + /> + + + + + {dialogTitle} + + + + {editingData && ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} + + + {isReadOnlyMode ? ( + + ) : ( + <> + + + + )} + + + + + + ); +}; + +export default CompanyPage; \ No newline at end of file diff --git a/codigo-fonte/frontend/src/pages/Course.tsx b/codigo-fonte/frontend/src/pages/Course.tsx new file mode 100644 index 00000000..e5c973cf --- /dev/null +++ b/codigo-fonte/frontend/src/pages/Course.tsx @@ -0,0 +1,560 @@ +import React, { useState, useEffect } from 'react'; +import { + Box, + Container, + TextField, + Button, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + CircularProgress, + Paper, + alpha, + Typography, + Chip, +} from '@mui/material'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import ClearIcon from '@mui/icons-material/Clear'; +import AddIcon from '@mui/icons-material/Add'; +import SearchIcon from '@mui/icons-material/Search'; +import EditIcon from '@mui/icons-material/Edit'; +import DeleteIcon from '@mui/icons-material/Delete'; +import Table, { Column } from '../components/Table'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import { ConfirmDialog } from '../components/ConfirmDelete'; +import { toast } from 'react-toastify'; + +import { + CoursesApi, + CreateCourseRequest, + EditCourseRequest, + ListCourseRequest, + Filter, + Op, +} from './../api'; +import { apiConfig } from '../services/auth'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; + +interface Course { + courseId?: number; + name?: string; + teamsCount?: number; + isDeleted?: boolean; +} + +const Course: React.FC = () => { + /* ------------------------------ Variáveis ------------------------------ */ + + const [search, setSearch] = useState(''); + const [courses, setCourses] = useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [openModal, setOpenModal] = useState(false); + const [editingCourse, setEditingCourse] = useState(null); + const [courseName, setCourseName] = useState(''); + const [isVisualizing, setIsVisualizing] = useState(false); + const [noDataMessage, setNoDataMessage] = useState(''); + const [loading, setLoading] = useState(false); + const [modalLoading, setModalLoading] = useState(false); + const [confirmDialog, setConfirmDialog] = useState({ + open: false, + course: null as Course | null, + loading: false, + }); + + const apiInstance = new CoursesApi(apiConfig); + + const dialogTitle = () => { + return isVisualizing + ? 'Visualizar Programa' + : editingCourse + ? 'Editar Programa' + : 'Adicionar Programa'; + }; + + const columns: Column[] = [ + { label: 'Id', field: 'courseId' }, + { label: 'Nome do Programa', field: 'name' }, + { label: 'Número de turmas', field: 'teamsCount', align: 'center' }, + ]; + + /* --------------------------------- Funções -------------------------------- */ + + const fetchCourses = async (noFilter?) => { + try { + setLoading(true); + + let filters: Filter[] = []; + + if (noFilter) filters = []; + else + filters = search.trim() + ? [ + { + propertyName: 'name', + operation: Op.NUMBER_7, + value: search, + }, + ] + : []; + + const listCourseRequest: ListCourseRequest = { + pageNumber: page + 1, + pageSize: rowsPerPage, + filters: filters, + }; + + const { data } = await apiInstance.listCourse(listCourseRequest); + + if (data.items?.length === 0) { + setNoDataMessage('Nenhum programa encontrado'); + setCourses([]); + return; + } + + setNoDataMessage(''); + setCourses((data.items as Course[]) || []); + setTotalCount(data.totalItems || 0); + } catch (error) { + console.error('Erro ao carregar programas:', error); + toast.error('Erro ao carregar programas'); + setCourses([]); + setTotalCount(0); + } finally { + setLoading(false); + } + }; + + const handleClearFilters = () => { + setPage(0); + setSearch(''); + fetchCourses([]); + }; + + const handleSearch = () => { + setPage(0); + fetchCourses(); + }; + + const handleAdd = () => { + setEditingCourse(null); + setCourseName(''); + setOpenModal(true); + }; + + const handleEdit = (course: Course) => { + setEditingCourse(course); + setCourseName(course.name ?? ''); + setOpenModal(true); + }; + + const handleView = async (course: Course) => { + try { + const id: number = course.courseId!; + const { data } = await apiInstance.getCourseById(id); + setIsVisualizing(true); + setCourseName(data.name || ''); + setOpenModal(true); + } catch (error) { + console.error('Erro ao visualizar programa:', error); + toast.error('Erro ao carregar detalhes do programa'); + } + }; + + const handleDelete = async (course: Course) => { + setConfirmDialog({ + open: true, + course: course, + loading: false, + }); + }; + + const handleCloseConfirmDialog = () => { + setConfirmDialog({ + open: false, + course: null, + loading: false, + }); + }; + + const handleConfirmDelete = async () => { + if (!confirmDialog.course) return; + + try { + setConfirmDialog((prev) => ({ ...prev, loading: true })); + const id: number = confirmDialog.course.courseId!; + await apiInstance.deleteCourse(id); + toast.success(`Programa "${confirmDialog.course.name}" excluído com sucesso!`); + handleCloseConfirmDialog(); + fetchCourses([]); + } catch (error: any) { + const message = + error?.response?.data?.message || + error?.response?.data?.errors?.join(', ') || + 'Erro ao excluir programa'; + + toast.error(message); + + console.error('Erro ao excluir programa:', error); + setConfirmDialog((prev) => ({ ...prev, loading: false })); + } + }; + + const handleSave = async () => { + if (!courseName.trim()) { + toast.error('O nome do programa é obrigatório!'); + return; + } + + try { + setModalLoading(true); + + if (editingCourse) { + const editCourseRequest: EditCourseRequest = { + name: courseName, + }; + + const id: number = editingCourse.courseId!; + + await apiInstance.editCourse(id, editCourseRequest); + toast.success('Programa atualizado com sucesso!'); + } else { + const createCourseRequest: CreateCourseRequest = { + name: courseName, + }; + + await apiInstance.createCourse(createCourseRequest); + toast.success('Programa criado com sucesso!'); + } + + handleCloseModal(); + fetchCourses([]); + } catch (error) { + console.error('Erro ao salvar programa:', error); + toast.error('Erro ao salvar programa'); + } finally { + setModalLoading(false); + } + }; + + const handleCloseModal = () => { + setOpenModal(false); + setTimeout(() => { + setEditingCourse(null); + setIsVisualizing(false); + setCourseName(''); + }, 300); + }; + + useEffect(() => { + fetchCourses(); + }, [page, rowsPerPage]); + + return ( + /* -------------------------------- Template -------------------------------- */ + + + + + + {/* Campo de pesquisa + botão */} + + + + + Filtro de Busca + + {search && ( + + )} + + + + setSearch(e.target.value)} + onKeyUp={(e) => { + if (e.key === 'Enter') { + handleSearch(); + } + }} + /> + + + + + + {/* Tabela */} + + {loading ? ( + + + + ) : ( + + columns={columns} + data={courses} + page={page} + rowsPerPage={rowsPerPage} + totalCount={totalCount} + onPageChange={setPage} + onRowsPerPageChange={setRowsPerPage} + onView={handleView} + onEdit={handleEdit} + onDelete={handleDelete} + noDataMessage={noDataMessage} + /> + )} + + + + + {/* --------------------------------- Modais --------------------------------- */} + + {/* ------------------------- Criação/Edição ------------------------ */} + + + + {dialogTitle()} + + + + setCourseName(e.target.value)} + onKeyUp={(e) => { + if (e.key === 'Enter') { + handleSave(); + } + }} + slotProps={{ + input: { + readOnly: isVisualizing, + }, + }} + sx={isVisualizing ? { pointerEvents: 'none' } : {}} + /> + + + {isVisualizing ? ( + + ) : ( + <> + + + + )} + + + + {/* -------------------- Confirmação de Exclusão -------------------- */} + + + ); +}; + +export default Course; diff --git a/codigo-fonte/frontend/src/pages/Donation.tsx b/codigo-fonte/frontend/src/pages/Donation.tsx new file mode 100644 index 00000000..3e6f41ca --- /dev/null +++ b/codigo-fonte/frontend/src/pages/Donation.tsx @@ -0,0 +1,329 @@ +import React, { useState, useEffect, useMemo } from 'react'; +import { + Box, Container, Button, Dialog, DialogTitle, DialogContent, DialogActions, + CircularProgress, Grid, Typography, Divider, TextField, Paper, + alpha, FormControl, InputLabel, Select, MenuItem, SelectChangeEvent +} from '@mui/material'; +import SearchIcon from '@mui/icons-material/Search'; +import ClearIcon from '@mui/icons-material/Clear'; +import Table, { Column } from '@/components/Table'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import { ConfirmDialog } from '@/components/ConfirmDelete'; +import { toast } from 'react-toastify'; +import dayjs from 'dayjs'; +import { apiConfig } from '@/services/auth'; +import { + CreateDonationEndpointApi, + ListDonationsEndpointApi, + ListDonationEndpointApi, + UpdateDonationEndpointApi, + DeleteDonationEndpointApi, + PersonsApi, + ListCompaniesEndpointApi, + OscsApi, + CoursesApi, + TeamsApi, + type CreateDonationCommand, + type UpdateDonationCommand, + type DonationViewModel, + type PersonViewModel, + type CompanyViewModel, + type OscViewModel, + type CourseViewModel, + type TeamViewModel, + type Filter, +} from '@/api'; + +interface DonationFullDetails { + id?: number; + value?: number; + donationDate?: string; + personId?: number | null; + companyId?: number | null; + oscId?: number | null; + courseId?: number | null; + teamId?: number | null; +} + +const columns: Column[] = [ + { label: 'ID', field: 'id' }, + { label: 'Valor', field: 'value', render: (data) => `R$ ${data.value?.toFixed(2).replace('.', ',')}` }, + { label: 'Data', field: 'donationDate' }, + { label: 'Doador', field: 'doadorNome' }, + { label: 'Destino', field: 'destinoNome' }, +]; + +type DoadorType = 'Pessoa' | 'Empresa'; +type DestinoType = 'OSC' | 'Team' | 'Nenhum'; + +const DonationPage: React.FC = () => { + const createApi = useMemo(() => new CreateDonationEndpointApi(apiConfig), []); + const listApi = useMemo(() => new ListDonationEndpointApi(apiConfig), []); + const listAllApi = useMemo(() => new ListDonationsEndpointApi(apiConfig), []); + const updateApi = useMemo(() => new UpdateDonationEndpointApi(apiConfig), []); + const deleteApi = useMemo(() => new DeleteDonationEndpointApi(apiConfig), []); + const peopleApi = useMemo(() => new PersonsApi(apiConfig), []); + const companiesApi = useMemo(() => new ListCompaniesEndpointApi(apiConfig), []); + const oscsApi = useMemo(() => new OscsApi(apiConfig), []); + const coursesApi = useMemo(() => new CoursesApi(apiConfig), []); + const teamsApi = useMemo(() => new TeamsApi(apiConfig), []); + + const [donations, setDonations] = useState([]); + const [editingData, setEditingData] = useState | null>(null); + const [filterId, setFilterId] = useState(''); + const [loading, setLoading] = useState(false); + const [modalLoading, setModalLoading] = useState(false); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [openModal, setOpenModal] = useState(false); + const [openDeleteModal, setOpenDeleteModal] = useState(false); + const [donationToDelete, setDonationToDelete] = useState(null); + const [uiDoadorTipo, setUiDoadorTipo] = useState('Pessoa'); + const [uiDestinoTipo, setUiDestinoTipo] = useState('Nenhum'); + + const [people, setPeople] = useState([]); + const [companies, setCompanies] = useState([]); + const [oscs, setOscs] = useState([]); + const [courses, setCourses] = useState([]); + const [teams, setTeams] = useState([]); + + const isCreating = editingData ? !('id' in editingData) : false; + const dialogTitle = isCreating ? 'Nova Doação' : 'Editar Doação'; + + const fetchDropdownData = async () => { + try { + const requestParams = { pageNumber: 1, pageSize: 1000 }; + const [peopleRes, companiesRes, oscsRes, coursesRes, teamsRes] = await Promise.all([ + peopleApi.listPerson(requestParams), + companiesApi.apiCompaniesSearchPost(requestParams), + oscsApi.listOsc(requestParams), + coursesApi.listCourse(requestParams), + teamsApi.listTeam(requestParams), + ]); + setPeople(peopleRes.data.items ?? []); + setCompanies(companiesRes.data.items ?? []); + setOscs(oscsRes.data.items ?? []); + setCourses(coursesRes.data.items ?? []); + setTeams(teamsRes.data.items ?? []); + } catch (error) { + toast.error("Erro ao carregar dados para os formulários."); + } + }; + + useEffect(() => { + fetchDropdownData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const fetchDonations = async (idFilter: string) => { + try { + setLoading(true); + const localFilters: Filter[] = []; + if (idFilter && !isNaN(parseInt(idFilter, 10))) { + localFilters.push({ propertyName: 'Id', operation: 0, value: parseInt(idFilter, 10) }); + } + const response = await listAllApi.apiDonationsSearchPost({ pageNumber: page + 1, pageSize: rowsPerPage, filters: localFilters }); + const items = response.data.items ?? []; + const formattedItems = items.map(d => ({ ...d, donationDate: d.donationDate ? dayjs(d.donationDate).format('DD/MM/YYYY') : '' })); + setDonations(formattedItems); + setTotalCount(response.data.totalItems ?? 0); + } catch (error) { + toast.error('Erro ao buscar doações.'); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchDonations(filterId); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [page, rowsPerPage]); + + const handleSearch = () => { + setPage(0); + if (page === 0) fetchDonations(filterId); + }; + + const handleClearFilters = () => { + if (filterId) setFilterId(''); + if (page !== 0) setPage(0); + else fetchDonations(''); + }; + + useEffect(() => { + if (filterId === '') fetchDonations(''); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [filterId]); + + const handleAdd = () => { + setEditingData({ value: 0, donationDate: dayjs().format('YYYY-MM-DD') }); + setUiDoadorTipo('Pessoa'); + setUiDestinoTipo('Nenhum'); + setOpenModal(true); + }; + + const handleEdit = async (donation: DonationViewModel) => { + if (!donation.id) return; + try { + setModalLoading(true); + const response = await listApi.getDonationById(donation.id); + const data = response.data as DonationFullDetails; + setEditingData({ ...data, donationDate: dayjs(data.donationDate).format('YYYY-MM-DD') }); + setUiDoadorTipo(data.personId ? 'Pessoa' : 'Empresa'); + setUiDestinoTipo(data.oscId ? 'OSC' : data.teamId ? 'Team' : 'Nenhum'); + setOpenModal(true); + } catch (error) { + toast.error('Erro ao carregar dados da doação.'); + } finally { + setModalLoading(false); + } + }; + + const handleDelete = (donation: DonationViewModel) => { + setDonationToDelete(donation); + setOpenDeleteModal(true); + }; + + const confirmDelete = async () => { + if (!donationToDelete?.id) return; + try { + setModalLoading(true); + await deleteApi.apiDonationsIdDelete(donationToDelete.id); + toast.success('Doação excluída com sucesso!'); + fetchDonations(filterId); + } catch (error) { + toast.error('Erro ao excluir doação.'); + } finally { + setModalLoading(false); + setOpenDeleteModal(false); + setDonationToDelete(null); + } + }; + + const handleFormChange = (event: SelectChangeEvent | React.ChangeEvent) => { + const { name, value } = event.target; + const numericFields = ['value', 'personId', 'companyId', 'oscId', 'courseId', 'teamId']; + + let finalValue: string | number | null = value; + + if (numericFields.includes(name)) { + finalValue = value === '' || value === null ? null : Number(value); + } + + setEditingData(prev => (prev ? { ...prev, [name]: finalValue } : null)); + }; + + const handleDoadorTipoChange = (event: SelectChangeEvent) => { + const newType = event.target.value as DoadorType; + setUiDoadorTipo(newType); + setEditingData(prev => (prev ? { ...prev, personId: null, companyId: null } : null)); + }; + + const handleDestinoTipoChange = (event: SelectChangeEvent) => { + const newType = event.target.value as DestinoType; + setUiDestinoTipo(newType); + setEditingData(prev => (prev ? { ...prev, oscId: null, courseId: null, teamId: null } : null)); + }; + + const handleSave = async () => { + const data = editingData; + if (!data) return; + if (!data.value || data.value <= 0) { + toast.error('O valor da doação deve ser positivo.'); + return; + } + + const payload = { + Value: Number(data.value), + DonationDate: data.donationDate, + PersonId: data.personId || undefined, + CompanyId: data.companyId || undefined, + OscId: data.oscId || undefined, + CourseId: data.courseId || undefined, + TeamId: data.teamId || undefined, + }; + + try { + setModalLoading(true); + if (isCreating) { + await createApi.apiDonationsPost(payload as CreateDonationCommand); + toast.success('Doação criada com sucesso!'); + } else { + await updateApi.apiDonationsIdPut(data.id!, payload as UpdateDonationCommand); + toast.success('Doação atualizada com sucesso!'); + } + handleCloseModal(); + fetchDonations(filterId); + } catch (error: any) { + toast.error(error?.response?.data?.title || 'Erro ao salvar doação.'); + } finally { + setModalLoading(false); + } + }; + + const handleCloseModal = () => { + setOpenModal(false); + setEditingData(null); + }; + + return ( + + + + + + Busca de Doação + + setFilterId(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSearch()} fullWidth size="small" type="number" /> + + + + + {loading ? :
0 ? '' : "Nenhuma doação encontrada."} />} + + setOpenDeleteModal(false)} onConfirm={confirmDelete} title='Confirmar Exclusão' message='Deseja realmente excluir esta Doação?' highlightText={`ID: ${donationToDelete?.id}`} confirmLabel='Excluir' cancelLabel='Cancelar' danger/> + + {dialogTitle} + + {editingData && ( + + + + + Doador + + Tipo de Doador + + + + {uiDoadorTipo === 'Pessoa' && Pessoa (Doador)} + {uiDoadorTipo === 'Empresa' && Empresa (Doador)} + + + Destino + + Tipo de Destino + + + + {uiDestinoTipo === 'OSC' && OSC} + {uiDestinoTipo === 'Team' && (<> + Programa + Turma + )} + + )} + + + + + + + + + + ); +}; + +export default DonationPage; \ No newline at end of file diff --git a/codigo-fonte/frontend/src/pages/ForgotPassword.tsx b/codigo-fonte/frontend/src/pages/ForgotPassword.tsx new file mode 100644 index 00000000..54f1a3de --- /dev/null +++ b/codigo-fonte/frontend/src/pages/ForgotPassword.tsx @@ -0,0 +1,153 @@ +import { useState } from 'react'; +import { Box, Button, TextField, Typography, Link } from '@mui/material'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import { toast } from 'react-toastify'; +import { AuthApi, Configuration, ForgotPasswordRequest } from './../api'; + +export default function ForgotPassword() { + const [email, setEmail] = useState(''); + const [buttonLoading, setButtonLoading] = useState(false); + const [errorMessage, setErrorMessage] = useState(''); + const [successMessage, setSuccessMessage] = useState(''); + + const configuration = new Configuration(); + const apiInstance = new AuthApi(configuration); + + // Função para validar formato do email + const validateEmail = (email: string): boolean => { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return emailRegex.test(email); + }; + + const handleSendEmail = async (e: React.FormEvent) => { + e.preventDefault(); + + // Validação básica + if (!email) { + setErrorMessage('Por favor, insira um endereço de e-mail.'); + setSuccessMessage(''); + setTimeout(() => setErrorMessage(''), 5000); + return; + } + + // Validação de formato + if (!validateEmail(email)) { + setErrorMessage('Por favor, insira um endereço de e-mail válido.'); + setSuccessMessage(''); + setTimeout(() => setErrorMessage(''), 5000); + return; + } + + console.log('Enviando e-mail para:', email); + + try { + setButtonLoading(true); + setErrorMessage(''); + setSuccessMessage(''); + + const emailRequest: ForgotPasswordRequest = { email: email }; + const { status, data } = await apiInstance.forgotPassword(emailRequest); + + if (status === 200) { + setSuccessMessage(data?.message || 'E-mail enviado com sucesso!'); + toast.success('Verifique sua caixa de entrada para mais instruções.'); + } + } catch (error) { + console.error('Erro ao enviar e-mail:', error); + setErrorMessage('Erro ao enviar o e-mail. Tente novamente mais tarde.'); + } finally { + setButtonLoading(false); + } + }; + + return ( + + + (window.location.href = '/login')} + sx={{ + display: 'flex', + alignItems: 'center', + mb: 3, + color: '#656D77', + fontWeight: 600, + textDecoration: 'none', + '&:hover': { textDecoration: 'underline' }, + }} + > + Voltar + + + + Esqueci minha senha + + + + Insira o seu endereço de e-mail associado à sua conta na plataforma. + + +
+ setEmail(e.target.value)} + error={!!errorMessage} + helperText={errorMessage} + margin="normal" + required + /> + + {successMessage && ( + + {successMessage} + + )} + + +
+
+ ); +} diff --git a/codigo-fonte/frontend/src/pages/Home.tsx b/codigo-fonte/frontend/src/pages/Home.tsx new file mode 100644 index 00000000..3423a100 --- /dev/null +++ b/codigo-fonte/frontend/src/pages/Home.tsx @@ -0,0 +1,138 @@ +import React from 'react'; +import { Button, Box } from '@mui/material'; +import logoGest from '../assets/logo-gesc.png'; +import { useNavigate } from 'react-router-dom'; +import { toast } from 'react-toastify'; + +const Home: React.FC = () => { + const exibirBotoes: boolean = false; // Alterar para true se quiser mostrar os botões + + const changeDisplay = exibirBotoes ? 'flex' : 'none'; + const navigate = useNavigate(); + + const deslogar = () => { + localStorage.removeItem('loginResponse'); + console.log('Usuário deslogado'); + toast.success('Usuário deslogado com sucesso!'); + navigate('/login'); + }; + + return ( + // Container que ocupa a altura total e centraliza o conteúdo na área disponível (ao lado do menu) + + + {/* Logo IGESC */} + + + + + +

Bem-vindo ao IGESC Conecta!

+

Esta é a página inicial do seu projeto.

+ + + + + + + + + + +
+
+ ); +}; + +export default Home; diff --git a/codigo-fonte/frontend/src/pages/Login.tsx b/codigo-fonte/frontend/src/pages/Login.tsx new file mode 100644 index 00000000..98ded290 --- /dev/null +++ b/codigo-fonte/frontend/src/pages/Login.tsx @@ -0,0 +1,169 @@ +// src/pages/Login.tsx +import { useMemo, useState } from 'react' +import { + Box, + Button, + Link as MUILink, + TextField, + Typography, + IconButton, + InputAdornment, +} from '@mui/material' +import Visibility from '@mui/icons-material/Visibility' +import VisibilityOff from '@mui/icons-material/VisibilityOff' +import { toast } from 'react-toastify' +import 'react-toastify/dist/ReactToastify.css' +import { Link as RouterLink, useNavigate } from 'react-router-dom' + +import { AuthApi, Configuration, LoginResponse, UserLogin, UsersApi } from './../api' +import logoGest from '../assets/logo-gesc.png' +import { apiConfig, persistLoginResponse, scheduleTokenRefresh } from '@/services/auth' +import { jwtDecode } from 'jwt-decode' + +export default function Login() { + const [email, setEmail] = useState('') + const [password, setPassword] = useState('') + const [touchedPassword, setTouchedPassword] = useState(false) + const [showPassword, setShowPassword] = useState(false) + + const isValidEmail = (rawEmail: string) => /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(rawEmail.trim()) + const isValidPassword = (pwd: string) => + pwd.length >= 6 && /[0-9]/.test(pwd) && /[a-z]/.test(pwd) && /[A-Z]/.test(pwd) + + const emailValid = useMemo(() => isValidEmail(email), [email]) + const passwordValid = useMemo(() => isValidPassword(password), [password]) + const formValid = emailValid && passwordValid + + const apiInstance = new AuthApi(new Configuration()) + const navigate = useNavigate() + + const handleSubmit: React.FormEventHandler = async (e) => { + e.preventDefault() + + if (!formValid) { + if (!emailValid && !passwordValid) toast.info('Preencha os campos obrigatórios.') + else if (!emailValid) toast.warning('E-mail inválido ou ausente.') + else toast.warning('Senha inválida. Verifique os requisitos.') + return + } + + const userLogin: UserLogin = { email, password } + + try { + const { status, data } = await apiInstance.login(userLogin) + if (status === 200) { + toast.success('Login realizado com sucesso!') + + const loginResponse: LoginResponse = { + accessToken: data.accessToken, + refreshToken: data.refresfToken, + expiresIn: data.expiresIn, + } + + persistLoginResponse(loginResponse) + + const expires = Number(loginResponse.expiresIn || 0) + if (expires > 0) scheduleTokenRefresh(expires) + + try { + const decoded: any = jwtDecode(loginResponse.accessToken || '') + const userId = Number( + decoded['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier'] + ) + if (userId) { + const usersApi = new UsersApi(apiConfig) + const { data: user } = await usersApi.getUserById(userId) + if (user?.name) { + persistLoginResponse(loginResponse, user.name) + } + } + } catch {} + + navigate('/home') + } + } catch { + toast.error('Erro ao realizar login. Verifique suas credenciais.') + } + } + + return ( + + + + + + + + + Login + + + + setEmail(e.target.value)} + margin="normal" + required + /> + + setPassword(e.target.value)} + onBlur={() => setTouchedPassword(true)} + margin="normal" + required + autoComplete="current-password" + slotProps={{ + input: { + endAdornment: ( + + setShowPassword((s) => !s)} + onMouseDown={(e) => e.preventDefault()} + edge="end" + aria-label={showPassword ? 'Ocultar senha' : 'Mostrar senha'} + > + {showPassword ? : } + + + ), + }, + }} + /> + + + + + + + + Esqueceu a Senha? + + + + + + ) +} diff --git a/codigo-fonte/frontend/src/pages/OriginBusinessCase.tsx b/codigo-fonte/frontend/src/pages/OriginBusinessCase.tsx new file mode 100644 index 00000000..46285fa8 --- /dev/null +++ b/codigo-fonte/frontend/src/pages/OriginBusinessCase.tsx @@ -0,0 +1,689 @@ +import React, { useState, useEffect, use } from 'react'; +import { + Box, + Container, + Button, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + CircularProgress, + FormControl, + InputLabel, + Select, + MenuItem, + Grid, + SelectChangeEvent, + Typography, + Stack, + Divider, + TextField, + Autocomplete +} from '@mui/material'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import SearchIcon from '@mui/icons-material/Search'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import dayjs, { Dayjs } from 'dayjs'; +import 'dayjs/locale/pt-br'; +import Table, { Column } from '../components/Table'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import { toast } from 'react-toastify'; +import { + OriginsBusinessCasesApi, + CreateOriginBusinessCaseRequest, + UpdateOriginBusinessCaseRequest, + ListOriginBusinessCaseRequest, + Filter, + Op, + ListOriginsBusinessCaseByBusinessCaseIdRequest +} from '../api'; +import { apiConfig } from '../services/auth'; +import { alpha } from '@mui/material/styles'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import ClearIcon from '@mui/icons-material/Clear'; +import { Chip, Paper } from '@mui/material'; +import { ConfirmDialog } from '@/components/ConfirmDelete'; +import { useNavigate, useLocation, useParams } from 'react-router-dom'; + +dayjs.locale('pt-br'); + +interface OriginBusinessCase { + originBusinessCaseId?: number; + name?: string; + notes?: string; + businessCaseId?: number; +} + +const OriginBusinessCase: React.FC = () => { + const { businessCaseId } = useParams<{ businessCaseId: string }>(); + + const [originBusinessCase, setOriginBusinessCase] = useState([]); + const [loading, setLoading] = useState(false); + const [modalLoading, setModalLoading] = useState(false); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [noDataMessage, setNoDataMessage] = useState(''); + const [openModal, setOpenModal] = useState(false); + const [isVisualizing, setIsVisualizing] = useState(false); + const [updateOriginBusinessCase, setUpdateOriginBusinessCase] = useState(null); + const [createOriginBusinessCase, setCreateOriginBusinessCase] = useState(null); + const [selectedOriginBusinessCase, setSelectedOriginBusinessCase] = useState(null); + + const [filterOriginBusinessCaseName, setFilterOriginBusinessCaseName] = useState(''); + + const [openDeleteModal, setOpenDeleteModal] = useState(false); + const [originBusinessCaseToDelete, setOriginBusinessCaseToDelete] = useState(null); + + const originBusinessCasesApi = new OriginsBusinessCasesApi(apiConfig); + const navigate = useNavigate(); + const locationName = useLocation(); + + const { name } = locationName.state || {}; + + const dialogTitle = () => { + return isVisualizing ? 'Visualizar Causa' : updateOriginBusinessCase ? 'Editar Causa' : 'Adicionar Causa'; + } + + useEffect(() => { + fetchOriginBusinessCases(); + }, [page, rowsPerPage]); + + const fetchOriginBusinessCases = async (customFilters?: Filter[]) => { + try { + setLoading(true); + setOriginBusinessCase([]); + + const filters: Filter[] = customFilters ? customFilters : []; + + const listOriginBusinessCaseRequest: ListOriginsBusinessCaseByBusinessCaseIdRequest = { + pageNumber: page + 1, + pageSize: rowsPerPage, + filters: filters.length > 0 ? filters : undefined, + businessCaseId: Number(businessCaseId!) + }; + + const { data } = await originBusinessCasesApi.listOriginsBusinessCaseByBusinessCaseId(listOriginBusinessCaseRequest); + + if (!data.items || data.items.length === 0) { + setNoDataMessage('Nenhuma causa encontrada'); + setOriginBusinessCase([]); + return; + } + + setOriginBusinessCase( + (data.items ?? []).map((item) => ({ + ...item + })) + ); + + setTotalCount(data.totalItems || 0); + setNoDataMessage(''); + } catch (error) { + console.error('Erro ao carregar causas:', error); + toast.error('Erro ao carregar causas'); + setOriginBusinessCase([]); + setTotalCount(0); + } finally { + setLoading(false); + } + } + + const handleSearch = () => { + const filters: Filter[] = []; + + if (filterOriginBusinessCaseName && filterOriginBusinessCaseName.trim() !== '') { + filters.push({ + propertyName: 'name', + operation: 7, + value: filterOriginBusinessCaseName.trim() + }); + } + setPage(0); + fetchOriginBusinessCases(filters); + } + + const handleClearFilters = () => { + setPage(0); + setFilterOriginBusinessCaseName(''); + fetchOriginBusinessCases([]); + } + + const handleAdd = () => { + setCreateOriginBusinessCase({ + name: '', + }); + setIsVisualizing(false); + resetForm(); + setOpenModal(true); + } + + const resetForm = () => { + setUpdateOriginBusinessCase(null); + } + + const handleCloseModal = () => { + setOpenModal(false); + setTimeout(() => { + resetForm(); + setIsVisualizing(false); + setSelectedOriginBusinessCase(null); + }, 300); + } + + const handleUpdateOriginBusinessCase = async (originBusinessCase: OriginBusinessCase) => { + try { + setModalLoading(true); + + const { data } = await originBusinessCasesApi.getOriginBusinessCase(originBusinessCase.originBusinessCaseId!); + + setUpdateOriginBusinessCase(data); + setIsVisualizing(false); + setOpenModal(true); + } catch (error) { + console.error('Erro ao carregar causa:', error); + toast.error('Erro ao carregar causa'); + } finally { + setModalLoading(false); + } + } + + const handleViewOriginBusinessCase = async (originBusinessCase: OriginBusinessCase) => { + try { + const { data } = await originBusinessCasesApi.getOriginBusinessCase(originBusinessCase.originBusinessCaseId!); + setSelectedOriginBusinessCase(data); + setIsVisualizing(true); + setOpenModal(true); + } catch (error) { + console.error('Erro ao carregar causa:', error); + toast.error('Erro ao carregar causa'); + } finally { + setModalLoading(false); + } + } + + const handleDelete = async (originBusinessCase: OriginBusinessCase) => { + setOriginBusinessCaseToDelete(originBusinessCase); + setOpenDeleteModal(true); + } + + const confirmDelete = async () => { + if (!originBusinessCaseToDelete) + return; + + try { + await originBusinessCasesApi.deleteOriginBusinessCase(originBusinessCaseToDelete.originBusinessCaseId!); + toast.success('Causa deletada com sucesso'); + fetchOriginBusinessCases(); + } catch (error) { + console.error('Erro ao deletar causa:', error); + toast.error('Erro ao deletar causa'); + } finally { + setOpenDeleteModal(false); + setOriginBusinessCaseToDelete(null); + } + } + + const handleSave = async () => { + const originBusinessCaseForm = updateOriginBusinessCase || createOriginBusinessCase; + + if (!validateBeneficiaryForm(originBusinessCaseForm)) + return; + + if (updateOriginBusinessCase) { + try { + const updateOriginBusinessCaseRequest: UpdateOriginBusinessCaseRequest = { + name: originBusinessCaseForm?.name!, + notes: originBusinessCaseForm?.notes!, + }; + + await originBusinessCasesApi.updateOriginBusinessCase(updateOriginBusinessCase!.originBusinessCaseId!, updateOriginBusinessCaseRequest); + toast.success('Causa atualizada com sucesso'); + handleCloseModal(); + fetchOriginBusinessCases(); + } catch (error) { + console.error('Erro ao atualizar causa:', error); + toast.error('Erro ao atualizar causa'); + } finally { + setModalLoading(false); + } + } + else { + try { + const createOriginBusinessCaseRequest: CreateOriginBusinessCaseRequest = { + name: originBusinessCaseForm?.name!, + notes: originBusinessCaseForm?.notes!, + businessCaseId: Number(businessCaseId), + }; + + await originBusinessCasesApi.createOriginBusinessCase(createOriginBusinessCaseRequest); + + toast.success('Causa criada com sucesso'); + handleCloseModal(); + fetchOriginBusinessCases(); + } catch (error) { + console.error('Erro ao criar causa:', error); + toast.error('Erro ao criar causa'); + } finally { + setModalLoading(false); + } + } + } + + const validateBeneficiaryForm = (originBusinessCase: any): boolean => { + const requiredFields = ['name', 'notes']; + + for (const field of requiredFields) { + if (!originBusinessCase[field] || originBusinessCase[field].toString().trim() === '') { + toast.error(`O campo "${formatFieldName(field)}" é obrigatório!`); + return false; + } + } + + return true; + } + + const formatFieldName = (field: string): string => { + const mapping: Record = { + name: 'Nome', + notes: 'Observações', + }; + return mapping[field] || field; + } + + const columns: Column[] = [ + { label: 'ID', field: 'originBusinessCaseId' }, + { label: 'Nome', field: 'name' }, + { label: 'Observações', field: 'notes' }, + ]; + + return ( + + + + + + + +
+ Grupo de Causas › + Grupo: {name} +
+ + + + {/* Filtro por nome de Causa */} + + + + + Busca de Causa + + + {filterOriginBusinessCaseName && ( + + )} + + + + + setFilterOriginBusinessCaseName(e.target.value)} + placeholder="Digite o nome..." + fullWidth + size="small" + sx={{ + '& .MuiOutlinedInput-root': { + borderRadius: 1.5, + backgroundColor: 'white', + '&:hover fieldset': { + borderColor: '#1E4EC4', + }, + '&.Mui-focused fieldset': { + borderColor: '#1E4EC4', + borderWidth: 2, + }, + }, + '& .MuiInputLabel-root.Mui-focused': { + color: '#1E4EC4', + }, + }} + /> + + + + + + + + + + + {/* Tabela */} + + {loading ? ( + + + + ) : ( +
+ )} + + + {/* Delete Modal */} + setOpenDeleteModal(false)} + onConfirm={confirmDelete} + title='Confirmar exclusão' + message='Deseja realmente excluir este Causa?' + highlightText={originBusinessCaseToDelete?.name} + confirmLabel='Excluir' + cancelLabel='Cancelar' + danger + /> + + {/* Modal */} + + + + {dialogTitle()} + + + + + {isVisualizing && selectedOriginBusinessCase ? ( + + {/* Dados principais */} + + Detalhes da Causa + + ID: {selectedOriginBusinessCase.originBusinessCaseId} + Nome: {selectedOriginBusinessCase.name} + Observações: {selectedOriginBusinessCase.notes} + + + ) : updateOriginBusinessCase ? ( + + {/* Campos de texto editáveis */} + setUpdateOriginBusinessCase({ ...updateOriginBusinessCase, name: e.target.value })} + fullWidth + /> + setUpdateOriginBusinessCase({ ...updateOriginBusinessCase, notes: e.target.value })} + fullWidth + /> + + ) : createOriginBusinessCase ? ( + + {/* Campos de texto editáveis */} + setCreateOriginBusinessCase({ ...createOriginBusinessCase, name: e.target.value })} + fullWidth + /> + setCreateOriginBusinessCase({ ...createOriginBusinessCase, notes: e.target.value })} + fullWidth + /> + ) : + ( + Nenhum dado encontrado. + )} + + + + {isVisualizing ? ( + + ) : ( + <> + + + + )} + + + + + + + ) +} + +export default OriginBusinessCase; \ No newline at end of file diff --git a/codigo-fonte/frontend/src/pages/Osc.tsx b/codigo-fonte/frontend/src/pages/Osc.tsx new file mode 100644 index 00000000..9e08b820 --- /dev/null +++ b/codigo-fonte/frontend/src/pages/Osc.tsx @@ -0,0 +1,1355 @@ +import React, { useState, useEffect, use } from 'react'; +import { + Box, + Container, + Button, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + CircularProgress, + FormControl, + InputLabel, + Select, + MenuItem, + Grid, + SelectChangeEvent, + Typography, + Stack, + Divider, + TextField, + Autocomplete +} from '@mui/material'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import SearchIcon from '@mui/icons-material/Search'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import dayjs, { Dayjs } from 'dayjs'; +import 'dayjs/locale/pt-br'; +import Table, { Column } from '../components/Table'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import { toast } from 'react-toastify'; +import { + OscsApi, + BeneficiariesApi, + OriginsBusinessCasesApi, + CreateOscRequest, + UpdateOscRequest, + ListOscRequest, + Filter, + Op, +} from './../api'; +import { apiConfig } from '../services/auth'; +import { alpha } from '@mui/material/styles'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import ClearIcon from '@mui/icons-material/Clear'; +import { Chip, Paper } from '@mui/material'; +import { ConfirmDialog } from '@/components/ConfirmDelete'; +import { PatternFormat } from 'react-number-format'; + +dayjs.locale('pt-br'); + +interface Osc { + oscId?: number; + name?: string; + objective?: string; + corporateName?: string; + address?: string; + neighborhood?: string; + city?: string; + state?: string; + phoneNumber?: string; + email?: string; + webUrl?: string; + socialMedia?: string; + zipCode?: string; + oscPrimaryDocumment?: string | null; + beneficiariesCount?: number; + beneficiaries?: Beneficiary[]; + originsBusinessCases?: OriginBusinessCase[]; +} + +interface Beneficiary { + beneficiaryId?: number; + name?: string; +} + +interface OriginBusinessCase { + originBusinessCaseId?: number; + name?: string; +} + +const Osc: React.FC = () => { + const [osc, setOscs] = useState([]); + const [loading, setLoading] = useState(false); + const [modalLoading, setModalLoading] = useState(false); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [noDataMessage, setNoDataMessage] = useState(''); + const [openModal, setOpenModal] = useState(false); + const [isVisualizing, setIsVisualizing] = useState(false); + const [updateOsc, setUpdateOsc] = useState(null); + const [createOsc, setCreateOsc] = useState(null); + const [selectedOsc, setSelectedOsc] = useState(null); + + const [selectedBeneficiary, setSelectedBeneficiary] = useState(null); + const [beneficiaryResults, setBeneficiaryResults] = useState([]); + const [beneficiaryLoading, setBeneficiaryLoading] = useState(false); + const [inputBeneficiaryValue, setInputBeneficiaryValue] = useState(''); + + const [selectedOriginBusinessCase, setSelectedOriginBusinessCase] = useState(null); + const [originBusinessCaseResults, setOriginBusinessCaseResults] = useState([]); + const [originBusinessCaseLoading, setOriginBusinessCaseLoading] = useState(false); + const [inputOriginBusinessCaseValue, setInputOriginBusinessCaseValue] = useState(''); + + const [filterOscName, setFilterOscName] = useState(''); + + const [openDeleteModal, setOpenDeleteModal] = useState(false); + const [oscToDelete, setOscToDelete] = useState(null); + + const oscApi = new OscsApi(apiConfig); + const beneficiariesApi = new BeneficiariesApi(apiConfig); + const originBusinessCaseApi = new OriginsBusinessCasesApi(apiConfig) + + const dialogTitle = () => { + return isVisualizing ? 'Visualizar OSC' : updateOsc ? 'Editar OSC' : 'Nova OSC'; + }; + + useEffect(() => { + fetchOscs(); + }, [page, rowsPerPage]); + + const fetchBeneficiaries = async (searchValue: string) => { + try { + setBeneficiaryLoading(true); + + const request: any = { + pageNumber: 1, + pageSize: 10, + }; + + if (searchValue && searchValue.trim() !== '') { + request.filters = [ + { + propertyName: 'name', + operation: 7, + value: searchValue + } + ]; + } + + const { data } = await beneficiariesApi.listBeneficiary(request); + + setBeneficiaryResults(data.items || []); + } catch (error) { + console.error('Erro ao buscar Público', error); + toast.error('Erro ao buscar Público'); + } finally { + setBeneficiaryLoading(false); + } + }; + + const fetchOriginBusinessCase = async (searchValue: string) => { + try { + setOriginBusinessCaseLoading(true); + + const request: any = { + pageNumber: 1, + pageSize: 10, + }; + + if (searchValue && searchValue.trim() !== '') { + request.filters = [ + { + propertyName: 'name', + operation: 7, + value: searchValue + } + ]; + } + + const { data } = await originBusinessCaseApi.listOriginBusinessCase(request); + + setOriginBusinessCaseResults(data.items || []); + } catch (error) { + console.error('Erro ao buscar Causa', error); + toast.error('Erro ao buscar Causa'); + } finally { + setOriginBusinessCaseLoading(false); + } + }; + + const fetchOscs = async (customFilters?: Filter[]) => { + try { + setLoading(true); + setOscs([]); + + const filters: Filter[] = customFilters ? customFilters : []; + + const listOscRequest: ListOscRequest = { + pageNumber: page + 1, + pageSize: rowsPerPage, + filters: filters.length > 0 ? filters : undefined, + }; + + const { data } = await oscApi.listOsc(listOscRequest); + + if (!data.items || data.items.length === 0) { + setNoDataMessage('Nenhuma OSC encontrada'); + setOscs([]); + return; + } + setOscs( + (data.items ?? []).map((item) => ({ + ...item, + })) + ); + + setTotalCount(data.totalItems || 0); + setNoDataMessage(''); + } catch (error) { + console.error('Erro ao carregar OSC:', error); + toast.error('Erro ao carregar OSC'); + setOscs([]); + setTotalCount(0); + } finally { + setLoading(false); + } + }; + + const handleSearch = () => { + + const filters: Filter[] = []; + + if (filterOscName && filterOscName.trim() !== '') { + filters.push({ + propertyName: 'name', + operation: 7, + value: filterOscName.trim(), + }); + } + setPage(0); + fetchOscs(filters); + }; + + const handleClearFilters = () => { + setPage(0); + setFilterOscName(''); + fetchOscs([]); + }; + + const handleAdd = () => { + setCreateOsc({ + name: '', + corporateName: '', + oscPrimaryDocumment: '', + objective: '', + address: '', + neighborhood: '', + city: '', + state: '', + phoneNumber: '', + email: '', + webUrl: '', + socialMedia: '', + zipCode: '', + beneficiaries: [], + originsBusinessCases: [] + }); + setUpdateOsc(null); + setIsVisualizing(false); + resetForm(); + setOpenModal(true); + }; + + const resetForm = () => { + setUpdateOsc(null); + }; + + const handleCloseModal = () => { + setOpenModal(false); + setTimeout(() => { + resetForm(); + setIsVisualizing(false); + setSelectedOsc(null); + }, 300); + }; + + const handleUpdateOsc = async (osc: Osc) => { + try { + setModalLoading(true); + + const { data } = await oscApi.getOsc(osc.oscId!); + + setUpdateOsc(data); + setIsVisualizing(false); + setOpenModal(true); + } catch (error) { + console.error('Erro ao carregar edição de OSC', error) + toast.error('Erro ao carregar edição de OSC') + } finally { + setModalLoading(false); + } + } + + const handleView = async (osc: Osc) => { + try { + const oscId: number = osc.oscId!; + const { data } = await oscApi.getOsc(oscId); + setSelectedOsc(data); + setIsVisualizing(true); + setOpenModal(true) + } + catch (error) { + console.error('Erro ao vizualizar OSC', error) + toast.error('Erro ao carregar detalhes da OSC') + } + } + + const handleDelete = async (osc: Osc) => { + setOscToDelete(osc); + setOpenDeleteModal(true); + } + + const confirmDelete = async () => { + if (!oscToDelete) + return; + + try { + await oscApi.deleteOsc(oscToDelete.oscId!); + toast.success('OSC excluida com sucesso!') + fetchOscs(); + } + catch (error) { + console.error('Erro ao excluir OSC', error) + toast.error('Erro ao excluir OSC') + } + finally { + setOpenDeleteModal(false); + setOscToDelete(null); + } + } + + const handleSave = async () => { + const ocsForm = updateOsc || createOsc; + + if (!validateOscForm(ocsForm)) + return + + if (updateOsc) { + try { + const updateOscRequest: UpdateOscRequest = { + name: updateOsc.name, + objective: updateOsc.objective, + corporateName: updateOsc.corporateName, + address: updateOsc.address, + neighborhood: updateOsc.neighborhood, + city: updateOsc.city, + state: updateOsc.state, + phoneNumber: updateOsc.phoneNumber, + email: updateOsc.email, + webUrl: updateOsc.webUrl, + socialMedia: updateOsc.socialMedia, + zipCode: updateOsc.zipCode, + oscPrimaryDocumment: updateOsc.oscPrimaryDocumment, + beneficiaryIds: updateOsc.beneficiaries?.map(b => b.beneficiaryId!) || [], + originBusinessCaseIds: updateOsc.originsBusinessCases?.map(obc => obc.originBusinessCaseId!) || [] + }; + + await oscApi.updateOsc(updateOsc.oscId!, updateOscRequest); + + toast.success('OSC atualizado com sucesso!'); + handleCloseModal(); + fetchOscs(); + } catch (error) { + console.error('Erro ao atualizar OSC', error) + toast.error('Erro ao atualizar OSC'); + } finally { + setModalLoading(false); + } + } + else { + try { + const createOscRequest: CreateOscRequest = { + name: createOsc?.name, + objective: createOsc?.objective, + corporateName: createOsc?.corporateName, + address: createOsc?.address, + neighborhood: createOsc?.neighborhood, + city: createOsc?.city, + state: createOsc?.state, + phoneNumber: createOsc?.phoneNumber, + email: createOsc?.email, + webUrl: createOsc?.webUrl, + socialMedia: createOsc?.socialMedia, + zipCode: createOsc?.zipCode, + oscPrimaryDocumment: createOsc?.oscPrimaryDocumment, + beneficiariesIds: createOsc?.beneficiaries?.map(b => b.beneficiaryId!) || [], + originsBusinessCasesIds: createOsc?.originsBusinessCases?.map(obc => obc.originBusinessCaseId!) || [] + }; + + await oscApi.createOsc(createOscRequest); + + toast.success('OSC criada com sucesso!'); + handleCloseModal(); + fetchOscs(); + } catch (error) { + console.error('Erro ao criar OSC', error) + toast.error('Erro ao criar OSC'); + } finally { + setModalLoading(false); + } + + } + } + + const validateOscForm = (osc: any): boolean => { + const requiredFields = [ + 'name', + 'corporateName', + 'objective', + 'address', + 'neighborhood', + 'city', + 'state', + 'phoneNumber', + 'zipCode' + ]; + + for (const field of requiredFields) { + if (!osc[field] || osc[field].toString().trim() === '') { + toast.error(`O campo "${formatFieldName(field)}" é obrigatório!`); + return false; + } + } + + return true; + }; + + const formatFieldName = (field: string): string => { + const mapping: Record = { + name: 'Nome', + corporateName: 'Nome Corporativo', + oscPrimaryDocumment: 'Razão Social', + objective: 'Objetivo', + address: 'Endereço', + neighborhood: 'Bairro', + city: 'Cidade', + state: 'Estado', + phoneNumber: 'Telefone', + email: 'Email', + webUrl: 'Website', + socialMedia: 'Mídia Social', + zipCode: 'CEP' + }; + return mapping[field] || field; + }; + + const columns: Column[] = [ + { label: 'ID', field: 'oscId' }, + { label: 'Nome', field: 'name' }, + { label: 'Razão Social', field: 'corporateName' }, + { + label: 'CNPJ', + field: 'oscPrimaryDocumment', + render: (value) => + typeof value === 'string' + ? value.replace(/^(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})$/, '$1.$2.$3/$4-$5') + : '', + }, + { label: 'Endereço', field: 'address' }, + { + label: 'CEP', + field: 'zipCode', + render: (value) => + typeof value === 'string' + ? value.replace(/^(\d{5})(\d{3})$/, '$1-$2') + : '', + }, + { label: 'Objetivo', field: 'objective' }, + { label: 'Público Atendido', field: 'beneficiariesCount' }, + ]; + + return ( + + + + + + + {/* Filtro por nome de OSC */} + + + + + Busca de OSC + + + {filterOscName && ( + + )} + + + + + setFilterOscName(e.target.value)} + placeholder="Digite o nome..." + fullWidth + size="small" + sx={{ + '& .MuiOutlinedInput-root': { + borderRadius: 1.5, + backgroundColor: 'white', + '&:hover fieldset': { + borderColor: '#1E4EC4', + }, + '&.Mui-focused fieldset': { + borderColor: '#1E4EC4', + borderWidth: 2, + }, + }, + '& .MuiInputLabel-root.Mui-focused': { + color: '#1E4EC4', + }, + }} + /> + + + + + + + + + + + {/* Tabela */} + + {loading ? ( + + + + ) : ( +
+ )} + + + {/* Delete Modal */} + setOpenDeleteModal(false)} + onConfirm={confirmDelete} + title='Confirmar exclusão' + message='Deseja realmente excluir esta OSC?' + highlightText={oscToDelete?.name} + confirmLabel='Excluir' + cancelLabel='Cancelar' + danger + /> + + {/* Modal */} + + + + {dialogTitle()} + + + + + {isVisualizing && selectedOsc ? ( + + {/* Dados principais */} + + Detalhes da OSC + + ID: {selectedOsc.oscId} + Nome: + Razão Social: {selectedOsc.corporateName} + CNPJ: + Telefone: {selectedOsc.phoneNumber} + Email: {selectedOsc.email} + Website: {selectedOsc.webUrl} + Mídia Social: {selectedOsc.socialMedia} + Objetivo: {selectedOsc.objective} + CEP: + Estado: {selectedOsc.state} + Cidade: {selectedOsc.city} + Bairro: {selectedOsc.neighborhood} + Endereço: {selectedOsc.address} + + + {/* Público */} + + + Público + + + {selectedOsc.beneficiaries && selectedOsc.beneficiaries.length > 0 ? ( + + {selectedOsc.beneficiaries.map((b) => ( + + ))} + + ) : ( + Nenhum beneficiário associado. + )} + + + + Causas + + + {selectedOsc.originsBusinessCases && selectedOsc.originsBusinessCases.length > 0 ? ( + + {selectedOsc.originsBusinessCases.map((c) => ( + + ))} + + ) : ( + + Nenhuma causa associada. + + )} + + + ) : updateOsc ? ( + + + {/* Campos de texto editáveis */} + setUpdateOsc({ ...updateOsc, name: e.target.value })} + fullWidth + /> + + setUpdateOsc({ ...updateOsc, phoneNumber: values.value }) + } + format="(##) #####-####" + mask="_" + /> + + + setUpdateOsc({ ...updateOsc, corporateName: e.target.value })} + fullWidth + /> + + setUpdateOsc({ ...updateOsc, email: e.target.value })} + fullWidth + /> + + + setUpdateOsc({ ...updateOsc, webUrl: e.target.value })} + fullWidth + /> + setUpdateOsc({ ...updateOsc, socialMedia: e.target.value })} + fullWidth + /> + + + + setUpdateOsc({ ...updateOsc, oscPrimaryDocumment: values.value }) + } + format="##.###.###/####-##" + mask="_" + /> + + setUpdateOsc({ ...updateOsc, objective: e.target.value })} + fullWidth + /> + + + + setUpdateOsc({ ...updateOsc, zipCode: values.value }) + } + format="#####-###" + mask="_" + /> + setUpdateOsc({ ...updateOsc, state: e.target.value })} + fullWidth + /> + + + + setUpdateOsc({ ...updateOsc, city: e.target.value })} + fullWidth + /> + setUpdateOsc({ ...updateOsc, neighborhood: e.target.value })} + fullWidth + /> + + + setUpdateOsc({ ...updateOsc, address: e.target.value })} + fullWidth + /> + + {/* Público editáveis */} + + Público + + + option.name || ''} + value={selectedBeneficiary} + onChange={(_, value) => { + if (value && !updateOsc.beneficiaries?.some(b => b.beneficiaryId === value.beneficiaryId)) { + setUpdateOsc({ + ...updateOsc, + beneficiaries: [...(updateOsc.beneficiaries || []), value] + }); + } + setSelectedBeneficiary(null); + setInputBeneficiaryValue(''); + }} + inputValue={inputBeneficiaryValue} + onInputChange={(_, value) => { + setInputBeneficiaryValue(value); + fetchBeneficiaries(value); + }} + onOpen={() => { + if (!inputBeneficiaryValue) { + fetchBeneficiaries(''); + } + }} + renderInput={(params) => ( + + )} + isOptionEqualToValue={(option, value) => option.beneficiaryId === value?.beneficiaryId} + fullWidth + /> + + {/* Chips de Público */} + {updateOsc.beneficiaries && updateOsc.beneficiaries.length > 0 ? ( + + {updateOsc.beneficiaries.map((b) => ( + { + setUpdateOsc({ + ...updateOsc, + beneficiaries: updateOsc.beneficiaries!.filter( + x => x.beneficiaryId !== b.beneficiaryId + ) + }); + }} + /> + ))} + + ) : ( + Nenhum beneficiário. + )} + + + {/* Causa editáveis */} + + Causa + + + option.name || ''} + value={selectedOriginBusinessCase} + onChange={(_, value) => { + if (value && !updateOsc.originsBusinessCases?.some(obc => obc.originBusinessCaseId === value.originBusinessCaseId)) { + setUpdateOsc({ + ...updateOsc, + originsBusinessCases: [...(updateOsc.originsBusinessCases || []), value] + }); + } + setSelectedOriginBusinessCase(null); + setInputOriginBusinessCaseValue(''); + }} + inputValue={inputOriginBusinessCaseValue} + onInputChange={(_, value) => { + setInputOriginBusinessCaseValue(value); + fetchOriginBusinessCase(value); + }} + onOpen={() => { + if (!inputOriginBusinessCaseValue) { + fetchOriginBusinessCase(''); + } + }} + renderInput={(params) => ( + + )} + isOptionEqualToValue={(option, value) => option.originBusinessCaseId === value?.originBusinessCaseId} + fullWidth + /> + + {/* Chips de Causa */} + {updateOsc.originsBusinessCases && updateOsc.originsBusinessCases.length > 0 ? ( + + {updateOsc.originsBusinessCases.map((obc) => ( + { + setUpdateOsc({ + ...updateOsc, + originsBusinessCases: updateOsc.originsBusinessCases!.filter( + x => x.originBusinessCaseId !== obc.originBusinessCaseId + ) + }); + }} + /> + ))} + + ) : ( + Nenhuma causa. + )} + + + ) : createOsc ? ( + + + {/* Campos de texto editáveis */} + setCreateOsc({ ...createOsc, name: e.target.value })} + fullWidth + /> + + setCreateOsc({ ...createOsc, phoneNumber: values.value }) + } + format="(##) #####-####" + mask="_" + /> + + setCreateOsc({ ...createOsc, corporateName: e.target.value })} + fullWidth + /> + setCreateOsc({ ...createOsc, email: e.target.value })} + fullWidth + /> + + setCreateOsc({ ...createOsc, webUrl: e.target.value })} + fullWidth + /> + setCreateOsc({ ...createOsc, socialMedia: e.target.value })} + fullWidth + /> + + + setCreateOsc({ ...createOsc, oscPrimaryDocumment: values.value }) + } + format="##.###.###/####-##" + mask="_" + /> + setCreateOsc({ ...createOsc, objective: e.target.value })} + fullWidth + /> + + + setCreateOsc({ ...createOsc, zipCode: values.value }) + } + format="#####-###" + mask="_" + /> + setCreateOsc({ ...createOsc, state: e.target.value })} + fullWidth + /> + + + setCreateOsc({ ...createOsc, city: e.target.value })} + fullWidth + /> + setCreateOsc({ ...createOsc, neighborhood: e.target.value })} + fullWidth + /> + + setCreateOsc({ ...createOsc, address: e.target.value })} + fullWidth + /> + + {/* Público editáveis */} + + Público + + + option.name || ''} + value={selectedBeneficiary} + onChange={(_, value) => { + if (value && !createOsc.beneficiaries?.some(b => b.beneficiaryId === value.beneficiaryId)) { + setCreateOsc({ + ...createOsc, + beneficiaries: [...(createOsc.beneficiaries || []), value] + }); + } + setSelectedBeneficiary(null); + setInputBeneficiaryValue(''); + }} + inputValue={inputBeneficiaryValue} + onInputChange={(_, value) => { + setInputBeneficiaryValue(value); + fetchBeneficiaries(value); + }} + onOpen={() => { + if (!inputBeneficiaryValue) { + fetchBeneficiaries(''); + } + }} + renderInput={(params) => ( + + )} + isOptionEqualToValue={(option, value) => option.beneficiaryId === value?.beneficiaryId} + fullWidth + /> + + {/* Chips de Público */} + {createOsc.beneficiaries && createOsc.beneficiaries.length > 0 ? ( + + {createOsc.beneficiaries.map((b) => ( + { + setCreateOsc({ + ...createOsc, + beneficiaries: createOsc.beneficiaries!.filter( + x => x.beneficiaryId !== b.beneficiaryId + ) + }); + }} + /> + ))} + + ) : ( + Nenhum beneficiário. + )} + + + {/* Causa editáveis */} + + Causa + + + option.name || ''} + value={selectedOriginBusinessCase} + onChange={(_, value) => { + if (value && !createOsc.originsBusinessCases?.some(obc => obc.originBusinessCaseId === value.originBusinessCaseId)) { + setCreateOsc({ + ...createOsc, + originsBusinessCases: [...(createOsc.originsBusinessCases || []), value] + }); + } + setSelectedOriginBusinessCase(null); + setInputOriginBusinessCaseValue(''); + }} + inputValue={inputOriginBusinessCaseValue} + onInputChange={(_, value) => { + setInputOriginBusinessCaseValue(value); + fetchOriginBusinessCase(value); + }} + onOpen={() => { + if (!inputOriginBusinessCaseValue) { + fetchOriginBusinessCase(''); + } + }} + renderInput={(params) => ( + + )} + isOptionEqualToValue={(option, value) => option.originBusinessCaseId === value?.originBusinessCaseId} + fullWidth + /> + + {/* Chips de Causa */} + {createOsc.originsBusinessCases && createOsc.originsBusinessCases.length > 0 ? ( + + {createOsc.originsBusinessCases.map((obc) => ( + { + setCreateOsc({ + ...createOsc, + originsBusinessCases: createOsc.originsBusinessCases!.filter( + x => x.originBusinessCaseId !== obc.originBusinessCaseId + ) + }); + }} + /> + ))} + + ) : ( + Nenhum causa. + )} + + ) : + ( + Nenhum dado encontrado. + )} + + + + {isVisualizing ? ( + + ) : ( + <> + + + + )} + + + + + + + ); +}; + +export default Osc; \ No newline at end of file diff --git a/codigo-fonte/frontend/src/pages/Person.tsx b/codigo-fonte/frontend/src/pages/Person.tsx new file mode 100644 index 00000000..a26ecfe0 --- /dev/null +++ b/codigo-fonte/frontend/src/pages/Person.tsx @@ -0,0 +1,611 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { + Box, + Container, + TextField, + Button, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + CircularProgress, + Paper, + alpha, + Typography, + Chip, +} from '@mui/material'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import ClearIcon from '@mui/icons-material/Clear'; +import SearchIcon from '@mui/icons-material/Search'; +import Table, { Column } from '@/components/Table'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import { ConfirmDialog } from '@/components/ConfirmDelete'; +import { toast } from 'react-toastify'; +import axios from 'axios'; + +import { + PersonsApi, + IgescConectaAPIFeaturesPersonsListPersonListPersonRequest as ListPersonRequest, + IgescConectaAPIFeaturesPersonsCreatePersonCreatePersonRequest as CreatePersonRequest, + IgescConectaAPIFeaturesPersonsUpdatePersonUpdatePersonRequest as UpdatePersonRequest, +} from '@/api'; +import { apiConfig } from '@/services/auth'; + +const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/; +const digits = (s: string) => (s || '').replace(/\D/g, ''); + +function isValidCPF(cpfRaw: string) { + const cpf = digits(cpfRaw); + if (!cpf || cpf.length !== 11 || /^(\d)\1+$/.test(cpf)) return false; + + const calc = (base: string, factor: number) => { + let total = 0; + for (let i = 0; i < base.length; i++) total += parseInt(base[i], 10) * (factor - i); + const rest = (total * 10) % 11; + return rest === 10 ? 0 : rest; + }; + + const d1 = calc(cpf.substring(0, 9), 10); + const d2 = calc(cpf.substring(0, 10), 11); + return d1 === parseInt(cpf[9], 10) && d2 === parseInt(cpf[10], 10); +} + +function extractApiErrors(err: any): string[] { + const messages: string[] = []; + const data = err?.response?.data; + + if (!data) return ['Erro ao comunicar com o servidor.']; + + if (Array.isArray(data.errors)) { + data.errors.forEach((m: any) => messages.push(String(m))); + } + + if (!messages.length && data.errors && typeof data.errors === 'object' && !Array.isArray(data.errors)) { + Object.values(data.errors).forEach((arr) => { + if (Array.isArray(arr)) arr.forEach((m) => messages.push(String(m))); + else messages.push(String(arr)); + }); + } + + if (!messages.length && typeof data.error === 'string') messages.push(data.error); + if (!messages.length && typeof data.message === 'string') messages.push(data.message); + if (!messages.length && typeof data.detail === 'string') messages.push(data.detail); + + if (!messages.length && typeof data.title === 'string') messages.push(data.title); + + if (!messages.length && typeof data === 'string') messages.push(data); + + return messages.length ? messages : ['Ocorreu um erro.']; +} + +interface PersonRow { + personId?: number; + name?: string; + email?: string; + personalDocumment?: string; + primaryPhone?: string | null; + isActive?: boolean; +} + +const PersonPage: React.FC = () => { + const api = useMemo(() => new PersonsApi(apiConfig), []); + + const [search, setSearch] = useState(''); + const [rows, setRows] = useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [loading, setLoading] = useState(false); + const [noDataMessage, setNoDataMessage] = useState(''); + + const [openModal, setOpenModal] = useState(false); + const [editingId, setEditingId] = useState(null); + const [isVisualizing, setIsVisualizing] = useState(false); + const [modalLoading, setModalLoading] = useState(false); + + const [name, setName] = useState(''); + const [cpf, setCpf] = useState(''); + const [email, setEmail] = useState(''); + const [secondaryEmail, setSecondaryEmail] = useState(''); + const [primaryPhone, setPrimaryPhone] = useState(''); + const [secondaryPhone, setSecondaryPhone] = useState(''); + const [education1, setEducation1] = useState(''); + const [education2, setEducation2] = useState(''); + const [professionalActivity, setProfessionalActivity] = useState(''); + + const nameError = !!name && !(name.trim().split(/\s+/).length >= 2); + const cpfError = !!cpf && !isValidCPF(cpf); + const emailError = !!email && !emailRegex.test(email.trim()); + const secEmailError = !!secondaryEmail && !emailRegex.test(secondaryEmail.trim()); + const phoneError = !!primaryPhone && digits(primaryPhone).length < 10; // aceita 10/11 + const secPhoneError = !!secondaryPhone && digits(secondaryPhone).length > 0 && digits(secondaryPhone).length < 10; + + const formValid = + name.trim().length > 0 && + !nameError && + cpf.trim().length > 0 && + !cpfError && + email.trim().length > 0 && + !emailError && + primaryPhone.trim().length > 0 && + !phoneError && + !secEmailError && + !secPhoneError; + + const columns: Column[] = [ + { label: 'Id', field: 'personId', width: 80 }, + { label: 'Nome', field: 'name' }, + { label: 'CPF', field: 'personalDocumment', width: 140 }, + { label: 'E-mail', field: 'email' }, + { label: 'Telefone', field: 'primaryPhone', width: 140 }, + { + label: 'Status', + field: 'isActive', + align: 'center', + render: (p) => ( + + ), + width: 120, + }, + ]; + + const fetchPeople = async () => { + try { + setLoading(true); + const req: ListPersonRequest = { + pageNumber: page + 1, + pageSize: rowsPerPage, + filters: search.trim() + ? [ + { + propertyName: 'name', + operation: 7, + value: search.trim(), + } as any, + ] + : [], + }; + const { data } = await api.listPerson({ igescConectaAPIFeaturesPersonsListPersonListPersonRequest: req }); + const items = (data as any)?.items || []; + setRows( + items.map((it: any) => ({ + personId: it.personId, + name: it.name, + email: it.email, + personalDocumment: it.personalDocumment, + primaryPhone: it.primaryPhone, + isActive: it.isActive, + })), + ); + setTotalCount((data as any)?.totalItems ?? items.length); + setNoDataMessage(items.length ? '' : 'Nenhuma pessoa encontrada'); + } catch (e) { + toast.error('Erro ao carregar pessoas.'); + setRows([]); + setTotalCount(0); + } finally { + setLoading(false); + } + }; + + const openCreate = () => { + setEditingId(null); + setIsVisualizing(false); + setName(''); + setCpf(''); + setEmail(''); + setSecondaryEmail(''); + setPrimaryPhone(''); + setSecondaryPhone(''); + setEducation1(''); + setEducation2(''); + setProfessionalActivity(''); + setOpenModal(true); + }; + + const handleView = async (p: PersonRow) => { + try { + const id = p.personId!; + const { data } = await api.getPerson(id); + const d: any = data; + setEditingId(id); + setIsVisualizing(true); + setName(d.name ?? ''); + setCpf(d.personalDocumment ?? ''); + setEmail(d.email ?? ''); + setSecondaryEmail(d.secondaryEmail ?? ''); + setPrimaryPhone(d.primaryPhone ?? ''); + setSecondaryPhone(d.secondaryPhone ?? ''); + setEducation1(d.education1 ?? ''); + setEducation2(d.education2 ?? ''); + setProfessionalActivity(d.professionalActivity ?? ''); + setOpenModal(true); + } catch { + toast.error('Erro ao carregar detalhes.'); + } + }; + + const handleEdit = async (p: PersonRow) => { + try { + const id = p.personId!; + const { data } = await api.getPerson(id); + const d: any = data; + setEditingId(id); + setIsVisualizing(false); + setName(d.name ?? ''); + setCpf(d.personalDocumment ?? ''); + setEmail(d.email ?? ''); + setSecondaryEmail(d.secondaryEmail ?? ''); + setPrimaryPhone(d.primaryPhone ?? ''); + setSecondaryPhone(d.secondaryPhone ?? ''); + setEducation1(d.education1 ?? ''); + setEducation2(d.education2 ?? ''); + setProfessionalActivity(d.professionalActivity ?? ''); + setOpenModal(true); + } catch { + toast.error('Erro ao carregar detalhes para edição.'); + } + }; + + const [confirmDialog, setConfirmDialog] = useState({ + open: false, + person: null as PersonRow | null, + loading: false, + }); + + const handleDelete = (p: PersonRow) => setConfirmDialog({ open: true, person: p, loading: false }); + + const handleConfirmDelete = async () => { + if (!confirmDialog.person?.personId) return; + try { + setConfirmDialog((s) => ({ ...s, loading: true })); + await api.deletePerson(confirmDialog.person.personId); + toast.success('Pessoa excluída com sucesso!'); + setConfirmDialog({ open: false, person: null, loading: false }); + fetchPeople(); + } catch (err) { + extractApiErrors(err).forEach((m) => toast.error(m)); + setConfirmDialog((s) => ({ ...s, loading: false })); + } + }; + + const handleCloseConfirmDialog = () => setConfirmDialog({ open: false, person: null, loading: false }); + + const handleSave = async () => { + if (!formValid) { + toast.error('Dados inválidos. Verifique os campos.'); + return; + } + + const payloadBase = { + name: name.trim(), + email: email.trim(), + personalDocumment: digits(cpf), + secondaryEmail: secondaryEmail.trim() || null, + primaryPhone: digits(primaryPhone) || null, + secondaryPhone: digits(secondaryPhone) || null, + education1: education1.trim() || null, + education2: education2.trim() || null, + professionalActivity: professionalActivity.trim() || null, + isActive: true, + }; + + try { + setModalLoading(true); + + if (editingId) { + const body: UpdatePersonRequest = payloadBase as UpdatePersonRequest; + await api.updatePerson(editingId, body); + toast.success('Pessoa atualizada com sucesso!'); + } else { + const body: CreatePersonRequest = payloadBase as CreatePersonRequest; + await api.createPerson(body); + toast.success('Pessoa criada com sucesso!'); + } + + handleCloseModal(); + fetchPeople(); + } catch (err) { + extractApiErrors(err).forEach((m) => toast.error(m)); + } finally { + setModalLoading(false); + } + }; + + const handleCloseModal = () => { + setOpenModal(false); + setTimeout(() => { + setEditingId(null); + setIsVisualizing(false); + }, 150); + }; + + const handleSearch = () => { + setPage(0); + fetchPeople(); + }; + const handleClearFilters = () => { + setSearch(''); + setPage(0); + fetchPeople(); + }; + + useEffect(() => { + fetchPeople(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [page, rowsPerPage]); + + return ( + + + + + + + + + + Filtro de Busca + + {search && ( + + )} + + + + setSearch(e.target.value)} + onKeyUp={(e) => e.key === 'Enter' && handleSearch()} + /> + + + + + + + {loading ? ( + + + + ) : ( + + columns={columns} + data={rows} + page={page} + rowsPerPage={rowsPerPage} + totalCount={totalCount} + onPageChange={setPage} + onRowsPerPageChange={setRowsPerPage} + onView={handleView} + onEdit={handleEdit} + onDelete={handleDelete} + noDataMessage={noDataMessage} + /> + )} + + + {/* Modal */} + + + + {isVisualizing ? 'Visualizar Pessoa' : editingId ? 'Editar Pessoa' : 'Adicionar Pessoa'} + + + + + + setName(e.target.value)} + error={nameError} + helperText={nameError ? 'Informe nome e sobrenome.' : ' '} + slotProps={{ input: { readOnly: isVisualizing } }} + /> + setCpf(digits(e.target.value))} + error={cpfError} + helperText={cpfError ? 'CPF inválido.' : ' '} + inputProps={{ inputMode: 'numeric' }} + slotProps={{ input: { readOnly: isVisualizing } }} + /> + setEmail(e.target.value)} + error={emailError} + helperText={emailError ? 'E-mail inválido.' : ' '} + slotProps={{ input: { readOnly: isVisualizing } }} + /> + + setSecondaryEmail(e.target.value)} + error={secEmailError} + helperText={secEmailError ? 'E-mail inválido.' : ' '} + slotProps={{ input: { readOnly: isVisualizing } }} + /> + setPrimaryPhone(digits(e.target.value))} + error={phoneError} + helperText={phoneError ? 'Informe DDD + número (10 ou 11 dígitos).' : ' '} + inputProps={{ inputMode: 'numeric' }} + slotProps={{ input: { readOnly: isVisualizing } }} + /> + setSecondaryPhone(digits(e.target.value))} + error={secPhoneError} + helperText={secPhoneError ? 'Informe DDD + número (10 ou 11 dígitos) ou deixe vazio.' : ' '} + inputProps={{ inputMode: 'numeric' }} + slotProps={{ input: { readOnly: isVisualizing } }} + /> + + setEducation1(e.target.value)} + slotProps={{ input: { readOnly: isVisualizing } }} + /> + setEducation2(e.target.value)} + slotProps={{ input: { readOnly: isVisualizing } }} + /> + setProfessionalActivity(e.target.value)} + slotProps={{ input: { readOnly: isVisualizing } }} + /> + + + + + {isVisualizing ? ( + + ) : ( + <> + + + + )} + + + + + + + + ); +}; + +export default PersonPage; diff --git a/codigo-fonte/frontend/src/pages/ResetPassword.tsx b/codigo-fonte/frontend/src/pages/ResetPassword.tsx new file mode 100644 index 00000000..c89a90ee --- /dev/null +++ b/codigo-fonte/frontend/src/pages/ResetPassword.tsx @@ -0,0 +1,270 @@ +import { useState, useMemo } from 'react'; +import { + Box, + Button, + TextField, + Typography, + Link, + IconButton, + InputAdornment, + Alert, + List, + ListItem, + ListItemIcon, + ListItemText, +} from '@mui/material'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import Visibility from '@mui/icons-material/Visibility'; +import VisibilityOff from '@mui/icons-material/VisibilityOff'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; +import CancelIcon from '@mui/icons-material/Cancel'; +import { useSearchParams, useNavigate } from 'react-router-dom'; +import { AuthApi, Configuration } from './../api'; +import { toast } from 'react-toastify'; + +// Validação de senha detalhada +const getPasswordValidation = (password) => { + return { + length: password.length >= 6, + hasNumber: /[0-9]/.test(password), + hasLowercase: /[a-z]/.test(password), + hasUppercase: /[A-Z]/.test(password), + isValid: + password.length >= 6 && + /[0-9]/.test(password) && + /[a-z]/.test(password) && + /[A-Z]/.test(password), + }; +}; + +export default function ResetPassword() { + const [novaSenha, setNovaSenha] = useState(''); + const [confirmacao, setConfirmacao] = useState(''); + const [loading, setLoading] = useState(false); + const [showPassword, setShowPassword] = useState(false); + const [showConfirm, setShowConfirm] = useState(false); + + const [searchParams] = useSearchParams(); + const navigate = useNavigate(); + + const uid = searchParams.get('uid'); + const token = searchParams.get('token'); + + const passwordValidation = useMemo(() => getPasswordValidation(novaSenha), [novaSenha]); + const passwordsMatch = novaSenha && confirmacao && novaSenha === confirmacao; + const showPasswordError = confirmacao.length > 0 && !passwordsMatch; + + const handleSubmit = async (e) => { + e.preventDefault(); + + if (!novaSenha || !confirmacao) { + toast.error('Preencha todos os campos.'); + return; + } + + if (!passwordValidation.isValid) { + toast.warning('Senha não atende aos critérios de segurança.'); + return; + } + + if (!passwordsMatch) { + toast.error('As senhas não coincidem.'); + return; + } + + if (!uid || !token) { + toast.error('Parâmetros inválidos. Tente acessar pelo link correto.'); + return; + } + + setLoading(true); + + try { + const configuration = new Configuration(); + const api = new AuthApi(configuration); + + const request = { + userId: Number(uid), + token, + newPassword: novaSenha, + }; + + await api.resetPassword(request); + + toast.success('Senha alterada com sucesso! Redirecionando para login...'); + setTimeout(() => { + navigate('/login'); + }, 2000); + } catch (err: any) { + console.error('Erro ao resetar senha:', err); + toast.error('Token inválido ou expirado. Solicite um novo link de recuperação.'); + } finally { + setLoading(false); + } + }; + + const ValidationItem = ({ isValid, text }) => ( + + + {isValid ? ( + + ) : ( + + )} + + + + ); + + return ( + + + navigate('/login')} + sx={{ + display: 'flex', + alignItems: 'center', + mb: 3, + color: '#656D77', + fontWeight: 600, + textDecoration: 'none', + '&:hover': { textDecoration: 'underline' }, + }} + > + Voltar ao Login + + + + Nova senha + + +
+ {/* Nova senha */} + setNovaSenha(e.target.value)} + margin="normal" + required + error={novaSenha.length > 0 && !passwordValidation.isValid} + InputProps={{ + endAdornment: ( + + setShowPassword((s) => !s)} + onMouseDown={(e) => e.preventDefault()} + edge="end" + aria-label={showPassword ? 'Ocultar senha' : 'Mostrar senha'} + > + {showPassword ? : } + + + ), + }} + /> + + {/* Critérios de validação da senha */} + {novaSenha.length > 0 && ( + + + Critérios da senha: + + + + + + + + + )} + + {/* Confirmação */} + setConfirmacao(e.target.value)} + margin="normal" + required + error={showPasswordError} + helperText={showPasswordError ? 'As senhas não coincidem' : ''} + InputProps={{ + endAdornment: ( + + setShowConfirm((s) => !s)} + onMouseDown={(e) => e.preventDefault()} + edge="end" + aria-label={showConfirm ? 'Ocultar senha' : 'Mostrar senha'} + > + {showConfirm ? : } + + + ), + }} + /> + + {/* Feedback de sucesso */} + {passwordValidation.isValid && passwordsMatch && ( + + Senha válida e confirmada! + + )} + + + +
+
+ ); +} diff --git a/codigo-fonte/frontend/src/pages/Team.tsx b/codigo-fonte/frontend/src/pages/Team.tsx new file mode 100644 index 00000000..f14fc6d6 --- /dev/null +++ b/codigo-fonte/frontend/src/pages/Team.tsx @@ -0,0 +1,1030 @@ +import React, { useState, useEffect } from 'react'; +import { + Box, + Container, + Button, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + CircularProgress, + FormControl, + InputLabel, + Select, + MenuItem, + Grid, + SelectChangeEvent, + Typography, + Chip, + Paper, + alpha, + TextField, + Autocomplete, + Divider, + Stack, + Checkbox, +} from '@mui/material'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import SearchIcon from '@mui/icons-material/Search'; +import FilterListIcon from '@mui/icons-material/FilterList'; +import ClearIcon from '@mui/icons-material/Clear'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import dayjs, { Dayjs } from 'dayjs'; +import 'dayjs/locale/pt-br'; +import Table, { Column } from '../components/Table'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import { ConfirmDialog } from '../components/ConfirmDelete'; +import { toast } from 'react-toastify'; +import { + TeamsApi, + CreateTeamRequest, + EditTeamRequest, + ListTeamRequest, + Filter, + Op, + CoursesApi, +} from './../api'; +import { apiConfig } from '../services/auth'; + +dayjs.locale('pt-br'); + +// Interfaces +interface Team { + teamId?: number; + name?: string | null; + lessonTime?: string | null; + start?: string | null; + finish?: string | null; + projectProgramId?: number | null; + courseId?: number | null; + projectProgramName?: string | null; + courseName?: string | null; + personTeamsCount?: number; + isDeleted?: boolean; +} + +interface Program { + id?: number; + name?: string; +} + +interface Course { + courseId?: number; + name?: string | null; +} + +interface Person { + id?: number; + name?: string; +} + +const Team: React.FC = () => { + /* ------------------------------ Variáveis ------------------------------ */ + + const [filterName, setFilterName] = useState(''); + const [filterProgramId, setFilterProgramId] = useState(''); + const [filterCourseId, setFilterCourseId] = useState(''); + const [filterStartDate, setFilterStartDate] = useState(null); + const [filterEndDate, setFilterEndDate] = useState(null); + + const [teams, setTeams] = useState([]); + const [programs, setPrograms] = useState([]); + const [courses, setCourses] = useState([]); + const [persons, setPersons] = useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [openModal, setOpenModal] = useState(false); + const [editingTeam, setEditingTeam] = useState(null); + const [isVisualizing, setIsVisualizing] = useState(false); + + const [teamName, setTeamName] = useState(''); + const [lessonTime, setLessonTime] = useState(''); + const [startDate, setStartDate] = useState(undefined); + const [endDate, setEndDate] = useState(undefined); + const [selectedProgramId, setSelectedProgramId] = useState(''); + const [selectedCourseId, setSelectedCourseId] = useState(''); + const [selectedPersonIds, setSelectedPersonIds] = useState([]); + const [personsResults, setPersonsResults] = useState([]); + const [personsLoading, setPersonsLoading] = useState(false); + const [inputPersonValue, setInputPersonValue] = useState(''); + const [selectedPerson, setSelectedPerson] = useState(null); + + const [loading, setLoading] = useState(false); + const [modalLoading, setModalLoading] = useState(false); + const [programsLoading, setProgramsLoading] = useState(false); + const [coursesLoading, setCoursesLoading] = useState(false); + const [noDataMessage, setNoDataMessage] = useState(''); + const [confirmDialog, setConfirmDialog] = useState({ + open: false, + team: null as Team | null, + loading: false, + }); + + // Instâncias da API + const teamsApi = new TeamsApi(apiConfig); + const coursesApi = new CoursesApi(apiConfig); + + const dialogTitle = () => { + return isVisualizing ? 'Visualizar Turma' : editingTeam ? 'Editar Turma' : 'Nova Turma'; + }; + + /* --------------------------------- Funções -------------------------------- */ + + useEffect(() => { + fetchTeams(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [page, rowsPerPage]); + + useEffect(() => { + fetchPrograms(); + fetchCourses(); + fetchPersons(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const fetchTeams = async (customFilters?: Filter[]) => { + try { + setLoading(true); + setTeams([]); + + const filters: Filter[] = customFilters ?? []; + + if (!customFilters) { + if (filterName) { + filters.push({ + propertyName: 'name', + operation: Op.NUMBER_7, + value: filterName, + }); + } + + if (filterProgramId) { + filters.push({ + propertyName: 'projectProgramId', + operation: Op.NUMBER_1, + value: filterProgramId, + }); + } + + if (filterCourseId) { + filters.push({ + propertyName: 'courseId', + operation: Op.NUMBER_1, + value: filterCourseId, + }); + } + + if (filterStartDate) { + filters.push({ + propertyName: 'start', + operation: Op.NUMBER_6, + value: filterStartDate.format('YYYY-MM-DDTHH:mm:ss'), + }); + } + + if (filterEndDate) { + filters.push({ + propertyName: 'finish', + operation: Op.NUMBER_4, + value: filterEndDate.format('YYYY-MM-DDTHH:mm:ss'), + }); + } + } + + const listTeamRequest: ListTeamRequest = { + pageNumber: page + 1, + pageSize: rowsPerPage, + filters: filters.length > 0 ? filters : undefined, + }; + + const { data } = await teamsApi.listTeam(listTeamRequest); + + if (!data.items || data.items.length === 0) { + setNoDataMessage('Nenhuma turma encontrada'); + setTeams([]); + setTotalCount(0); + return; + } + + setTeams( + (data.items ?? []).map((item) => ({ + ...item, + start: item.start ? dayjs(item.start).format('DD/MM/YYYY') : '', + finish: item.finish ? dayjs(item.finish).format('DD/MM/YYYY') : '', + })) + ); + + setTotalCount(data.totalItems || 0); + setNoDataMessage(''); + } catch (error) { + console.error('Erro ao carregar turmas:', error); + toast.error('Erro ao carregar turmas'); + setTeams([]); + setTotalCount(0); + } finally { + setLoading(false); + } + }; + + /* Em mock */ + const fetchPrograms = async () => { + try { + setProgramsLoading(true); + // TODO: Substituir por chamada real quando ProjectProgramsApi estiver disponível + await new Promise((resolve) => setTimeout(resolve, 300)); + const mockPrograms: Program[] = [ + // { id: 101, name: 'Projeto de Inovação' }, + // { id: 102, name: 'Projeto de Tecnologia' }, + // { id: 103, name: 'Projeto de Liderança' }, + // { id: 104, name: 'Projeto de Desenvolvimento Pessoal' }, + // { id: 105, name: 'Projeto de Empreendedorismo' }, + ]; + setPrograms(mockPrograms); + } catch (error) { + console.error('Erro ao carregar projetos:', error); + toast.error('Erro ao carregar projetos'); + setPrograms([]); + } finally { + setProgramsLoading(false); + } + }; + + const fetchPersons = async () => { + try { + setPersonsLoading(true); + // TODO: Substituir por chamada real quando PersonsApi estiver disponível + await new Promise((resolve) => setTimeout(resolve, 300)); + const mockPersons: Person[] = [ + { id: 1, name: 'João Silva' }, + { id: 2, name: 'Maria Santos' }, + { id: 3, name: 'Pedro Oliveira' }, + ]; + setPersons(mockPersons); + } catch (error) { + console.error('Erro ao carregar pessoas:', error); + toast.error('Erro ao carregar pessoas'); + setPersons([]); + } finally { + setPersonsLoading(false); + } + }; + + const fetchCourses = async () => { + try { + setCoursesLoading(true); + const { data } = await coursesApi.listCourse({ + pageNumber: 1, + pageSize: 100, + }); + setCourses(data.items || []); + } catch (error) { + console.error('Erro ao carregar programas:', error); + toast.error('Erro ao carregar programas'); + setCourses([]); + } finally { + setCoursesLoading(false); + } + }; + + const columns: Column[] = [ + { label: 'Nome', field: 'name' }, + { label: 'Data Início', field: 'start' }, + { label: 'Data Fim', field: 'finish' }, + { label: 'Projeto', field: 'projectProgramName' }, + { label: 'Programa', field: 'courseName' }, + { label: 'Nº Alunos', field: 'personTeamsCount', align: 'center' }, + ]; + + const handleSearch = () => { + setPage(0); + fetchTeams(); + }; + + const handleClearFilters = () => { + setFilterName(''); + setFilterProgramId(''); + setFilterCourseId(''); + setFilterStartDate(null); + setFilterEndDate(null); + setPage(0); + fetchTeams([]); + }; + + const handleAdd = () => { + resetForm(); + setOpenModal(true); + }; + + const handleEdit = (team: Team) => { + setEditingTeam(team); + setTeamName(team.name || ''); + setLessonTime(team.lessonTime || ''); + setStartDate(team.start ? dayjs(team.start, 'DD/MM/YYYY') : undefined); + setEndDate(team.finish ? dayjs(team.finish, 'DD/MM/YYYY') : undefined); + setSelectedProgramId(team.projectProgramId || ''); + setSelectedCourseId(team.courseId || ''); + setSelectedPersonIds([]); // Será carregado no getTeamById + setOpenModal(true); + }; + + const handleView = async (team: Team) => { + try { + const id: number = team.teamId!; + const { data } = await teamsApi.getTeamById(id); + setIsVisualizing(true); + setTeamName(data.name || ''); + setLessonTime(data.lessonTime || ''); + setStartDate(data.start ? dayjs(data.start) : undefined); + setEndDate(data.finish ? dayjs(data.finish) : undefined); + setSelectedProgramId(data.projectProgramId || ''); + setSelectedCourseId(data.courseId || ''); + + // TODO: Quando a API retornar personTeamsIds, usar: + // setSelectedPersonIds(data.personTeamsIds || []); + setSelectedPersonIds([]); // Por enquanto vazio + + setOpenModal(true); + } catch (error) { + console.error('Erro ao visualizar turma:', error); + toast.error('Erro ao carregar detalhes da turma'); + } + }; + + const handleDelete = async (team: Team) => { + setConfirmDialog({ + open: true, + team: team, + loading: false, + }); + }; + + const handleConfirmDelete = async () => { + if (!confirmDialog.team) return; + + try { + setConfirmDialog((prev) => ({ ...prev, loading: true })); + const id: number = confirmDialog.team.teamId!; + await teamsApi.deleteTeam(id); + toast.success(`Turma "${confirmDialog.team.name}" excluída com sucesso!`); + handleCloseConfirmDialog(); + fetchTeams(); + } catch (error) { + console.error('Erro ao excluir turma:', error); + toast.error('Erro ao excluir turma'); + setConfirmDialog((prev) => ({ ...prev, loading: false })); + } + }; + + const handleCloseConfirmDialog = () => { + setConfirmDialog({ + open: false, + team: null, + loading: false, + }); + }; + + const validateForm = (): boolean => { + if (!selectedCourseId) { + toast.error('Deve ser informado um programa!'); + return false; + } + if (endDate && endDate.isBefore(startDate)) { + toast.error('A data de fim deve ser posterior à data de início!'); + return false; + } + return true; + }; + + const handleSave = async () => { + if (!validateForm()) return; + + try { + setModalLoading(true); + + if (editingTeam) { + const editTeamRequest: EditTeamRequest = { + name: teamName || undefined, + lessonTime: lessonTime || undefined, + start: startDate ? startDate.format('YYYY-MM-DD') : undefined, + finish: endDate ? endDate.format('YYYY-MM-DD') : undefined, + courseId: selectedCourseId as number, + // TODO: alterar pós adição de CRUD + /* Crud ainda n implementado */ + // projectProgramId: selectedProgramId ? (selectedProgramId as number) : undefined, + // personTeamsIds: selectedPersonIds.length > 0 ? selectedPersonIds : undefined, + }; + + const id: number = editingTeam.teamId!; + await teamsApi.editTeam(id, editTeamRequest); + toast.success('Turma atualizada com sucesso!'); + } else { + const createTeamRequest: CreateTeamRequest = { + name: teamName || undefined, + lessonTime: lessonTime || undefined, + start: startDate ? startDate.format('YYYY-MM-DD') : undefined, + finish: endDate ? endDate.format('YYYY-MM-DD') : undefined, + courseId: selectedCourseId as number, + // TODO: alterar pós adição de CRUD + /* Crud ainda n implementado */ + // projectProgramId: selectedProgramId ? (selectedProgramId as number) : undefined, + // personTeamsIds: selectedPersonIds.length > 0 ? selectedPersonIds : [], + }; + + await teamsApi.createTeam(createTeamRequest); + toast.success('Turma criada com sucesso!'); + } + + handleCloseModal(); + fetchTeams([]); + } catch (error) { + console.error('Erro ao salvar turma:', error); + toast.error('Erro ao salvar turma'); + } finally { + setModalLoading(false); + } + }; + + const resetForm = () => { + setEditingTeam(null); + setTeamName(''); + setLessonTime(''); + setStartDate(undefined); + setEndDate(undefined); + setSelectedProgramId(''); + setSelectedCourseId(''); + setSelectedPersonIds([]); + }; + + const handleCloseModal = () => { + setOpenModal(false); + setTimeout(() => { + resetForm(); + setIsVisualizing(false); + }, 300); + }; + + const handleProgramChange = (event: SelectChangeEvent) => { + setSelectedProgramId(event.target.value as number | ''); + }; + + const handleCourseChange = (event: SelectChangeEvent) => { + setSelectedCourseId(event.target.value as number | ''); + }; + + const handleFilterProgramChange = (event: SelectChangeEvent) => { + setFilterProgramId(event.target.value as number | ''); + }; + + const handleFilterCourseChange = (event: SelectChangeEvent) => { + setFilterCourseId(event.target.value as number | ''); + }; + + const handlePersonChange = (event: SelectChangeEvent) => { + const value = event.target.value; + setSelectedPersonIds(typeof value === 'string' ? [] : value); + }; + + return ( + + + + + + + {/* Campo de pesquisa + botão */} + + + + + Filtro de Busca + + {(filterName || + filterStartDate || + filterEndDate || + filterProgramId || + filterCourseId) && ( + + )} + + + + setFilterName(e.target.value)} + /> + + + + Projeto + + + + Programa + + + + + {/* Testan */} + + + + + + + {/* Tabela */} + {loading ? ( + + + + ) : ( + + columns={columns} + data={teams} + page={page} + rowsPerPage={rowsPerPage} + totalCount={totalCount} + onPageChange={setPage} + onRowsPerPageChange={setRowsPerPage} + onView={handleView} + onEdit={handleEdit} + onDelete={handleDelete} + noDataMessage={noDataMessage} + /> + )} + + + + {/* --------------------------------- Modais --------------------------------- */} + + {/* ------------------------- Criação/Edição ------------------------ */} + + + + {dialogTitle()} + + + + + + setTeamName(e.target.value)} + slotProps={{ + input: { + readOnly: isVisualizing, + }, + }} + sx={isVisualizing ? { pointerEvents: 'none' } : {}} + /> + + + + setLessonTime(e.target.value)} + placeholder="Ex: 19:00 - 22:00" + slotProps={{ + input: { + readOnly: isVisualizing, + }, + }} + sx={isVisualizing ? { pointerEvents: 'none' } : {}} + /> + + + + setStartDate(value || undefined)} + format="DD/MM/YYYY" + disabled={isVisualizing} + maxDate={endDate} + slotProps={{ + textField: { + fullWidth: true, + variant: 'outlined', + margin: 'dense', + }, + }} + /> + + + + setEndDate(value || undefined)} + format="DD/MM/YYYY" + minDate={startDate} + disabled={isVisualizing || !startDate} + slotProps={{ + textField: { + fullWidth: true, + variant: 'outlined', + margin: 'dense', + }, + }} + /> + + + + + Projeto + + + + + + + Programa * + + + + + + {/* Alunos editáveis */} + + + Alunos + + + + option.name || ''} + value={persons.filter((p) => selectedPersonIds.includes(p.id))} + onChange={(_, values) => { + setSelectedPersonIds(values.map((v) => v.id)); + }} + renderOption={(props, option, { selected }) => ( +
  • + + {option.name} +
  • + )} + renderTags={() => null} + renderInput={(params) => ( + + )} + isOptionEqualToValue={(option, value) => option.id === value.id} + fullWidth + disabled={personsLoading || isVisualizing} + /> + + {/* Chips de Alunos */} + {selectedPersonIds.length > 0 ? ( + + {persons + .filter((p) => selectedPersonIds.includes(p.id)) + .map((p) => ( + { + setSelectedPersonIds(selectedPersonIds.filter((id) => id !== p.id)); + }} + /> + ))} + + ) : ( + + Nenhum aluno. + + )} +
    +
    +
    +
    + + {isVisualizing ? ( + + ) : ( + <> + + + + )} + +
    + + {/* -------------------- Confirmação de Exclusão -------------------- */} + +
    + ); +}; + +export default Team; diff --git a/codigo-fonte/frontend/src/pages/User.tsx b/codigo-fonte/frontend/src/pages/User.tsx new file mode 100644 index 00000000..e1fd3fa2 --- /dev/null +++ b/codigo-fonte/frontend/src/pages/User.tsx @@ -0,0 +1,647 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { + Box, + Button, + Chip, + Container, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + FormControl, + InputLabel, + MenuItem, + Paper, + Select, + TextField, + Typography, + alpha, + CircularProgress, + Grid, +} from '@mui/material'; +import TitleAndButtons from '@/components/TitleAndButtons'; +import Table, { Column } from '@/components/Table'; +import { ConfirmDialog } from '@/components/ConfirmDelete'; +import { toast } from 'react-toastify'; +import SearchIcon from '@mui/icons-material/Search'; +import ClearIcon from '@mui/icons-material/Clear'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import { + UsersApi, + type CreateUserRequest, + type UpdateUserRequest, + type ListUserRequest, + type Filter, + Op, +} from '@/api'; +import { apiConfig } from '@/services/auth'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; + +interface UserRow { + userId?: number; + name?: string; + email?: string; + role?: 'Admin' | 'Editor' | 'Viewer'; + phoneNumber?: string; + isActive?: boolean; +} + +const DEFAULT_PASSWORD = '123@Mudar'; + +const roleLabelToApi: Record = { + Administrador: 'Admin', + Editor: 'Editor', + Leitor: 'Viewer', +}; + +const roleApiToLabel: Record<'Admin' | 'Editor' | 'Viewer', string> = { + Admin: 'Administrador', + Editor: 'Editor', + Viewer: 'Leitor', +}; + +const onlyDigits = (s: string) => s.replace(/\D/g, ''); + +function handleApiError(err: any, defaultMsg: string) { + const status = err?.response?.status; + if (status === 403) { + toast.error('Usuário não tem permissão para essa função'); + } else if (status === 401) { + toast.error('Sessão expirada ou inválida. Faça login novamente.'); + } else if (!status) { + toast.error('Falha de conexão com o servidor.'); + } else { + toast.error(defaultMsg); + } + // eslint-disable-next-line no-console + console.error(defaultMsg, err); +} + +const UserPage: React.FC = () => { + const api = useMemo(() => new UsersApi(apiConfig), []); + + const [users, setUsers] = useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + const [totalCount, setTotalCount] = useState(0); + const [loading, setLoading] = useState(false); + const [noDataMessage, setNoDataMessage] = useState(''); + + const [search, setSearch] = useState(''); + + const [openModal, setOpenModal] = useState(false); + const [isViewing, setIsViewing] = useState(false); + const [editingUser, setEditingUser] = useState(null); + + const [formName, setFormName] = useState(''); + const [formEmail, setFormEmail] = useState(''); + const [formPhone, setFormPhone] = useState(''); + const [formRoleLabel, setFormRoleLabel] = useState<'Administrador' | 'Editor' | 'Leitor'>('Leitor'); + const [modalLoading, setModalLoading] = useState(false); + + const [confirmDelete, setConfirmDelete] = useState<{ open: boolean; user: UserRow | null; loading: boolean }>({ + open: false, + user: null, + loading: false, + }); + + const columns: Column[] = [ + { label: 'ID', field: 'userId' }, + { label: 'Nome', field: 'name' }, + { label: 'Email', field: 'email' }, + { label: 'Tipo', field: 'role', align: 'center' }, + { label: 'Telefone', field: 'phoneNumber' }, + ]; + + const fetchUsers = async (noFilter?: boolean) => { + try { + setLoading(true); + + let filters: Filter[] = []; + if (!noFilter && search.trim()) { + filters = [ + { + propertyName: 'name', + operation: Op.NUMBER_7, + value: search.trim(), + }, + ]; + } + + const req: ListUserRequest = { + pageNumber: page + 1, + pageSize: rowsPerPage, + filters, + }; + + const { data } = await api.listUser(req); + const items = data.items ?? []; + + if (items.length === 0) { + setNoDataMessage('Nenhum usuário encontrado'); + setUsers([]); + setTotalCount(0); + return; + } + + const mapped = items.map((u) => ({ + ...u, + role: u.role ? (u.role as 'Admin' | 'Editor' | 'Viewer') : undefined, + })); + + setUsers(mapped); + setTotalCount(data.totalItems || 0); + setNoDataMessage(''); + } catch (err) { + handleApiError(err, 'Erro ao carregar usuários'); + setUsers([]); + setTotalCount(0); + } finally { + setLoading(false); + } + }; + + const handleClearFilters = () => { + setSearch(''); + setPage(0); + fetchUsers(true); + }; + + const handleSearch = () => { + setPage(0); + fetchUsers(); + }; + + const openCreate = () => { + setEditingUser(null); + setIsViewing(false); + setFormName(''); + setFormEmail(''); + setFormPhone(''); + setFormRoleLabel('Leitor'); + setOpenModal(true); + }; + + const openEdit = async (row: UserRow) => { + try { + setModalLoading(true); + setIsViewing(false); + + const id = row.userId!; + const { data } = await api.getUserById(id); + + setEditingUser(data); + setFormName(data.name ?? ''); + setFormEmail(data.email ?? ''); + setFormPhone(data.phoneNumber ?? ''); + setFormRoleLabel( + roleApiToLabel[(data.role as 'Admin' | 'Editor' | 'Viewer') ?? 'Viewer'] as 'Administrador' | 'Editor' | 'Leitor', + ); + + setOpenModal(true); + } catch (err) { + handleApiError(err, 'Erro ao carregar usuário'); + } finally { + setModalLoading(false); + } + }; + + const openView = async (row: UserRow) => { + try { + setModalLoading(true); + setIsViewing(true); + + const id = row.userId!; + const { data } = await api.getUserById(id); + + setEditingUser(data); + setFormName(data.name ?? ''); + setFormEmail(data.email ?? ''); + setFormPhone(data.phoneNumber ?? ''); + setFormRoleLabel( + roleApiToLabel[(data.role as 'Admin' | 'Editor' | 'Viewer') ?? 'Viewer'] as 'Administrador' | 'Editor' | 'Leitor', + ); + + setOpenModal(true); + } catch (err) { + handleApiError(err, 'Erro ao visualizar usuário'); + setIsViewing(false); + } finally { + setModalLoading(false); + } + }; + + const openDelete = (row: UserRow) => { + setConfirmDelete({ open: true, user: row, loading: false }); + }; + + const closeModal = () => { + setOpenModal(false); + setTimeout(() => { + setIsViewing(false); + setEditingUser(null); + setFormName(''); + setFormEmail(''); + setFormPhone(''); + setFormRoleLabel('Leitor'); + }, 300); + }; + + const validateForm = (): boolean => { + if (!formName.trim() || !formEmail.trim() || !formPhone.trim() || !formRoleLabel) { + toast.error('Todos os campos são obrigatórios.'); + return false; + } + + const nameParts = formName.trim().split(/\s+/); + if (nameParts.length < 2) { + toast.error('Informe nome e sobrenome.'); + return false; + } + + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailRegex.test(formEmail.trim())) { + toast.error('Informe um e-mail válido.'); + return false; + } + + const digits = onlyDigits(formPhone); + if (digits.length < 11) { + toast.error('Informe um telefone válido com DDD (11 dígitos).'); + return false; + } + + return true; + }; + + const handleSave = async () => { + if (!validateForm()) return; + + try { + setModalLoading(true); + + const roleApi = roleLabelToApi[formRoleLabel]; + + if (editingUser) { + const req: UpdateUserRequest = { + userId: editingUser.userId!, + name: formName.trim(), + email: formEmail.trim(), + phoneNumber: onlyDigits(formPhone), + role: roleApi, + isActive: true, + }; + await api.updateUser(editingUser.userId!, req); + toast.success('Usuário atualizado com sucesso!'); + } else { + const req: CreateUserRequest = { + name: formName.trim(), + email: formEmail.trim(), + phoneNumber: onlyDigits(formPhone), + role: roleApi, + password: DEFAULT_PASSWORD, + }; + await api.createUser(req); + toast.success('Usuário criado com sucesso!'); + } + + closeModal(); + fetchUsers(); + } catch (err) { + handleApiError(err, 'Erro ao salvar usuário'); + } finally { + setModalLoading(false); + } + }; + + const confirmRemove = async () => { + if (!confirmDelete.user?.userId) return; + + try { + setConfirmDelete((prev) => ({ ...prev, loading: true })); + await api.deleteUser(confirmDelete.user.userId); + toast.success('Usuário excluído com sucesso!'); + setConfirmDelete({ open: false, user: null, loading: false }); + fetchUsers(); + } catch (err) { + handleApiError(err, 'Erro ao excluir usuário'); + setConfirmDelete((prev) => ({ ...prev, loading: false })); + } + }; + + const dialogTitle = () => (isViewing ? 'Visualizar Usuário' : editingUser ? 'Editar Usuário' : 'Adicionar Usuário'); + + useEffect(() => { + fetchUsers(); + }, [page, rowsPerPage]); + + return ( + + + + + + + + + + + Filtro de Busca + + {search && ( + + )} + + + + setSearch(e.target.value)} + size="small" + onKeyUp={(e) => e.key === 'Enter' && handleSearch()} + /> + + + + + + + {loading ? ( + + + + ) : ( + + columns={columns} + data={users.map((u) => ({ + ...u, + role: u.role ? (roleApiToLabel[u.role] as any) : undefined, + }))} + page={page} + rowsPerPage={rowsPerPage} + totalCount={totalCount} + onPageChange={setPage} + onRowsPerPageChange={setRowsPerPage} + onView={openView} + onEdit={openEdit} + onDelete={openDelete} + noDataMessage={noDataMessage} + /> + )} + + + + + + {dialogTitle()} + + + + + {modalLoading ? ( + + + + ) : ( + + + setFormName(e.target.value)} + fullWidth + size="small" + InputProps={{ readOnly: isViewing }} + /> + + + + setFormEmail(e.target.value)} + fullWidth + size="small" + InputProps={{ readOnly: isViewing }} + /> + + + + setFormPhone(e.target.value)} + fullWidth + size="small" + InputProps={{ readOnly: isViewing }} + /> + + + + + Tipo + + + + + )} + + + + {isViewing ? ( + + ) : ( + <> + + + + )} + + + + setConfirmDelete({ open: false, user: null, loading: false })} + onConfirm={confirmRemove} + loading={confirmDelete.loading} + danger + /> + + + + + ); +}; + +export default UserPage; diff --git a/codigo-fonte/frontend/src/routes/AppRoutes.tsx b/codigo-fonte/frontend/src/routes/AppRoutes.tsx new file mode 100644 index 00000000..368b4a00 --- /dev/null +++ b/codigo-fonte/frontend/src/routes/AppRoutes.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import { Routes, Route, Navigate } from 'react-router-dom'; +import Login from './../pages/Login'; +import ResetPassword from './../pages/ResetPassword'; +import ForgotPassword from './../pages/ForgotPassword'; +import Home from './../pages/Home'; +import PrivateRoute from './privateRoute'; +import Course from './../pages/Course'; +import Team from '@/pages/Team'; +import Osc from './../pages/Osc'; +import Beneficiary from '@/pages/Beneficiary'; +import { Box } from '@mui/material'; +import SideMenu from '@/components/SideMenu'; +import BusinessCase from '@/pages/BusinessCase'; +import OriginBusinessCase from '@/pages/OriginBusinessCase'; +import Company from '@/pages/Company'; +import Donation from '@/pages/Donation'; +import User from '@/pages/User'; +import Person from '@/pages/Person'; + +const routeConfig = [ + { path: '/login', element: , isPrivate: false }, + { path: '/forgot-password', element: , isPrivate: false }, + { path: '/reset-password', element: , isPrivate: false }, + { path: '/home', element: , isPrivate: true }, + { path: '/course', element: , isPrivate: true }, + { path: '/team', element: , isPrivate: true }, + { path: '/osc', element: , isPrivate: true }, + { path: '/beneficiary', element: , isPrivate: true }, + { path: '/business-case', element: , isPrivate: true }, + { path: '/business-case/:businessCaseId/origin-business-case', element: , isPrivate: true }, + { path: '/company', element: , isPrivate: true }, + { path: '/donation', element: , isPrivate: true }, + { path: '/user', element: , isPrivate: true }, + { path: '/person', element: , isPrivate: true }, +]; + +export default function AppRoutes() { + return ( + + {/* Redirect para login */} + } /> + + {/* Rotas mapeadas */} + {routeConfig.map(({ path, element, isPrivate }) => ( + + {/* Provisório para testes */} + + {element} + + ) : ( + element + ) + } + /> + ))} + + {/* Fallback para rotas não encontradas */} + } /> + + ); +} diff --git a/codigo-fonte/frontend/src/routes/privateRoute.tsx b/codigo-fonte/frontend/src/routes/privateRoute.tsx new file mode 100644 index 00000000..0c39ab88 --- /dev/null +++ b/codigo-fonte/frontend/src/routes/privateRoute.tsx @@ -0,0 +1,45 @@ +import React, { useEffect, useState } from 'react'; +import { Navigate } from 'react-router-dom'; +import { isTokenValid, refreshAccessToken } from '../services/auth'; +import { scheduleTokenRefresh } from '../services/auth'; + +import type { ReactNode } from 'react'; + +interface PrivateRouteProps { + children: ReactNode; +} + +const PrivateRoute: React.FC = ({ children }) => { + const [authorized, setAuthorized] = useState(null); // null = carregando + + useEffect(() => { + const checkAuth = async () => { + const accessToken = localStorage.getItem('accessToken'); + + if (isTokenValid(accessToken)) { + const loginResponse = JSON.parse(localStorage.getItem('loginResponse')!); + scheduleTokenRefresh(parseInt(loginResponse.expiresIn)); + setAuthorized(true); + } else { + const refreshed = await refreshAccessToken(); + if (refreshed) { + const newLogin = JSON.parse(localStorage.getItem('loginResponse')!); + scheduleTokenRefresh(parseInt(newLogin.expiresIn)); + } + setAuthorized(refreshed); + } + }; + + checkAuth(); +}, []); + + + if (authorized === null) { + // Spinner ou tela de carregamento enquanto valida + return
    Carregando...
    ; + } + + return authorized ? children : ; +}; + +export default PrivateRoute; diff --git a/codigo-fonte/frontend/src/services/auth.ts b/codigo-fonte/frontend/src/services/auth.ts new file mode 100644 index 00000000..bab4ac01 --- /dev/null +++ b/codigo-fonte/frontend/src/services/auth.ts @@ -0,0 +1,76 @@ +import { AuthApi, Configuration, LoginResponse } from '../api'; +import { jwtDecode } from 'jwt-decode'; +import { AxiosResponse } from 'axios'; +import { BASE_PATH } from '@/api/base'; + +interface JwtPayload { exp: number; } + +export function persistLoginResponse(data: LoginResponse, name?: string) { + const payload = { + accessToken: data.accessToken, + refreshToken: data.refreshToken, + expiresIn: data.expiresIn, + ...(name ? { name } : {}), + ...(data as any).name ? { name: (data as any).name } : {}, + }; + localStorage.setItem('loginResponse', JSON.stringify(payload)); + localStorage.setItem('accessToken', data.accessToken || ''); + localStorage.setItem('refreshToken', data.refreshToken || ''); +} + +const configuration = new Configuration(); +const apiInstance = new AuthApi(configuration); + +export const isTokenValid = (token: string | null): boolean => { + if (!token) return false; + try { + const decoded = jwtDecode(token); + const now = Date.now() / 1000; + return decoded.exp > now; + } catch { + return false; + } +}; + +export const scheduleTokenRefresh = (expiresInSeconds: number) => { + const expires = Number(expiresInSeconds); + const timeout = ((Number.isFinite(expires) && expires > 0 ? expires : 600) - 60) * 1000; + setTimeout(async () => { + const success = await refreshAccessToken(); + if (success) { + const newLogin = JSON.parse(localStorage.getItem('loginResponse') || '{}'); + scheduleTokenRefresh(Number(newLogin.expiresIn || 600)); + } else { + localStorage.removeItem('loginResponse'); + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + window.location.href = '/login'; + } + }, Math.max(timeout, 15000)); +}; + +export const refreshAccessToken = async (): Promise => { + const loginResponseStr = localStorage.getItem('loginResponse'); + if (!loginResponseStr) return false; + + const loginResponse: LoginResponse = JSON.parse(loginResponseStr); + + try { + const response: AxiosResponse = await apiInstance.refreshToken(loginResponse); + if (response.status === 200 && response.data) { + persistLoginResponse(response.data); + return true; + } + return false; + } catch { + return false; + } +}; + +export const apiConfig = new Configuration({ + basePath: BASE_PATH, + accessToken: async () => { + const t = localStorage.getItem('accessToken'); + return t || ''; + }, +}); diff --git a/codigo-fonte/frontend/src/store/.gitkeep b/codigo-fonte/frontend/src/store/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/codigo-fonte/frontend/src/styles/.gitkeep b/codigo-fonte/frontend/src/styles/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/codigo-fonte/frontend/src/types/.gitkeep b/codigo-fonte/frontend/src/types/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/codigo-fonte/frontend/src/utils/theme.ts b/codigo-fonte/frontend/src/utils/theme.ts new file mode 100644 index 00000000..e7971e64 --- /dev/null +++ b/codigo-fonte/frontend/src/utils/theme.ts @@ -0,0 +1,80 @@ +// theme.ts +import { createTheme } from '@mui/material/styles'; + +const theme = createTheme({ + palette: { + primary: { + main: '#1E4EC4', // azul institucional claro + dark: '#264197', // azul institucional escuro + }, + success: { + main: '#21AD53', // verde ação + }, + background: { + default: '#fcfcfc', // quase branco + paper: '#ffffff', + }, + text: { + primary: '#000000', + secondary: '#656d77', // cinza escuro + }, + }, + components: { + MuiTextField: { + defaultProps: { + variant: 'outlined', + }, + }, + MuiOutlinedInput: { + styleOverrides: { + root: { + borderRadius: 8, + backgroundColor: '#fcfcfc', + '&:hover .MuiOutlinedInput-notchedOutline': { + borderColor: '#1E4EC4', + }, + '&.Mui-focused:not(.Mui-disabled) .MuiOutlinedInput-notchedOutline:not(.Mui-disabled)': { + borderColor: '#1E4EC4', + borderWidth: 2, + }, + }, + input: { + color: '#000000', + '&:-webkit-autofill': { + WebkitBoxShadow: '0 0 0 1000px #fcfcfc inset', + WebkitTextFillColor: '#000000', + }, + }, + }, + }, + MuiInputLabel: { + styleOverrides: { + root: { + color: '#656d77', + '&.Mui-focused': { + color: '#1E4EC4', + }, + '&:hover': { + color: '#1E4EC4', + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + contained: { + borderRadius: 15, + backgroundColor: '#21AD53', + color: '#FFFFFF', + textTransform: 'none', + fontWeight: 600, + '&:hover': { + transform: 'scale(1.02)' + } + }, + }, + }, + }, +}); + +export default theme; diff --git a/codigo-fonte/frontend/src/vite-env.d.ts b/codigo-fonte/frontend/src/vite-env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/codigo-fonte/frontend/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/codigo-fonte/frontend/swagger.json b/codigo-fonte/frontend/swagger.json new file mode 100644 index 00000000..fbb259dc --- /dev/null +++ b/codigo-fonte/frontend/swagger.json @@ -0,0 +1,3894 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "IgescConecta.API", + "version": "1.0" + }, + "paths": { + "/api/auth/Login": { + "post": { + "tags": [ + "Auth" + ], + "operationId": "Login", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserLogin" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UserLogin" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UserLogin" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UserToken" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserToken" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UserToken" + } + } + } + } + } + } + }, + "/api/auth/RefreshToken": { + "post": { + "tags": [ + "Auth" + ], + "operationId": "RefreshToken", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoginResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/LoginResponse" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/LoginResponse" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/auth/reset-password": { + "patch": { + "tags": [ + "Auth" + ], + "operationId": "ResetPassword", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPasswordRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ResetPasswordRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ResetPasswordRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ResetPasswordResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPasswordResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ResetPasswordResponse" + } + } + } + } + } + } + }, + "/api/auth/forgot-password": { + "post": { + "tags": [ + "Auth" + ], + "operationId": "ForgotPassword", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForgotPasswordRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ForgotPasswordRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ForgotPasswordRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ForgotPasswordResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ForgotPasswordResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ForgotPasswordResponse" + } + } + } + } + } + } + }, + "/api/beneficiaries/{beneficiaryId}": { + "put": { + "tags": [ + "Beneficiaries" + ], + "operationId": "UpdateBeneficiary", + "parameters": [ + { + "name": "beneficiaryId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBeneficiaryRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBeneficiaryRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UpdateBeneficiaryRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UpdateBeneficiaryResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBeneficiaryResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBeneficiaryResponse" + } + } + } + } + } + }, + "get": { + "tags": [ + "Beneficiaries" + ], + "operationId": "GetBeneficiary", + "parameters": [ + { + "name": "beneficiaryId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/GetBeneficiaryResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetBeneficiaryResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/GetBeneficiaryResponse" + } + } + } + } + } + } + }, + "/api/beneficiary/ListBeneficiary": { + "post": { + "tags": [ + "Beneficiaries" + ], + "operationId": "ListBeneficiary", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListBeneficiaryRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListBeneficiaryRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ListBeneficiaryRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ListBeneficiaryViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListBeneficiaryViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListBeneficiaryViewModel" + } + } + } + } + } + } + }, + "/api/beneficiary/{beneficiaryId}": { + "delete": { + "tags": [ + "Beneficiaries" + ], + "operationId": "DeleteBeneficiary", + "parameters": [ + { + "name": "beneficiaryId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/beneficiary/CreateBeneficiary": { + "post": { + "tags": [ + "Beneficiaries" + ], + "operationId": "CreateBeneficiary", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateBeneficiaryRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateBeneficiaryRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateBeneficiaryRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/CreateBeneficiaryResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateBeneficiaryResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateBeneficiaryResponse" + } + } + } + } + } + } + }, + "/api/businesscases/{businessCaseId}": { + "put": { + "tags": [ + "BusinessCases" + ], + "operationId": "UpdateBusinessCase", + "parameters": [ + { + "name": "businessCaseId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBusinessCaseRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBusinessCaseRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UpdateBusinessCaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UpdateBusinessCaseResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBusinessCaseResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBusinessCaseResponse" + } + } + } + } + } + }, + "get": { + "tags": [ + "BusinessCases" + ], + "operationId": "GetBusinessCase", + "parameters": [ + { + "name": "businessCaseId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/GetBusinessCaseResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetBusinessCaseResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/GetBusinessCaseResponse" + } + } + } + } + } + } + }, + "/api/businesscase/ListBusinessCase": { + "post": { + "tags": [ + "BusinessCases" + ], + "operationId": "ListBusinessCase", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListBusinessCaseRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListBusinessCaseRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ListBusinessCaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ListBusinessCaseViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListBusinessCaseViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListBusinessCaseViewModel" + } + } + } + } + } + } + }, + "/api/businesscase/{businessCaseId}": { + "delete": { + "tags": [ + "BusinessCases" + ], + "operationId": "DeleteBusinessCase", + "parameters": [ + { + "name": "businessCaseId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/businesscase/CreateBusinessCase": { + "post": { + "tags": [ + "BusinessCases" + ], + "operationId": "CreateBusinessCase", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateBusinessCaseRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateBusinessCaseRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateBusinessCaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/CreateBusinessCaseResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateBusinessCaseResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateBusinessCaseResponse" + } + } + } + } + } + } + }, + "/api/courses/search": { + "post": { + "tags": [ + "Courses" + ], + "operationId": "ListCourse", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListCourseRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListCourseRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ListCourseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ListCourseViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListCourseViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListCourseViewModel" + } + } + } + } + } + } + }, + "/api/courses/{id}": { + "get": { + "tags": [ + "Courses" + ], + "operationId": "GetCourseById", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/GetCourseByIdViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetCourseByIdViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/GetCourseByIdViewModel" + } + } + } + } + } + } + }, + "/api/courses/{courseId}": { + "put": { + "tags": [ + "Courses" + ], + "operationId": "EditCourse", + "parameters": [ + { + "name": "courseId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EditCourseRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/EditCourseRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/EditCourseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/EditCourseResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/EditCourseResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/EditCourseResponse" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Courses" + ], + "operationId": "DeleteCourse", + "parameters": [ + { + "name": "courseId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/DeleteCourseResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteCourseResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/DeleteCourseResponse" + } + } + } + } + } + } + }, + "/api/courses": { + "post": { + "tags": [ + "Courses" + ], + "operationId": "CreateCourse", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCourseRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateCourseRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateCourseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/CreateCourseResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCourseResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateCourseResponse" + } + } + } + } + } + } + }, + "/api/companies": { + "post": { + "tags": [ + "CreateCompanyEndpoint" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateCompanyCommand" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateCompanyCommand" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateCompanyCommand" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/donations": { + "post": { + "tags": [ + "CreateDonationEndpoint" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateDonationCommand" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateDonationCommand" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateDonationCommand" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/donations/{id}": { + "delete": { + "tags": [ + "DeleteDonationEndpoint" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "get": { + "tags": [ + "ListDonationEndpoint" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "put": { + "tags": [ + "UpdateDonationEndpoint" + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateDonationCommand" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateDonationCommand" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UpdateDonationCommand" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/companies/{cnpj}": { + "delete": { + "tags": [ + "InactivateCompanyEndpoint" + ], + "parameters": [ + { + "name": "cnpj", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "get": { + "tags": [ + "ListCompanyEndpoint" + ], + "parameters": [ + { + "name": "cnpj", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "put": { + "tags": [ + "UpdateCompanyEndpoint" + ], + "parameters": [ + { + "name": "cnpj", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateCompanyCommand" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateCompanyCommand" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UpdateCompanyCommand" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/origins-business-cases/{originBusinessCaseId}": { + "put": { + "tags": [ + "OriginsBusinessCases" + ], + "operationId": "UpdateOriginBusinessCase", + "parameters": [ + { + "name": "originBusinessCaseId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOriginBusinessCaseRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOriginBusinessCaseRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UpdateOriginBusinessCaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UpdateOriginBusinessCaseResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOriginBusinessCaseResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOriginBusinessCaseResponse" + } + } + } + } + } + }, + "get": { + "tags": [ + "OriginsBusinessCases" + ], + "operationId": "GetOriginBusinessCase", + "parameters": [ + { + "name": "originBusinessCaseId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/GetOriginBusinessCaseResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetOriginBusinessCaseResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/GetOriginBusinessCaseResponse" + } + } + } + } + } + }, + "delete": { + "tags": [ + "OriginsBusinessCases" + ], + "operationId": "DeleteOriginBusinessCase", + "parameters": [ + { + "name": "originBusinessCaseId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/origins-business-cases/ListOriginBusinessCase": { + "post": { + "tags": [ + "OriginsBusinessCases" + ], + "operationId": "ListOriginBusinessCase", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOriginBusinessCaseRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListOriginBusinessCaseRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ListOriginBusinessCaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ListOriginBusinessCaseViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOriginBusinessCaseViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListOriginBusinessCaseViewModel" + } + } + } + } + } + } + }, + "/api/origins-business-cases/ListOriginsBusinessCaseByBusinessCaseId": { + "post": { + "tags": [ + "OriginsBusinessCases" + ], + "operationId": "ListOriginsBusinessCaseByBusinessCaseId", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOriginsBusinessCaseByBusinessCaseIdRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListOriginsBusinessCaseByBusinessCaseIdRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ListOriginsBusinessCaseByBusinessCaseIdRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ListOriginsBusinessCaseByBusinessCaseIdViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOriginsBusinessCaseByBusinessCaseIdViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListOriginsBusinessCaseByBusinessCaseIdViewModel" + } + } + } + } + } + } + }, + "/api/origins-business-cases/CreateOriginBusinessCase": { + "post": { + "tags": [ + "OriginsBusinessCases" + ], + "operationId": "CreateOriginBusinessCase", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateOriginBusinessCaseRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateOriginBusinessCaseRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateOriginBusinessCaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/CreateOriginBusinessCaseResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateOriginBusinessCaseResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateOriginBusinessCaseResponse" + } + } + } + } + } + } + }, + "/api/oscs/{oscId}": { + "put": { + "tags": [ + "Oscs" + ], + "operationId": "UpdateOsc", + "parameters": [ + { + "name": "oscId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOscRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOscRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UpdateOscRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UpdateOscResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOscResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateOscResponse" + } + } + } + } + } + }, + "get": { + "tags": [ + "Oscs" + ], + "operationId": "GetOsc", + "parameters": [ + { + "name": "oscId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/GetOscResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetOscResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/GetOscResponse" + } + } + } + } + } + } + }, + "/api/osc/ListOsc": { + "post": { + "tags": [ + "Oscs" + ], + "operationId": "ListOsc", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOscRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListOscRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ListOscRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ListOscViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListOscViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListOscViewModel" + } + } + } + } + } + } + }, + "/api/osc/{oscId}": { + "delete": { + "tags": [ + "Oscs" + ], + "operationId": "DeleteOsc", + "parameters": [ + { + "name": "oscId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/osc/CreateOsc": { + "post": { + "tags": [ + "Oscs" + ], + "operationId": "CreateOsc", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateOscRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateOscRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateOscRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/CreateOscResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateOscResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateOscResponse" + } + } + } + } + } + } + }, + "/api/teams/search": { + "post": { + "tags": [ + "Teams" + ], + "operationId": "ListTeam", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListTeamRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListTeamRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ListTeamRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ListTeamViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListTeamViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListTeamViewModel" + } + } + } + } + } + } + }, + "/api/teams/{teamId}": { + "get": { + "tags": [ + "Teams" + ], + "operationId": "GetTeamById", + "parameters": [ + { + "name": "teamId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/GetTeamByIdResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetTeamByIdResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/GetTeamByIdResponse" + } + } + } + } + } + }, + "put": { + "tags": [ + "Teams" + ], + "operationId": "EditTeam", + "parameters": [ + { + "name": "teamId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EditTeamRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/EditTeamRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/EditTeamRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/EditTeamResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/EditTeamResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/EditTeamResponse" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Teams" + ], + "operationId": "DeleteTeam", + "parameters": [ + { + "name": "teamId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/DeleteTeamResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteTeamResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/DeleteTeamResponse" + } + } + } + } + } + } + }, + "/api/teams/CreateTeam": { + "post": { + "tags": [ + "Teams" + ], + "operationId": "CreateTeam", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTeamRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateTeamRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateTeamRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/CreateTeamResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTeamResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateTeamResponse" + } + } + } + } + } + } + }, + "/api/users/{userId}": { + "put": { + "tags": [ + "Users" + ], + "operationId": "UpdateUser", + "parameters": [ + { + "name": "userId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateUserRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateUserRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/UpdateUserRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UpdateUserResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateUserResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UpdateUserResponse" + } + } + } + } + } + }, + "get": { + "tags": [ + "Users" + ], + "operationId": "GetUserById", + "parameters": [ + { + "name": "userId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/UserViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/UserViewModel" + } + } + } + }, + "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" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ProblemDetails" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Users" + ], + "operationId": "DeleteUser", + "parameters": [ + { + "name": "userId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/api/users/ListUser": { + "post": { + "tags": [ + "Users" + ], + "operationId": "ListUser", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListUserRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListUserRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/ListUserRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/ListUserViewModel" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListUserViewModel" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/ListUserViewModel" + } + } + } + } + } + } + }, + "/api/users/CreateUser": { + "post": { + "tags": [ + "Users" + ], + "operationId": "CreateUser", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateUserRequest" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateUserRequest" + } + }, + "application/*+json": { + "schema": { + "$ref": "#/components/schemas/CreateUserRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "$ref": "#/components/schemas/CreateUserResponse" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateUserResponse" + } + }, + "text/json": { + "schema": { + "$ref": "#/components/schemas/CreateUserResponse" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "BeneficiaryViewModel": { + "type": "object", + "properties": { + "beneficiaryId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "oscsCount": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "BusinessCaseViewModel": { + "type": "object", + "properties": { + "businessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "originsBusinessCases": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CourseViewModel": { + "type": "object", + "properties": { + "courseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + }, + "teamsCount": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateBeneficiaryRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "notes": { + "type": "string" + } + }, + "additionalProperties": false + }, + "CreateBeneficiaryResponse": { + "type": "object", + "properties": { + "beneficiaryId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateBusinessCaseRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "originsBusinessCasesIds": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + }, + "additionalProperties": false + }, + "CreateBusinessCaseResponse": { + "type": "object", + "properties": { + "businessCaseId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateCompanyCommand": { + "type": "object", + "properties": { + "cnpj": { + "type": "string" + }, + "companyName": { + "type": "string" + }, + "corporateReason": { + "type": "string", + "nullable": true + }, + "fieldOfActivity": { + "type": "string", + "nullable": true + }, + "zipCode": { + "type": "string", + "nullable": true + }, + "address": { + "type": "string", + "nullable": true + }, + "neighborhood": { + "type": "string", + "nullable": true + }, + "city": { + "type": "string", + "nullable": true + }, + "state": { + "type": "string", + "nullable": true + }, + "phoneNumber": { + "type": "string", + "nullable": true + }, + "website": { + "type": "string", + "nullable": true + }, + "socialMedia": { + "type": "string", + "nullable": true + }, + "isActive": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "CreateCourseRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "CreateCourseResponse": { + "type": "object", + "properties": { + "courseId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateDonationCommand": { + "type": "object", + "properties": { + "value": { + "type": "number", + "format": "double" + }, + "donationDate": { + "type": "string", + "format": "date-time" + }, + "personId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "companyId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "oscId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "teamId": { + "type": "integer", + "format": "int32", + "nullable": true + } + }, + "additionalProperties": false + }, + "CreateOriginBusinessCaseRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "businessCaseId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateOriginBusinessCaseResponse": { + "type": "object", + "properties": { + "originBusinessCaseId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateOscRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "objective": { + "type": "string" + }, + "corporateName": { + "type": "string" + }, + "address": { + "type": "string" + }, + "neighborhood": { + "type": "string" + }, + "city": { + "type": "string" + }, + "state": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "email": { + "type": "string" + }, + "webUrl": { + "type": "string" + }, + "socialMedia": { + "type": "string" + }, + "zipCode": { + "type": "string" + }, + "oscPrimaryDocumment": { + "type": "string", + "nullable": true + }, + "beneficiariesIds": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + }, + "originsBusinessCasesIds": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + }, + "additionalProperties": false + }, + "CreateOscResponse": { + "type": "object", + "properties": { + "oscId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateTeamRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true + }, + "lessonTime": { + "type": "string", + "nullable": true + }, + "start": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "finish": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "personTeamsIds": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + }, + "projectProgramId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "courseId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateTeamResponse": { + "type": "object", + "properties": { + "teamId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "CreateUserRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "email": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "role": { + "type": "string" + } + }, + "additionalProperties": false + }, + "CreateUserResponse": { + "type": "object", + "properties": { + "userId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "DeleteCourseResponse": { + "type": "object", + "properties": { + "courseId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "DeleteTeamResponse": { + "type": "object", + "properties": { + "teamId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "EditCourseRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "EditCourseResponse": { + "type": "object", + "properties": { + "courseId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "EditTeamRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true + }, + "lessonTime": { + "type": "string", + "nullable": true + }, + "start": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "finish": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "personTeamsIds": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + }, + "nullable": true + }, + "projectProgramId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "courseId": { + "type": "integer", + "format": "int32", + "nullable": true + } + }, + "additionalProperties": false + }, + "EditTeamResponse": { + "type": "object", + "properties": { + "teamId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "Filter": { + "type": "object", + "properties": { + "propertyName": { + "type": "string" + }, + "operation": { + "$ref": "#/components/schemas/Op" + }, + "value": { } + }, + "additionalProperties": false + }, + "ForgotPasswordRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + } + }, + "additionalProperties": false + }, + "ForgotPasswordResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "GetBeneficiaryOscResponse": { + "type": "object", + "properties": { + "oscId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "corporateName": { + "type": "string" + } + }, + "additionalProperties": false + }, + "GetBeneficiaryResponse": { + "type": "object", + "properties": { + "beneficiaryId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "oscs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GetBeneficiaryOscResponse" + } + } + }, + "additionalProperties": false + }, + "GetBusinessCaseOriginResponse": { + "type": "object", + "properties": { + "originBusinessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "GetBusinessCaseResponse": { + "type": "object", + "properties": { + "businessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "origins": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GetBusinessCaseOriginResponse" + } + } + }, + "additionalProperties": false + }, + "GetCourseByIdViewModel": { + "type": "object", + "properties": { + "courseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + }, + "isDeleted": { + "type": "boolean" + }, + "teamsCount": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "createdBy": { + "type": "integer", + "format": "int32" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedBy": { + "type": "integer", + "format": "int32" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "teams": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TeamViewModel" + } + } + }, + "additionalProperties": false + }, + "GetOriginBusinessCaseOscResponse": { + "type": "object", + "properties": { + "oscId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + } + }, + "additionalProperties": false + }, + "GetOriginBusinessCaseResponse": { + "type": "object", + "properties": { + "originBusinessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "oscs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GetOriginBusinessCaseOscResponse" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "GetOscBeneficiaryResponse": { + "type": "object", + "properties": { + "beneficiaryId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "GetOscOriginBusinessCaseResponse": { + "type": "object", + "properties": { + "originBusinessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "GetOscResponse": { + "type": "object", + "properties": { + "oscId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "corporateName": { + "type": "string" + }, + "objective": { + "type": "string" + }, + "address": { + "type": "string" + }, + "neighborhood": { + "type": "string" + }, + "city": { + "type": "string" + }, + "state": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "email": { + "type": "string" + }, + "webUrl": { + "type": "string" + }, + "socialMedia": { + "type": "string" + }, + "zipCode": { + "type": "string" + }, + "oscPrimaryDocumment": { + "type": "string", + "nullable": true + }, + "beneficiaries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GetOscBeneficiaryResponse" + } + }, + "originsBusinessCases": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GetOscOriginBusinessCaseResponse" + } + } + }, + "additionalProperties": false + }, + "GetTeamByIdResponse": { + "type": "object", + "properties": { + "teamId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + }, + "lessonTime": { + "type": "string", + "nullable": true + }, + "start": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "finish": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "courseId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "courseName": { + "type": "string", + "nullable": true + }, + "projectProgramId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "projectProgramName": { + "type": "string", + "nullable": true + }, + "personTeamsCount": { + "type": "integer", + "format": "int32" + }, + "isDeleted": { + "type": "boolean" + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "ListBeneficiaryRequest": { + "type": "object", + "properties": { + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "filters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Filter" + } + } + }, + "additionalProperties": false + }, + "ListBeneficiaryViewModel": { + "type": "object", + "properties": { + "totalItems": { + "type": "integer", + "format": "int32" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BeneficiaryViewModel" + } + } + }, + "additionalProperties": false + }, + "ListBusinessCaseRequest": { + "type": "object", + "properties": { + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "filters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Filter" + } + } + }, + "additionalProperties": false + }, + "ListBusinessCaseViewModel": { + "type": "object", + "properties": { + "totalItems": { + "type": "integer", + "format": "int32" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BusinessCaseViewModel" + } + } + }, + "additionalProperties": false + }, + "ListCourseRequest": { + "type": "object", + "properties": { + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "filters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Filter" + } + } + }, + "additionalProperties": false + }, + "ListCourseViewModel": { + "type": "object", + "properties": { + "totalItems": { + "type": "integer", + "format": "int32" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CourseViewModel" + } + } + }, + "additionalProperties": false + }, + "ListOriginBusinessCaseRequest": { + "type": "object", + "properties": { + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "filters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Filter" + } + } + }, + "additionalProperties": false + }, + "ListOriginBusinessCaseViewModel": { + "type": "object", + "properties": { + "totalItems": { + "type": "integer", + "format": "int32" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OriginBusinessCaseViewModel" + } + } + }, + "additionalProperties": false + }, + "ListOriginsBusinessCaseByBusinessCaseIdRequest": { + "type": "object", + "properties": { + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "filters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Filter" + } + }, + "businessCaseId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "ListOriginsBusinessCaseByBusinessCaseIdViewModel": { + "type": "object", + "properties": { + "totalItems": { + "type": "integer", + "format": "int32" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OriginBusinessCaseByBusinessCaseIdViewModel" + } + } + }, + "additionalProperties": false + }, + "ListOscRequest": { + "type": "object", + "properties": { + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "filters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Filter" + } + } + }, + "additionalProperties": false + }, + "ListOscViewModel": { + "type": "object", + "properties": { + "totalItems": { + "type": "integer", + "format": "int32" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OscViewModel" + } + } + }, + "additionalProperties": false + }, + "ListTeamItemViewModel": { + "type": "object", + "properties": { + "teamId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + }, + "lessonTime": { + "type": "string", + "nullable": true + }, + "start": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "finish": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "projectProgramId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "projectProgramName": { + "type": "string", + "nullable": true + }, + "courseId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "courseName": { + "type": "string", + "nullable": true + }, + "personTeamsCount": { + "type": "integer", + "format": "int32" + }, + "isDeleted": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "ListTeamRequest": { + "type": "object", + "properties": { + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "filters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Filter" + } + } + }, + "additionalProperties": false + }, + "ListTeamViewModel": { + "type": "object", + "properties": { + "totalItems": { + "type": "integer", + "format": "int32" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ListTeamItemViewModel" + } + } + }, + "additionalProperties": false + }, + "ListUserRequest": { + "type": "object", + "properties": { + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "filters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Filter" + } + } + }, + "additionalProperties": false + }, + "ListUserViewModel": { + "type": "object", + "properties": { + "totalItems": { + "type": "integer", + "format": "int32" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserViewModel" + } + } + }, + "additionalProperties": false + }, + "LoginResponse": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "expiresIn": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false + }, + "Op": { + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ], + "type": "integer", + "format": "int32" + }, + "OriginBusinessCaseByBusinessCaseIdViewModel": { + "type": "object", + "properties": { + "originBusinessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "businessCaseId": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "OriginBusinessCaseViewModel": { + "type": "object", + "properties": { + "originBusinessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + } + }, + "additionalProperties": false + }, + "OscViewModel": { + "type": "object", + "properties": { + "oscId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "objective": { + "type": "string" + }, + "corporateName": { + "type": "string" + }, + "address": { + "type": "string" + }, + "neighborhood": { + "type": "string" + }, + "city": { + "type": "string" + }, + "state": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "email": { + "type": "string" + }, + "webUrl": { + "type": "string" + }, + "socialMedia": { + "type": "string" + }, + "zipCode": { + "type": "string" + }, + "oscPrimaryDocumment": { + "type": "string" + }, + "beneficiariesCount": { + "type": "integer", + "format": "int32" + } + }, + "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": { } + }, + "ResetPasswordRequest": { + "type": "object", + "properties": { + "userId": { + "type": "integer", + "format": "int32" + }, + "token": { + "type": "string" + }, + "newPassword": { + "type": "string" + } + }, + "additionalProperties": false + }, + "ResetPasswordResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "TeamViewModel": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + }, + "lessonTime": { + "type": "string", + "nullable": true + }, + "start": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "finish": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateBeneficiaryInOscResponse": { + "type": "object", + "properties": { + "beneficiaryId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateBeneficiaryRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "notes": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UpdateBeneficiaryResponse": { + "type": "object", + "properties": { + "beneficiaryId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UpdateBusinessCaseRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true + }, + "originsBusinessCasesIds": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + }, + "additionalProperties": false + }, + "UpdateBusinessCaseResponse": { + "type": "object", + "properties": { + "businessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "originsBusinessCases": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UpdateOriginBusinessCaseInBusinessCaseResponse" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateCompanyCommand": { + "type": "object", + "properties": { + "cnpj": { + "type": "string" + }, + "companyName": { + "type": "string" + }, + "corporateReason": { + "type": "string", + "nullable": true + }, + "fieldOfActivity": { + "type": "string", + "nullable": true + }, + "zipCode": { + "type": "string", + "nullable": true + }, + "address": { + "type": "string", + "nullable": true + }, + "neighborhood": { + "type": "string", + "nullable": true + }, + "city": { + "type": "string", + "nullable": true + }, + "state": { + "type": "string", + "nullable": true + }, + "phoneNumber": { + "type": "string", + "nullable": true + }, + "website": { + "type": "string", + "nullable": true + }, + "socialMedia": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateDonationCommand": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "value": { + "type": "number", + "format": "double" + }, + "donationDate": { + "type": "string", + "format": "date-time" + }, + "oscId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "teamId": { + "type": "integer", + "format": "int32", + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateOriginBusinessCaseInBusinessCaseResponse": { + "type": "object", + "properties": { + "originBusinessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UpdateOriginBusinessCaseInOscResponse": { + "type": "object", + "properties": { + "originBusinessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateOriginBusinessCaseRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "notes": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UpdateOriginBusinessCaseResponse": { + "type": "object", + "properties": { + "originBusinessCaseId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "notes": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UpdateOscRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true + }, + "corporateName": { + "type": "string", + "nullable": true + }, + "objective": { + "type": "string", + "nullable": true + }, + "address": { + "type": "string", + "nullable": true + }, + "zipCode": { + "type": "string", + "nullable": true + }, + "oscPrimaryDocumment": { + "type": "string", + "nullable": true + }, + "beneficiaryIds": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + }, + "nullable": true + }, + "originBusinessCaseIds": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateOscResponse": { + "type": "object", + "properties": { + "oscId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "corporateName": { + "type": "string" + }, + "objective": { + "type": "string" + }, + "address": { + "type": "string" + }, + "zipCode": { + "type": "string" + }, + "oscPrimaryDocumment": { + "type": "string", + "nullable": true + }, + "beneficiaries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UpdateBeneficiaryInOscResponse" + }, + "nullable": true + }, + "originsBusinessCases": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UpdateOriginBusinessCaseInOscResponse" + }, + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateUserRequest": { + "type": "object", + "properties": { + "userId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "nullable": true + }, + "password": { + "type": "string", + "nullable": true + }, + "email": { + "type": "string", + "nullable": true + }, + "phoneNumber": { + "type": "string", + "nullable": true + }, + "isActive": { + "type": "boolean" + }, + "role": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "UpdateUserResponse": { + "type": "object", + "properties": { + "userId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "role": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UserLogin": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UserToken": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "expiresIn": { + "type": "string", + "format": "date-time" + }, + "refresfToken": { + "type": "string" + } + }, + "additionalProperties": false + }, + "UserViewModel": { + "type": "object", + "properties": { + "userId": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "isActive": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "securitySchemes": { + "Bearer": { + "type": "http", + "description": "Informe: Bearer {seu_token}", + "scheme": "bearer", + "bearerFormat": "JWT" + } + } + }, + "security": [ + { + "Bearer": [ ] + } + ] +} \ No newline at end of file diff --git a/codigo-fonte/frontend/tsconfig.app.json b/codigo-fonte/frontend/tsconfig.app.json new file mode 100644 index 00000000..227a6c67 --- /dev/null +++ b/codigo-fonte/frontend/tsconfig.app.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/codigo-fonte/frontend/tsconfig.json b/codigo-fonte/frontend/tsconfig.json new file mode 100644 index 00000000..1eb5967f --- /dev/null +++ b/codigo-fonte/frontend/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "moduleResolution": "Bundler", + "jsx": "react-jsx", + "strict": true, + "noImplicitAny": false, + "skipLibCheck": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "paths": { "@/*": ["src/*"] }, + "noEmit": true + }, + "include": ["src"] +} \ No newline at end of file diff --git a/codigo-fonte/frontend/tsconfig.node.json b/codigo-fonte/frontend/tsconfig.node.json new file mode 100644 index 00000000..f85a3990 --- /dev/null +++ b/codigo-fonte/frontend/tsconfig.node.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/codigo-fonte/frontend/vite.config.ts b/codigo-fonte/frontend/vite.config.ts new file mode 100644 index 00000000..17e2d14b --- /dev/null +++ b/codigo-fonte/frontend/vite.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import path from "path"; + +export default defineConfig({ + plugins: [react()], + resolve: { + alias: { "@": path.resolve(__dirname, "src") } + }, + server: { + port: 3000 + } +}); diff --git a/codigo-fonte/package-lock.json b/codigo-fonte/package-lock.json new file mode 100644 index 00000000..5d2b6b00 --- /dev/null +++ b/codigo-fonte/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "codigo-fonte", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git "a/documentos/01-Documenta\303\247\303\243o de Contexto.md" "b/documentos/01-Documenta\303\247\303\243o de Contexto.md" index c2514737..a02773ea 100644 --- "a/documentos/01-Documenta\303\247\303\243o de Contexto.md" +++ "b/documentos/01-Documenta\303\247\303\243o de Contexto.md" @@ -1,31 +1,52 @@ # Introdução -Texto descritivo apresentando a compreensão sobre extensão universitária discutido no microfundamento de nivelamento, relacionando a situação-problema da organização e ao sistema sociotécnico que será desenvolvido e implantado. +A proposta deste projeto parte da compreensão de extensão universitária como prática acadêmica que articula ensino, pesquisa e compromisso social por meio de intervenções cocriadas com a comunidade. No microfundamento de nivelamento, discutimos a extensão como um processo dialógico e formativo, no qual estudantes e parceiros constroem conhecimento aplicável a problemas reais, fortalecendo capacidades institucionais e cidadãs. + +Nesse espírito, o projeto IGESC Conecta será concebido como um sistema sociotécnico: não é apenas software, mas a integração de tecnologia, pessoas, papéis, dados e processos. A solução busca modernizar a gestão interna do Instituto GESC, substituindo o uso intensivo de planilhas por uma plataforma integrada que centralize informações e organize fluxos de trabalho, ampliando controle, rastreabilidade e acessibilidade aos dados, com foco na sustentabilidade do uso no dia a dia da equipe. ## Problema -Nesse momento o grupo deve apresentar a situação-problema (dor/oportunidade) do parceiro onde será desenvolvido sistema sociotécnico. +Com base nas conversas iniciais e na leitura do cenário, o grupo identifica eixos de atenção que orientam a situação-problema a ser enfrentada. São eles: dispersão de informações, continuidade do legado, rastreabilidade, análises/consolidações e permissões/acesso. -> **Links Úteis**: -> - [Objetivos, Problema de pesquisa e Justificativa](https://medium.com/@versioparole/objetivos-problema-de-pesquisa-e-justificativa-c98c8233b9c3) -> - [Matriz Certezas, Suposições e Dúvidas](https://medium.com/educa%C3%A7%C3%A3o-fora-da-caixa/matriz-certezas-suposi%C3%A7%C3%B5es-e-d%C3%BAvidas-fa2263633655) -> - [Brainstorming](https://www.euax.com.br/2018/09/brainstorming/) +Além disso, há um ponto já reconhecido pelo parceiro: existe um histórico relevante de dados legados e é necessária uma ferramenta de importação (por arquivo CSV) para garantir autonomia, sem depender de terceiros na carga inicial ou em cargas de atualização. ## Objetivos -Aqui o grupo deve descrever os objetivos do trabalho indicando que o objetivo é aplicar os conceitos de extensão universitária no desenvolvimento de um sistema sociotécnico que impacte positivamente a comunidade. +### Objetivo geral +Aplicar os conceitos de extensão universitária no desenvolvimento e implantação de um sistema sociotécnico que modernize a gestão interna do IGESC e impacte positivamente sua rede de relacionamento (OSCs, turmas, pessoas e empresas). + +### Objetivos específicos + +* Centralizar cadastros e vínculos hoje dispersos (OSCs, pessoas e seus papéis, programas/turmas, projetos, empresas, doações). + +* Estruturar processos de registro, atualização e consulta com controle de acesso e auditoria. + +* Facilitar análises por meio de consultas e planilhas (Excel), além de painéis definidos pelo IGESC. + +* Viabilizar importação de dados via CSV para aproveitar o legado informacional com autonomia. + +* Promover apropriação da solução pela equipe do IGESC, com documentação e capacitação para uso contínuo. ## Justificativa -Descreva as dores/dificuldades do parceiro que motivam trabalhar na construção da solução. +A construção do IGESC Conecta se justifica por: + +* Organização e confiabilidade: reduzir a dispersão em planilhas e explicitar vínculos complexos (pessoas com múltiplos papéis por turma; projetos vinculados a turma e OSC; representantes de empresa). + +* Memória institucional: incorporar o legado de dados de forma segura, padronizada e autônoma (importação CSV). -> **Links Úteis**: -> - [Como montar a justificativa](https://guiadamonografia.com.br/como-montar-justificativa-do-tcc/) +* Rastreabilidade e governança: registrar quem criou/alterou e quando, além de aplicar perfis de acesso compatíveis com a rotina do instituto. + +* Agilidade de análise: gerar planilhas e painéis para apoiar decisões, transparência e prestação de contas. + +* Sustentabilidade: diminuir retrabalhos, dependência de pessoas-chave e riscos de inconsistência. ## Relação com a Extensão Universitária -Relacionar a situação-problema da organização com o impacto social esperado com a implantação do sistema sociotécnico. -Apresentar aqui como este projeto extensionista transforma a realidade do parceiro e dos alunos. +O projeto promove aprendizagem significativa aos estudantes (levantamento e modelagem de requisitos, desenho sociotécnico, implementação fullstack, documentação, implantação) e fortalecimento institucional ao parceiro (processos claros, dados confiáveis, capacidade analítica). A interação continuada escuta, prototipação, validação e ajustes materializa a extensão como via de mão dupla, transformando a prática acadêmica e a realidade do parceiro. + +O impacto social esperado decorre de uma gestão mais eficiente e transparente: com informações estruturadas, o IGESC tende a qualificar o apoio às OSCs, ampliar a capacidade de monitorar resultados das turmas e projetos e facilitar parcerias com empresas, fortalecendo a rede de colaboração que sustenta ações de interesse público. ## Descrição do Parceiro -Apresente uma descrição resumida sobre a organização onde o projeto será desenvolvido para que possa ser compreendido o cenário do sistema sociotécnico. +O Instituto GESC (IGESC) surgiu em 2004 em vínculo com a Faculdade FIA de Administração e Negócios, atuando como ponte entre o mundo corporativo e a sociedade civil. Combina referências acadêmicas com práticas de gestão aplicadas a Organizações da Sociedade Civil (OSCs) de diferentes portes e causas. Sua atuação se organiza por programas e turmas, envolvendo participantes, consultores sociais, professores e coordenadores, e conta com empresas parceiras em iniciativas de apoio. +Atualmente, o IGESC busca modernizar sua gestão interna por meio de um sistema integrado que substitua planilhas, estruture vínculos entre entidades (pessoas, OSCs, turmas, projetos, empresas) e simplifique análises via planilhas e painéis, incluindo uma estratégia de importação CSV para aproveitar o histórico legado com autonomia. diff --git "a/documentos/02-Especifica\303\247\303\243o do Projeto.md" "b/documentos/02-Especifica\303\247\303\243o do Projeto.md" index 48bfa85f..25d28308 100644 --- "a/documentos/02-Especifica\303\247\303\243o do Projeto.md" +++ "b/documentos/02-Especifica\303\247\303\243o do Projeto.md" @@ -2,67 +2,89 @@ Pré-requisitos: Documentação de Contexto -Definição do problema e ideia de solução a partir da perspectiva do usuário. +### Definição do problema e ideia de solução a partir da perspectiva do usuário. + +Pessoas do IGESC precisam sair do mosaico de planilhas e trabalhar em uma plataforma única que centralize dados de OSCs, Programas/Turmas, Pessoas (com papéis contextuais), Projetos, Empresas e Doações. +A solução proposta (IGESC Conecta) organiza cadastros, vínculos e documentos PDF dos Projetos, permitindo consultas com exportação para Excel, painéis definidos pelo IGESC e importação via CSV para incorporar o legado, com perfis de acesso e auditoria mínimos. ## Usuários -| Tipo de Usuário | Descrição | Responsabilidades | + +| Tipo de Usuário | Descrição | Responsabilidades | |------------------|-----------|------------------| -| **xxx** | xxxxx | xxxxx | +| **Administrador (IGESC)** | Governança da aplicação. | Gerenciar usuários e perfis; configurar painéis; manter catálogos (Causas, Públicos, Temas de Projeto); supervisionar auditoria; executar importações CSV; administrar OSCs, Programas/Turmas, Pessoas, Projetos (1–5 PDFs), Empresas e Doações; gerar planilhas Excel. | +| Editor (IGESC) | Operação diária de cadastros e fluxos. | Criar/editar/excluir OSCs, Programas/Turmas, Pessoas (papéis em Turmas; representantes de Empresa/OSC), Projetos (anexar 1–5 PDFs), Empresas e Doações; gerar planilhas Excel; visualizar painéis; não executa importação CSV; não gerencia usuários/perfis. | +| Consulta (IGESC) | Acesso somente leitura. | Consultar dados; visualizar painéis; gerar planilhas Excel; sem criar/editar/excluir; sem importação CSV. | -### Exemplo +## Arquitetura e Tecnologias -| Tipo de Usuário | Descrição | Responsabilidades | -|------------------|-----------|------------------| -| **Administrador** | Gerencia a aplicação e os usuários. | Gerenciar usuários, configurar o sistema, acessar todos os relatórios. | -| **Funcionário** | Usa a aplicação para suas tarefas principais. | Criar e editar registros, visualizar relatórios. | +A solução IGESC Conecta tem três camadas principais: Frontend Web, API Backend e Banco de Dados. +A API expõe REST via HTTPS, com JWT e RBAC por perfil. Faz importação por CSV, exportação em Excel e armazenamento de PDFs no banco. +![Arquitetura da Solução](img/arquitetura.jpeg) -## Arquitetura e Tecnologias +### Tecnologias -Descreva brevemente a arquitetura definida para o projeto e as tecnologias a serem utilizadas. Sugere-se a criação de um diagrama de componentes da solução. +* Frontend: React + TypeScript (SPA, roteamento, fetch), acessibilidade ARIA. -## Project Model Canvas +* API/Backend: ASP.NET Core Web API, Entity Framework Core, FluentValidation, AutoMapper, Swagger. + +* Segurança: ASP.NET Identity (ou equivalente) + JWT; RBAC por perfil; CORS e TLS. -Deve ser desenvolvido a partir do microfundamento: Empreendedorismo e inovação. -Colocar a imagem do modelo construído apresentando a proposta de solução. +* Exportação: planilhas Excel (ClosedXML ou EPPlus). -> **Links Úteis**: -> Disponíveis em material de apoio do projeto +* Importação: CSV (CsvHelper) com validações. + +* Banco: SQL Server (modelo relacional; PDFs em VARBINARY MAX). + +## Project Model Canvas + +![Project Model Canva](https://github.com/ICEI-PUC-Minas-PMV-ADS/pmv-ads-2025-2-e5-proj-empext-t1-pmv-ads-2025-2-e5-projigescconecta/blob/felipe/documentos/img/PMC%20-%20Igesc.png) ## Requisitos As tabelas que se seguem apresentam os requisitos funcionais e não funcionais que detalham o escopo do projeto. Para determinar a prioridade de requisitos, aplicar uma técnica de priorização de requisitos e detalhar como a técnica foi aplicada. -Para mais informações, consulte os microfundamentos Fundamentos de Engenharia de Software e Engenharia de Requisitos de Software. +Técnica de priorização aplicada: MoSCoW, mapeada para ALTA (MUST), MÉDIA (SHOULD) e BAIXA (COULD), considerando valor para o IGESC, dependências técnicas e obrigações de segurança/compliance. ### Requisitos Funcionais |ID | Descrição do Requisito | Prioridade | |------|-----------------------------------------|----| -|RF-001| Permitir que o usuário cadastre tarefas | ALTA | -|RF-002| Emitir um relatório de tarefas no mês | MÉDIA | +|RF-001| Manter OSCs (inclui referência a Causa, Público e campo Volume de Público atendido) | ALTA | +|RF-002| Manter Pessoas (CPF como chave; papéis contextuais à Turma, Empresa e OSC) | ALTA | +|RF-003| Manter Programas | ALTA | +|RF-004| Manter Turmas (filha de Programa) | ALTA | +|RF-005| Manter Projetos (vinculada a Turma e OSC; ODS como atributo; armazenar 1-5 PDFs) | ALTA | +|RF-006| Manter Temas de Projeto (relacionado a Projetos) | ALTA | +|RF-007| Manter Causas (relacionado à OSC) | ALTA | +|RF-008| Manter Públicos (relacionado à OSC) | ALTA | +|RF-009| Manter Empresas | ALTA | +|RF-010| Manter Usuários (perfis: Administrador, Editor, Consulta) | ALTA | +|RF-011| Manter Doações (doador = Pessoa ou Empresa; data, valor; destino = Turma/OSC/nenhum) | MÉDIA | +|RF-012| Anexar documentos PDFs (1-5) dentro de Projeto, com download/abertura em aba do navegador | MÉDIA | +|RF-013| Geração de planilhas Excel a partir de consultas (modelo a definir na especificação técnica) | MÉDIA | +|RF-014| Importar dados via CSV (modelo a definir na especificação técnica) | MÉDIA | +|RF-015| Controle de acesso por perfil (somente usuários do IGESC operam o sistema) | ALTA | +|RF-016| Auditoria mínima (registrar quem criou/alterou) | BAIXA | +|RF-017| Painel de Dashboards definidos pelo IGESC | MÉDIA | +|RF-018| O site deve permitir que usuários realizem login utilizando e-mail e senha. | ALTA | ### Requisitos não Funcionais |ID | Descrição do Requisito |Prioridade | |-------|-------------------------|----| -|RNF-001| O sistema deve ser responsivo para rodar em um dispositivos móvel | MÉDIA | -|RNF-002| Deve processar requisições do usuário em no máximo 3s | BAIXA | - -Com base nas Histórias de Usuário, enumere os requisitos da sua solução. Classifique esses requisitos em dois grupos: - -- [Requisitos Funcionais - (RF)](https://pt.wikipedia.org/wiki/Requisito_funcional): - correspondem a uma funcionalidade que deve estar presente na - plataforma (ex: cadastro de usuário). -- [Requisitos Não Funcionais - (RNF)](https://pt.wikipedia.org/wiki/Requisito_n%C3%A3o_funcional): - correspondem a uma característica técnica, seja de usabilidade, - desempenho, confiabilidade, segurança ou outro (ex: suporte a - dispositivos iOS e Android). -Lembre-se que cada requisito deve corresponder à uma e somente uma -característica alvo da sua solução. Além disso, certifique-se de que -todos os aspectos capturados nas Histórias de Usuário foram cobertos. +|RNF-001| Frontend web responsivo e utilizável em resoluções >= 1366x768 (suporte básico em mobile) | MÉDIA | +|RNF-002| Desempenho de leitura: respostas em até ~2s para consultas típicas; exportação Excel sem travar a interface | MÉDIA | +|RNF-003| Segurança: autenticação JWT e autorização por perfil (RBAC) em todas as rotas protegidas | ALTA | +|RNF-004| LGPD: proteção de dados pessoais, mínimo necessário, perfis de acesso, registro de operações | ALTA | +|RNF-005| Compatibilidade: navegadores Chrome/Edge versões suportadas pelo LTS | MÉDIA | +|RNF-006| Documentação da API via Swagger/OpenAPI | BAIXA | +|RNF-007| Integridade de arquivo: aceitar apenas PDFs nos anexos de Projeto; validar tipo MIME e tamanho (limite a definir) | ALTA | +|RNF-008| Persistência dos PDFs no banco (VARBINARY) com checagem de integridade (hash) | MÉDIA | +|RNF-009| Logs de aplicação no backend com correlação de requisições | MÉDIA | +|RNF-010| Migrações de banco versionadas (EF Core Migrations) | MÉDIA | +|RNF-011| Tratamento de erros padronizado na API (códigos/contratos de erro) | MÉDIA | +|RNF-012| CORS e TLS habilitados no acesso ao backend | ALTA | ## Restrições @@ -70,33 +92,38 @@ O projeto está restrito pelos itens apresentados na tabela a seguir. |ID| Restrição | |--|-------------------------------------------------------| -|01| O projeto deverá ser entregue até o final do semestre | -|02| Não pode ser desenvolvido um módulo de backend | +|01| Apenas usuários do IGESC operam o sistema (Admin, Editor, Consulta) | +|02| Importação exclusivamente via arquivos CSV (sem XLSX) | +|03| Relatórios exclusivamente como planilhas Excel (sem PDFs/BI externos nesta fase) | +|04| ODS é lista fixa, sem CRUD; usada apenas como atributo de Projeto | +|05| Projetos sempre vinculados a Turma + OSC | +|06| Em Projeto, somente PDFs (1-5) são aceitos e armazenados no banco | +|07| Programa é um agrupamento de Turmas (Turma pertence a um único Programa) | +|08| Pessoa identificada unicamente por CPF | +|09| Empresa identificada unicamente por CNPJ | +|10| OSC possui CNPJ opcional; chave operacional por código interno mantendo CNPJ ou nome único | +|11| Papéis em Turma: a mesma pessoa pode ter múltiplos papéis na mesma Turma | +|12| Participante em Turma exige vínculo da Pessoa a uma OSC (indicar qual) | +|13| Representante de Empresa é vínculo Pessoa-Empresa; Representante da Organização é vínculo Pessoa-OSC | +|14| Tecnologias definidas: Frontend React+TypeScript, Backend ASP.NET Core (.NET 8), SQL Server | +|15| Campos detalhados de cada entidade serão definidos posteriormente pelo IGESC | -Enumere as restrições à sua solução. Lembre-se de que as restrições geralmente limitam a solução candidata. - -> **Links Úteis**: -> - [O que são Requisitos Funcionais e Requisitos Não Funcionais?](https://codificar.com.br/requisitos-funcionais-nao-funcionais/) -> - [O que são requisitos funcionais e requisitos não funcionais?](https://analisederequisitos.com.br/requisitos-funcionais-e-requisitos-nao-funcionais-o-que-sao/) ## Diagrama de Caso de Uso O diagrama de casos de uso é o próximo passo após a elicitação de requisitos, que utiliza um modelo gráfico e uma tabela com as descrições sucintas dos casos de uso e dos atores. Ele contempla a fronteira do sistema e o detalhamento dos requisitos funcionais com a indicação dos atores, casos de uso e seus relacionamentos. -Para mais informações, consulte o microfundamento Engenharia de Requisitos de Software +![Diagrama de Caso de Uso](img/CasoDeUso.png) + +## Modelo ER -As referências abaixo irão auxiliá-lo na geração do artefato “Diagrama de Casos de Uso”. +O Modelo ER (Entidade-Relacionamento) utiliza um diagrama para ilustrar de forma clara como as entidades, que representam objetos ou conceitos relevantes, se interrelacionam dentro da aplicação interativa. Este modelo facilita a visualização das conexões e interações entre os diferentes componentes do sistema, proporcionando uma compreensão abrangente da estrutura de dados subjacente. -> **Links Úteis**: -> - [Criando Casos de Uso](https://www.ibm.com/docs/pt-br/elm/6.0?topic=requirements-creating-use-cases) -> - [Como Criar Diagrama de Caso de Uso: Tutorial Passo a Passo](https://gitmind.com/pt/fazer-diagrama-de-caso-uso.html/) -> - [Lucidchart](https://www.lucidchart.com/) -> - [Astah](https://astah.net/) -> - [Diagrams](https://app.diagrams.net/) +![Modelo ER](img/MER.png) ## Projeto da Base de Dados O projeto da base de dados corresponde à representação das entidades e relacionamentos identificadas no Modelo ER, no formato de tabelas, com colunas e chaves primárias/estrangeiras necessárias para representar corretamente as restrições de integridade. - -Para mais informações, consulte o microfundamento "Modelagem de Dados". + + ![Projeto da Base de Dados](img/BaseDeDados.png) diff --git a/documentos/03-Projeto de Interface.md b/documentos/03-Projeto de Interface.md index 98cc93fb..6197a47d 100644 --- a/documentos/03-Projeto de Interface.md +++ b/documentos/03-Projeto de Interface.md @@ -4,3 +4,22 @@ Pré-requisitos: Especificação do Projeto Visão geral da interação do usuário com as funcionalidades que fazem parte do sistema sociotécnico (protótipo de telas). + +## Wireframes +### Login +![login tela](https://github.com/user-attachments/assets/29e6787a-0cc6-4c7f-bfa2-580b0464456f) + + + + +### Esqueci Senha +![esqueci senha tela](https://github.com/user-attachments/assets/e586d4f8-14bb-4f25-bcf1-65329e552a4a) + +### Inserir email associado +![esqueci senha tela](https://github.com/user-attachments/assets/4ccb6aa6-01e1-4183-807d-086c57c7706f) + +### Nova Senha +![nova senha tela](https://github.com/user-attachments/assets/5c038e6b-d21a-4fcd-845b-9d426efe4014) + + + diff --git a/documentos/04-Testes de Software.md b/documentos/04-Testes de Software.md index 47f8a725..e4057ede 100644 --- a/documentos/04-Testes de Software.md +++ b/documentos/04-Testes de Software.md @@ -6,20 +6,20 @@ Apresente os casos de testes utilizados na realização da verificação e valid - **Sucesso**: Tem o objetivo de verificar se as funcionalidades funcionam corretamente. - **Insucesso**: Tem o objetivo de verificar se o sistema trata erros de maneira correta. -#### Exemplo de Caso de Teste de Sucesso -O caso de teste de sucesso deve ser identificado por CT - xxx - S +### ETAPA 2 +
    - + - + - + @@ -27,44 +27,129 @@ O caso de teste de sucesso deve ser identificado por CT - xxx - S - + - +
    CT-001 - S
    Login com credenciais válidas
    CT-001 - S
    Teste de Login
    DescriçãoEste caso de teste verifica se um usuário pode fazer login com sucesso utilizando credenciais válidas.Este caso de teste verifica se um usuário pode fazer login com sucesso.
    Responsável Caso de Teste José da SilvaJoão Victor
    Tipo do Teste
    Requisitos associadosRF-001: O funcionário deve conseguir logar no aplicativoRF-018
    Passos - 1. Abrir o aplicativo.
    - 2. Inserir o CPF válido.
    - 3. Inserir a senha válida.
    + 1. Abrir o site.
    + 2. Inserir o Email.
    + 3. Inserir a senha.
    4. Clicar no botão "Entrar".
    Dados de teste - - CPF: Colocar CPF cadastrado na base
    + - Email: Colocar Email cadastrado
    - Senha: Colocar valor de senha válida
    Critérios de êxitoO sistema deve redirecionar o usuário para a página inicial do aplicativo após o login bem-sucedido.O sistema deve redirecionar o usuário para a página inicial do site após o login bem-sucedido.
    -#### Exemplo de Caso de Teste de Insucesso -Os casos de testes de insucesso devem ser identificados por CT - xxx - I + sequencial de insucesso. -Para cada etapa do projeto, criar uma seção com o nome da Etapa do projeto: Etapa 2, Etapa 3 e Etapa 4 -### ETAPA 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002 - S
    Teste Recuperação de Senha
    DescriçãoEste caso de teste verifica se um usuário pode redefinir sua senha.
    Responsável Caso de Teste João Victor
    Tipo do TesteSucesso
    Requisitos associadosRF-018
    Passos + 1. selecionar "esqueceu senha".
    + 2. Inserir o Email cadastrado.
    + 3. Certificar Recebimento de Email.
    + 4. Selecionar Mudar senha.
    + 5. Informar nova senha. +
    Dados de teste + - Email: Conferir recebimento de email
    + - Senha: Informar nova senha +
    Critérios de êxitoUma mensagem de confirmação deve ser exibida e o sistema deve redirecionar o usuário para a página de login.
    + +__________________________________________________________________________________________________________________________ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-001 - I01
    Login com email inexistente ou inválido
    DescriçãoEste caso de teste verifica o tratamento da tentativa de login com Email inexistente ou inválido.
    Responsável Caso de Teste João Victor
    Tipo do TesteInsucesso
    Requisitos associadosRF-018
    Passos + 1. Acessar o site.
    + 2. Inserir um Email que não foi cadastrado ou inválido.
    + 3. Inserir senha.
    + 4. Clicar no botão "Entrar". +
    Dados de teste + - Email: Colocar Email inexistente
    + - Senha: Colocar senha. +
    Critérios de êxitoO sistema deve apresentar mensagem de erro.
    + + - + - + - + @@ -72,34 +157,150 @@ Para cada etapa do projeto, criar uma seção com o nome da Etapa do projeto: Et - + + + + + +
    CT-001 - I01
    Login com credenciais inválidas
    CT-001 - I02
    Login com senha incorreta
    DescriçãoEste caso de teste verifica o tratamento de credenciais inválidas no login.Este caso de teste verifica o tratamento da tentativa de login com senha incorreta.
    Responsável Caso de Teste José da SilvaJoão Victor
    Tipo do Teste
    Requisitos associadosRF-001: O funcionário não conseguirá logar no aplicativoRF-018
    Passos - 1. Abrir o aplicativo.
    - 2. Inserir o CPF válido.
    - 3. Inserir a senha inválida.
    + 1. Acessar o site.
    + 2. Inserir um Email.
    + 3. Inserir senha incorreta.
    4. Clicar no botão "Entrar".
    Dados de teste - - CPF: Colocar CPF cadastrado na base
    - - Senha: Colocar senha inválida + - Email: Colocar Email
    + - Senha: Colocar senha incorreta. +
    Critérios de êxitoO sistema deve apresentar mensagem de erro.
    + +__________________________________________________________________________________________________________________________ + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + +
    CT-002 - I01
    Redefinir senha informando um Email não cadastrado.
    DescriçãoEste caso de teste verifica o tratamento de recuperação de senha por meio de um Email não cadastrado.
    Responsável Caso de Teste João Victor
    Tipo do TesteInsucesso
    Requisitos associadosRF-018
    Passos + 1. selecionar "esqueceu senha".
    + 2. Inserir um Email inválido.
    + 3. clicar em enviar +
    Dados de teste + - Email: Colocar Email não cadastrado
    Critérios de êxitoO sistema deve apresentar a mensagem de login inválido.O sistema não deve enviar o e-mail de redefinição.
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002 - I02
    Redefinição de senha com caracteres inválidos.
    DescriçãoEste caso de teste avalia a redefinição de senha quando os caracteres informados não atendem aos requisitos de segurança.
    Responsável Caso de Teste João Victor
    Tipo do TesteInsucesso
    Requisitos associadosRF-018
    Passos + 1. selecionar "esqueceu senha".
    + 2. Inserir uma senha que não atende aos requisitos de segurança ou que nao coincidam.
    +
    Dados de teste + - Senha: Colocar senha que não cumpra os requisitos
    +
    Critérios de êxitoO sistema instrui o usuário aos critérios de nova senha.
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002 - I03
    Redefinição de senha com token expirado.
    DescriçãoEste caso de teste avalia se o sistema impede o uso de um token expirado
    Responsável Caso de Teste João Victor
    Tipo do TesteInsucesso
    Requisitos associadosRF-018
    Passos + 1. selecionar "esqueceu senha".
    + 2. Inserir uma email.
    + 3. Acessar o link enviado por e-mail contendo o token vencido. +
    Dados de teste + - Token: selecionar link após o mesmo estar expirado
    +
    Critérios de êxitoO sistema deve apresentar mensagem de erro.
    -### ETAPA 3 -Criar casos de teste da etapa 3 -### ETAPA 4 -Criar casos de teste da etapa 4 # Evidências de Testes de Software @@ -108,11 +309,10 @@ Apresente imagens e/ou vídeos que comprovam que um determinado teste foi execut ## Parte 1 - Testes de desenvolvimento Cada funcionalidade desenvolvida deve ser testada pelo próprio desenvolvedor, utilizando casos de teste, tanto de sucesso quanto de insucesso, elaborados por ele. Todos os testes devem ser evidenciados. -### Exemplo ### ETAPA 2 - + @@ -120,9 +320,9 @@ Cada funcionalidade desenvolvida deve ser testada pelo próprio desenvolvedor, u - + - + @@ -132,37 +332,197 @@ Cada funcionalidade desenvolvida deve ser testada pelo próprio desenvolvedor, u - + + +
    CT-001
    Login com credenciais válidas
    CT-001
    Teste de Login
    Critérios de êxito
    Responsável pela funcionalidade (desenvolvimento e teste)José da Silva Desenvolvimento: Realizado em grupo
    Teste: João Victor
    Data do Teste08/05/202420/09/2025
    ComentárioEvidência
    + +Captura de tela 2025-09-20 225859 + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002
    Teste Recuperação de Senha
    Critérios de êxitoUma mensagem de confirmação deve ser exibida e o sistema deve redirecionar o usuário para a página de login.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: João Victor
    Data do Teste20/09/2025
    ComentárioEstá sendo possível a recuperação de senha.
    Evidência
    +Captura de tela 2025-09-20 232754 + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-001 - I01
    Login com email inexistente ou inválido
    Critérios de êxitoO sistema deve apresentar mensagem de erro.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: João Victor
    Data do Teste20/09/2025
    ComentárioNão é possivel fazer login com email inexistente ou inválido.
    Evidência
    +Captura de tela 2025-09-20 235820 + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-001 - I02
    Login com senha incorreta
    Critérios de êxitoO sistema deve apresentar mensagem de erro.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: João Victor
    Data do Teste20/09/2025
    ComentárioNão é possivel fazer login com senha incorreta.
    Evidência
    +Captura de tela 2025-09-20 235820 + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002 - I01
    Redefinir senha informando um Email não cadastrado
    Critérios de êxitoO sistema não deve enviar o e-mail de redefinição.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: João Victor
    Data do Teste20/09/2025
    ComentárioO Email não é encaminhado.
    Evidência
    +Captura de tela 2025-09-21 001917 + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002 - I02
    Redefinição de senha com caracteres inválidos.
    Critérios de êxitoO sistema instrui o usuário aos critérios de nova senha.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: João Victor
    Data do Teste20/09/2025
    ComentárioTodos os critérios devem ser respeitados.
    Evidência
    + +Captura de tela 2025-09-21 003646 + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002 - I03
    Redefinição de senha com token expirados.
    Critérios de êxitoO sistema deve apresentar mensagem de erro.
    Responsável pela funcionalidade (desenvolvimento e teste)João Victor Data do Teste20/09/2025
    ComentárioSerá necessário criar um novo token.
    Evidência
    -### ETAPA 3 -Colocar evidências de teste da etapa 3 -### ETAPA 4 -Colocar evidências de teste da etapa 4 + ## Parte 2 - Testes por pares A fim de aumentar a qualidade da aplicação desenvolvida, cada funcionalidade deve ser testada por um colega e os testes devem ser evidenciados. O colega "Tester" deve utilizar o caso de teste criado pelo desenvolvedor responsável pela funcionalidade (desenvolveu a funcionalidade e criou o caso de testes descrito no plano de testes) e caso perceba a necessidade de outros casos de teste, deve acrescentá-los na sessão "Plano de Testes". ### ETAPA 2 -### Exemplo - + - - - - - - + + + + @@ -172,13 +532,177 @@ A fim de aumentar a qualidade da aplicação desenvolvida, cada funcionalidade d - + + +
    CT-001
    Login com credenciais válidas
    CT-001
    Teste de Login
    Critérios de êxito O sistema deve redirecionar o usuário para a página inicial do aplicativo após o login bem-sucedido.
    Responsável pela funcionalidadeJosé da Silva Responsável pelo testeMaria Oliveira Data do teste08/05/2024Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: Lucas Bebiano
    Data do Teste21/09/2025
    ComentárioEvidência
    +image + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002
    Teste Recuperação de Senha
    Critérios de êxitoUma mensagem de confirmação deve ser exibida e o sistema deve redirecionar o usuário para a página de login.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: Lucas Bebiano
    Data do Teste21/09/2025
    ComentárioEstá sendo possível a recuperação de senha.
    Evidência
    +image -### ETAPA 3 -Colocar evidências de teste da etapa 3 -### ETAPA 4 -Colocar evidências de teste da etapa 4 + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-001 - I01
    Login com email inexistente ou inválido
    Critérios de êxitoO sistema deve apresentar mensagem de erro.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: Lucas Bebiano
    Data do Teste21/09/2025
    ComentárioNão é possivel fazer login com email inexistente ou inválido.
    Evidência
    +image + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-001 - I02
    Login com senha incorreta
    Critérios de êxitoO sistema deve apresentar mensagem de erro.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: Lucas Bebiano
    Data do Teste21/09/2025
    ComentárioNão é possivel fazer login com senha incorreta.
    Evidência
    +image + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002 - I01
    Redefinir senha informando um Email não cadastrado
    Critérios de êxitoO sistema não deve enviar o e-mail de redefinição.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: Lucas Bebiano
    Data do Teste21/09/2025
    ComentárioO Email não é encaminhado.
    Evidência
    image +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002 - I02
    Redefinição de senha com caracteres inválidos.
    Critérios de êxitoO sistema instrui o usuário aos critérios de nova senha.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: Lucas Bebiano
    Data do Teste21/09/2025
    ComentárioTodos os critérios devem ser respeitados. Valida se as senhas concidem na confirmação. Só permite o botão se tudo estiver correto.
    Evidência
    image +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CT-002 - I03
    Redefinição de senha com token expirados.
    Critérios de êxitoO sistema deve apresentar mensagem de erro.
    Responsável pela funcionalidade (desenvolvimento e teste)Desenvolvimento: Realizado em grupo
    Teste: Lucas Bebiano
    Data do Teste21/09/2025
    ComentárioApresenta mensagem de erro e não permite a alteração.
    Evidência
    image +
    diff --git a/documentos/img/BaseDeDados.png b/documentos/img/BaseDeDados.png new file mode 100644 index 00000000..6b8f55c3 Binary files /dev/null and b/documentos/img/BaseDeDados.png differ diff --git a/documentos/img/CasoDeUso.png b/documentos/img/CasoDeUso.png new file mode 100644 index 00000000..fe3e9380 Binary files /dev/null and b/documentos/img/CasoDeUso.png differ diff --git a/documentos/img/MER.png b/documentos/img/MER.png new file mode 100644 index 00000000..b0920383 Binary files /dev/null and b/documentos/img/MER.png differ diff --git a/documentos/img/PMC - Igesc.png b/documentos/img/PMC - Igesc.png new file mode 100644 index 00000000..da8a42f6 Binary files /dev/null and b/documentos/img/PMC - Igesc.png differ diff --git a/documentos/img/ProjectModelCanva.png b/documentos/img/ProjectModelCanva.png new file mode 100644 index 00000000..b99862db Binary files /dev/null and b/documentos/img/ProjectModelCanva.png differ diff --git a/documentos/img/arquitetura.jpeg b/documentos/img/arquitetura.jpeg new file mode 100644 index 00000000..93d67242 Binary files /dev/null and b/documentos/img/arquitetura.jpeg differ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..3ce84715 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "pmv-ads-2025-2-e5-proj-empext-t1-pmv-ads-2025-2-e5-projigescconecta", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}