The checkout form and payment-method lookup were hardcoded to the live
payment router, so any local LMS (next dev included) created real
orders: a stray test click on 20261111 produced order 1794380127.
- resolvePayBase(): NEXT_PUBLIC_PAY_BASE_URL if set, otherwise the live
router for production builds and /dev/pay-stub for everything else.
- /dev/pay-stub/pay/{methods,order}: dev-only stand-ins (404 in
production) that make no outbound calls and store nothing.
- Document in CLAUDE.md that a local `next build && next start` still
hits the live router unless NEXT_PUBLIC_PAY_BASE_URL is set.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Комментарии к урокам рендерятся через react-markdown + remark-gfm, и
это меняет то, как надо писать сами ответы. Проверено на уроке
Zotero 2.3: четыре пункта строками через «—» в ответе от 21.09
склеились в один абзац (GFM не считает тире маркером списка), а
длинный адрес с параметрами запроса автолинк обрывает на «&».
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Выяснилось при выкате писем об ответах под уроками: отправка глотает ошибки,
уведомления висят на серверном действии (а не на таблице), в проекте были две
расходящиеся копии addComment, дефолты настроек живут в коде.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Audit of the shipped Chistyy PDF feature against the actual code found
three documentation defects and one misplaced gate:
- The SSRF write-up understated the hole. assertPublicUrl resolves DNS
exactly once, for the initial URL; the in-browser filter never resolves
hostnames at all. Any new hostname after the first navigation (redirect,
subresource, fetch, ws://) goes unchecked - a DNS rebind is not even
required. Corrected in TECHNICAL.md and the design spec.
- The prod gate was tied to TOOLBOX_VISIBLE, but /api/pdf sits in
PUBLIC_ROUTES and authenticates itself, so the feature goes live the
moment browserless and BROWSER_WS_URL appear on prod - before the flag.
Gate is now tied to the renderer.
- TECHNICAL.md claimed the browserless port is published on neither
staging nor prod. It is published on dev/staging (127.0.0.1:3333) and
the SSH tunnel depends on it.
- AGENTS.md described a src/proxy.ts that does not exist; route protection
lives in src/middleware.ts.
Also adds a state snapshot (docs/plans) and a "grabli uklada" section to
CLAUDE.md covering the non-obvious conventions already enforced in code:
the two ToolUsage ids, the vitest include pattern, page.pdf() without a
timeout option, context.route not seeing WebSockets, and NEXT_PUBLIC_*
being inlined at build time.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sy7vY7WQ1A3q1MkgsDd8VB