Files
lonc/README.md
T
bblaz 054a7ad0dd
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
Add category management: list API, UI integration, and search updates
2026-05-02 22:47:46 +02:00

211 lines
8.3 KiB
Markdown

# Lonc
Lonc is a responsive PWA frontend for household kitchen stock and labeling workflows backed by Tryton APIs.
## Stack
- Vite for a lightweight client build
- Bootstrap 5 for layout and form styling
- Alpine.js for local component state and interaction
- Plain `fetch()` service modules for backend communication
- Static manifest and service worker for PWA installability
## Scripts
- `npm install`
- `npm run dev`
- `npm test`
- `npm run test:coverage`
- `npm run build`
- `npm run preview`
## Production installation
### Requirements
- Node.js 20 or newer
- npm 10 or newer
- A static web server for the generated `dist/` directory
- A Tryton backend that exposes the `kitchen` user application and kitchen endpoints
### Build for production
1. Install dependencies:
```bash
npm install
```
2. Create the production build:
```bash
npm run build
```
3. Deploy the generated `dist/` directory to your web server.
### Serve the built app
Lonc is a static frontend. In production you do not run a Node.js application server for it. You build the app once and serve the files from `dist/` with a normal static web server such as:
- Nginx
- Apache
- Caddy
- a CDN/static hosting platform
The frontend uses hash-based routing, so no special SPA history fallback is required for route handling.
### Example deployment flow
```bash
npm install
npm run build
rsync -av dist/ /var/www/lonc/
```
Then configure your web server to serve `/var/www/lonc` as a static site.
### Runtime configuration
The application does not require build-time environment variables for the Tryton connection. Users configure the following in the login screen:
- Tryton server base URL (optional, leave empty for same-origin deployment)
- database name
- user login
Authentication is done with Tryton user application keys for the `kitchen` application, not with JSON-RPC session login.
### Reverse proxy / browser requirements
If the frontend and Tryton backend are served from different origins, the Tryton server must allow cross-origin requests from the frontend origin.
If Lonc is served by the same nginx origin as the API, leave the server URL empty in the app settings so requests stay same-origin and avoid unnecessary browser CORS checks.
At minimum, production should ensure:
- `Authorization` headers are accepted for API requests
- CORS is configured for the frontend origin when origins differ
- HTTPS is enabled in production
### PWA notes
For installability and service worker support:
- serve `manifest.webmanifest` with an appropriate web manifest content type
- make sure `service-worker.js` is reachable from the deployed site root
- make sure `version.json` is reachable from the deployed site root for app update checks
- avoid aggressive caching on `index.html` during upgrades so new builds are picked up reliably
### Smoke test after deployment
After deployment, verify that:
1. the site loads from the production URL
2. login can create a Tryton user application key
3. kitchen selection loads successfully
4. stock review and label creation can reach the backend
5. the browser can install the app as a PWA
## Project structure
```text
public/
icons/
manifest.webmanifest
offline.html
service-worker.js
version.json
src/
api/
app/
components/
features/
styles/
main.js
index.html
package.json
```
## Working guide
Project-specific operating conventions for future contributors and coding agents are documented in [AGENTS.md](/Users/blaz/PycharmProjects/lonc/AGENTS.md).
## Current MVP features
- Login/configuration screen for Tryton server URL and database
- Session restore and logout shell
- Active kitchen selection and switching
- Dashboard with quick actions
- Label creation flow with item lookup, location loading, preview, and stock entry creation
- Grouped-first stock review with search and overview filters
- Stock detail page with stock adjustment workflow
- PWA manifest, icons, service worker, and offline fallback
## Tryton integration assumptions
The frontend is intentionally organized around adapter-style API modules so the exact backend contract can be finalized without rewriting screens.
Default endpoint placeholders live in [`src/app/config.js`](/Users/blaz/PycharmProjects/lonc/src/app/config.js), and the canonical URL builder lives in [`src/api/client.js`](/Users/blaz/PycharmProjects/lonc/src/api/client.js).
Expected shapes today:
- Kitchen application resources use database-scoped routes:
`/{database}/kitchen/{resource}`
- User application key management uses:
`/{database}/user/application/`
- `POST /{database}/user/application/`
Sends `{ user, application: "kitchen" }` and returns the application key as a JSON string.
- `DELETE /{database}/user/application/`
Sends `{ user, key, application: "kitchen" }` and disconnects the client.
- `GET /{database}/kitchen/kitchens`
Requires `Authorization: Bearer <application_key>` and is used as the current lightweight verification call after key approval.
Returns `{ data: [...] }` or `{ kitchens: [...] }`.
- `GET /{database}/kitchen/items?search_name=...`
Returns item definitions for autocomplete.
Item payloads now expose category links via `categories` (array of IDs).
- `GET /{database}/kitchen/items`
Returns the current stock review list. Endpoint is paginated (`limit`/`offset`, backend default `limit=100`); frontend helpers aggregate pages by default unless explicit pagination is passed.
- `GET /{database}/kitchen/items/grouped?expanded=true|false`
Returns grouped stock data; grouped review uses summary-first loading (`expanded=false`) and hydrates item children in background (`expanded=true`).
With `expanded=false`, child `items` can be ID-only stubs (`{ id }`) instead of full item payloads.
- `GET /{database}/kitchen/items/{uuid_b64}`
Returns one item detail payload.
Supports `allow_inactive=true|false` query filtering when needed.
- `GET /{database}/kitchen/changes`
Returns `{ since, next_cursor, changes }` feed payload for item/stock updates.
- `POST /{database}/kitchen/items/upsert?mode=preview|apply`
Used by label submit flow for create-or-update behavior and conflict-safe matching.
- `POST /{database}/kitchen/items/lookup`
Identifier lookup response includes source/freshness metadata (`source`, `cache_hit`, `stale_cache`, `payload_fetched_at`, `retry_after_seconds`) used for richer user feedback.
- `POST /{database}/kitchen/items/{uuid_b64}/lookup?update=true|false`
Item-scoped OpenFoodFacts lookup used by stock detail to preview (`update=false`) or apply missing fields (`update=true`).
- `POST /{database}/kitchen/items?label=true&preview=true`
Returns an image blob, `{ imageUrl }`, or `{ imageSvg }` for in-browser preview.
- `GET /{database}/kitchen/items/{uuid_b64}/label`
Returns rendered label PNG for an existing item.
- `POST /{database}/kitchen/items/{uuid_b64}/stock`
Creates a stock event for measured or descriptive updates using `{ quantity }` or `{ level }`,
and for non-consumed gone transitions (for example `{ level: "gone", gone_reason: "spoiled" }`).
Response shape is `{ status, stock }`; frontend re-fetches the item detail after successful update.
- `POST /{database}/kitchen/items/{uuid_b64}/use`
Marks an item consumed/used up (`gone`) via stock-event semantics.
- `POST /{database}/kitchen/items/{uuid_b64}/print-label`
Prints label for an existing item; called from the save flow when `Print` is enabled.
- `PATCH /{database}/kitchen/items/{uuid_b64}`
Used for item-level edits from stock detail (for example identifier code updates).
- `GET /{database}/kitchen/locations`
Returns a nested location tree.
- `GET /{database}/kitchen/categories`
Returns categories (paged). Frontend now resolves category labels from
`categories_detail` when present, and falls back to this endpoint by ID.
## Notes
- Hash-based routing is used to keep static deployment simple.
- Local storage only keeps non-sensitive app config, session payload, active kitchen, and label draft state.
- Kitchen context now lives in the URL path instead of a custom header.
- The API client now builds database-scoped kitchen routes by default; it always keeps bearer authentication handling separate from URL shaping.
- Label submit uses upsert-first apply semantics and an optional `Print` checkbox (default on for the current page session).
- Stock detail supports inline identifier editing and OpenFoodFacts refresh/apply actions with rate-limit and cache-freshness hints.