Releases: satisfecho/pos
v2.0.5
v1.0.15
Added
Testing docs – known issues and follow-up: docs/testing.md now has a Known issues and follow-up (to address later) section: test-provider-register (unknown state), debug-reservations-public (422/time validation), login tests hitting 429 when run in quick succession, and no test data cleanup for provider/restaurant registration. Coverage summary table includes Kitchen display; cross-reference §5 → §4 fixed.
Rate limiting: API rate limits per the security roadmap: global 100 req/min per IP; login POST /token 5 per 15 minutes; register POST /register and POST /register/provider 3 per hour; payment endpoints 10/min. Uses slowapi + Redis (in-memory fallback when Redis is down). Client IP from X-Forwarded-For when behind proxy. Each 429 is logged (path, method, client). Login page shows "Too many login attempts. Please try again later." on 429. Env: RATE_LIMIT_ENABLED, RATE_LIMIT_REDIS_URL, RATE_LIMIT_* (see docs/0020-rate-limiting-production.md). Tests: test:rate-limit (API, 429 after limit), test:rate-limit-puppeteer (Puppeteer, login 6 wrong attempts → error banner).
Reservations – no-show feature (standing out): Because “they didn’t show” deserved its own status. Staff can mark as no-show (with confirmation), freeing the table and recording the outcome instead of pretending it was a cancellation. Filter and badge for no-shows; optional Send reminder for booked reservations with an email (SMTP required). Backend: ReservationStatus.no_show, status handler clears table_id; POST /reservations/{id}/send-reminder; send_reservation_reminder in email service. i18n: STATUS_NO_SHOW, NO_SHOW, SEND_REMINDER, etc. (en, de, es, fr, ca, zh-CN, hi). The one feature that admits your guests are human.
No-show – implementation plan: docs/0019-no-show-implementation-plan.md documents goals, what was implemented, step-by-step implementation plan (backend model/API/email, frontend, i18n), optional extensions (reports, view link in reminder, scheduled reminders), and a checklist. README Documentation table updated with link to the new doc.
Reports – reservations by status: Sales report now includes reservation counts by status (booked, seated, finished, cancelled, no_show). Backend: reservations_summary.by_status in _build_report_payload; Excel export Reservations sheet includes Status/Count rows. Frontend: Reports page shows “Reservations – By status” block with translated labels; SalesReport.reservations.by_status and getReservationStatusLabel(). i18n: REPORTS.RESERVATIONS_BY_STATUS (en, de, es, fr, ca, zh-CN, hi).
Products page – search: On /products, a search input above the category filters lets you filter the product list by name, ingredients, description, category, or subcategory (case-insensitive, live as you type). Works together with the existing category/subcategory ribbons. i18n: PRODUCTS.SEARCH_PLACEHOLDER (en, de, es, fr, ca, zh-CN, hi).
Per-tenant SMTP / email settings: Restaurant owners can configure their own SMTP (host, port, TLS, user, password, from address/name) in Settings → Email (SMTP). If left empty, the app uses the global SMTP from config.env. Backend: new optional fields on Tenant and TenantUpdate; GET/PUT /tenant/settings read and update them (password masked in responses). Email service uses tenant config when both smtp_user and smtp_password are set, otherwise falls back to global. Migration 20260316150000_add_tenant_smtp_email.sql. i18n: SETTINGS.EMAIL_SETTINGS, SMTP_, EMAIL_FROM (en).
Gmail setup guide: docs/0018-gmail-setup.md – step-by-step: create Gmail account, enable 2FA, create App Password at myaccount.google.com/apppasswords, then enter Gmail and password in POS → Settings → Email (SMTP).
SMTP debug script: back/scripts/debug_smtp.py – minimal script that parses config.env (handles passwords with apostrophes when wrapped in double quotes), tests SMTP connection, and optionally sends a test email. Run: PYTHONPATH=back python back/scripts/debug_smtp.py [to_email] from repo root, or pipe config.env into the back container.
Products – category labels from i18n: On /products, the main category names (Starters, Main Course, Desserts, Beverages, Sides) are now translated. Added PRODUCTS.CATEGORY_STARTERS, CATEGORY_MAIN_COURSE, CATEGORY_DESSERTS, CATEGORY_BEVERAGES, CATEGORY_SIDES in en, de, es, ca, fr, zh-CN, hi. Category filter pills, dropdowns, table column, and Categories tab use the translated labels; stored values remain in English.
Supply chain hardening (npm): Pinned all dependency versions in front/package.json and the lockfile root to exact versions (no ^/~). Added front/.npmrc with save-exact=true and ignore-scripts=true so new deps are pinned and install lifecycle scripts never run. Dockerfiles (front/Dockerfile, front/Dockerfile.prod) now copy .npmrc and use npm ci --ignore-scripts.
French (Français) locale: New language for Morocco and Francophone users. Added fr to supported languages (label "Français", locale fr-FR) and full translation file front/public/i18n/fr.json. Language picker and app UI available in French.
Translations: Review of remaining locales (de, es, ca, hi, zh-CN): removed English-only strings (e.g. Dashboard → Übersicht, Website → Webseite in German; Balance → Saldo, Stock → Existencias in Spanish), added missing keys (COMMON, MENU, ORDERS, REPORTS, RESERVATIONS, KITCHEN_DISPLAY, SETTINGS where needed), and localized placeholders (e.g. yourbusiness → example/udaharan where appropriate).
Invoice – open source footer: Printed invoices (Print invoice / Print Factura) now show a small grey line at the bottom: "Open source · Made with ♥ in Barcelona and Mexico", GitHub repo URL (plain text for print), app version, and commit hash. A separator line above this block matches the total-row line; spacing is symmetric. Styled in 9px grey. i18n: ORDERS.INVOICE_FOOTER, ORDERS.INVOICE_OSS_PREFIX (en, es, ca, de, hi, zh-CN).
Tables – confirm before closing (#18): Clicking "Close Table" now opens a confirmation modal ("Close table "…"? This will end the current session.") with Confirm and Cancel. On confirm, the table is closed and a success snackbar ("Table closed.") is shown. i18n: TABLES.CLOSE_TABLE_CONFIRM, TABLES.TABLE_CLOSED (en, de, es, fr, ca, zh-CN, hi).
Login and register – language selector (#16): The login and create-account (register) pages now include the same language dropdown as the rest of the app, in the top-right of the auth card header, so users can switch language before signing in or creating an account.
Password confirmation and show/hide (#17): Registration (tenant and provider) and user create/edit now have a "Confirm password" field; both fields must match before submit. All password inputs (login, register, provider login/register, Users modal) have an eye icon to toggle visibility. i18n: AUTH.CONFIRM_PASSWORD, AUTH.PASSWORDS_DO_NOT_MATCH, AUTH.SHOW_PASSWORD, AUTH.HIDE_PASSWORD; USERS.CONFIRM_PASSWORD, USERS.PASSWORDS_DO_NOT_MATCH, USERS.SHOW_PASSWORD, USERS.HIDE_PASSWORD (en, de, es, ca, fr, zh-CN, hi).
Reservations – email field: The table reservation (book a table) page and staff reservations now include an optional Email field. Public booking form, success confirmation, and view-by-token page show it when provided; staff list and create/edit modal display and persist it. Backend: customer_email on Reservation, ReservationCreate, ReservationUpdate; migration 20260316160000_add_reservation_customer_email.sql. i18n: RESERVATIONS.CUSTOMER_EMAIL (en, de, es, ca, fr, zh-CN, hi).
Opening hours – copy to other days and summary: In Settings → Opening hours, a "Copy from [day]" dropdown and Copy to other days button copy one day’s hours to all others. A formatted summary (e.g. "Mon–Fri 09:00–22:00, Sat 10:00–20:00, Sun closed") is shown above the grid. Public tenant API now returns opening_hours so the book page can display them. i18n: SETTINGS.COPY_FROM_DAY, SETTINGS.COPY_TO_OTHER_DAYS, BOOK.OPENING_HOURS (en, de, es, ca, fr, zh-CN, hi).
Changed
ROADMAP and README – customer accounts: Customer accounts (end-customer registration, login, email verification, MFA, order history, customer-facing invoices) are now listed under Completed in ROADMAP.md. README planned list and Roadmap section no longer list them as planned; docs table entry for docs/0002-customer-features-plan.md describes the implemented scope.
Opening hours summary – localized: The opening hours summary in Settings → Opening hours and the opening hours text on the public book page now use the current UI language: short day names (e.g. Lun, Mar, Mié in Spanish; Mon, Tue, Wed in English) via Intl.DateTimeFormat, and the word "closed" from SETTINGS.CLOSED (e.g. Cerrado, Closed, Geschlossen).
Opening hours and reservation time – 15-minute steps, 24h format: Settings opening hours and the book (reservation) page now use time selectors with minutes 0, 15, 30, 45 only, in European 24h format (e.g. 20:00). Settings: time inputs replaced by dropdowns; existing values are rounded to the nearest quarter hour. Book page: time is a dropdown, default 20:00; opening hours are shown in the hero when set. Next-available reservation slot API returns 15-minute slots.
Kitchen display: On /kitchen, only orders that have at least one item in pending or preparing are shown; within each order only those items are listed (ready/delivered/cancelled lines are hidden). Status badge and dropdown buttons use the same size as on the Orders page (min-height 44px / 48px) for thumb-friendly tapping.
Documentation: Merged GEMINI.md into AGENTS.md. Agent instructions now include project overview, architecture, setup & development (quick start, manual commands), development conventions, and key URLs in a single file.
Fixed
Logout – single click and land on login view (https://github.com...