|
| 1 | +# Contributing to Decision Intelligence Logistics Engine |
| 2 | + |
| 3 | +Thank you for your interest in contributing. This document covers everything you need to get started: setting up your environment, running tests, formatting code, and submitting a pull request. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Table of Contents |
| 8 | + |
| 9 | +1. [Prerequisites](#prerequisites) |
| 10 | +2. [Fork and Clone](#fork-and-clone) |
| 11 | +3. [Environment Setup](#environment-setup) |
| 12 | +4. [Project Structure](#project-structure) |
| 13 | +5. [Running Tests](#running-tests) |
| 14 | +6. [Code Formatting](#code-formatting) |
| 15 | +7. [Branching and Commits](#branching-and-commits) |
| 16 | +8. [Opening a Pull Request](#opening-a-pull-request) |
| 17 | +9. [Reporting Issues](#reporting-issues) |
| 18 | + |
| 19 | +--- |
| 20 | + |
| 21 | +## Prerequisites |
| 22 | + |
| 23 | +- Python **3.11 or higher** |
| 24 | +- `git` |
| 25 | +- A virtual environment tool (`venv` is fine) |
| 26 | + |
| 27 | +--- |
| 28 | + |
| 29 | +## Fork and Clone |
| 30 | + |
| 31 | +1. Fork the repository on GitHub. |
| 32 | +2. Clone your fork locally: |
| 33 | + |
| 34 | +```bash |
| 35 | +git clone https://github.com/<your-username>/decision-intelligence-logistics-engine.git |
| 36 | +cd decision-intelligence-logistics-engine |
| 37 | +``` |
| 38 | + |
| 39 | +3. Add the upstream remote so you can stay in sync: |
| 40 | + |
| 41 | +```bash |
| 42 | +git remote add upstream https://github.com/chripiermarini/decision-intelligence-logistics-engine.git |
| 43 | +``` |
| 44 | + |
| 45 | +--- |
| 46 | + |
| 47 | +## Environment Setup |
| 48 | + |
| 49 | +Create and activate a virtual environment, then install all dependencies (core + dev): |
| 50 | + |
| 51 | +```bash |
| 52 | +python -m venv .venv |
| 53 | +source .venv/bin/activate # Windows: .venv\Scripts\activate |
| 54 | + |
| 55 | +pip install -e ".[dev]" |
| 56 | +pip install -r requirements.txt |
| 57 | +``` |
| 58 | + |
| 59 | +The `.[dev]` extras install `pytest`, `hypothesis`, and `black`. The `requirements.txt` adds the API dependencies (`fastapi`, `uvicorn`) and any other runtime packages. |
| 60 | + |
| 61 | +--- |
| 62 | + |
| 63 | +## Project Structure |
| 64 | + |
| 65 | +``` |
| 66 | +src/ |
| 67 | + api/ # FastAPI app and LogisticsAPI facade |
| 68 | + forecasting/ # Per-destination forecasting pipeline and models |
| 69 | + optimization/ # LP formulation and OR-Tools solver |
| 70 | + simulation/ # Stochastic scenario generation |
| 71 | + utils/ # Shared helpers |
| 72 | +tests/ |
| 73 | + forecaster/ # Unit tests for individual forecasters |
| 74 | + forecasting/ # Integration tests for the forecasting pipeline |
| 75 | + optimization/ # Tests for the optimization module |
| 76 | + utils/ # Tests for shared utilities |
| 77 | +scripts/ # Runnable end-to-end examples |
| 78 | +configs/ # YAML configuration files |
| 79 | +``` |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +## Running Tests |
| 84 | + |
| 85 | +All tests live under `tests/` and are run with `pytest`. The project uses both standard unit tests and property-based tests via `hypothesis`. |
| 86 | + |
| 87 | +**Run the full suite:** |
| 88 | + |
| 89 | +```bash |
| 90 | +python -m pytest tests/ -v |
| 91 | +``` |
| 92 | + |
| 93 | +Or via the Makefile shortcut: |
| 94 | + |
| 95 | +```bash |
| 96 | +make test |
| 97 | +``` |
| 98 | + |
| 99 | +**Run a specific module:** |
| 100 | + |
| 101 | +```bash |
| 102 | +python -m pytest tests/optimization/ -v |
| 103 | +``` |
| 104 | + |
| 105 | +**What to check before opening a PR:** |
| 106 | + |
| 107 | +- All existing tests pass. |
| 108 | +- New behaviour is covered by at least one test. |
| 109 | +- Property-based tests (if any) are not flaky — run them a couple of times if unsure. |
| 110 | + |
| 111 | +--- |
| 112 | + |
| 113 | +## Code Formatting |
| 114 | + |
| 115 | +This project uses [Black](https://black.readthedocs.io/) with a line length of **88** and a target of Python 3.11 (configured in `pyproject.toml`). |
| 116 | + |
| 117 | +**Format all source files before committing:** |
| 118 | + |
| 119 | +```bash |
| 120 | +python -m black src/ tests/ scripts/ |
| 121 | +``` |
| 122 | + |
| 123 | +Or via the Makefile: |
| 124 | + |
| 125 | +```bash |
| 126 | +make format |
| 127 | +``` |
| 128 | + |
| 129 | +**Check formatting without modifying files** (useful in CI or for a quick pre-commit sanity check): |
| 130 | + |
| 131 | +```bash |
| 132 | +python -m black --check src/ tests/ scripts/ |
| 133 | +``` |
| 134 | + |
| 135 | +Or: |
| 136 | + |
| 137 | +```bash |
| 138 | +make lint |
| 139 | +``` |
| 140 | + |
| 141 | +> Pull requests that fail the `black --check` step will be asked to reformat before merging. Running `make format` locally is the easiest way to avoid this. |
| 142 | +
|
| 143 | +--- |
| 144 | + |
| 145 | +## Branching and Commits |
| 146 | + |
| 147 | +**Branch naming:** |
| 148 | + |
| 149 | +| Type | Pattern | Example | |
| 150 | +|---|---|---| |
| 151 | +| Feature | `feat/<short-description>` | `feat/add-exponential-smoothing` | |
| 152 | +| Bug fix | `fix/<short-description>` | `fix/optimizer-infeasible-edge-case` | |
| 153 | +| Refactor | `refactor/<short-description>` | `refactor/decouple-optimize-from-forecast-config` | |
| 154 | +| Docs | `docs/<short-description>` | `docs/update-api-readme` | |
| 155 | +| Tests | `test/<short-description>` | `test/hypothesis-coverage-forecaster` | |
| 156 | + |
| 157 | +**Commits:** |
| 158 | + |
| 159 | +- Use the [Conventional Commits](https://www.conventionalcommits.org/) style: `type(scope): short description`. |
| 160 | +- Keep commits focused — one logical change per commit. |
| 161 | +- Write the subject line in the imperative mood: *"add exponential smoothing"*, not *"added"* or *"adding"*. |
| 162 | + |
| 163 | +Examples: |
| 164 | + |
| 165 | +``` |
| 166 | +feat(forecasting): add exponential smoothing model |
| 167 | +fix(optimization): handle infeasible LP when demand exceeds capacity |
| 168 | +refactor(api): make PerDestinationConfig optional for optimize-only usage |
| 169 | +test(forecasting): add hypothesis tests for pipeline edge cases |
| 170 | +``` |
| 171 | + |
| 172 | +--- |
| 173 | + |
| 174 | +## Opening a Pull Request |
| 175 | + |
| 176 | +1. Push your branch to your fork: |
| 177 | + |
| 178 | +```bash |
| 179 | +git push origin feat/your-feature |
| 180 | +``` |
| 181 | + |
| 182 | +2. Open a PR against `chripiermarini:main` on GitHub. |
| 183 | + |
| 184 | +3. In the PR description, include: |
| 185 | + - What problem it solves (reference the issue with `Closes #N` if applicable). |
| 186 | + - A brief summary of the approach. |
| 187 | + - Any trade-offs or alternatives you considered. |
| 188 | + |
| 189 | +4. Before requesting review, confirm locally: |
| 190 | + |
| 191 | +```bash |
| 192 | +make format # or: python -m black src/ tests/ scripts/ |
| 193 | +make lint # should report "All done! ✨" |
| 194 | +make test # all tests must pass |
| 195 | +``` |
| 196 | + |
| 197 | +Pull requests are automatically checked through GitHub Actions. |
| 198 | +PRs must pass all formatting and test checks before they can be merged. |
| 199 | +--- |
| 200 | + |
| 201 | +## Reporting Issues |
| 202 | + |
| 203 | +Open a GitHub Issue and include: |
| 204 | + |
| 205 | +- A short, descriptive title. |
| 206 | +- Steps to reproduce (for bugs) or a clear description of the desired behaviour (for features). |
| 207 | +- Any relevant tracebacks, logs, or code snippets. |
| 208 | +- Your Python version (`python --version`) and OS. |
| 209 | + |
| 210 | +For questions or discussion, prefer opening an Issue over a direct message so the conversation stays visible to all contributors. |
0 commit comments