Add the planning baseline: business case, stakeholders, plan, dictionary, milestones and their reviews

This commit is contained in:
2026-10-13 15:20:38 +08:00
parent 0388ca586f
commit 165e91a018
20 changed files with 1455 additions and 0 deletions
@@ -0,0 +1,90 @@
# MIL-001: Project foundation
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-001 |
| CrossReference | [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version, reviewed in RC-004 (Go) | pending |
---
## Purpose
This gate decides whether the repository has the files that carry no program logic yet: configuration, ignore rules, constants, README, source documentation settings, the continuous integration workflow, and the repository description and topics. The work is delivered on the branch `mil-001-project-foundation` and one pull request.
## Deliverable
`pyproject.toml`, the Python `.gitignore`, the package `src/weather/` with `__init__.py` and `constants.py`, `tests/test_constants.py`, `README.md` following the Product Owner's template, `Doxyfile`, and `.gitea/workflows/ci.yml`. The repository description and topics on the git host are set.
Proposed repository description and topics, for S01 to confirm by accepting the plan:
- Description: "Reading CSV weather data in Python with the csv library and pandas, day 25 of Udemy's 100 Days of Code bootcamp: DataFrame and Series, average, maximum, row selection, create and export. pytest tests, Doxygen docs, no runtime dependencies for the csv part."
- Topics: `100-days-of-code`, `csv`, `data-analysis`, `doxygen`, `education`, `pandas`, `pytest`, `python`, `python-bootcamp`, `udemy`.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | In a fresh clone, `python -m venv .venv`, `python -m pip install --upgrade pip` and `python -m pip install -e ".[dev]"` succeed in Windows PowerShell | All three commands exit 0 | Any command fails |
| 2 | `pytest` runs | Exit code 0, at least one test of `constants.py` | Failing test, or no test of `constants.py` |
| 3 | `pyproject.toml` states the Python version and the dependencies | `requires-python = ">=3.13"`, `dependencies = []`, an extra `pandas`, a `dev` extra with pytest, ruff, mypy and pandas, and a repository URL that names this repository | Any of the four is missing or different |
| 4 | The `.gitignore` protects local files | `git check-ignore .venv .env __pycache__ build` lists all four | One of them is not ignored |
| 5 | `constants.py` holds the file names and the Fahrenheit factors with Doxygen comments | Every value is an `UPPER_SNAKE` constant with a Doxygen comment | A value is missing or has no Doxygen comment |
| 6 | `doxygen Doxyfile` builds the source documentation | Ends with 0 warnings and writes HTML for `src/` | Any warning, or no output |
| 7 | The README follows the Product Owner's template | Every section title of the template in the given order (Requirements, Set up with Windows powershell, Linux debian and MacOS, Run, Run the tests, Continuous integration, Build the source documentation, Project layout, License), with commands for the three systems | A heading is missing or out of order, or a section has no commands |
| 8 | The CI workflow exists | `.gitea/workflows/ci.yml` installs `.[dev]` and runs `pytest`, `ruff` and `mypy` on Python 3.13, and nothing under `.github/workflows` exists | No workflow, or it does not run the tests, or a file exists under `.github/workflows` |
| 9 | The repository page is complete | Description is non-empty and there are at least 5 topics on the git host | Description empty or fewer than 5 topics |
| 10 | The code is reviewed | `RC-*` against `QC-PY-001` has the verdict `Go` | Verdict `No-Go` or `Go-with-conditions` |
| 11 | No secret is in the change | `.env` is not tracked and no token appears in any changed file | A token is found in the diff |
## Dependencies
| Depends on | Reason |
| --- | --- |
| [PP-001] accepted | The plan schedules this gateway; the plan-first gate needs it before any code |
| This milestone accepted with a `Go` review | The plan-first gate allows no file under `src/` or `tests/` before that |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Objective 9: reproducible environment, `csv` part without dependencies | [BC-001], criteria 8 and 10 in Success Criteria |
| Objective 10: tests with temporary files | [BC-001], criterion 7 in Success Criteria |
| Objective 11: Doxygen and README | [BC-001], criteria 8 and 9 in Success Criteria |
| Objective 13: repository page | [BC-001], criterion 12 in Success Criteria |
| Objective 12: traceable steps | [BC-001], criterion 11 in Success Criteria |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S01 |
| Approving reviewer | S01 |
## Target Date
2026-10-15 — first of five gateways, inside the plan of [PP-001] that ends 2026-10-23.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Add pyproject.toml for the Day 25 weather repository | Create `pyproject.toml` for the project `weather`: `requires-python = ">=3.13"`, an empty `dependencies` list, an optional extra `pandas`, a `dev` extra with pytest, ruff, mypy and pandas, the `src` layout for the package `weather`, the pytest settings, and a description and repository URL that name this repository and day 25. Serves objective 9. | No | |
| 2 | Add the Python .gitignore for the Day 25 weather repository | Add the Python `.gitignore`: bytecode, `.venv/`, build and packaging output, pytest, ruff, mypy and Doxygen caches. It also ignores `.env`, so the personal tokens can never be committed. | No | |
| 3 | Add constants.py and its test | Create `src/weather/__init__.py`, `src/weather/constants.py` and `tests/test_constants.py`. Every value (the data file name, the column names, the Fahrenheit factors, the export file name) is an `UPPER_SNAKE` constant with a Doxygen comment. Serves objective 8. | No | |
| 4 | Add the README for the Day 25 weather repository | Write `README.md` in the Product Owner's template. Document creating a local `.venv`, `python -m pip install --upgrade pip` and `python -m pip install -e ".[dev]"`, with Windows PowerShell, Linux Debian (Debian 13 or newer) and macOS. The Run section is finished in MIL-005. Serves S02 and S03. | No | |
| 5 | Add the Doxyfile for the Day 25 weather repository | Add a `Doxyfile` that reads `src/`, writes to `build/doxygen`, extracts documentation for Python and treats warnings as failures; the project brief names day 25. | No | |
| 6 | Add the continuous integration workflow | Add `.gitea/workflows/ci.yml`: check out, set up Python 3.13, upgrade `pip`, install `.[dev]`, run `pytest`, `ruff` and `mypy`. The file stays in `.gitea/workflows`, not `.github/workflows`. | No | |
| 7 | Set the repository description and topics | Set the description and at least 5 topics of this repository on the git host with the Gitea application programming interface (API), using `GITEA_TOKEN` from the personal `.env` file; the file is only read by the command, never imported, tested or tracked. Use the proposed text of the Deliverable section. Serves S03 and objective 13. | No | |
---
[BC-001]: ../business-case.md
[PP-001]: ../project-plan.md
+76
View File
@@ -0,0 +1,76 @@
# MIL-002: Read with the csv library
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-002 |
| CrossReference | [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version, reviewed in RC-005 (Go) | pending |
---
## Purpose
This gate decides whether the first half of the first lecture is delivered: the weather data file is in the repository and its rows and temperatures are read with Python's built-in `csv` library, without any dependency. The work is delivered on the branch `mil-002-read-with-csv` and one pull request.
## Deliverable
`src/weather/weather_data.csv` (the lecture's file, adopted unchanged), `src/weather/csv_reader.py` with `read_rows` and `read_temperatures`, and `tests/test_csv_reader.py`.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | The data file is the lecture's | Header `day,temp,condition` and 7 data rows, Monday to Sunday, identical to the file S01 downloaded | A different header, row count or content |
| 2 | `read_rows` returns the rows as lists of strings | The first element is `["day", "temp", "condition"]`; 8 rows in all | Rows are not lists of strings or the header is lost |
| 3 | `read_temperatures` returns whole numbers without the header | `[12, 14, 15, 14, 21, 22, 24]`, every element an `int` | A string in the list, the header word, or a wrong value |
| 4 | The default path does not depend on the working directory | Running from another folder finds the file; a `path` argument overrides the default | The call fails when started elsewhere |
| 5 | The file is closed and opened with `with` | Review of `src/` finds no `open` outside `with` | A file left open |
| 6 | The module needs no dependency | `import weather.csv_reader` works with `pandas` not installed | An import of `pandas` in the module |
| 7 | Tests are green and use no file outside `tmp_path` | `pytest` exit code 0 | A failing test, or a write outside a temporary folder |
| 8 | The code is reviewed | `RC-*` against `QC-PY-001` has the verdict `Go` | Verdict `No-Go` or `Go-with-conditions` |
## Dependencies
| Depends on | Reason |
| --- | --- |
| [MIL-001] accepted and merged | The package, `constants.py` and the test set-up come from it |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Objective 1: the data file | [BC-001], criterion 1 in Success Criteria |
| Objective 2: reading with `csv` | [BC-001], criteria 2 and 10 in Success Criteria |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S01 |
| Approving reviewer | S01 |
## Target Date
2026-10-17 — second of five gateways, inside the plan of [PP-001] that ends 2026-10-23.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Add the weather data file | Copy `weather_data.csv` from S01's download folder to `src/weather/weather_data.csv` unchanged (header `day,temp,condition`, 7 rows). Add its name to `constants.py`. Serves objective 1. | No | |
| 2 | Read the weather rows with the csv library | Add `read_rows(path)` in `src/weather/csv_reader.py`: open the file with `with`, read it with `csv.reader` and return the rows as a list of lists of strings, header included, as the lecture does. The default path is the data file next to the module. Serves objective 2. | No | |
| 3 | Extract the temperatures as integers | Add `read_temperatures(path)`: skip the header row, take the second value of each row and convert it with `int`, as the lecture does, returning the list `temperatures`. Serves objective 2. | No | |
| 4 | Add the tests for the csv reader | Add `tests/test_csv_reader.py`: the real file gives `[12, 14, 15, 14, 21, 22, 24]`, a small file in `tmp_path` gives its own values, the header is skipped, and importing the module needs no `pandas`. | No | |
---
[BC-001]: ../business-case.md
[PP-001]: ../project-plan.md
[MIL-001]: ./mil-001-project-foundation.md
@@ -0,0 +1,83 @@
# MIL-003: Read and analyse with pandas
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-003 |
| CrossReference | [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version, reviewed in RC-006 (Go) | pending |
---
## Purpose
This gate decides whether the pandas half of both lectures is delivered: the data file is read in one line, the `DataFrame` and `Series` are used, converted to a dictionary and a list, and the average and maximum temperature and the row selections are computed. The work is delivered on the branch `mil-003-pandas-analysis` and one pull request.
## Deliverable
`src/weather/analysis.py` with `read_data`, `to_data_dict`, `to_temp_list`, `average_temp`, `average_temp_mean`, `max_temp`, `row_for_day`, `hottest_row` and `day_in_fahrenheit`, the `pandas` extra in `pyproject.toml` used as designed, and `tests/test_analysis.py`.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | `read_data` returns a `DataFrame` | `isinstance(data, pandas.DataFrame)`, 7 rows, columns `day`, `temp`, `condition`; the body is one `pandas.read_csv` call | Another type, or a different row or column count |
| 2 | A column is a `Series` | `isinstance(data["temp"], pandas.Series)` | Another type |
| 3 | The conversions work | `to_data_dict(data)` has the keys `day`, `temp`, `condition`; `to_temp_list(data)` is `[12, 14, 15, 14, 21, 22, 24]` | A wrong key or value |
| 4 | The average is right two ways | `average_temp` (sum and length) and `average_temp_mean` (`Series.mean()`) both give 17.428571... | The two ways differ, or a wrong value |
| 5 | The maximum is right | `max_temp(data)` is 24 | A different value |
| 6 | Row selection is right | `row_for_day(data, "Monday")` is one row with `condition` `Sunny` and `temp` 12; `hottest_row(data)` is the row of Sunday | A wrong row or an empty result |
| 7 | Fahrenheit is right | `day_in_fahrenheit(data, "Monday")` is 53.6 | A different value |
| 8 | The `csv` part still needs no dependency | `dependencies = []` and `import weather.csv_reader` works without `pandas` | A dependency added, or `csv_reader` imports `pandas` |
| 9 | The `csv` and `pandas` readers agree | `to_temp_list(read_data())` equals `read_temperatures()` | The lists differ |
| 10 | Tests are green | `pytest` exit code 0 | A failing test |
| 11 | The code is reviewed | `RC-*` against `QC-PY-001` has the verdict `Go` | Verdict `No-Go` or `Go-with-conditions` |
## Dependencies
| Depends on | Reason |
| --- | --- |
| [MIL-002] accepted and merged | The data file and the `csv` reader are the reference for the agreement test |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Objective 3: reading with `pandas` | [BC-001], criterion 3 in Success Criteria |
| Objective 4: conversions | [BC-001], criterion 3 in Success Criteria |
| Objective 5: average and maximum | [BC-001], criterion 4 in Success Criteria |
| Objective 6: row selection and Fahrenheit | [BC-001], criterion 5 in Success Criteria |
| Objective 9: `pandas` is an extra | [BC-001], criterion 10 in Success Criteria |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S01 |
| Approving reviewer | S01 |
## Target Date
2026-10-19 — third of five gateways, inside the plan of [PP-001] that ends 2026-10-23.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Read the weather data with pandas | Add `read_data(path)` in `src/weather/analysis.py`: one `pandas.read_csv` call returning the `DataFrame` `data`; the default path is the data file. `pandas` is imported only in this module. Serves objective 3. | No | |
| 2 | Convert the data to a dictionary and a list | Add `to_data_dict(data)` (`DataFrame.to_dict()`) and `to_temp_list(data)` (`data["temp"].to_list()`), as the lecture does. Serves objective 4. | No | |
| 3 | Compute the average and maximum temperature | Add `average_temp(data)` that returns the sum of `temp_list` divided by its length, and `average_temp_mean(data)` that uses `Series.mean()`, so the two ways of the lecture can be compared; add `max_temp(data)` with `Series.max()`. Serves objective 5. | No | |
| 4 | Select rows by a condition | Add `row_for_day(data, day)` (`data[data.day == day]`), `hottest_row(data)` (`data[data.temp == data.temp.max()]`) and `day_in_fahrenheit(data, day)` (`temp * 9 / 5 + 32`, factors from `constants.py`). Serves objective 6. | No | |
| 5 | Add the tests for the pandas analysis | Add `tests/test_analysis.py` for the criteria of this gateway, including that the two readers agree. The test module is skipped with `pytest.importorskip` when `pandas` is missing. | No | |
---
[BC-001]: ../business-case.md
[PP-001]: ../project-plan.md
[MIL-002]: ./mil-002-read-with-csv.md
@@ -0,0 +1,75 @@
# MIL-004: Create and export a DataFrame
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-004 |
| CrossReference | [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version, reviewed in RC-007 (Go) | pending |
---
## Purpose
This gate decides whether the end of the second lecture is delivered: a `DataFrame` is created from a dictionary and exported to a CSV file, and the whole lecture can be run with one command that prints each result. The work is delivered on the branch `mil-004-create-and-export` and one pull request.
## Deliverable
`src/weather/export.py` with `create_scores_frame` and `export_frame`, `src/weather/__main__.py` so that `python -m weather` prints the results of both lectures, and `tests/test_export.py` and `tests/test_main.py`.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | A `DataFrame` is created from a dictionary | `create_scores_frame()` has the columns `students` and `scores` and the lecture's values | Another shape or values |
| 2 | The frame is exported to CSV | `export_frame(frame, path)` writes the file; reading it back gives an equal frame | The file is missing or the content differs |
| 3 | Export never writes where it is not told to | The default file name is `new_data.csv` from `constants.py`, written to the path given; tests use only `tmp_path` | A test writes in the working directory |
| 4 | `python -m weather` prints the lecture's results | Output lists the rows, the temperatures, the average, the maximum, the Monday row, the hottest row and Monday in Fahrenheit; exit code 0 | A result is missing or the exit code is not 0 |
| 5 | The program does not write a file by itself | Running `python -m weather` in an empty folder leaves it empty, unless the flag `--export` with a path is given | A file appears without the flag |
| 6 | Tests are green | `pytest` exit code 0 | A failing test |
| 7 | The code is reviewed | `RC-*` against `QC-PY-001` has the verdict `Go` | Verdict `No-Go` or `Go-with-conditions` |
## Dependencies
| Depends on | Reason |
| --- | --- |
| [MIL-003] accepted and merged | The program prints what the analysis module computes |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Objective 7: create and export | [BC-001], criterion 6 in Success Criteria |
| Objective 10: tests with temporary files | [BC-001], criterion 7 in Success Criteria |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S01 |
| Approving reviewer | S01 |
## Target Date
2026-10-21 — fourth of five gateways, inside the plan of [PP-001] that ends 2026-10-23.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Create a DataFrame from a dictionary | Add `create_scores_frame()` in `src/weather/export.py`: a dictionary `data_dict` with `students` and `scores` is turned into a `DataFrame` with `pandas.DataFrame`, as the lecture does. The values are constants. Serves objective 7. | No | |
| 2 | Export a DataFrame to a CSV file | Add `export_frame(frame, path)` that calls `DataFrame.to_csv(path)`; the default name `new_data.csv` is a constant. Serves objective 7. | No | |
| 3 | Add the main flow | Add `src/weather/__main__.py`: print the results of both lectures in the order of the lectures; export only when `--export <path>` is given. Serves objectives 2 to 7. | No | |
| 4 | Add the tests for create, export and the main flow | Add `tests/test_export.py` (round trip through `tmp_path`) and `tests/test_main.py` (output of `main` captured with `capsys`, nothing written without the flag). | No | |
---
[BC-001]: ../business-case.md
[PP-001]: ../project-plan.md
[MIL-003]: ./mil-003-pandas-analysis.md
@@ -0,0 +1,79 @@
# MIL-005: Screenshot, wiki and finish
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-005 |
| CrossReference | [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version, reviewed in RC-008 (Go) | pending |
---
## Purpose
This gate decides whether the repository is finished for S02 and S03: a real screenshot of the program running, shown in the README and on a wiki in English, Danish and Bahasa Melayu, and the README checked against the finished program. The work is delivered on the branch `mil-005-screenshot-wiki-and-finish` and one pull request.
## Deliverable
`docs/images/weather-run.png`, the README Run section with the screenshot, and the wiki pages `wiki/Home.md`, `wiki/Home.da.md`, `wiki/Home.ms.md` and `wiki/_Sidebar.md`, in the form of the wiki of `TirSystem/github-action`.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | The screenshot is real | `docs/images/weather-run.png` is a capture of a terminal window in which `python -m weather` has run, and shows the average and the maximum temperature | A drawn or edited picture, or one that does not show the output |
| 2 | The README shows it | The Run section contains the image with alternative text | The image is missing or its path is broken |
| 3 | The wiki exists in three languages | `Home.md` (English), `Home.da.md` (Danish) and `Home.ms.md` (Bahasa Melayu) exist, each with description, functions, how to run it and the screenshot, and `_Sidebar.md` links all three | A page or a language is missing |
| 4 | The wiki refers to the screenshot on `main` | The address of the image on `main` answers HTTP 200 with an image content type | Any other status |
| 5 | The README steps work from a fresh clone | The commands of Set up, Run and Run the tests for Windows PowerShell end with a green `pytest` and the printed results | A command fails |
| 6 | Doxygen still builds | `doxygen Doxyfile` ends with 0 warnings | Any warning |
| 7 | The repository page is still complete | Non-empty description and at least 5 topics on the git host | Description empty or fewer than 5 topics |
| 8 | Every milestone is merged and its issues are closed | MIL-001 to MIL-004 pull requests merged; every issue of them closed | An open issue of an earlier milestone |
| 9 | The code and documents are reviewed | `RC-*` records have the verdict `Go` | Verdict `No-Go` or `Go-with-conditions` |
| 10 | No secret is in the change | `.env` is not tracked and no token appears in any changed file | A token is found in the diff |
## Dependencies
| Depends on | Reason |
| --- | --- |
| [MIL-004] accepted and merged | The screenshot shows the finished program |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Objective 11: README with set-up instructions | [BC-001], criterion 8 in Success Criteria |
| Objective 13: repository page and wiki | [BC-001], criterion 12 in Success Criteria |
| Objective 14: screenshot | [BC-001], criterion 13 in Success Criteria |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S01 |
| Approving reviewer | S01 |
## Target Date
2026-10-23 — last of five gateways, the end of the plan of [PP-001].
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Take the screenshot of the program running | Run `python -m weather` in a terminal window and capture that window once, with a one-off script outside the repository, into `docs/images/weather-run.png`. Say in the pull request how it was taken. Serves objective 14. | No | |
| 2 | Show the screenshot in the README | Add the image to the Run section of `README.md` and finish the Run section against the finished program (all commands, with the `--export` flag). Serves S02 and S03. | No | |
| 3 | Write the wiki in English, Danish and Bahasa Melayu | Write `wiki/Home.md`, `wiki/Home.da.md`, `wiki/Home.ms.md` and `wiki/_Sidebar.md` in the form of the wiki of `TirSystem/github-action`, each page with the description, the functions of the lectures, how to run it and the screenshot by its address on `main`. Serves objective 13. | No | |
| 4 | Verify the finished repository end to end | In a fresh clone follow the README on Windows PowerShell: set-up, run, tests, Doxygen. Check the repository description and topics and that every earlier pull request is merged. Record the result in the pull request. Serves S01. | No | |
---
[BC-001]: ../business-case.md
[PP-001]: ../project-plan.md
[MIL-004]: ./mil-004-create-and-export.md