Commit Graph

33 Commits

Author SHA1 Message Date
pavlov346346-source
2d49563b9d Add banquet packages, dish sections and guest totals 2026-09-17 21:07:54 +03:00
pavlov346346-source
57f5807953 Require account login and isolate all company client caches 2026-09-17 20:40:24 +03:00
pavlov346346-source
c18c49770d Start new companies with empty private catalogs 2026-09-17 20:27:07 +03:00
pavlov346346-source
48ffa51748 Preserve imported order history and saved order pricing 2026-09-17 20:15:32 +03:00
pavlov346346-source
11b2bf84c9 Separate account sidebar identity from company document branding 2026-09-17 19:51:01 +03:00
pavlov346346-source
c31f868c83 Apply saved theme before first paint and prevent startup flicker 2026-09-17 19:16:19 +03:00
pavlov346346-source
da8ff042f7 Restore Caterium schema and switch production to fresh Supabase 2026-09-17 17:30:57 +03:00
pavlov346346-source
2f7b8b9ea9 feat: add banquet menu constructor tab
Add a new "Банкетное меню" catalog tab (category 6) alongside Боксы/
Премиум/Посуда for composing wedding/banquet/anniversary menus. Unlike
the other tabs, dishes here are priced and weighed per guest, grouped
by menu section (catalogSection), and clicking a checkbox doesn't add
to the order directly -- it toggles inclusion in a live summary panel
showing a running per-guest price table for the whole composed menu.

The item editor gets two new fields (menu section, weight per guest)
shown only for this category, reusing the existing generic item CRUD
(editBox/saveBox) rather than building a parallel admin UI.

Also re-bumped index.html's script cache-busting query string, which
the previous whitelist-fix commit changed the content of app-runtime.js
without updating -- the same stale-cache bug fixed earlier in the
session, now closed for directly-tagged scripts too.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 18:02:02 +03:00
pavlov346346-source
7446a551f6 fix: allow premium-dark/premium-emerald in template id whitelists
Two separate Set-based whitelists (OFFER_TEMPLATE_IDS in app-runtime.js
and TEMPLATE_IDS in ux-fixes-v1764.js) validated any explicit template
selection before persisting/rendering it, but neither had been updated
when premium-dark/premium-emerald were added. The per-order "Оформление
PDF" picker's click handler calls persistOfferTemplate(), which silently
returned false when the id failed this check -- so clicking either
premium card in an order's offer modal did nothing, no error, no toast.
Verified end-to-end against a real order: both ids now persist and the
picker shows the selected state correctly.

Also bumped performance.js's internal RELEASE tag, since it gates the
cache-busting query string used to dynamically load ux-fixes-v1764.js
and eight other core modules -- otherwise this fix would hit the same
stale-cache issue just fixed in index.html.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 13:46:15 +03:00
pavlov346346-source
14e3d6b45b fix: merge addon pills into one card, wire it to editable Settings
Two related fixes reported directly against live screenshots:

1. addonRow rendered each addon ("Напитки", "Чайная станция", ...) as
   its own tall bordered pill sitting side by side -- disjointed, and
   unlike the single-card "Полезные дополнения" treatment in the
   referenced design. Now draws one card with a heading
   ("Рекомендуем добавить") containing all the icon+label items,
   matching how checklistCard already works.

2. The addon list and the "Всё под контролем" checklist were hardcoded
   constants in the canvas module, completely bypassing the app's
   existing editable Client Offer Settings (Настройки → Предложение →
   "Дополнительно к заказу", textarea-backed extraServices/controlLines
   the user can already edit for the old templates). preparedSnapshot
   now attaches the resolved controlLines/extraServices/titles onto
   every snapshot; the 8 signature templates read them via a local
   shadowing const (falls back to the previous defaults when nothing
   is configured), so editing that Settings textarea now actually
   changes what shows up in these templates too, on all 8 of them from
   one change since addonRow/checklistCard are shared helpers.

Verified locally: default list (6 items) lays out cleanly in one card
with 2-line wrapping where needed; a snapshot with custom
controlLines/extraServices renders those exact custom strings instead
of the defaults, confirming the wiring actually works end to end and
isn't just falling back silently.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 11:28:18 +03:00
pavlov346346-source
44bf5e9af1 feat: add 2 new templates modeled on the referenced menu.furset.ru design
User pointed at https://menu.furset.ru/view/23855347 as a design they
like and asked for a couple more templates in that direction. Added:

