# Project pack: Grocy @ 41206cb

Facts about **Grocy** for an AI following the [BespokeAI handover guide](https://handoff.bespokeai.software/guide/v1.md). This pack is pinned to one version and never changes after publication.

> Grocy helps you run your household. It keeps track of the food in your fridge and cupboards and warns you before things go out of date. It builds your shopping list from what is running low, plans meals from your recipes, and reminds you about chores, tasks and batteries. It runs on your own computer or server, or as a simple Windows app.

## Version and source
- Repository: https://github.com/grocy/grocy
- Pinned commit: `41206cb90154e0d17d3e108cc1f182b94fdb465d`. Use exactly this version.
- Get it: `git clone https://github.com/grocy/grocy grocy && cd grocy && git checkout 41206cb90154e0d17d3e108cc1f182b94fdb465d`
- Or download a zip: https://github.com/grocy/grocy/archive/41206cb90154e0d17d3e108cc1f182b94fdb465d.zip
- Live demo: https://demo.grocy.info. Public demo of the latest stable release, filled with example data and no login. Shared with everyone, so don't enter anything private.
- Licence: **MIT**. Free to use, change and share, even commercially. Keep the copyright and licence notice when you share it. No other obligations.

## Running it
- Easiest: docker run -d --name grocy -e PUID=1000 -e PGID=1000 -e TZ=Europe/London -p 9283:80 -v grocy-config:/config lscr.io/linuxserver/grocy:latest # community image by LinuxServer.io (linked from the README); open http://localhost:9283, # log in as admin / admin and change the password straight away
- Needs: Docker, or PHP 8.5 with SQLite 3.40+ and a web server; Grocy Desktop for Windows
- Develop: `composer install && yarn install && cp config-dist.php data/config.php   # then point a web server (or php -S localhost:8080 -t public) at the public folder`
- Stack: php, javascript, css (Slim 4, Blade templates, Bootstrap 4, jQuery). Difficulty for a non-developer with an AI: **moderate**. Plain PHP (Slim and Blade) with jQuery page scripts and one SQLite file, with no front-end build step. Almost everything can be switched on or off with settings and feature flags. Upstream does not accept code contributions, so code changes stay in your own copy.

## Customisation points (settings → extend → code)
- **feature-flags** [settings]: Hide the parts you don't use (chores, batteries, equipment, tasks, price tracking, multiple shopping lists). → `FEATURE_FLAG_* settings in data/config.php (defaults in config-dist.php) or GROCY_FEATURE_FLAG_* environment variables`
- **currency-language-calendar** [settings]: Currency, language, first day of the week and kcal or kJ. → `CURRENCY, DEFAULT_LOCALE, CALENDAR_FIRST_DAY_OF_WEEK, MEAL_PLAN_FIRST_DAY_OF_WEEK, ENERGY_UNIT in config-dist.php; per-user settings page`
- **master-data** [settings]: Your own cupboards, freezer, shops and units, plus warning periods such as "due soon" days. → `Master data menu (locations, product groups, quantity units, stores) and Stock / Shopping list / Recipes settings pages`
- **userfields-and-userentities** [extend]: Add your own fields to products, chores and more, or whole new lists such as "Wine cellar" without code. → `Master data → Userfields and Userentities (views/userfields.blade.php, views/userentities.blade.php)`
- **custom-css-js** [extend]: Change colours and layout or add small scripts without modifying the app itself. → `data/custom_css.html and data/custom_js.html (added to every page by views/layout/default.blade.php)`
- **api-and-plugins** [extend]: Home Assistant, scripts and phone shortcuts; your own barcode lookup source; label printing. → `REST API with Swagger UI at /api (grocy.openapi.json); barcode lookup plugins in data/plugins/ (example in plugins/DemoBarcodeLookupPlugin.php); label printer webhook (docs/label-printing.md)`
- **pages-and-logic** [code]: New screens and new behaviour. → `routes.php, controllers/*.php, services/*.php, views/*.blade.php, public/viewjs/*.js, public/css/grocy.css`
- **database-schema** [code]: New tables or columns. → `migrations/ (add the next numbered .sql or .php file; never edit old ones)`

## Must keep working
- The data folder (database, pictures and config). Back it up before any change.
- Stock bookings and the stock journal. Amounts must still add up after purchases, consumption and transfers.
- The REST API, which the web pages themselves and many add-ons use.
- Database changes go in a new numbered file in migrations/; never edit old ones.
- Login and per-user permissions. Change the default admin password.

## Staying updatable
Upstream does not accept code contributions, so every code change lives only in your copy and must be re-applied after updates. Prefer settings, feature flags, userfields, userentities, custom_css.html / custom_js.html and the API, which all survive updates.

## Data, costs and safety
- Personal data: **yes**. Stored in: One SQLite database in the data folder (inside the /config volume in the LinuxServer Docker image), plus uploaded pictures and data/config.php. Back up the whole data folder. update.sh creates a backup in data/backups when updating a manual install. Data includes what you buy, what you spend and household routines.
- Service: Open Food Facts (optional, free): Look up a product's name and details from its barcode (the default barcode lookup plugin).
- Service: Label printer or thermal printer (optional, hardware only): Print stock labels with Grocycodes (through a webhook) or shopping lists on a receipt printer.
- Setting `GROCY_CURRENCY`: Any setting in config-dist.php can be set as an environment variable with the GROCY_ prefix. This one sets the currency (e.g. GBP).
- Setting `GROCY_DEFAULT_LOCALE`: Default language (e.g. en_GB). Each user can also pick their own.
- Setting `GROCY_BASE_URL`: The address you open Grocy at, if it isn't at the root of a domain.
- Setting `GROCY_ENTRY_PAGE`: The first page after login (stock by default).
- Setting `GROCY_FEATURE_FLAG_CHORES`: Example feature flag. Set the matching GROCY_FEATURE_FLAG_* to false to hide chores, batteries, equipment, tasks and so on.
- Setting `GROCY_LDAP_BIND_PW` (**secret**: the person enters it themselves, never in chat): Only if you log in through LDAP. Never paste it into an AI chat.
- The default login is admin / admin. Change it immediately.
- Self-hosted with its own login. Use HTTPS before exposing it to the internet; camera barcode scanning also needs HTTPS.
- Never set MODE to demo or DISABLE_AUTH on an instance other people can reach; both turn off login.

---

# Customising Grocy

Grocy is plain PHP (Slim and Blade templates) with jQuery page scripts and a single SQLite file. **It is unusually configurable without code:** feature flags, custom fields, custom lists and a custom CSS/JS hook. Upstream does not accept code contributions, so stay on levels 1 and 2 where you can.

## Level 1: Settings (no code)
- **Config file or environment:** every setting in `config-dist.php` can go in `data/config.php`, or be set as an environment variable with the `GROCY_` prefix (e.g. `GROCY_CURRENCY=GBP`). A `.txt` file in `data/settingoverrides/` wins over both.
- **Feature flags:** set `FEATURE_FLAG_CHORES`, `FEATURE_FLAG_BATTERIES`, `FEATURE_FLAG_EQUIPMENT`, `FEATURE_FLAG_TASKS` and others to `false` to hide what you don't use.
- **Currency, language and calendar:** `CURRENCY`, `DEFAULT_LOCALE`, `CALENDAR_FIRST_DAY_OF_WEEK`, `MEAL_PLAN_FIRST_DAY_OF_WEEK`, `ENERGY_UNIT`. Each user can pick their own language on the user settings page.
- **Master data:** locations (fridge, freezer, cupboard), product groups, quantity units and stores.
- **Per-area settings:** Stock, Shopping list, Recipes, Chores and Tasks each have a settings page (for example how many days count as "due soon").
- **Users and permissions:** Users page; new users get `DEFAULT_PERMISSIONS`.

## Level 2: Extend (no fork)
- **Userfields:** add your own fields (text, number, date, checkbox, file, link…) to products, chores, batteries, recipes and more.
- **Userentities:** create whole new lists with their own fields, such as a wine cellar or a medicine cabinet, with their own menu entry.
- **Custom CSS and JS:** put HTML in `data/custom_css.html` (added before `</head>`) or `data/custom_js.html` (added before `</body>`) on every page. Good for bigger buttons, family colours or a kiosk look.
- **REST API:** Swagger UI at `/api` on your instance (spec in `grocy.openapi.json`). The web pages use the same API, so anything you can click can be scripted. Create keys under the user menu → Manage API keys.
- **Barcode lookup plugins:** put a PHP class in `data/plugins/` (see `plugins/DemoBarcodeLookupPlugin.php`) and set `STOCK_BARCODE_LOOKUP_PLUGIN`. Open Food Facts is the default.
- **Label printing:** a webhook that receives print jobs (`docs/label-printing.md`), plus optional thermal printer support for shopping lists.
- **Add-ons:** the community list at grocy.info/addons (Home Assistant, Android apps and more).

## Level 3: Code
There is no upstream `AGENTS.md`. The structure is simple:

| Change | Where |
|---|---|
| Routes | `routes.php` |
| Page controllers | `controllers/*Controller.php` (API controllers in `controllers/Api/`) |
| Logic | `services/*Service.php` |
| Page templates | `views/*.blade.php`, main layout in `views/layout/default.blade.php` |
| Page scripts | `public/viewjs/<page>.js` |
| Styles | `public/css/grocy.css`, `public/css/grocy_night_mode.css` |
| New data | next numbered file in `migrations/` (`.sql` or `.php`) |
| Text | `localization/en/strings.po` (other languages come from Transifex) |

## Running locally
- **Just use it (Docker):** `docker run -d --name grocy -e PUID=1000 -e PGID=1000 -e TZ=Europe/London -p 9283:80 -v grocy-config:/config lscr.io/linuxserver/grocy:latest`, then open http://localhost:9283 and log in as `admin` / `admin`. Change the password at once.
- **Windows without a server:** Grocy Desktop (linked from the README).
- **Develop:**
  1. Install PHP 8.5 (extensions `fileinfo`, `pdo_sqlite`, `gd`, `ctype`, `intl`, `zlib`, `mbstring`), Composer and Yarn.
  2. Run `composer install` and `yarn install` (front-end packages go into `public/packages`).
  3. Copy `config-dist.php` to `data/config.php`. Set `MODE` to `dev` for demo data with login turned off.
  4. Point a web server at `public/` (with nginx, add `try_files $uri /index.php$is_args$query_string;`).
- **Check:** there is no automated test suite. Click through the changed pages and the stock overview, and try the same action through `/api`.

## Pitfalls
- Back up the `data` folder first. It holds the database, pictures and your config.
- Database migrations run when you open `/`. They are meant to work between releases, not between every commit.
- Dates are always shown and typed as ISO (YYYY-MM-DD) on purpose. Don't "fix" this per locale.
- Camera barcode scanning only works over HTTPS.
- Code changes are never merged upstream. Keep them small, in new files where you can, and note them so you can re-apply them after each update.

---
Machine-readable: [bespoke.yaml](https://handoff.bespokeai.software/p/grocy/41206cb/bespoke.yaml) · Agent skill: [SKILL.md](https://handoff.bespokeai.software/p/grocy/41206cb/SKILL.md)
