{"id":21879536,"url":"https://github.com/nerooc/spotspotter","last_synced_at":"2026-04-13T17:04:50.273Z","repository":{"id":124517185,"uuid":"533307044","full_name":"nerooc/spotspotter","owner":"nerooc","description":"\"Creating applications based on Azure services\" - final project","archived":false,"fork":false,"pushed_at":"2024-10-18T15:15:20.000Z","size":2383,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-26T18:31:45.915Z","etag":null,"topics":["azure","nestjs","react"],"latest_commit_sha":null,"homepage":"https://spotspotter.azurewebsites.net/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nerooc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-06T12:12:58.000Z","updated_at":"2023-06-08T07:25:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"abd1f651-0fa7-434f-aaa2-56aa1ea965d9","html_url":"https://github.com/nerooc/spotspotter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2Fspotspotter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2Fspotspotter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2Fspotspotter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2Fspotspotter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nerooc","download_url":"https://codeload.github.com/nerooc/spotspotter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244885696,"owners_count":20526296,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","nestjs","react"],"created_at":"2024-11-28T08:17:08.800Z","updated_at":"2026-04-13T17:04:50.242Z","avatar_url":"https://github.com/nerooc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spotspotter\n\nAplikacja dla fanów fotografii motoryzacyjnej (i nie tylko), która pozwala na udostepnianie lokalizacji (spotów) do robienia zdjęć.\n\n\n![spotspotter-logo](https://user-images.githubusercontent.com/31045802/212891761-c7e76cb5-438f-485d-b494-ed0d8bb84fd1.svg)\n\nDEMO: [https://spotspotter.azurewebsites.net/login](https://spotspotter.azurewebsites.net/login)\n\n# Diagram architektury\n\n![image](https://user-images.githubusercontent.com/31045802/214276591-f44263ee-a3b7-44ee-a220-625ad24499fe.png)\n\n# Technologie\n\nDo stworzenia aplikacji serwerowej wykorzystany został framework `NestJS`. \nAplikacja frontendowa używa natomiast biblioteki `React`. Próba zabawy z frameworkiem `NextJS` zakończyły się niestety niepowodzeniem. \nW przypadku obu elementów jako główny język używany jest Typescript.\n\nAplikacja deployowana jest na chmurę Microsoft Azure przy pomocy Github Actions. \n\n# Struktura katalogów repozytorium\n\n```bash\n├── azure/ # zrzuty ekranu z konfiguracji Azure\n├── preview/ # zrzuty ekranu z aplikacji\n├── client/ # kod zawierający część kliencką aplikacji\n│   ├── public/ # pliki statyczne (np. favicon, index.html)\n│   ├── package.json # zależności części klienckiej\n│   ├── src/ # folder z plikami źródłowymi części klienckiej\n│   │   ├── api/ # pliki dotyczące naszego połączenia z API serwerowym\n│   │   ├── azure/ # pliki konfiguracyjne Azure \n│   │   ├── containers/ # kontenery aplikacji trzymające stan\n│   │   ├── components/ # komponenty\n│   │   ├── layouts/ # layouty aplikacji pozwalające na łatwe dodawanie nowych stron\n│   │   ├── pages/ # ekrany/podstrony aplikacji\n│   │   ├── styles/ # globalne style aplikacji\n│   │   ├── types/ # typy wykorzystane w aplikacji\n│   │   └── App.tsx # punkt startowy aplikacji\n│   │\n│   └── # dodatkowe pliki konfiguracyjne React, Typescript\n│\n├── src/ # kod zawierający część serwerową aplikacji\n│   ├── location/ # moduł dotyczący lokalizacji\n│   └── main.ts # moduł główny aplikacji serwerowej\n│\n├── README.md # krótka dokumentacja projektu\n├── package.json # zależności części serwerowej\n└── .github/workflows # pliki dot. pipeline'u\n\n```\n\n# Interfejs aplikacji\n\n## Strona logowania\n\nStrona, na której możemy zobaczyć logo aplikacji oraz zalogować się do niej za pomocą konta Microsoft (Azure AD).\nLogo aplikacji dostarczone jest za pomocą `Azure Blob Storage`.\n\n![](preview/login_page.jpg)\n\n## Strona główna (lista lokalizacji)\n\nNa stronie głównej możemy zobaczyć dwa główne elementy aplikacji - mapa będąca tłem oraz interfejsem do zarządzania lokalizacjami oraz modal z listą zapisanych wcześniej lokalizacji. Na tym ekranie dostajemy podstawowe informacje o lokalizacji, takie jak nazwa i adres. \n\n``` TBA: Dodatkowo możemy zobaczyć liczbę zdjęć, które zostały dodane do danej lokalizacji. ```\n\n![](preview/main_page.jpg)\n\n### Strona pojedynczej lokalizacji\n\nStrona pojedynczej lokalizacji przedstawia dokładny adres wraz z opisem danego miejsca, oprócz tego możemy zobaczyć lokalizację na mapie. \n``` TBA: Możemy też zobaczyć zdjęcia dodane do danej lokalizacji. ```\n\n![](preview/location_page.jpg)\n\n\n### Strona tworzenia nowej lokalizacji\n\nKlikając w jakieś miejsce na mapie otwieramy stronę tworzenia nowej lokalizacji.\nMożemy tam podać nazwę, opis oraz adres. Dokłade koordynaty są przesyłane przez samą mapę. \n\n``` TBA: Dodatkowo możemy dodać zdjęcia do danej lokalizacji. ```\n\n![](preview/new_location_page.jpg)\n\n# Funkcjonalności Azure\n\nNa rzecz projektu utworzyłem specjalną grupę zasobów o nazwie `spotspotter-resources`. W niej umieszczone zostały wykorzystane komponenty:\n\n![](azure/resource_group.jpg)\n\nNa wykorzystane komponenty w projekcie składa się:\n- App Service (w tym deployment sloty na staging i production)\n- Azure Cosmos DB\n- Storage account (Blob Storage)\n- Monitoring:\n  - Application Insights\n  - Metryki\n  - Alerty\n\nJedyny komponent, który został umieszczony w ramach innej grupy zasobów oraz w ramach innej subskrypcji to Active Directory. Spowodowane jest to ograniczeniami nałożonymi przez organizację, w której znajduje się AGH'owe konto Azure:\n- Active Directory\n\n## App Service\n\nPo nierównej walce przeprowadzonej z frameworkiem NextJS, powróciłem do czystego Reacta. Oczywiście do hostowania aplikacji wykorzystałem usługę `App Service`. W tym celu utworzyłem dwa deployment sloty - `staging` oraz `production`. Deploy aplikacji odbywa się automatycznie za pomocą GitHub Actions. Pliki yml dotyczące pipeline'u znajdują się w folderze `.github/workflows`.\n\nWszystkie zmiany w kodzie aplikacji są wdrażane na slot `staging`, a dopiero po jego przetestowaniu mogą po manualnym deployu trafić na `production`.\n\nNode'owa aplikacja stworzona za pomocą frameworka NestJS serwuje statyczne pliki zbudowane przez Reacta. \n\n![](azure/app_service.jpg)\n\n## Azure Cosmos DB\n\nW bazie danych NoSQL Azure Cosmos DB przechowywane są dane o lokalizacjach. Składa się ona z jednego kontenera o nazwie `locations`. W nim znajdziemy wszystkie dokumenty dotyczące lokalizacji zapisane w bazie.\n\n![](azure/cosmos_db.jpg)\n\n\n## SQL Blob Storage\n\nDo przechowywania zdjęć wykorzystałem usługę `Blob Storage`. Na ten moment utworzyłem kontener o nazwie `public`. \nW nim znajdują się podstawowe zdjęcia używane w aplikacji. W późniejszej fazie rozwoju prawdopodobnie dodam więcej kontenerów.\n\n![](azure/blob_storage.jpg)\n\n\n## Autoryzacja w aplikacji\n\nDo autoryzacji w aplikacji wykorzystałem usługę `Active Directory`, ze specjalną konfiguracją przeznaczoną dla aplikacji typu SPA (np. React/Next.js).\n\n![](azure/active_directory.jpg)\n\n\n## Monitoring\n\nW ramach monitoringu wykorzystałem kilka funkcjonalności oferowanych przez Azure:\n\n### Application Insights\n\nApplication Insights jest usługą, która zbiera informacje o działaniu aplikacji. W tym przypadku zbiera ona informacje o wyjątkach, które mogą wystąpić w aplikacji. Funkcjonalność ta jest aktualnie podpięta do aplikacji i przedstawia nam dane.\n\n![](azure/application_insights.jpg)\n\n\n### Metryki\n\nW ramach metryk wykorzystałem usługę `Metrics`, która zbiera informacje o wydajności aplikacji.\n\n![](azure/metrics.jpg)\n\n\n### Alerty\n\nW ramach alertów wykorzystałem usługę `Alerts`, która pozwala na automatyczne wysyłanie maili w przypadku wystąpienia błędu w aplikacji. Stworzyłem dwie reguły:\n - failed-server-requests - wysyła maila w przypadku wystąpienia większej liczby (\u003e 5) nieudanych żądań do aplikacji,\n - response-time-alert - wysyła alert w przypadku wystąpienia większej liczby żądań, które zajęły więcej niż 3 sekundy.\n\n![](azure/alert_rules.jpg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerooc%2Fspotspotter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnerooc%2Fspotspotter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerooc%2Fspotspotter/lists"}