- premium-dark: near-black background, warm gold accents, real
  line-drawn icon badges (calendar/people/box -- not emoji) for the
  date/guests/boxes stats, bullet-point value props under the title,
  minimal flat menu list -- closely matching that reference's visual
  language instead of the card-heavy style of the existing templates.
- premium-emerald: the same layout in an emerald-green palette, as
  the second "couple" of designs requested, sharing the cover code
  with premium-dark and only differing by PALETTES entry.

Both plug into the existing shared renderContentPages engine, so they
get proper multi-page menu + pricing pages for free, consistent with
all 6 existing signature templates. New icon-drawing helpers
(iconBadge/iconCalendar/iconPeople/iconGauge/iconBox, statBadgeRow,
bulletList) live in the shared helper section for reuse.

Verified locally: both render in <70ms combined, produce 3 pages each
for a normal order, and hold up under the same adversarial-data pass
used for the other 6 (long names, 350 guests, seven-figure price,
item with no photo/price/category) -- no overlap, no crashes, generous
ellipsis truncation throughout. Fixed one real bug found while
testing: the date value in the stat badge ("8 августа 2026 г.") was
getting ellipsis-truncated at font-size 20px; reduced to 16px so it
fits cleanly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 11:11:43 +03:00
pavlov346346-source
d78ca14baf feat: bring the other 4 signature templates up to the same quality bar
- Fix the price band on cream-elegance: it was a solid muddy olive
  fill that didn't read as "this is your total" (reported directly by
  the user). It's now a white card with a gold border, matching the
  rest of that template's light card language; the dark templates'
  solid-fill price band is unchanged since that already reads well
  against a dark background.
- Give emerald-circles, midnight-checklist, gourmet-hero and
  diamond-gold the same treatment as the first 2: real fonts
  (Playfair Display/Montserrat or Unbounded/Manrope depending on
  aesthetic) instead of Arial/Georgia, the same center-alignment fixes
  applied everywhere text used align:'center', and their own
  fully-styled inner pages (menu + pricing) via the shared
  renderContentPages engine instead of the old generic base renderer.
- Fix two real regressions the font swap introduced and caught by
  rendering each template locally: gourmet-hero's headline was
  overflowing width and getting ellipsis-truncated ("КЕЙТЕРИНГ..."),
  and diamond-gold's heading was wrapping to a second line that
  collided with the subtitle below it. Both fixed with size/width
  adjustments verified by direct canvas measurement.
- All 6 signature templates are selectable in Settings again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 10:14:25 +03:00
pavlov346346-source
c0bb18d5f7 fix: polish the 2 kept offer templates — alignment, fonts, gallery
- Fix a systemic centering bug: several canvas text() calls used
  align:'center' but passed the box's left edge as x instead of its
  midpoint, so headings, badge numbers, checkmarks and chip labels
  rendered pinned to the left instead of centered (most visible on
  cream-elegance's "МЕНЮ" heading and neon-menu's guest badge).
- Fix cream-elegance's category icons: the emoji glyph was never
  actually passed into iconCircle, so the icon circles rendered empty.
- Even out cream-elegance's bottom row (stat cards vs price band had
  mismatched heights).
- Load distinctive Cyrillic-friendly type pairs instead of default
  Arial/Georgia: Playfair Display + Montserrat for cream-elegance,
  Unbounded + Manrope for neon-menu, awaited via the Font Loading API
  before each render so text never draws in the fallback face.
- Narrow the Settings gallery to just these two templates per request
  ("остановимся на 2х пдф пока"); the other 4 signature designs and
  the original 13 classic templates stay intact and renderable for any
  order that already used one, just not offered for new ones.

