# How-to Guides

Task-oriented recipes for maintaining the app. If you want to understand *why* things are built this way, see [Explanation](../../user-guide/explanation/index.md) instead. For the test suite specifically, see [Run the Tests](../../user-guide/how-to/run-tests.md).


# Regenerate the workout data

`src/daily_dose/data/workouts.json` and `src/daily_dose/www/images/` are generated by `scripts/build_workouts_data.py`. Re-run it after editing the legacy Rmd source (kept at `scripts/_rmd_src/`) or the workout photos.

The original photos aren't kept in this repo. They're 325MB of raw phone photos, compressed down to ~21MB in `www/`. To regenerate from scratch:

1.  Install the script's one extra dependency (already in the `dev` extra): `Pillow`.

2.  Restore the original photos from the `rmarkdown-archive` branch, which still has them:

    ``` bash
    git archive rmarkdown-archive -- images | tar -x
    ```

3.  Run the build script:

    ``` bash
    python3 scripts/build_workouts_data.py
    ```

    It parses all five Rmd files, matches dated photos in `images/`, prefers the typed entry on any date that has both, and writes the deduplicated result to `workouts.json`. Every photo it keeps is re-encoded as a downsized JPEG (~1600px max dimension, quality 82) into `src/daily_dose/www/images/`.

    If a date heading in the Rmd source is malformed in a way the parser can't safely handle (wrong heading level, trailing text after the date, …), the script raises `ValueError` naming the file and line instead of silently merging it into the previous entry. See [Design Notes](../../user-guide/explanation/index.md) for why.

4.  Remove the restored source photos, which aren't meant to be committed:

    ``` bash
    rm -rf images/
    ```

5.  Confirm the data is sane:

    ``` bash
    uv run pytest tests/test_data.py
    ```


# Update the tutorial screenshots

The screenshots in [Tutorials](../../user-guide/tutorials/index.md) are checked-in PNGs, not generated at build time, so a UI change won't update them on its own. To refresh them:

1.  Launch the app: `shiny run daily_dose.app:app`
2.  Install a headless browser once: `pip install playwright && playwright install chromium`
3.  Drive the running app with Playwright, screenshotting each state: initial load, after clicking **Random Workout**, and after clicking **On This Day**. Run **Random Workout** a few times to catch both a text and a photo entry.
4.  Save the results into `tutorials/assets/`, overwriting the existing files by name.


# Deploy to Posit Connect Cloud

[Connect Cloud](https://docs.posit.co/connect-cloud/how-to/python/shiny-python.html) deploys straight from a public GitHub repo, but it has two fixed expectations that don't match this project's layout: the app object must be importable from an `app.py` **at the repo root**, and dependencies come from a `requirements.txt`, not `pyproject.toml`. Both files already exist here for exactly that reason, and you shouldn't need to touch either:

- `requirements.txt` (repo root) holds a plain `shiny[theme]>=1.0.0`, mirroring `pyproject.toml`'s `[project.dependencies]` by hand. It has to be a real dependency list: Connect Cloud's resolver doesn't run `pip install -e .`, so an editable-install line here just fails outright (`Error determining requirements: / does not appear to be a Python project`) instead of installing anything, `daily_dose` included.
- `app.py` (repo root) is a shim. Since `daily_dose` is never actually installed on Connect Cloud, it puts `src/` on `sys.path` before importing `from daily_dose.app import app`. Local development still uses `daily_dose.app:app` directly (see the [Tutorials](../../user-guide/tutorials/index.md) launch command); this file exists only for Connect Cloud's sake.

To deploy:

1.  Make sure the repo is public and the latest commit is pushed to `main`. Connect Cloud deploys from GitHub, not a local push.
2.  Sign in to [Connect Cloud](https://connect.posit.cloud) and click **Publish**.
3.  Choose **Shiny** as the app type and select this repository.
4.  Confirm the branch (`main`) and the primary file: `app.py` at the repo root, the shim, not `src/daily_dose/app.py`.
5.  Click **Publish**.

To publish an update later, push to `main` and use the republish action in Connect Cloud's content list. It re-clones the repo and reinstalls from `requirements.txt`, so there's no separate build step on your end.


# Rebuild the docs site

One command from the repo root rebuilds the whole site:

``` bash
great-docs build
```

That's the homepage from `README.md`, this guide, Explanation, and the API Reference from `daily_dose.core`'s docstrings, all written into `great-docs/_site/`.
