{"id":30971670,"url":"https://github.com/neodelf/forecast","last_synced_at":"2025-09-12T02:24:51.633Z","repository":{"id":228671593,"uuid":"710779201","full_name":"Neodelf/forecast","owner":"Neodelf","description":null,"archived":false,"fork":false,"pushed_at":"2023-10-27T12:36:21.000Z","size":66,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-03-19T22:48:03.639Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/Neodelf.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}},"created_at":"2023-10-27T12:24:46.000Z","updated_at":"2024-03-19T22:48:06.333Z","dependencies_parsed_at":"2024-03-19T22:58:08.266Z","dependency_job_id":null,"html_url":"https://github.com/Neodelf/forecast","commit_stats":null,"previous_names":["neodelf/forecast"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Neodelf/forecast","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Neodelf%2Fforecast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Neodelf%2Fforecast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Neodelf%2Fforecast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Neodelf%2Fforecast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Neodelf","download_url":"https://codeload.github.com/Neodelf/forecast/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Neodelf%2Fforecast/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274743630,"owners_count":25341135,"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","status":"online","status_checked_at":"2025-09-12T02:00:09.324Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-09-12T02:24:45.614Z","updated_at":"2025-09-12T02:24:51.625Z","avatar_url":"https://github.com/Neodelf.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Coding Assignment.\n## Implement the Minimum Viable Product (MVP) according to the requirements:\n\n### Functional requirements\n- Must be done in Ruby on Rails\n- Accept an address as input\n- Retrieve forecast data for the given address. This should include, at minimum, the current temperature\n(Bonus points - Retrieve high/low and/or extended forecast)\n- Display the requested forecast details to the user\n- Cache the forecast details for 30 minutes for all subsequent requests by zip codes. Display indicator if\nresult is pulled from cache.\n\n### Non Functional requirements\n- Availability\n- Scalability\n- Reliability\n- Maintainability\n- Usability\n\n## Solution\n\n### High level system design\n\n\u003cimg width=\"536\" alt=\"Screenshot 2023-10-27 at 15 35 22\" src=\"https://github.com/Neodelf/forecast/assets/2521090/832f933f-4f0b-4afc-a0bc-5fa322d78c14\"\u003e\n\n### Compliance with the functional requirements\n\n- The application is developed using Ruby version `3.2.2` and Rails version `7.0.6`, ensuring compatibility with\nthe latest language and framework releases.\n\n- When accessing the `/forecasts` page, users are presented with a form featuring an input field to enter\nthe zip code.\n\n- The application retrieves the current temperature in Fahrenheit based on the provided zip code.\n\n- To provide real-time updates, the temperature is displayed through a `WebSocket` connection and dynamically\nshown in the `.forecast-results` div on the page. This allows users to receive immediate updates without\nneeding to manually refresh the page.\n\n- `Redis`, a database technology, is utilized for storing previously retrieved data. If the requested data is\navailable in the cache, the user is presented with a label in the color `#055160` indicating that the data was\nretrieved from the cache. This ensures efficient retrieval and reduces the need for repetitive data fetching.\n\n### Compliance with the non functional requirements\n\n- The system ensures accessibility by utilizing a message queue, allowing asynchronous and ordered processing\nof user requests. To meet the MVP requirements and optimize development time and reliability, `Sidekiq` in\nconjunction with `Redis` was chosen as the primary technology stack.\n\n- The application architecture is designed to provide high-level extensibility, both horizontally and\nvertically, within the asynchronous server component. Currently, Sidekiq is utilized as the asynchronous\nserver solution. However, the architecture leverages `Active Job` as a wrapper, allowing for easy integration\nwith alternative asynchronous server options such as `RabbitMQ` or `Apache Kafka`. This design choice enhances the\nreliability and stability of the application.\n\n- The codebase follows the principles of the `Rate Limiter`, `Strategy`, and `Observer` patterns, which contribute\nto a well-structured and maintainable codebase. These patterns help manage and control the rate of incoming\nrequests, define flexible strategies for handling different scenarios, and observe changes within the\napplication.\n\n- Additionally, the architecture is designed to support future scalability for `mobile clients` or `API\nprovision`. This means that the application can easily accommodate the needs of mobile applications or expose\nits functionality through an API, allowing for broader usage and integration possibilities.\n\n- Overall, the architecture demonstrates a focus on extensibility, scalability, and adherence to established\ndesign patterns to ensure a robust and flexible application foundation.  \n\n- Redis, the non-relational database used for caching, can be easily scaled horizontally to accommodate\nincreased demand. `Redis Sentinel` can also be employed to enhance the reliability of `Redis` by introducing\nadditional database instances and setting up replications.\n\n- To facilitate application maintenance, the codebase is developed with readability in mind, and comprehensive\ndocumentation is provided for each class, clearly describing their functionality. This allows for easy\nunderstanding and future reusability of system modules, enabling the system to adapt and support evolving\nuser cases.\n\n- The codebase adheres to high-quality coding standards and follows the guidelines set by the `RuboCop` linter.\nBy formatting the code with `RuboCop`, the codebase maintains a consistent and standardized style, improving\nreadability and ensuring a unified code structure across the project. This adherence to a linter helps to\nidentify and enforce best practices, reducing potential coding errors and enhancing the maintainability of the\ncodebase. The `RuboCop` linter plays a crucial role in maintaining code quality and consistency throughout the\ndevelopment process.\n\n- Usability is a priority, demonstrated by the simple user interface featuring a straightforward form with\na `zip code` input. Users receive `real-time feedback` indicating that their request is being processed, and\nonce the processing is complete, they are presented with the relevant information on the same page without\nany need for page reloading.\n\n- In addition to the documentation, the codebase maintains a high test coverage percentage of `98.52%`. This\nextensive test coverage ensures that the application's functionality is thoroughly tested, reducing the risk\nof introducing bugs and providing confidence in the reliability of the system. The comprehensive test suite\nserves as a safety net, enabling developers to make changes and refactor code with confidence, knowing that\nthey can catch regressions through automated tests.\n\u003cimg width=\"803\" alt=\"Screenshot 2023-10-27 at 11 44 52\" src=\"https://github.com/Neodelf/forecast/assets/2521090/7a6bebc9-939b-4910-bcc9-4680e890e331\"\u003e\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneodelf%2Fforecast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneodelf%2Fforecast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneodelf%2Fforecast/lists"}