Verified via a local static server (public/, http-server) with a real
uploaded box photo run through window.SunSignatureOfferPDFV18 and the
production sunClientOfferDebugPdfPages pipeline directly — 3 pages,
no duplicate cover, both fonts confirmed loaded via document.fonts.check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 08:49:39 +03:00
pavlov346346-source
90482d0e7d fix: stop signature PDF pages from double-rendering a cover
renderOfferPdfPages routed the signature templates' inner pages back
through the classic module's own renderPages, which drew its own
extra cover page on top of the real content pages -- doubling the
render work and producing an extra page. Route straight to the plain
base renderer instead. Also await the gourmet-hero template's photo
cards instead of firing them off unawaited.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 18:42:32 +03:00
pavlov346346-source
b92b52e03e feat: add 6 new client-offer PDF templates, archive the old 13
New "signature" template pack (cream-elegance, neon-menu,
emerald-circles, midnight-checklist, gourmet-hero, diamond-gold)
replaces the visible template gallery in Settings. The previous 13
classic/archive templates keep rendering correctly for any existing
order that already used one, but are no longer selectable for new
orders — nothing was deleted.

Also adds a Settings option to upload a custom logo and company name
for PDF documents, replacing the hardcoded "Солнце Кейтеринг" branding
wherever a logo fails to load.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 18:27:23 +03:00
pavlov346346-source
3610927a33 fix: restore write permissions in local-only mode
RBAC permission checks (has()) always deferred to the cloud
workspace's role, which is null when using "work locally without
internet" — so every guarded action (save/delete order, edit catalog,
etc.) was blocked with "no permission" even though there is no
workspace to restrict against. Local-only mode now grants full access,
matching how nav permissions already behave with no cloud session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 17:49:05 +03:00
pavlov346346-source
26681195b0 fix: accept emergency export format in Settings backup restore
The Settings "load from file" button only understood its own
sun-catering-backup format. Extend it to also read the
caterium-full-export format produced by the browser-console
emergency export (localStorage + IndexedDB), so an already-downloaded
export file can be restored directly through the UI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 17:30:31 +03:00
pavlov346346-source
345ee8e052 feat: add JSON file backup export/import to Settings
Lets users download the local database as a JSON file and restore it
from a file, independent of cloud sync — needed while Supabase is
unreachable to move data between computers or recover after an outage.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 17:29:32 +03:00
pavlov346346-source
caa13eca59 feat: add "work locally without internet" option to login gate
When Supabase is unreachable, employees were stuck on the login
screen with no way in, even though the app is fully usable offline
(orders, catalog, stock, etc. all live in localStorage already).

Adds a low-key link on the login screen that sets a local-only flag
and skips the auth gate entirely until a real cloud sign-in succeeds
(which clears the flag). Deliberately does not touch any cloud/session
state, so it can't trigger an automatic cloud pull that would overwrite
data created while working offline.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 16:57:56 +03:00
pavlov346346-source
834557e865 fix: show real error text instead of "[object Object]" in auth gate
String(err) on a plain object (a PostgrestError-shaped object without a
.message, or any non-Error rejection) renders as the literal string
"[object Object]" with no useful information. Added errText() that
prefers err.message, falls back to JSON-stringifying the object, and
only then falls back to a generic message - and applied it to the three
catch blocks in the login/company-creation gate flow (auth(), the
pending-registration finisher, and the "retry workspace access" button),
which is what surfaced the raw "[object Object]" during login.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 17:30:17 +03:00
pavlov346346-source
5d73b2c37e Route Supabase REST/Auth/Storage/Functions traffic through api.caterium.ru proxy
The api.caterium.ru PHP reverse proxy has been deployed and verified end-to-end
(curl tests plus live authenticated RPC calls through a real browser session).
This switches the client's Supabase fetch calls to go through the proxy so
requests from Russia work without a VPN. Realtime's WebSocket connection is
unaffected since it doesn't go through fetch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 02:50:37 +03:00
pavlov346346-source
aafad18d6a fix: remove the racy forced password-change gate for new employees
showPasswordChangeGate() replaced the auth gate's content and returned,
but the same login also fires onAuthStateChange, which kicks off
loadMemberships() independently. Once that resolved (workspace found),
ensureAuthGate()'s periodic poll (every 5s, plus assorted event-driven
calls) saw signedIn+workspace and tore the gate down immediately,
regardless of whether a password-change form was currently blocking
it - the employee would see the "create a new password" screen flash
and vanish before they could use it, dropping them straight into the
app still on their temporary password.

