diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/CopilotIndices/17.14.1561.44479/CodeChunks.db b/jobs/Backend/Task/.vs/ExchangeRateUpdater/CopilotIndices/17.14.1561.44479/CodeChunks.db new file mode 100644 index 0000000000..c5f5534d12 Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/CopilotIndices/17.14.1561.44479/CodeChunks.db differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/CopilotIndices/17.14.1561.44479/SemanticSymbols.db b/jobs/Backend/Task/.vs/ExchangeRateUpdater/CopilotIndices/17.14.1561.44479/SemanticSymbols.db new file mode 100644 index 0000000000..7f986412dc Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/CopilotIndices/17.14.1561.44479/SemanticSymbols.db differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/DesignTimeBuild/.dtbcache.v2 b/jobs/Backend/Task/.vs/ExchangeRateUpdater/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000000..eafba410b4 Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/DesignTimeBuild/.dtbcache.v2 differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/1529f4e8-7121-44d7-a522-f9458941e288.vsidx b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/1529f4e8-7121-44d7-a522-f9458941e288.vsidx new file mode 100644 index 0000000000..3885b9ca24 Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/1529f4e8-7121-44d7-a522-f9458941e288.vsidx differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/270454c7-59aa-4032-9097-c8628fc3e48d.vsidx b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/270454c7-59aa-4032-9097-c8628fc3e48d.vsidx new file mode 100644 index 0000000000..e500a71662 Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/270454c7-59aa-4032-9097-c8628fc3e48d.vsidx differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/b458b426-8543-4dbb-9281-b6b850fe5a50.vsidx b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/b458b426-8543-4dbb-9281-b6b850fe5a50.vsidx new file mode 100644 index 0000000000..580960b3a1 Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/b458b426-8543-4dbb-9281-b6b850fe5a50.vsidx differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/ba775ec1-5bc6-4bf6-b449-7820d82c70d8.vsidx b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/ba775ec1-5bc6-4bf6-b449-7820d82c70d8.vsidx new file mode 100644 index 0000000000..d6592805c2 Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/ba775ec1-5bc6-4bf6-b449-7820d82c70d8.vsidx differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/c5c0f666-451b-4ebb-ac3c-ee67c67229f9.vsidx b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/c5c0f666-451b-4ebb-ac3c-ee67c67229f9.vsidx new file mode 100644 index 0000000000..f833502a25 Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/FileContentIndex/c5c0f666-451b-4ebb-ac3c-ee67c67229f9.vsidx differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/copilot-chat/6c67098b/sessions/f77f7d85-a1fd-4ed5-a771-869a169f1e73 b/jobs/Backend/Task/.vs/ExchangeRateUpdater/copilot-chat/6c67098b/sessions/f77f7d85-a1fd-4ed5-a771-869a169f1e73 new file mode 100644 index 0000000000..6bde8cf69a Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/copilot-chat/6c67098b/sessions/f77f7d85-a1fd-4ed5-a771-869a169f1e73 differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/v17/.futdcache.v2 b/jobs/Backend/Task/.vs/ExchangeRateUpdater/v17/.futdcache.v2 new file mode 100644 index 0000000000..9059b41916 Binary files /dev/null and b/jobs/Backend/Task/.vs/ExchangeRateUpdater/v17/.futdcache.v2 differ diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/v17/DocumentLayout.backup.json b/jobs/Backend/Task/.vs/ExchangeRateUpdater/v17/DocumentLayout.backup.json new file mode 100644 index 0000000000..b43643971a --- /dev/null +++ b/jobs/Backend/Task/.vs/ExchangeRateUpdater/v17/DocumentLayout.backup.json @@ -0,0 +1,162 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\readme.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:readme.md||{EFC0BB08-EA7D-40C6-A696-C870411A895B}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\responses\\exchangeratefixingresponse.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:responses\\exchangeratefixingresponse.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\models\\currencyratemodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:models\\currencyratemodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\models\\currencymodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:models\\currencymodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\models\\exchangeratemodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:models\\exchangeratemodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\exchangerateupdater.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:exchangerateupdater.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\providers\\exchangerateprovider.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:providers\\exchangerateprovider.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 129, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "ExchangeRateFixingResponse.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Responses\\ExchangeRateFixingResponse.cs", + "RelativeDocumentMoniker": "Responses\\ExchangeRateFixingResponse.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Responses\\ExchangeRateFixingResponse.cs", + "RelativeToolTip": "Responses\\ExchangeRateFixingResponse.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-23T11:29:39.762Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "CurrencyRateModel.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\CurrencyRateModel.cs", + "RelativeDocumentMoniker": "Models\\CurrencyRateModel.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\CurrencyRateModel.cs", + "RelativeToolTip": "Models\\CurrencyRateModel.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAAsAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-23T11:27:31.354Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "CurrencyModel.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\CurrencyModel.cs", + "RelativeDocumentMoniker": "Models\\CurrencyModel.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\CurrencyModel.cs", + "RelativeToolTip": "Models\\CurrencyModel.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-23T11:46:42.54Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "ExchangeRateModel.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\ExchangeRateModel.cs", + "RelativeDocumentMoniker": "Models\\ExchangeRateModel.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\ExchangeRateModel.cs", + "RelativeToolTip": "Models\\ExchangeRateModel.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABcAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-23T13:31:29.018Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "ExchangeRateUpdater", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\ExchangeRateUpdater.csproj", + "RelativeDocumentMoniker": "ExchangeRateUpdater.csproj", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\ExchangeRateUpdater.csproj", + "RelativeToolTip": "ExchangeRateUpdater.csproj", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAAvAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2025-12-23T13:31:50.793Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "Program.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Program.cs", + "RelativeDocumentMoniker": "Program.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Program.cs", + "RelativeToolTip": "Program.cs", + "ViewState": "AgIAABwAAAAAAAAAAAA6wEYAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-22T15:14:03.972Z", + "EditorCaption": "" + } + ] + }, + { + "DockedWidth": 379, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "Readme.md", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Readme.md", + "RelativeDocumentMoniker": "Readme.md", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Readme.md", + "RelativeToolTip": "Readme.md", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAcAAAAiAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001818|", + "WhenOpened": "2025-12-23T13:16:40.632Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "ExchangeRateProvider.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Providers\\ExchangeRateProvider.cs", + "RelativeDocumentMoniker": "Providers\\ExchangeRateProvider.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Providers\\ExchangeRateProvider.cs", + "RelativeToolTip": "Providers\\ExchangeRateProvider.cs", + "ViewState": "AgIAABcAAAAAAAAAAAAUwDYAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-22T15:11:46.713Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/jobs/Backend/Task/.vs/ExchangeRateUpdater/v17/DocumentLayout.json b/jobs/Backend/Task/.vs/ExchangeRateUpdater/v17/DocumentLayout.json new file mode 100644 index 0000000000..49001edad8 --- /dev/null +++ b/jobs/Backend/Task/.vs/ExchangeRateUpdater/v17/DocumentLayout.json @@ -0,0 +1,122 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\responses\\exchangeratefixingresponse.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:responses\\exchangeratefixingresponse.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\models\\currencyratemodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:models\\currencyratemodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\models\\currencymodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:models\\currencymodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\models\\exchangeratemodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:models\\exchangeratemodel.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\exchangerateupdater.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:exchangerateupdater.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|" + }, + { + "AbsoluteMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|c:\\users\\raula\\source\\repos\\backendmewsraul\\jobs\\backend\\task\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{7B2695D6-D24C-4460-A58E-A10F08550CE0}|ExchangeRateUpdater.csproj|solutionrelative:program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 129, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "ExchangeRateFixingResponse.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Responses\\ExchangeRateFixingResponse.cs", + "RelativeDocumentMoniker": "Responses\\ExchangeRateFixingResponse.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Responses\\ExchangeRateFixingResponse.cs", + "RelativeToolTip": "Responses\\ExchangeRateFixingResponse.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAcAAAAFAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-23T11:29:39.762Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "CurrencyRateModel.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\CurrencyRateModel.cs", + "RelativeDocumentMoniker": "Models\\CurrencyRateModel.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\CurrencyRateModel.cs", + "RelativeToolTip": "Models\\CurrencyRateModel.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAAsAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-23T11:27:31.354Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "CurrencyModel.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\CurrencyModel.cs", + "RelativeDocumentMoniker": "Models\\CurrencyModel.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\CurrencyModel.cs", + "RelativeToolTip": "Models\\CurrencyModel.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-23T11:46:42.54Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "ExchangeRateModel.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\ExchangeRateModel.cs", + "RelativeDocumentMoniker": "Models\\ExchangeRateModel.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Models\\ExchangeRateModel.cs", + "RelativeToolTip": "Models\\ExchangeRateModel.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABcAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-23T13:31:29.018Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "ExchangeRateUpdater", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\ExchangeRateUpdater.csproj", + "RelativeDocumentMoniker": "ExchangeRateUpdater.csproj", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\ExchangeRateUpdater.csproj", + "RelativeToolTip": "ExchangeRateUpdater.csproj", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAAvAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2025-12-23T13:31:50.793Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "Program.cs", + "DocumentMoniker": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Program.cs", + "RelativeDocumentMoniker": "Program.cs", + "ToolTip": "C:\\Users\\raula\\source\\repos\\backendMewsRaul\\jobs\\Backend\\Task\\Program.cs", + "RelativeToolTip": "Program.cs", + "ViewState": "AgIAABwAAAAAAAAAAAA6wEYAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-12-22T15:14:03.972Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/jobs/Backend/Task/.vs/ProjectEvaluation/exchangerateupdater.metadata.v9.bin b/jobs/Backend/Task/.vs/ProjectEvaluation/exchangerateupdater.metadata.v9.bin new file mode 100644 index 0000000000..9560f800a6 Binary files /dev/null and b/jobs/Backend/Task/.vs/ProjectEvaluation/exchangerateupdater.metadata.v9.bin differ diff --git a/jobs/Backend/Task/.vs/ProjectEvaluation/exchangerateupdater.projects.v9.bin b/jobs/Backend/Task/.vs/ProjectEvaluation/exchangerateupdater.projects.v9.bin new file mode 100644 index 0000000000..c3c5238ca1 Binary files /dev/null and b/jobs/Backend/Task/.vs/ProjectEvaluation/exchangerateupdater.projects.v9.bin differ diff --git a/jobs/Backend/Task/.vs/ProjectEvaluation/exchangerateupdater.strings.v9.bin b/jobs/Backend/Task/.vs/ProjectEvaluation/exchangerateupdater.strings.v9.bin new file mode 100644 index 0000000000..afe08be56b Binary files /dev/null and b/jobs/Backend/Task/.vs/ProjectEvaluation/exchangerateupdater.strings.v9.bin differ diff --git a/jobs/Backend/Task/ExchangeRateProvider.cs b/jobs/Backend/Task/ExchangeRateProvider.cs deleted file mode 100644 index 6f82a97fbe..0000000000 --- a/jobs/Backend/Task/ExchangeRateProvider.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace ExchangeRateUpdater -{ - public class ExchangeRateProvider - { - /// - /// Should return exchange rates among the specified currencies that are defined by the source. But only those defined - /// by the source, do not return calculated exchange rates. E.g. if the source contains "CZK/USD" but not "USD/CZK", - /// do not return exchange rate "USD/CZK" with value calculated as 1 / "CZK/USD". If the source does not provide - /// some of the currencies, ignore them. - /// - public IEnumerable GetExchangeRates(IEnumerable currencies) - { - return Enumerable.Empty(); - } - } -} diff --git a/jobs/Backend/Task/ExchangeRateUpdater.csproj b/jobs/Backend/Task/ExchangeRateUpdater.csproj index 2fc654a12b..463cc45993 100644 --- a/jobs/Backend/Task/ExchangeRateUpdater.csproj +++ b/jobs/Backend/Task/ExchangeRateUpdater.csproj @@ -5,4 +5,9 @@ net6.0 + + + + + \ No newline at end of file diff --git a/jobs/Backend/Task/ExchangeRateUpdater.sln b/jobs/Backend/Task/ExchangeRateUpdater.sln index 89be84daff..9e294baa09 100644 --- a/jobs/Backend/Task/ExchangeRateUpdater.sln +++ b/jobs/Backend/Task/ExchangeRateUpdater.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36811.4 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeRateUpdater", "ExchangeRateUpdater.csproj", "{7B2695D6-D24C-4460-A58E-A10F08550CE0}" EndProject @@ -19,4 +19,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A2D251C4-D515-440F-B0FB-050BDDD9A5F3} + EndGlobalSection EndGlobal diff --git a/jobs/Backend/Task/Currency.cs b/jobs/Backend/Task/Models/CurrencyModel.cs similarity index 71% rename from jobs/Backend/Task/Currency.cs rename to jobs/Backend/Task/Models/CurrencyModel.cs index f375776f25..40028e1477 100644 --- a/jobs/Backend/Task/Currency.cs +++ b/jobs/Backend/Task/Models/CurrencyModel.cs @@ -1,8 +1,8 @@ -namespace ExchangeRateUpdater +namespace ExchangeRateUpdater.Models { - public class Currency + public class CurrencyModel { - public Currency(string code) + public CurrencyModel(string code) { Code = code; } diff --git a/jobs/Backend/Task/Models/CurrencyRateModel.cs b/jobs/Backend/Task/Models/CurrencyRateModel.cs new file mode 100644 index 0000000000..f34d324bc3 --- /dev/null +++ b/jobs/Backend/Task/Models/CurrencyRateModel.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; + +namespace ExchangeRateUpdater.Models +{ + public class CurrencyRateModel + { + [JsonPropertyName("validFor")] + public string ValidFor { get; set; } + + [JsonPropertyName("order")] + public int Order { get; set; } + + [JsonPropertyName("country")] + public string Country { get; set; } + + [JsonPropertyName("currency")] + public string Currency { get; set; } + + [JsonPropertyName("amount")] + public int Amount { get; set; } + + [JsonPropertyName("currencyCode")] + public string CurrencyCode { get; set; } + + [JsonPropertyName("rate")] + public decimal Rate { get; set; } + } +} diff --git a/jobs/Backend/Task/ExchangeRate.cs b/jobs/Backend/Task/Models/ExchangeRateModel.cs similarity index 52% rename from jobs/Backend/Task/ExchangeRate.cs rename to jobs/Backend/Task/Models/ExchangeRateModel.cs index 58c5bb10e0..9889f950ba 100644 --- a/jobs/Backend/Task/ExchangeRate.cs +++ b/jobs/Backend/Task/Models/ExchangeRateModel.cs @@ -1,17 +1,17 @@ -namespace ExchangeRateUpdater +namespace ExchangeRateUpdater.Models { - public class ExchangeRate + public class ExchangeRateModel { - public ExchangeRate(Currency sourceCurrency, Currency targetCurrency, decimal value) + public ExchangeRateModel(CurrencyModel sourceCurrency, CurrencyModel targetCurrency, decimal value) { SourceCurrency = sourceCurrency; TargetCurrency = targetCurrency; Value = value; } - public Currency SourceCurrency { get; } + public CurrencyModel SourceCurrency { get; } - public Currency TargetCurrency { get; } + public CurrencyModel TargetCurrency { get; } public decimal Value { get; } diff --git a/jobs/Backend/Task/Program.cs b/jobs/Backend/Task/Program.cs index 379a69b1f8..072b2f51df 100644 --- a/jobs/Backend/Task/Program.cs +++ b/jobs/Backend/Task/Program.cs @@ -1,30 +1,57 @@ -using System; +using ExchangeRateUpdater.Models; +using ExchangeRateUpdater.Providers; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace ExchangeRateUpdater { public static class Program { - private static IEnumerable currencies = new[] + private static IEnumerable currencies = new[] { - new Currency("USD"), - new Currency("EUR"), - new Currency("CZK"), - new Currency("JPY"), - new Currency("KES"), - new Currency("RUB"), - new Currency("THB"), - new Currency("TRY"), - new Currency("XYZ") + new CurrencyModel("USD"), + new CurrencyModel("EUR"), + new CurrencyModel("CZK"), + new CurrencyModel("JPY"), + new CurrencyModel("KES"), + new CurrencyModel("RUB"), + new CurrencyModel("THB"), + new CurrencyModel("TRY"), + new CurrencyModel("XYZ") }; - public static void Main(string[] args) + public static async Task Main(string[] args) { + using var host = Host.CreateDefaultBuilder(args) + .ConfigureLogging(logging => + { + logging.ClearProviders(); + logging.AddSimpleConsole(); + }) + .ConfigureServices(services => + { + services.AddHttpClient(client => + { + client.BaseAddress = new Uri("https://api.cnb.cz/"); + client.Timeout = TimeSpan.FromSeconds(10); + + client.DefaultRequestHeaders.Accept.Clear(); + client.DefaultRequestHeaders.Accept.Add( + new MediaTypeWithQualityHeaderValue("application/json")); + }); + }) + .Build(); + try { - var provider = new ExchangeRateProvider(); - var rates = provider.GetExchangeRates(currencies); + var provider = host.Services.GetRequiredService(); + var rates = await provider.GetExchangeRatesAsync(currencies); Console.WriteLine($"Successfully retrieved {rates.Count()} exchange rates:"); foreach (var rate in rates) diff --git a/jobs/Backend/Task/Providers/ExchangeRateProvider.cs b/jobs/Backend/Task/Providers/ExchangeRateProvider.cs new file mode 100644 index 0000000000..9f97afad19 --- /dev/null +++ b/jobs/Backend/Task/Providers/ExchangeRateProvider.cs @@ -0,0 +1,54 @@ +using ExchangeRateUpdater.Interfaces; +using ExchangeRateUpdater.Models; +using ExchangeRateUpdater.Responses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; + +namespace ExchangeRateUpdater.Providers +{ + public class ExchangeRateProvider + { + private readonly HttpClient _httpClient; + + public ExchangeRateProvider(HttpClient httpClient) + { + _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); + } + /// + /// Should return exchange rates among the specified currencies that are defined by the source. But only those defined + /// by the source, do not return calculated exchange rates. E.g. if the source contains "CZK/USD" but not "USD/CZK", + /// do not return exchange rate "USD/CZK" with value calculated as 1 / "CZK/USD". If the source does not provide + /// some of the currencies, ignore them. + /// + + private async Task> AccessCurrentExchangeRateFixingCZKAsync() + { + var exchangeRateFixingResponse = await _httpClient.GetStringAsync("cnbapi/exrates/daily") ?? throw new Exception("Could not retrieve exchange rate fixing from CNB."); + + ExchangeRateFixingResponse exchangeRateFixing = JsonSerializer.Deserialize(exchangeRateFixingResponse); + + if (exchangeRateFixing?.Rates == null) + throw new InvalidOperationException("CNB response did not contain 'rates'."); + + List exchangeRates = new List(); + + foreach (var line in exchangeRateFixing.Rates) + { + exchangeRates.Add(new ExchangeRateModel(new CurrencyModel(line.CurrencyCode), new CurrencyModel("CZK"), line.Amount > 1 ? line.Rate/line.Amount : line.Rate)); + } + + return exchangeRates; + } + + public async Task> GetExchangeRatesAsync(IEnumerable currencies) + { + List exchanges = await AccessCurrentExchangeRateFixingCZKAsync(); + + return exchanges.Where(ex => currencies.Any(cur => cur.Code == ex.TargetCurrency.Code) && currencies.Any(cur => cur.Code == ex.SourceCurrency.Code)); + } + } +} diff --git a/jobs/Backend/Task/Readme.md b/jobs/Backend/Task/Readme.md new file mode 100644 index 0000000000..c60099eee4 --- /dev/null +++ b/jobs/Backend/Task/Readme.md @@ -0,0 +1,8 @@ +I refactored the provider into a real implementation by introducing a clear separation +between domain models and API responses. The provider is now injected via the .NET Generic Host using AddHttpClient, +which centralizes HTTP configuration (base address, timeout, headers) and improves maintainability. + +Exchange rates are fetched asynchronously from the CNB daily endpoint, deserialized with System.Text.Json, +and normalized for currencies quoted per multiple units (rate divided by amount). + +Finally, results are filtered to only include currencies requested by the caller from what the source provides. \ No newline at end of file diff --git a/jobs/Backend/Task/Responses/ExchangeRateFixingResponse.cs b/jobs/Backend/Task/Responses/ExchangeRateFixingResponse.cs new file mode 100644 index 0000000000..35b4e883b3 --- /dev/null +++ b/jobs/Backend/Task/Responses/ExchangeRateFixingResponse.cs @@ -0,0 +1,12 @@ +using ExchangeRateUpdater.Models; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace ExchangeRateUpdater.Responses +{ + public class ExchangeRateFixingResponse + { + [JsonPropertyName("rates")] + public List Rates { get; set; } + } +}