diff --git a/assignment.md b/assignment.md index 3b65fb3..c60d942 100644 --- a/assignment.md +++ b/assignment.md @@ -1,108 +1,77 @@ +# Assignment: Sensor Measurements API -# Assignment: Sensor measurements API +The goal of this assignment is to see how you apply practical software engineering skills in a real-world-ish setting. You'll build a backend for a simplified part of our product, with realistic expectations for quality, clarity, and completeness. -The goal of this assignment is to verify that you can apply software engineering techniques in -practice. To do so, we ask that you build a backend for a hypothetical part of our product. +## Context -## Instructions +Modern greenhouses rely on lots of sensors to monitor both the external weather and the internal environment. These parameters—like temperature, humidity, CO₂ levels, and light—are influenced by both external weather and internal control systems (screens, windows, heating, etc). -Modern greenhouses contain lots of sensors to measure the climate in the greenhouse and the -environment around the plants. The environment consists of parameters such as air temperature, -humidity, CO2 concentration and access to water and nutrients. These parameters are influenced -by conditions outside, as well as control mechanisms inside the greenhouse. To achieve the right -environment, the grower manipulates mechanical components of the greenhouse based on forecasted -external weather conditions. These components include but are not limited to: screens, -ventilation (through opening windows) and heating systems. +We want to give growers insight into how the environment evolves over time, so they can assess and improve their growing strategy. This assignment focuses on the backend logic for a small part of that: ingesting and serving weather (meteo) data. -We want to give growers insights in the current and historical environmental parameters so they -can assess the performance of their growing strategy. I.e. did they manage to keep the temperature, -humidity etc. within the right bounds to create the ideal growing conditions for the plants. -To be able to build a dashboard with these insights, we need a backend that exposes the right -information through one or more API endpoints that can be consumed by the frontend. +## Your Task -For this assignment, you're going to build a part of the backend that deals with meteo (weather) -data. +Implement a backend service with the following functionality: -## Requirements +### 1. API endpoints -Your solution should include the following functionality: - -1. An API endpoint that can be used to push raw data (according to the provided format) - from the climate computer to your service (see below for access to data) -2. One or more API endpoints to expose the meteo data in a _sane_ and _convenient_ - format for consumption by the frontend. The frontend expects at least the following - functionality: - - - Expose the _latest_ weather conditions (i.e. show what's happening _now_) - - Expose the development of the weather parameters over the last 24h in 15 min increments - - Expose the average for each of the weather parameters for the last 24h - - Expose the development of the weather parameters over the last 7 days in 1 day increments - (average per day) - - Expose the average of the weather parameters over the last 7 days - -**Some hints and tips:** - -- It's up to you how you store the measurements. Can be in-memory, in a database, etc. -- The format of the raw data is _not necessarily_ the ideal format to expose the data in for the - frontend. Consider the design of your API output well! -- Consider **all** aspects of API design, including but not limited to: paths, return codes, - input/output formats etc. - -### Bonus objectives - -- Store the sensor data in a persistent way (i.e. not in-memory) so it's available between restarts -- Add authentication between the API and allow for different roles between the "write" endpoint - and the "read" endpoints -- Provide a way to ingest raw data in bulk - -### Non-functional requirements - -- Use Python 3.10 or higher _or_ use Golang 1.19 or higher - -> [!IMPORTANT] -> At Source, we're increasingly moving towards Golang as our main language for backend development outside of building -> ML models. For that reason, **we consider it a huge plus if you develop your solution in Golang**. - -- Maintainability is favoured over performance. No complex performance optimizations should be - needed. Another developer should be able to continue where you left off -- It should be possible to run the project (and all of its components) on any machine, including - our laptops -- This assignment was designed to be completed in 6-8h. The evaluation will take into account the - choices you make and what you focus on given the time you have. However, it's up to you if you - spend less or more time on it. -- Please make sure the final commit to your repository is done at least 24 hours before the start - of your interview +- Ingest raw meteo data (see "Data" section below). +- Expose weather data to a frontend, with: + - Current weather conditions (latest value per parameter) + - 24h time series view (15 min resolution) + - 24h average per parameter + - 7-day time series view (1-day resolution) + - 7-day average per parameter -## Deliverables +### 2. Data handling + +- Transform data into a clean, structured API response — don't just echo the ingestion format. +- Handle duplicates, missing data, malformed data, and other edge cases gracefully. +- Store data persistently (e.g. in a DB) so it's available between restarts. + +### 3. Security & robustness -This assignment should be delivered in the following way: +- Add authentication and authorization. At minimum, separate read/write access. +- Provide a way to ingest raw data in bulk. +- Add an appropriate level of test coverage. +- Structure your codebase so that it's easy to navigate and extend. +- Ensure the system runs locally with minimal effort. -- All code is pushed to your private fork of this repository. -- Documentation is provided in the README.md on how the solution works, and how to run and test it. -- Any information, (dummy)-data, files, and other assets that are needed to run this project, are - provided in this repository. -- Please provide a copy of your entire repository to us as a [git bundle](https://stackoverflow.com/a/11795549) in an email attachment. You can create one using `git bundle create repo.bundle --all`. +## Requirements + +- Use **Go 1.22+** or **Python 3.12+** + > [!note] + > At Source.ag we're moving toward Go as our main backend language (outside of ML). Using Go is a strong plus. -## Assessment Criteria +- The code should be easy to understand and maintain. Performance is secondary. +- The system should run cleanly on any machine (including ours). +- You're encouraged to use LLM-assisted tools, but **you** own the code. Don't leave behind things you don't understand, and be ready to explain your implementation choices. +- Timebox to ~6-8 hours. You don't need to cover every edge case — just be clear about trade-offs. + +## Deliverables -The solution will be assessed on the following criteria: +- Commit your code to a private fork of this repo. +- Provide a `README.md` with: + - Setup & run instructions + - Testing instructions + - Brief explanation of your architecture, assumptions, and trade-offs + - An overview of next steps you would take if you had 3 months instead of 8 hours to work on this +- Send us a [`.git bundle`](https://stackoverflow.com/a/11795549) via email -- How is your code structured? Is it easy to read and follow? -- How clear is the documentation? -- How is the API design? Is it easy for a frontend developer to use? -- What does your (internal) data model look like? How does your solution represent and store data? -- Are there any clear bugs in your code? -- How does the solution perform? -- Can you clearly and concisely describe the process you have followed and the choices you have made? -- Can you describe the biggest short-comings of your solution and which steps could be taken to - improve on that? +## Evaluation Criteria -**NOTE:** your experience as a software engineer influences our expectations on the completeness of -your solution - both in terms of requirements and bonus objectives met. In other words: we expect -different things from someone with 1 year of experience than from someone with 10 years of experience. +We'll assess your work based on: -## Additional information and assumptions +- Architectural choices (did you pick the right tools for the job? Did you solve problems on the infrastructure level where appropriate?) +- Code clarity and project structure (e.g. how easy is it to understand and navigate the codebase? How easy is it to contribute to the codebase?) +- API usability and design (e.g. how easy is it to consume the API? How easy is it to evolve the API in a backwards-compatible way?) +- Data modeling and storage (e.g. how flexible is the data model to new sensor types? How would it perform at scale?) +- Handling of real-world issues (e.g. invalid input, missing or duplicate data) +- Testing strategy (e.g. unit vs. integration tests, test coverage) +- Your ability to explain your choices and identify trade-offs or next steps -- The required raw data to test your solution can be found through this link: https://drive.google.com/drive/folders/1TV20EVuxcmaqro7e0HfmX2j6HtILNwXB?usp=sharing +We adjust expectations based on experience level. A staff/senior engineer is expected to cover more ground than someone early in their career — especially now that LLMs can help you move faster. +## Data +Use the sample data available here: +https://drive.google.com/drive/folders/1TV20EVuxcmaqro7e0HfmX2j6HtILNwXB?usp=sharing