All notable changes to this project are documented in this file.
The format follows Keep a Changelog. Versions are listed newest first. Entries use past tense, one line per item where possible, and emphasize user-visible impact. Issue numbers in parentheses point to GitHub when they add context.
Versioning: Semantic Versioning (MAJOR.MINOR.PATCH): incompatible API or behavior → major; backward-compatible features → minor; fixes and small improvements → patch.
- Reservations / opening hours: database-backed planned weekly patterns (effective from a date) and date-range overrides (closed or alternate weekly-style hours); staff manage entries under Settings → Opening hours. Public
/reservations/book-*endpoints and reservation validation resolve effective hours per calendar date (#194).
- API / rate limiting: centralized SlowAPI helpers in
back/app/rate_limits.py;admin_user_limiton included routers (/inventory,/reports(incl. attendance Excel),/staff-contracts,/staff-contract-templates,/tenant/data-export,/tenant/purge);public_menu_ip_limiton public tenant discovery (/public/tenants*,/public/legal-urls) andGET /internal/validate-table/{table_token}.docs/0020-rate-limiting-production.mdupdated (#193). - Repository: ignored
claude-session.logandagents2/001-gh-reviewer/time-of-last-review.txt(001 reviewer local stamp) so routine agent runs do not produce recurring diffs; stopped tracking the stamp file in Git. - Agents:
AGENT_COMMITTER_LOCAL(default on) andAGENT_COMMITTER_USE_CURSOR(default off):agents2/pos-cursor-loop.shcommitter runsgit commit/git pushlocally when the only dirty paths areagents2/001-gh-reviewer/time-of-last-review.txt; setAGENT_COMMITTER_USE_CURSOR=1to run040-committer.mdviacursor-agentfor fullCHANGELOG.md/ version handling. - Agents:
AGENT_001_LOCAL_LOG_REVIEWER(default on):agents2/pos-cursor-loop.shskipscursor-agentfor 001 when only Docker log heuristics fire andG001_GH_OK=1with zero untracked issues; appends a stamp toagents2/001-gh-reviewer/time-of-last-review.txt; digest and Ollama triage stay local.AGENT_001_LOCAL_LOG_REVIEWER=0restorescursor-agentfor that case.have_cursor_agentis checked only when the gate would invokecursor-agent. - Agents: 001 log triage (
scripts/agent-ollama-log-triage.sh): Ollama first by default, then llama.cpp (AGENT_001_LLAMA_CPP_FIRST=1restores llama-first); one alternate-backend attempt if the primary reply is ambiguous; stricter SKIP/ESCALATE prompt and last-word parse; defaultOLLAMA_MODELGemma4:latest(loop passes it explicitly); optionalAGENT_001_LOG_TRIAGE_DEBUG=1;docs/agent-loop.mdupdated for triage order and whencursor-agentstill runs for 001. - Agents: GitHub reviewer (001) recorded latest preflight run in
agents2/001-gh-reviewer/time-of-last-review.txt. - Tables floor plan: payment chip on the SVG aligned with the bottom of the table shape; pill and label scale on very small shapes (#188).
- Tables / payments:
GET /tables/with-statuspreservespayment_status: pendingwhen kitchen orders are ready or completed and a bill was still relevant; improved detection of active order andbill_requested_at(#189). - Orders / tables: staff mark paid and finish order no longer cleared
bill_requested_at, so after unmark paid the floor plan still showed payment pending when a bill had been requested (#190).
- Marketing deploy:
sync-all-marketing-sites.shhonorsMARKETING_VERIFY_NO_PLACEHOLDERS=1(set indeploy-amvara9fetch step): if anyconfig/marketing-sites.jsonslug still hasbundle not loadedafter sync, the workflow fails instead of deploying placeholders. Typical cause: PAT scoped only to040_gustazowhile010_antillanaand other repos need Actions artifact access.
- Documentation:
config.env.example— PAT must cover every listed marketing repo, not Gustazo alone.
- CI / amvara9:
deploy-amvara9runs on push tomasteronly (workflow_dispatchunchanged); removeddevelopmentfromon.pushso commits todevelopmentno longer trigger deploy or front/back builds.
- Deploy (amvara9) / marketing: rsync of
front/sites/now runs aftergit reset --hardon the server. Previously, reset restored committed placeholders and overwrote the CI-fetched bundles, so production (e.g./gustazo/) served the stub page. Deploy still needsGUSTAZO_ARTIFACT_TOKEN(orMARKETING_ARTIFACT_TOKEN) in GitHub for the “Fetch marketing” step. Smoke warns if Gustazo HTML still contains “bundle not loaded”.
- Production nginx:
marketing-sites.generated.confis written to/etc/nginx/snippets/, notconf.d/. Files underconf.d/*.confare merged athttpcontext;locationblocks there are invalid (directive is not allowed here).default.confnow **include**s the snippets file only inside theserverblock.
- Production nginx:
includefor marketing static sites now uses an absolute path (see 2.0.80 forconf.dvssnippets). The previous relativeinclude marketing-sites.generated.confresolved to/etc/nginx/marketing-sites.generated.confand nginx failed to start (open() … failed (2: No such file or directory)),pos-frontrestarted in a loop, HAProxyfrontend_backendreturned 503 on/.
- Production (amvara9): Promotes the current
developmentline, including multi-repo marketing static sites (front/sites/<slug>/, generated nginx locations, deploy-timesync-all-marketing-sites.shwithMARKETING_ARTIFACT_TOKEN) as documented in 2.0.76 and 2.0.77.
- Marketing:
config/marketing-sites.jsonaligned with satisfecho GitHub org repos010_antillana,020_dilruba,030_flamanapolitana,040_gustazo,050_hakone(paths/antillana/…/hakone/);040_gustazoartifactgustazo-dist, branchmain. Placeholderfront/sites/<slug>/trees for packaging and nginx generation.
- Marketing SPAs (repos named
NNN_slug, three digits + underscore):config/marketing-sites.jsonlistsslug,repo,branch,artifact, optionalcloneDir, andautoDiscoverSiblingReposto scanPOS_REPO_ROOT/../*for^[0-9]{3}_*/package.json.scripts/sync-all-marketing-sites.shfillsfront/sites/<slug>/from GitHub Actions artifacts (curl/jq, tokenMARKETING_ARTIFACT_TOKENwith fallbacksGUSTAZO_ARTIFACT_TOKEN/GH_TOKEN) or runsng buildin a sibling clone with--base-href /<slug>/.flatten-marketing-for-angular.shmirrors intofront/marketing-flat/<slug>/fordevelopment-no-ssr;front/scripts/generate-marketing-nginx-include.shemits nginxlocationblocks at prod image build. scripts/fetch-marketing-artifact.sh— generic artifact download;scripts/fetch-gustazo-artifact.shremains a thin wrapper forfront/sites/gustazo.scripts/sync-gustazo-for-dev.shdelegates tosync-all-marketing-sites.sh.- Local dev: optional sync on
pos-frontstart viaSYNC_MARKETING_ON_START(fallbackSYNC_GUSTAZO_ON_START).docker-compose.dev.ymlcontinues to mount./scriptsand.:/repowithPOS_REPO_ROOT=/repo.
- Deploy (amvara9): workflow runs
sync-all-marketing-sites.shand rsync’sfront/sites/to the server before build;Dockerfile.prodcopiesfront/sitesto/usr/share/nginx/html/sites/and includes generated per-slug nginx config;nginx.confno longer hard-codes Gustazo-only locations. docker-compose.yml: documentsMARKETING_ARTIFACT_TOKEN;config.env.examplecomments updated accordingly..gitignore:front/marketing-flat/.
- Tables floor plan:
GET /tables/with-statusexposespayment_status(none|pending|paid) and keepsoperational_statusfor kitchen / service only. Table fill and legend reflect service state; payment uses a bottom chip on each table SVG.bill_requested_atdrivespending; a still-referenced paid order can showpaid. Joined groups mergepayment_statuslikeoperational_status. FrontendCanvasTable.payment_status, i18nTABLES.PAYMENT_*/TABLES.LEGEND_PAYMENT_*. Tests:back/tests/test_tables_with_status_operational.py(#187).
- Landing: removed the For restaurant staff block and Create staff account CTA; For guests card centered with a max width (#183).
- Tables floor plan: Ready to serve vs payment pending;
bill_requested_atdrives pending state (#186). Legend Ready to serve for bill issued (#185). - Tables / reservations: POST /tables/{id}/close marks seated reservations finished like the finish-reservation flow, so tables are not shown occupied only due to an old seated booking (#184).
- Reports: Spanish registro horario monthly Excel export (#170).
- Google Review settings: i18n strings for public review description and instructions; settings screen uses clearer labels (#176).
- Public booking page: stronger frosted hero panel; Website link gets a normalized
https://URL and hostname as link text (#173). - Tables canvas: on load and when switching floors, the view fit and centered tables with padding; Reset uses the same logic; repeat refreshes no longer reset pan/zoom (#172).
- Staff tables: joined groups appear as one list row and one tile; Activate / Open menu warn when another group member has a session or order; optional activity badges and floor-plan dot (#174).
- Orders: while a line-item status menu is open, the order card uses the same elevation as the order-level menu so dropdowns are not covered by the next card (#179).
- Landing: hero inner container widened for large viewports (#181). Staff panel hint merged into main copy; removed redundant hint key (#182).
- Tables: DELETE /tables/{id} no longer blocked after orders were soft-deleted; soft-delete clears
order.table_id(migration + canvas queries ignore soft-deleted orders for “open order” checks) (#180). - API: when PostgreSQL is unreachable, DB-backed endpoints return 503 with JSON
detailinstead of a generic 500. - English locale: restored full
front/public/i18n/en.jsonafter a fragment had broken the UI (#178). - Frontend:
TenantSummaryinapi.service.tsextended to match the backend (take_away_table_token, reservation fields), fixing template compile errors on book and reservation views. - Reports: monthly attendance Excel — staff filter hint appears above the dropdown (#171).
- Reports: monthly attendance Excel with
staff_idsno longer returned 500 (Excel styling no longer shadowedsqlmodel.col) (#168).