Removes the forced gate entirely (mustChangePassword/
showPasswordChangeGate) and adds a "Пароль" box to the account
settings card instead, so changing your password is a deliberate,
always-available action rather than a one-shot dialog racing the rest
of the login flow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 01:59:36 +03:00
pavlov346346-source
4afde880d2 revert: back out the api.caterium.ru fetch rewrite for now
The previous commit accidentally carried over an uncommitted proxy
cutover (supabaseProxyFetch wired into createClient's global.fetch)
that was left sitting in the working tree from an earlier, paused
verification session - it was never meant to ship without first
completing the full checklist (auth, clients, orders, Storage,
Functions) against the live proxy. Reverting just that piece so
main goes back to calling cksuehzcimitsxmeloes.supabase.co directly,
keeping the "Загрузить из облака" button fix from the same commit.
The proxy cutover will come back once it's actually been verified
end-to-end.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 18:37:56 +03:00
pavlov346346-source
38a4ba47eb fix: restore the missing "Загрузить из облака" button in settings
bindCloudUI() already wires a click handler on #sunCloudPullV2
(confirm dialog -> pullRemote({replace:true, quiet:false}), which
backs up the local copy and force-replaces it with the server's
orders/clients/etc.), but renderCloudUI()'s template never actually
emitted a button with that id - the handler was permanently a no-op.
Adds the missing button to the "Профиль и аккаунт" settings card.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 18:35:20 +03:00
pavlov346346-source
09d54682c2 fix: add timeout and error handling to loadMemberships
Every other cloud RPC call goes through sunCloudAwait (12s timeout),
but loadMemberships() (which resolves which workspace to open right
after login, showing "Загружаю рабочую базу...") called client.rpc/
.from directly with no timeout and no catch. A single slow or dropped
request left the auth gate stuck on that message forever instead of
surfacing a retryable error - there's already a "Проверить ещё раз"
button wired to reloadMemberships(), but nothing ever told the user
they needed to press it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 15:50:04 +03:00
pavlov346346-source
4aa66d0a56
Caterium v17.7.3 — clients server read
Server-preferred normalized client profiles with legacy fallback, canonical snapshot RPC, preserved order metrics, release metadata and tests.
2026-09-09 12:07:37 +03:00
pavlov346346-source
815cc602c5
Caterium v17.7.2 — clients foundation
Canonical client identity, client data layer, legacy loyalty/communication compatibility, normalized Supabase client RPC, release metadata and tests.
2026-09-09 10:42:14 +03:00
github-actions[bot]
b6ec42b2e2 Caterium v17.7.1 - data layer adoption 2026-09-08 23:34:45 +00:00
pavlov346346-source
f8bb0a78b4
Caterium v17.7.0 — architecture foundation
Introduce the first data layer, move order auto-completion to server cron with legacy/cloud compatibility, clean error telemetry, update PWA/versioning, and add regression coverage.
2026-09-08 13:24:34 +03:00
pavlov346346-source
a3616b7387
Caterium v17.6.7 — restore classic client proposal PDFs
Restore presentation-style client proposal PDFs with 10 classic designs, 3 hidden archive templates, and exact preview/download canvas parity.
2026-09-08 07:29:40 +03:00
pavlov346346-source
cd776d5647
Caterium v17.6.6 — proposal templates and Menu icon
Fix Menu sidebar icon alignment and make all four client proposal templates structurally distinct in preview and PDF.
2026-09-08 07:01:35 +03:00
pavlov346346-source
71d9cdc92e
Caterium v17.6.5 stability hardening
* Prepare v17.6.5 stability hardening patch

* Move v17.6.5 stability patch logic to script

* Fix v17.6.5 stability patch workflow

* Harden Caterium v17.6.5 stability

* Remove one-time v17.6.5 patch workflow

* Remove one-time v17.6.5 patch script

* Update static stability checks for v17.6.5

* Fix v17.6.5 E2E version expectation

* Update v17.6.5 E2E version expectation

* Remove one-time v17.6.5 test patch workflow

* Capture failing v17.6.5 E2E diagnostics

* Capture v17.6.5 E2E failures

* Make v17.6.5 stability E2E deterministic

* Make v17.6.5 E2E checks deterministic

* Remove one-time deterministic E2E workflow

* Remove one-time E2E diagnostic workflow

* Remove temporary E2E diagnostics

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-08 05:55:48 +03:00
pavlov346346-source
2cd5c3404f Caterium v17.6.0 - GitHub Cloudflare autodeploy 2026-09-07 15:29:20 +03:00