fix(subscriptions): correct Ollama typo, drop Kimi K3, restore footer GitHub icon #19

Closed
opened 2026-08-07 18:15:18 +03:00 by slaid098 · 0 comments
Owner

Контекст

Зачем: на сайте slaid098-dev (Next.js 15 App Router + React 19 + TS + Tailwind v4, bilingual i18n через src/lib/i18n.ts) накопились три мелких бага контента/UI: опечатка в карточке Ollama, устаревшее упоминание модели в карточке Synthetic.new и подменённый иконок в футере.

Контекст:

  1. В карточке Ollama (RU) пропущена запятая: «как Pro так и» вместо «как Pro, так и» — нарушает правило русской пунктуации при двойном союзе.
  2. В карточке Synthetic.new (RU + EN) упоминается модель «Kimi K3». Провайдер может сменить модель в любой момент — называть её в копи-тексте немaintainable.
  3. В src/components/site-footer.tsx (строки 28–30) рендерится «точка в круге» (radio-button/target dot, viewBox 0 0 24 24, path M12 2C6.48 2...zm0 18c-4.41...zm-3-9c0-1.66...). Это заменило оригинальный GitHub-octocat SVG в коммите 9ab8d5c (PR #15, 2026-08-07) — commit message утверждал «forgejo svg», но путь является радиокнопкой, а не настоящей маркой Forgejo. Ссылка осталась на https://git.slaid098.dev/slaid098 с aria-label="Forgejo" — меняется только видимый глиф.

Задача

Файл 1: src/lib/i18n.ts

Объект subscriptions.cards хранит 4 карточки, индексы позиционно соответствуют SUBSCRIPTIONS в src/lib/subscriptions.ts (порядок: 0=OpenCode Go, 1=Synthetic.new, 2=Ollama, 3=Umans). RU-блок в строках 160–189, EN-блок в строках 275–304. Каждая строка в descriptions рендерится отдельным <p> на /[locale]/subscriptions.

Редакт 1 — строка 179 (RU, карточка Ollama, индекс 2):

  • Текущий текст: Прозрачный расчёт за серверное время: экономишь токены — получаешь больше запросов. Тестировал, как Pro так и Max.
  • Целевой текст: Прозрачный расчёт за серверное время: экономишь токены — получаешь больше запросов. Тестировал, как Pro, так и Max.
  • Изменение: добавить запятую после Proкак Pro, так и.

Редакт 2 — строка 174 (RU, карточка Synthetic.new, индекс 1):

  • Текущий текст: Скользящие лимиты: 5-часовой и недельный, оба постоянно восстанавливаются. Лимиты масштабируются пакетами. Внутри — Kimi K3.
  • Целевой текст: Скользящие лимиты: 5-часовой и недельный, оба постоянно восстанавливаются. Лимиты масштабируются пакетами.
  • Изменение: удалить хвостовую Внутри — Kimi K3. (текст заканчивается на ...пакетами.).

Редакт 3 — строка 289 (EN, карточка Synthetic.new, индекс 1):

  • Текущий текст: Sliding limits: 5-hour and weekly, both continuously refill. Limits scale in packages. Inside — Kimi K3.
  • Целевой текст: Sliding limits: 5-hour and weekly, both continuously refill. Limits scale in packages.
  • Изменение: удалить хвостовую Inside — Kimi K3. (текст заканчивается на ...packages.).

Редакт 4 — строка 184 (RU, карточка Umans, индекс 3, первое описание):

  • Текущий текст: Успел попробовать подписку за 20 USD. Было 400 запросов на 5 часов без недельных лимитов. Code Max попробовать не успел. Единственным ограничением было количество одновременных потоков. Без 5-часовых и недельных лимитов.
  • Целевой текст: Успел попробовать подписку за 20 USD. Было 400 запросов на 5 часов без недельных лимитов. Code Max попробовать не успел. Единственным ограничением было количество одновременных потоков.
  • Изменение: удалить хвостовую Без 5-часовых и недельных лимитов. (повторяет «без недельных лимитов» из середины предложения).

Редакт 5 — строка 299 (EN, карточка Umans, индекс 3, первое описание):

  • Текущий текст: Tried the $20 subscription. Had 400 requests per 5 hours with no weekly limits. Didn't get to try Code Max. The only constraint was the number of concurrent threads. No 5-hour or weekly limits.
  • Целевой текст: Tried the $20 subscription. Had 400 requests per 5 hours with no weekly limits. Didn't get to try Code Max. The only constraint was the number of concurrent threads.
  • Изменение: удалить хвостовую No 5-hour or weekly limits.

Без изменений — строки 185 / 300 (карточка Umans, второе описание, RU/EN): текст остаётся дословно.

Заменить SVG-блок в строках 28–30 (внутри <a> строк 21–27) на оригинальный GitHub-octocat SVG, использовавшийся до коммита 9ab8d5c:

<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
  <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z" />
</svg>

Окружающий <a> (строки 21–27) остаётся без изменений: href="https://git.slaid098.dev/slaid098", aria-label={d.footer.repo} (= «Forgejo»), rel="noreferrer", target="_blank". <span className="sr-only">{d.footer.repo}</span> (строка 31) остаётся. Меняется только блок <svg> (строки 28–30).

Контракты

  • Количество карточек: 4 (RU и EN) — без изменений.
  • Каждая карточка имеет ≥1 непустую строку описания — все правки сохраняют это свойство.
  • Карточки позиционно соответствуют SUBSCRIPTIONS в src/lib/subscriptions.ts.
  • Ссылка в футере: href="https://git.slaid098.dev/slaid098", aria-label="Forgejo", rel="noreferrer", target="_blank" — без изменений.
  • Восстановленный SVG: width="16" height="16" viewBox="0 0 16 16", fill="currentColor", aria-hidden="true" — размер 16×16 сохранён (требование теста contacts.test.tsx:138–149).

Инварианты

  • i18n остаётся bilingual: каждый ключ синхронизирован между RU и EN блоками (количество строк и порядок сохраняются; правки только внутри строк).
  • SVG-иконки в футере: width="16" height="16" (heart = 16×16, restored github icon = 16×16).
  • Никаких новых зависимостей, компонентов или экспортов не добавляется.
  • Тексты описаний — статические строки, без разметки markdown (рендерятся как <p>).

Граничные случаи

  • Удаление хвостовых предложений сохраняет непустые строки (descriptions.every(d => d.length > 0) проходит) — тест subscriptions.test.ts:24–35 остаётся зелёным.
  • Восстановленный SVG использует viewBox="0 0 16 16" вместо viewBox="0 0 24 24" — но тест проверяет только width/height атрибуты, не viewBox → проходит.
  • aria-label={d.footer.repo} остаётся «Forgejo» — текстовое содержимое <span className="sr-only"> не зависит от выбранного SVG.

Влияние на связанные компоненты

  • src/lib/subscriptions.ts — без изменений (только данные карточек; имена/URL не трогаются).
  • src/__tests__/subscriptions.test.ts — без изменений: проверяет ровно 4 карточки с непустыми описаниями (RU+EN) — правки сохраняют инварианты теста.
  • src/__tests__/contacts.test.tsx:126–130 («retains Forgejo link») — проходит: href и aria-label не меняются.
  • src/__tests__/contacts.test.tsx:138–149 («renders heart icon at same size as github icon (16x16)») — проходит: восстановленный SVG имеет width="16" height="16".
  • Страница /[locale]/subscriptions — текст карточек 1 (Synthetic.new), 2 (Ollama), 3 (Umans) обновляется; карточка 0 (OpenCode Go) не трогается.
  • Футер на всех страницах — видимый глиф меняется с «точка в круге» на octocat; ссылка и aria-label без изменений.

Вне scope

  • Переименование aria-label="Forgejo" или тестов, упоминающих «github icon» — только восстановление видимого глифа.
  • Смена URL футера на GitHub.com — ссылка остаётся на git.slaid098.dev/slaid098.
  • Правки карточки OpenCode Go (индекс 0) — текст корректен, не трогается.
  • Второе описание карточки Umans (строки 185 / 300) — остаётся дословно.
  • Добавление настоящей Forgejo-марки (нет официального SVG в проекте; user явно просил вернуть GitHub-octocat).

Критерии приемки

  • Строка 179 src/lib/i18n.ts: текст содержит как Pro, так и (запятая после Pro).
  • Строка 174 src/lib/i18n.ts: текст заканчивается на ...пакетами. без Внутри — Kimi K3..
  • Строка 289 src/lib/i18n.ts: текст заканчивается на ...packages. без Inside — Kimi K3..
  • Строка 184 src/lib/i18n.ts: текст заканчивается на ...потоков. без Без 5-часовых и недельных лимитов..
  • Строка 299 src/lib/i18n.ts: текст заканчивается на ...concurrent threads. без No 5-hour or weekly limits.
  • src/components/site-footer.tsx строки 28–30: рендерится GitHub-octocat SVG (viewBox="0 0 16 16", путь M8 0C3.58 0 0 3.58 0 8...).
  • <a> футера: href="https://git.slaid098.dev/slaid098", aria-label="Forgejo", target="_blank", rel="noreferrer" — без изменений.
  • npm test (vitest run) — все тесты зелёные, включая subscriptions i18n и SiteFooter.
  • npm run lint (biome check) — без ошибок.
  • npm run typecheck (tsc --noEmit) — без ошибок.
## Контекст Зачем: на сайте slaid098-dev (Next.js 15 App Router + React 19 + TS + Tailwind v4, bilingual i18n через `src/lib/i18n.ts`) накопились три мелких бага контента/UI: опечатка в карточке Ollama, устаревшее упоминание модели в карточке Synthetic.new и подменённый иконок в футере. Контекст: 1. В карточке Ollama (RU) пропущена запятая: «как Pro так и» вместо «как Pro, так и» — нарушает правило русской пунктуации при двойном союзе. 2. В карточке Synthetic.new (RU + EN) упоминается модель «Kimi K3». Провайдер может сменить модель в любой момент — называть её в копи-тексте немaintainable. 3. В `src/components/site-footer.tsx` (строки 28–30) рендерится «точка в круге» (radio-button/target dot, viewBox `0 0 24 24`, path `M12 2C6.48 2...zm0 18c-4.41...zm-3-9c0-1.66...`). Это заменило оригинальный GitHub-octocat SVG в коммите `9ab8d5c` (PR #15, 2026-08-07) — commit message утверждал «forgejo svg», но путь является радиокнопкой, а не настоящей маркой Forgejo. Ссылка осталась на `https://git.slaid098.dev/slaid098` с `aria-label="Forgejo"` — меняется только видимый глиф. ## Задача ### Файл 1: `src/lib/i18n.ts` Объект `subscriptions.cards` хранит 4 карточки, индексы позиционно соответствуют `SUBSCRIPTIONS` в `src/lib/subscriptions.ts` (порядок: 0=OpenCode Go, 1=Synthetic.new, 2=Ollama, 3=Umans). RU-блок в строках 160–189, EN-блок в строках 275–304. Каждая строка в `descriptions` рендерится отдельным `<p>` на `/[locale]/subscriptions`. **Редакт 1 — строка 179 (RU, карточка Ollama, индекс 2):** - Текущий текст: `Прозрачный расчёт за серверное время: экономишь токены — получаешь больше запросов. Тестировал, как Pro так и Max.` - Целевой текст: `Прозрачный расчёт за серверное время: экономишь токены — получаешь больше запросов. Тестировал, как Pro, так и Max.` - Изменение: добавить запятую после `Pro` → `как Pro, так и`. **Редакт 2 — строка 174 (RU, карточка Synthetic.new, индекс 1):** - Текущий текст: `Скользящие лимиты: 5-часовой и недельный, оба постоянно восстанавливаются. Лимиты масштабируются пакетами. Внутри — Kimi K3.` - Целевой текст: `Скользящие лимиты: 5-часовой и недельный, оба постоянно восстанавливаются. Лимиты масштабируются пакетами.` - Изменение: удалить хвостовую ` Внутри — Kimi K3.` (текст заканчивается на `...пакетами.`). **Редакт 3 — строка 289 (EN, карточка Synthetic.new, индекс 1):** - Текущий текст: `Sliding limits: 5-hour and weekly, both continuously refill. Limits scale in packages. Inside — Kimi K3.` - Целевой текст: `Sliding limits: 5-hour and weekly, both continuously refill. Limits scale in packages.` - Изменение: удалить хвостовую ` Inside — Kimi K3.` (текст заканчивается на `...packages.`). **Редакт 4 — строка 184 (RU, карточка Umans, индекс 3, первое описание):** - Текущий текст: `Успел попробовать подписку за 20 USD. Было 400 запросов на 5 часов без недельных лимитов. Code Max попробовать не успел. Единственным ограничением было количество одновременных потоков. Без 5-часовых и недельных лимитов.` - Целевой текст: `Успел попробовать подписку за 20 USD. Было 400 запросов на 5 часов без недельных лимитов. Code Max попробовать не успел. Единственным ограничением было количество одновременных потоков.` - Изменение: удалить хвостовую ` Без 5-часовых и недельных лимитов.` (повторяет «без недельных лимитов» из середины предложения). **Редакт 5 — строка 299 (EN, карточка Umans, индекс 3, первое описание):** - Текущий текст: `Tried the $20 subscription. Had 400 requests per 5 hours with no weekly limits. Didn't get to try Code Max. The only constraint was the number of concurrent threads. No 5-hour or weekly limits.` - Целевой текст: `Tried the $20 subscription. Had 400 requests per 5 hours with no weekly limits. Didn't get to try Code Max. The only constraint was the number of concurrent threads.` - Изменение: удалить хвостовую ` No 5-hour or weekly limits.` **Без изменений — строки 185 / 300 (карточка Umans, второе описание, RU/EN):** текст остаётся дословно. ### Файл 2: `src/components/site-footer.tsx` Заменить SVG-блок в строках 28–30 (внутри `<a>` строк 21–27) на оригинальный GitHub-octocat SVG, использовавшийся до коммита `9ab8d5c`: ```jsx <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"> <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z" /> </svg> ``` Окружающий `<a>` (строки 21–27) остаётся без изменений: `href="https://git.slaid098.dev/slaid098"`, `aria-label={d.footer.repo}` (= «Forgejo»), `rel="noreferrer"`, `target="_blank"`. `<span className="sr-only">{d.footer.repo}</span>` (строка 31) остаётся. Меняется только блок `<svg>` (строки 28–30). ## Контракты - Количество карточек: 4 (RU и EN) — без изменений. - Каждая карточка имеет ≥1 непустую строку описания — все правки сохраняют это свойство. - Карточки позиционно соответствуют `SUBSCRIPTIONS` в `src/lib/subscriptions.ts`. - Ссылка в футере: `href="https://git.slaid098.dev/slaid098"`, `aria-label="Forgejo"`, `rel="noreferrer"`, `target="_blank"` — без изменений. - Восстановленный SVG: `width="16" height="16" viewBox="0 0 16 16"`, `fill="currentColor"`, `aria-hidden="true"` — размер 16×16 сохранён (требование теста `contacts.test.tsx:138–149`). ## Инварианты - i18n остаётся bilingual: каждый ключ синхронизирован между RU и EN блоками (количество строк и порядок сохраняются; правки только внутри строк). - SVG-иконки в футере: `width="16" height="16"` (heart = 16×16, restored github icon = 16×16). - Никаких новых зависимостей, компонентов или экспортов не добавляется. - Тексты описаний — статические строки, без разметки markdown (рендерятся как `<p>`). ## Граничные случаи - Удаление хвостовых предложений сохраняет непустые строки (`descriptions.every(d => d.length > 0)` проходит) — тест `subscriptions.test.ts:24–35` остаётся зелёным. - Восстановленный SVG использует `viewBox="0 0 16 16"` вместо `viewBox="0 0 24 24"` — но тест проверяет только `width`/`height` атрибуты, не `viewBox` → проходит. - `aria-label={d.footer.repo}` остаётся «Forgejo» — текстовое содержимое `<span className="sr-only">` не зависит от выбранного SVG. ## Влияние на связанные компоненты - `src/lib/subscriptions.ts` — без изменений (только данные карточек; имена/URL не трогаются). - `src/__tests__/subscriptions.test.ts` — без изменений: проверяет ровно 4 карточки с непустыми описаниями (RU+EN) — правки сохраняют инварианты теста. - `src/__tests__/contacts.test.tsx:126–130` («retains Forgejo link») — проходит: `href` и `aria-label` не меняются. - `src/__tests__/contacts.test.tsx:138–149` («renders heart icon at same size as github icon (16x16)») — проходит: восстановленный SVG имеет `width="16" height="16"`. - Страница `/[locale]/subscriptions` — текст карточек 1 (Synthetic.new), 2 (Ollama), 3 (Umans) обновляется; карточка 0 (OpenCode Go) не трогается. - Футер на всех страницах — видимый глиф меняется с «точка в круге» на octocat; ссылка и aria-label без изменений. ## Вне scope - ❌ Переименование `aria-label="Forgejo"` или тестов, упоминающих «github icon» — только восстановление видимого глифа. - ❌ Смена URL футера на GitHub.com — ссылка остаётся на `git.slaid098.dev/slaid098`. - ❌ Правки карточки OpenCode Go (индекс 0) — текст корректен, не трогается. - ❌ Второе описание карточки Umans (строки 185 / 300) — остаётся дословно. - ❌ Добавление настоящей Forgejo-марки (нет официального SVG в проекте; user явно просил вернуть GitHub-octocat). ## Критерии приемки - [ ] Строка 179 `src/lib/i18n.ts`: текст содержит `как Pro, так и` (запятая после `Pro`). - [ ] Строка 174 `src/lib/i18n.ts`: текст заканчивается на `...пакетами.` без `Внутри — Kimi K3.`. - [ ] Строка 289 `src/lib/i18n.ts`: текст заканчивается на `...packages.` без `Inside — Kimi K3.`. - [ ] Строка 184 `src/lib/i18n.ts`: текст заканчивается на `...потоков.` без `Без 5-часовых и недельных лимитов.`. - [ ] Строка 299 `src/lib/i18n.ts`: текст заканчивается на `...concurrent threads.` без `No 5-hour or weekly limits.` - [ ] `src/components/site-footer.tsx` строки 28–30: рендерится GitHub-octocat SVG (`viewBox="0 0 16 16"`, путь `M8 0C3.58 0 0 3.58 0 8...`). - [ ] `<a>` футера: `href="https://git.slaid098.dev/slaid098"`, `aria-label="Forgejo"`, `target="_blank"`, `rel="noreferrer"` — без изменений. - [ ] `npm test` (vitest run) — все тесты зелёные, включая `subscriptions i18n` и `SiteFooter`. - [ ] `npm run lint` (biome check) — без ошибок. - [ ] `npm run typecheck` (tsc --noEmit) — без ошибок.
Sign in to join this conversation.
No labels
bug
performance
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
slaid098/slaid098-dev#19
No description provided.