feat(offer): live catalog price list in the public offer, served by the render sidecar
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 26s
CI / ui (pull_request) Successful in 1m13s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Failing after 16m19s

Robokassa moderation requires the public offer to list every digital good with
its price. Move /offer/ off the static landing container to the render sidecar:
it splices the live catalog price list (§4.4) into the owner-edited
ui/legal/offer_ru.md and renders it with the shared ui/src/lib/offer.ts — one
renderer, no drift, always matching the current catalog with no redeploy.

- backend: /api/v1/internal/offer/pricing (internal, off the edge allow-list)
  projects the active catalog into two markdown tables — chip packs priced per
  rail (roubles / VK votes / Telegram Stars) and chip-priced values — through
  payments.Money so no float reaches the page. Cached in memory: warmed at boot,
  marked stale on every catalog mutation, so a served render issues no query.
- renderer: GET /offer/ fetches the tables and substitutes them at the
  <#pricing_template#> marker, then renders; offer_ru.md is baked into the image
  and marked is bundled from ui. GET /offer -> 301. Only /offer/ is edge-exposed.
- caddy: route /offer/ to the sidecar; drop the now-dead landing /offer/
  handlers and the vite emit-offer plugin.
- offer: fill §4.3 (the chip-payment wording) and drop the in-page back link.
- landing footer: a feedback link (the offer's Telegram contact) beside the
  offer link.
- docs (ARCHITECTURE, FUNCTIONAL +_ru, renderer README), CI /offer/ probe,
  unit + integration + node tests.
This commit is contained in:
Ilia Denisov
2026-07-10 20:25:41 +02:00
parent a241e43d79
commit b6c2598710
32 changed files with 524 additions and 90 deletions
+9 -1
View File
@@ -80,6 +80,12 @@
**4.2.** Все расчеты по Договору производятся в безналичном порядке.
**4.3.** Порядок расчётов. Приобретаемым Товаром является внутриигровая валюта «Фишка» — условная учётная единица, используемая исключительно в пределах Сайта Продавца. «Фишки» предоставляют Покупателю возможность получения внутриигровых благ и дополнительных функций, включая, но не ограничиваясь: отказ от показа рекламы, приобретение подсказок в игре и иные внутриигровые возможности. «Фишка» не является электронным средством платежа либо денежным средством, не подлежит обмену на денежные средства и не может быть использована за пределами Сайта Продавца. «Фишки» зачисляются на внутриигровой счёт Покупателя единовременно после поступления оплаты; дальнейшее их использование для получения внутриигровых благ осуществляется Покупателем самостоятельно в интерфейсе игры.
**4.4.** Стоимость Товаров:
<#pricing_template#>
## 5. Обмен и возврат Товара
**5.1.** Покупатель вправе осуществить возврат (обмен) Продавцу Товара, приобретенный дистанционным способом, за исключением перечня товаров, не подлежащих обмену и возврату согласно действующему законодательству Российской Федерации. Условия, сроки и порядок возврата Товара надлежащего и ненадлежащего качества установлены в соответствии с Гражданским кодексом РФ, Закона РФ от 07.02.1992 N 2300-1 «О защите прав потребителей», Правил, утвержденных Постановлением Правительства РФ от 31.12.2020 N 2463.
@@ -120,7 +126,7 @@
**9.3.** Договор вступает в силу с момента Акцепта условий настоящей Оферты Покупателем и действует до полного исполнения Сторонами обязательств по Договору.
**9.4.** Изменения, внесенные Продавцом в Договор и опубликованные на сайте в форме актуализированной Оферты, считаются принятыми Покупателем в полном объеме.
**9.4.** Изменения, внесенные Продавцом в Договор и опубликованные на сайте в форме актуализированной Оферты, считаются принятыми Покупателем в полном объеме при оплате Товаров.
## 10. Дополнительные условия
@@ -143,3 +149,5 @@
## 11. Реквизиты Продавца
Денисов Илья Аркадьевич, ИНН 290210610742.
Обратная связь в Telegram: [@Erudit_GameBot](https://t.me/Erudit_GameBot).