{"id":18928342,"url":"https://github.com/codefab-io/powerplant-coding-challenge","last_synced_at":"2026-03-15T20:30:17.970Z","repository":{"id":200579079,"uuid":"705839218","full_name":"CodeFab-io/powerplant-coding-challenge","owner":"CodeFab-io","description":"Coding challenge for GEM-SPaaS","archived":false,"fork":false,"pushed_at":"2023-10-19T17:41:02.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-12-31T19:15:39.167Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","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/CodeFab-io.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":"2023-10-16T19:40:31.000Z","updated_at":"2023-10-16T19:59:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"fcc7c3b4-117c-40cc-a28b-9208e6033f9c","html_url":"https://github.com/CodeFab-io/powerplant-coding-challenge","commit_stats":null,"previous_names":["codefab-io/powerplant-coding-challenge"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeFab-io%2Fpowerplant-coding-challenge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeFab-io%2Fpowerplant-coding-challenge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeFab-io%2Fpowerplant-coding-challenge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeFab-io%2Fpowerplant-coding-challenge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CodeFab-io","download_url":"https://codeload.github.com/CodeFab-io/powerplant-coding-challenge/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239923656,"owners_count":19719171,"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":[],"created_at":"2024-11-08T11:25:06.415Z","updated_at":"2026-03-15T20:30:15.865Z","avatar_url":"https://github.com/CodeFab-io.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# powerplant-coding-challenge\n\n## A potential solution, by Fábio Beirão\n\n### High-level overview\n\nThere are 3 dotnet projects: `powerplant-coding-challenge`, `REST_API`, `Tests`\n\n`powerplant-coding-challenge` is where are the models and calculations exist.\n\n`REST_API` only concerns itself with API matters: serialization, deserialization and invoking the `powerplant-coding-challenge` function.\n\n`Tests` is primarily focused on testing the internals of `powerplant-coding-challenge`, according to the requirements and provided examples.\n\n## Code style\n\nFor this assignment I used my preferred style of writing c# code (and nearly any type of production code I write these days).\n\nDepending on how familiar you are with functional languages, the approach might either look alien or familiar.\n\nFor me, the great advantage of functional-style code is the restrictions on what the code **cannot** do: functions are not allowed to \"reach out\" to the universe/context,\nor mutate any of the arguments. Another way to look at it is that a (pure) function will always return the same output, given the same inputs.\n\nI would be happy to discuss further about the different trade-offs of functional-style programming.\n\nYou will also see things such as `public sealed record Load(decimal LoadValue)`. This is a pattern I adopted to move away from primitive obsession. To me this solves different problems:\n\n* Battle scars from mixing different compatible types (strings with strings, decimals with decimals, etc) and the headache of debugging such silly mistakes;\n\n* Increases the clarity (from my point of view) for the consumer of the functions: they don't just have to provide a `decimal` as input to a function, they need to provide a `Load`;\n\n* You get to better leverage the compiler when you have to perform refactors. I am usually a fan of trying to refactor something and then following the compiler and unit tests to get everything working again.\n\n## Unit tests\n\nIn order to run the unit tests you can simply run `dotnet test` (on the root of the project) or use your favorite IDE (tested on Visual Studio 2022 Community Edition).\n\n\n## Docker\n\nThe requirement states that we should export port `8888` so we can achieve this using the Docker port mapping (mapping the container's internal port `80` to the host's port `8888`).\n\nSecond step is building the container. On the root of the project we can run:\n\n```\ndocker build -t powerplant -f .\\REST_API\\Dockerfile .\n```\n\nThis will use the `Dockerfile` in `REST_API\\Dockerfile` to build an image called `powerplant`.\n\nNext we can run this image:\n\n```\ndocker run --rm -p 8888:80 powerplant\n```\n\n(the parameter `--rm` makes Docker auto destroy the container once it exits, to prevent clutter on your machine).\n\nIf all goes well, we should see some logs in the console.\n\nWe can now open the browser in `http://localhost:8888/swagger` to use the SwaggerUI and interact with the API.\n\n## Cleanup\n\nWe executed `docker run` with the `--rm` flag, so that cleared the container, but we still have the `powerplant` image lying around.\n\nTo clean up we should run `docker rmi powerplant`\n\n## Added details\n\nI will be honest that I have some unfamiliarity with the Energy Management sector. I understand, from my own curiosity, and from following youtube\ncreators such as Pratical Engineering, that there is both an inherent complexity as well as a built-in resiliency on the power grid. I have always\nfound it amazing the fact that the power grid needs to meet demand in real-time to keep the voltage on the network stable.\n\nFor this assignment, it wasn't stated (or clear to me) what should happen in scenarios where the Load is higher than all powerplants are able to meet,\nand vice-versa what happens when all plants have a higher pmin than the Load.\n\nFor this reason, I decided to add an additional header `unsatisfied-load` on the response. Under normal circumstances, this will be `0`. However,\nwhen the powerplants were not able to meet demand, this value would be a positive value of unmet KWh. On the flip-side, if due to pmin we exceeded the\nload, this value will be negative, signaling (perhaps) that energy storage should be activated.\n\n## Final remarks\n\nAll in all this was a fun assignment, I am always thrilled to explore new domains and concepts. I am looking forward to hearing your feedback,\nbecause feedback is how I keep my skills sharp. \nThank you for your time,\n\nFábio Beirão\nfabio@codefab.io","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodefab-io%2Fpowerplant-coding-challenge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodefab-io%2Fpowerplant-coding-challenge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodefab-io%2Fpowerplant-coding-challenge/lists"}