Концепції, цінність і типові сценарії
Концепції, цінність і типові сценарії
Preparing Ring content
Preparing Ring content
Preparing Ring content
Використовуйте вкладки Founder / Developer на бічній панелі документації, щоб відфільтрувати цю сторінку. Поєднуйте її з Ring CDN для публічної доставки завантажених об’єктів. Ring File Cabinet є повноцінним споживачем file() (getCabinetStorageConfig(), gallery derivativesProfile).
RingFileBase — це власний контур об’єктного сховища Ring: Express API (ring-filebase-api), який приймає автентифіковані multipart-завантаження та записує їх у S3-сумісне сховище (MinIO або Ceph RGW). Застосунки Ring ніколи не звертаються до MinIO з браузера — вони викликають file().upload(...), а той вибирає RingBaseAdapter, коли провайдер сховища — ring_filebase.
| Аспект | RingFileBase (ця сторінка) | Ring CDN |
|---|---|---|
| Роль | Автентифікований API запису | Публічний edge читання |
| Prod URL | In-cluster http://ring-filebase-api.ring-filebase.svc.cluster.local | https://cdn.<your-domain> |
| Dev / CI URL | Публічний https://filebase-api.ring-platform.org (лише k3s-or або primary) | Той самий CDN (кілька A-edge; master push до slave ingest) |
| Клієнт | Server-side file() / Server Actions | Браузери, <img>, OG-теги |
| Auth | Bearer token (RINGBASE_API_TOKEN) | Немає (GET /files/...) |
Джерело істини: записи завжди йдуть на k3s-or (Oregon). Потім API надсилає об’єкти до ingest endpoint-ів slave MinIO (Finland / Ukraine). Slave ніколи не забирають дані з master; pull CronJob-и вимкнено.
Порядок визначення в lib/storage/storage-config.ts (віддзеркалює db()):
NEXT_PUBLIC_STORAGE_PROVIDER або STORAGE_PROVIDERring-config.json → storage.providerlocal_storage (розробка) / vercel_blob (продакшн)| Значення провайдера | Адаптер | Коли використовувати |
|---|---|---|
local_storage | LocalStorageAdapter | Локальний npm run dev, завантаження на PVC |
vercel_blob | VercelAdapter | Клони на Vercel із BLOB_READ_WRITE_TOKEN |
ring_filebase | RingBaseAdapter | Self-hosted / Ringdom k8s з RingFileBase API |
firebase_storage | У selector повертається local | Наразі не є повноцінним шляхом завантаження |
Зображення продуктів, KYC-скани, вкладення чатів і результати ImageConductor потребують надійного місця зберігання. Vercel Blob підходить для невеликих OSS-демо; маркетплейсу, який володіє своїми даними, зазвичай потрібен RingFileBase, щоб медіа залишалися у вашому кластері, за вашим CDN-хостом і без рахунків Blob за кожен GB.
Залиште storage.provider / env рівним local_storage — файли потраплятимуть у public/uploads (або на ваш PVC mount).
Задайте ring_filebase, спрямовуйте RINGBASE_API_URL на внутрішньокластерний API, публікуйте URL через Ring CDN (див. Related нижче).
Завантаження учасників викликають з MIME-лімітами cabinet/25MB; елементи публічної галереї повторно використовують CDN .
Наступний крок: публічний edge /files/..., мапа host→bucket і географічна доставка завантажених об’єктів.
Той самий процес: завантаження учасника /file-cabinet через file() + getCabinetStorageConfig; галерея використовує derivativesProfile gallery; subscriber+ /profile/shared — лише ACL (без власних завантажень).
Залежність: блок env сховища (RINGBASE_*) і передумови generative conductor.
Див. також: object store — окремий ресурс резервного копіювання від Postgres.
Використовуйте вкладки Founder / Developer на бічній панелі документації, щоб відфільтрувати цю сторінку. Поєднуйте її з Ring CDN для публічної доставки завантажених об’єктів. Ring File Cabinet є повноцінним споживачем file() (getCabinetStorageConfig(), gallery derivativesProfile).
RingFileBase — це власний контур об’єктного сховища Ring: Express API (ring-filebase-api), який приймає автентифіковані multipart-завантаження та записує їх у S3-сумісне сховище (MinIO або Ceph RGW). Застосунки Ring ніколи не звертаються до MinIO з браузера — вони викликають file().upload(...), а той вибирає RingBaseAdapter, коли провайдер сховища — ring_filebase.
| Аспект | RingFileBase (ця сторінка) | Ring CDN |
|---|---|---|
| Роль | Автентифікований API запису | Публічний edge читання |
| Prod URL | In-cluster http://ring-filebase-api.ring-filebase.svc.cluster.local | https://cdn.<your-domain> |
| Dev / CI URL | Публічний https://filebase-api.ring-platform.org (лише k3s-or або primary) | Той самий CDN (кілька A-edge; master push до slave ingest) |
| Клієнт | Server-side file() / Server Actions | Браузери, <img>, OG-теги |
| Auth | Bearer token (RINGBASE_API_TOKEN) | Немає (GET /files/...) |
Джерело істини: записи завжди йдуть на k3s-or (Oregon). Потім API надсилає об’єкти до ingest endpoint-ів slave MinIO (Finland / Ukraine). Slave ніколи не забирають дані з master; pull CronJob-и вимкнено.
Порядок визначення в lib/storage/storage-config.ts (віддзеркалює db()):
NEXT_PUBLIC_STORAGE_PROVIDER або STORAGE_PROVIDERring-config.json → storage.providerlocal_storage (розробка) / vercel_blob (продакшн)| Значення провайдера | Адаптер | Коли використовувати |
|---|---|---|
local_storage | LocalStorageAdapter | Локальний npm run dev, завантаження на PVC |
vercel_blob | VercelAdapter | Клони на Vercel із BLOB_READ_WRITE_TOKEN |
ring_filebase | RingBaseAdapter | Self-hosted / Ringdom k8s з RingFileBase API |
firebase_storage | У selector повертається local | Наразі не є повноцінним шляхом завантаження |
Зображення продуктів, KYC-скани, вкладення чатів і результати ImageConductor потребують надійного місця зберігання. Vercel Blob підходить для невеликих OSS-демо; маркетплейсу, який володіє своїми даними, зазвичай потрібен RingFileBase, щоб медіа залишалися у вашому кластері, за вашим CDN-хостом і без рахунків Blob за кожен GB.
Залиште storage.provider / env рівним local_storage — файли потраплятимуть у public/uploads (або на ваш PVC mount).
Задайте ring_filebase, спрямовуйте RINGBASE_API_URL на внутрішньокластерний API, публікуйте URL через Ring CDN (див. Related нижче).
Завантаження учасників викликають з MIME-лімітами cabinet/25MB; елементи публічної галереї повторно використовують CDN .
Наступний крок: публічний edge /files/..., мапа host→bucket і географічна доставка завантажених об’єктів.
Той самий процес: завантаження учасника /file-cabinet через file() + getCabinetStorageConfig; галерея використовує derivativesProfile gallery; subscriber+ /profile/shared — лише ACL (без власних завантажень).
Залежність: блок env сховища (RINGBASE_*) і передумови generative conductor.
Див. також: object store — окремий ресурс резервного копіювання від Postgres.
Використовуйте вкладки Founder / Developer на бічній панелі документації, щоб відфільтрувати цю сторінку. Поєднуйте її з Ring CDN для публічної доставки завантажених об’єктів. Ring File Cabinet є повноцінним споживачем file() (getCabinetStorageConfig(), gallery derivativesProfile).
RingFileBase — це власний контур об’єктного сховища Ring: Express API (ring-filebase-api), який приймає автентифіковані multipart-завантаження та записує їх у S3-сумісне сховище (MinIO або Ceph RGW). Застосунки Ring ніколи не звертаються до MinIO з браузера — вони викликають file().upload(...), а той вибирає RingBaseAdapter, коли провайдер сховища — ring_filebase.
| Аспект | RingFileBase (ця сторінка) | Ring CDN |
|---|---|---|
| Роль | Автентифікований API запису | Публічний edge читання |
| Prod URL | In-cluster http://ring-filebase-api.ring-filebase.svc.cluster.local | https://cdn.<your-domain> |
| Dev / CI URL | Публічний https://filebase-api.ring-platform.org (лише k3s-or або primary) | Той самий CDN (кілька A-edge; master push до slave ingest) |
| Клієнт | Server-side file() / Server Actions | Браузери, <img>, OG-теги |
| Auth | Bearer token (RINGBASE_API_TOKEN) | Немає (GET /files/...) |
Джерело істини: записи завжди йдуть на k3s-or (Oregon). Потім API надсилає об’єкти до ingest endpoint-ів slave MinIO (Finland / Ukraine). Slave ніколи не забирають дані з master; pull CronJob-и вимкнено.
Порядок визначення в lib/storage/storage-config.ts (віддзеркалює db()):
NEXT_PUBLIC_STORAGE_PROVIDER або STORAGE_PROVIDERring-config.json → storage.providerlocal_storage (розробка) / vercel_blob (продакшн)| Значення провайдера | Адаптер | Коли використовувати |
|---|---|---|
local_storage | LocalStorageAdapter | Локальний npm run dev, завантаження на PVC |
vercel_blob | VercelAdapter | Клони на Vercel із BLOB_READ_WRITE_TOKEN |
ring_filebase | RingBaseAdapter | Self-hosted / Ringdom k8s з RingFileBase API |
firebase_storage | У selector повертається local | Наразі не є повноцінним шляхом завантаження |
Зображення продуктів, KYC-скани, вкладення чатів і результати ImageConductor потребують надійного місця зберігання. Vercel Blob підходить для невеликих OSS-демо; маркетплейсу, який володіє своїми даними, зазвичай потрібен RingFileBase, щоб медіа залишалися у вашому кластері, за вашим CDN-хостом і без рахунків Blob за кожен GB.
Залиште storage.provider / env рівним local_storage — файли потраплятимуть у public/uploads (або на ваш PVC mount).
Задайте ring_filebase, спрямовуйте RINGBASE_API_URL на внутрішньокластерний API, публікуйте URL через Ring CDN (див. Related нижче).
Завантаження учасників викликають з MIME-лімітами cabinet/25MB; елементи публічної галереї повторно використовують CDN .
Наступний крок: публічний edge /files/..., мапа host→bucket і географічна доставка завантажених об’єктів.
Той самий процес: завантаження учасника /file-cabinet через file() + getCabinetStorageConfig; галерея використовує derivativesProfile gallery; subscriber+ /profile/shared — лише ACL (без власних завантажень).
Залежність: блок env сховища (RINGBASE_*) і передумови generative conductor.
Див. також: object store — окремий ресурс резервного копіювання від Postgres.
file()/files/{uuid}Хости api. часто маршрутизуються на ingress застосунку Ring. Завантаження мають потрапляти до ring-filebase-api (внутрішньокластерно) або https://filebase-api.ring-platform.org (публічний запис на primary) — ніколи не до розгортання Next.js. Неправильний URL повертає HTML або HTTP 500 замість JSON з успіхом/fileId/url.
lib/uploads/server/upload-core.tsУніфіковане завантаження, яке використовує POST /api/uploads |
app/api/uploads/route.ts | Точка входу browser/form upload |
infrastructure/ring-file-base/services/ring-filebase-api/ | Джерело API (derivatives + propagate) |
infrastructure/ring-file-base/k8s/ring-filebase/10-api-deployment.yaml | Шаблон розгортання |
infrastructure/k3s-or/ring-filebase/60-propagate-slaves-configmap.yaml | Реєстр slave ingest |
| Змінна | Потрібна для ring_filebase | Примітки |
|---|---|---|
NEXT_PUBLIC_STORAGE_PROVIDER | Так | Задайте ring_filebase (псевдоніми: ringbase, filebase) |
RINGBASE_API_URL | Так | Host або host + /api/v1; адаптер нормалізує до …/api/v1 |
RINGBASE_API_TOKEN | Так | Bearer для middleware автентифікації API |
RINGBASE_PUBLIC_URL | Рекомендовано | Публічна база для URL у відповідях (зазвичай origin CDN) |
NEXT_PUBLIC_RINGBASE_API_URL | Необов’язково | Fallback, якщо RINGBASE_API_URL не задано |
BLOB_READ_WRITE_TOKEN | Ні | Лише для vercel_blob |
NEXT_PUBLIC_LOCAL_STORAGE_URL | Ні | Лише для local_storage |
Приклад ring-config.json:
Шаблон k8s ConfigMap / Secret (див. k8s/secrets.example.yaml):
resolveRingBaseUploadType)API перевіряє MIME-типи для поля type. Адаптер мапить:
| Вміст / доступ | type, який надсилається до API |
|---|---|
access: 'private' | document |
image/* | image (повноцінний тип; product — застарілий псевдонім) |
video/* або audio/* | media |
| Усе інше | other |
Необов’язкові перевизначення: ringbaseType, derivativesProfile (none | thumb | gallery | product | news).
| Шаблон | Статус |
|---|---|
{fileId}_v_{variant} наприклад _v_thumb.webp, _v_blur.webp, _v_sync_thumb.jpg | Поточна — єдина схема, яку записує API |
{fileId}_v_video_frame_N.jpg / _v_video_frame_N_480.webp | Поточна — асинхронні HEIC/video frames (_480.webp під _v_ навмисно) |
{fileId}_thumb, {fileId}_thumb_v{N}, {fileId}_thumb_v{N}_480w.webp | Заборонена — ніколи не записуйте; очищайте orphan-и через infrastructure/ring-file-base/scripts/purge-legacy-derivative-keys.sh |
Для raster-файлів надавайте перевагу upload type=image (product — застарілий псевдонім → image). Poll статусу thumbnail: GET /api/v1/files/{fileId}/thumbnail?type=image.
Підключення застосунку (2026-07-15): upload-core і /api/uploads використовують request ladder, коли storage.provider дорівнює ring_filebase (purpose→profile: news→news, product media→product, nft/chat images→gallery, avatar/logos→thumb, docs→none). Відповіді містять fileId + derivatives. Зберігайте їх як MediaImageAsset у news (featuredImageAsset / gallery) і GalleryItem.derivatives у store/NFT. Відображайте через pickImageSrc / pickGalleryDisplayUrl. Застарілу подвійну сумісність Vikka (vikka-field-normalize / NEXT_PUBLIC_NEWS_VIKKA_COMPAT) видалено — лише camelCase JSONB.
Надсилання зображень як media не проходить валідацію (A/V + HEIC дозволені лише чинними правилами API).
Виконайте dry-run на primary, потім на slave FI/UA: ./scripts/purge-legacy-derivative-keys.sh --endpoint https://… --bucket ring-filebase. Додавайте --delete лише після перегляду зразка списку. Команда не зачіпає навмисні _v_video_frame_*_480.webp або _v_thumb.webp.
Задайте env та/або storage.provider у ring-config.json рівним ring_filebase. Після змін env перезапустіть Next.js.
Застосуйте маніфести RingFileBase з infrastructure/ring-file-base/k8s/ring-filebase/ (API Deployment/Service, namespace MinIO, CDN stack). Переконайтеся, що API може дістатися minio-service.ring-filebase-minio.svc.cluster.local:9000, а цільовий bucket існує.
Автентифікація API (services/ring-filebase-api/src/middleware/auth.ts) очікує JWT, чиї декодовані claims містять:
iss = kubernetes/serviceaccountkubernetes.io/serviceaccount/namespacekubernetes.io/serviceaccount/service-account.nameСьогодні middleware декодує claims і не викликає TokenReview та не перевіряє exp. Надавайте перевагу довгоживучому токену з такими claims у Secrets — не вставляйте одногодинний projected ServiceAccount JWT у RINGBASE_API_TOKEN, забуваючи про його строк дії.
Очікуйте JSON із success: true, fileId, url і необов’язковими derivatives під вашим CDN-хостом. Протягом кількох секунд HEAD того самого ключа на slave ingest має повернути 200 (master push).
Browser forms мають використовувати POST /api/uploads (уніфіковане upload core), а не викликати RingFileBase напряму.
| Симптом | Ймовірна причина |
|---|---|
| HTML / 500 від URL завантаження | RINGBASE_API_URL вказує на Next.js (api. ingress) |
401 Invalid ServiceAccount token | Відсутня legacy SA claim shape у токені |
Invalid file type … got: image/png | type=media замість image / other |
| Завантаження успішне, CDN на slave короткочасно повертає 404 | Рідкісна race до push; edge мають зберігати proxy_cache_valid 404 0 |
| Завантаження успішне, CDN повертає 403 | У bucket MinIO немає анонімного GetObject (або неправильно налаштовано CDN Host header) |
Node stream.isDisturbed для Blob | Надавайте перевагу local_storage або ring_filebase; Vercel adapter завантажує Uint8Array |
Propagate завис у failed | POST /api/v1/replication/redrive на primary (максимум 3 повтори, потім зупинка) |
Див. також: повний хаб каталогу інтеграцій.
file()/files/{uuid}Хости api. часто маршрутизуються на ingress застосунку Ring. Завантаження мають потрапляти до ring-filebase-api (внутрішньокластерно) або https://filebase-api.ring-platform.org (публічний запис на primary) — ніколи не до розгортання Next.js. Неправильний URL повертає HTML або HTTP 500 замість JSON з успіхом/fileId/url.
lib/uploads/server/upload-core.tsУніфіковане завантаження, яке використовує POST /api/uploads |
app/api/uploads/route.ts | Точка входу browser/form upload |
infrastructure/ring-file-base/services/ring-filebase-api/ | Джерело API (derivatives + propagate) |
infrastructure/ring-file-base/k8s/ring-filebase/10-api-deployment.yaml | Шаблон розгортання |
infrastructure/k3s-or/ring-filebase/60-propagate-slaves-configmap.yaml | Реєстр slave ingest |
| Змінна | Потрібна для ring_filebase | Примітки |
|---|---|---|
NEXT_PUBLIC_STORAGE_PROVIDER | Так | Задайте ring_filebase (псевдоніми: ringbase, filebase) |
RINGBASE_API_URL | Так | Host або host + /api/v1; адаптер нормалізує до …/api/v1 |
RINGBASE_API_TOKEN | Так | Bearer для middleware автентифікації API |
RINGBASE_PUBLIC_URL | Рекомендовано | Публічна база для URL у відповідях (зазвичай origin CDN) |
NEXT_PUBLIC_RINGBASE_API_URL | Необов’язково | Fallback, якщо RINGBASE_API_URL не задано |
BLOB_READ_WRITE_TOKEN | Ні | Лише для vercel_blob |
NEXT_PUBLIC_LOCAL_STORAGE_URL | Ні | Лише для local_storage |
Приклад ring-config.json:
Шаблон k8s ConfigMap / Secret (див. k8s/secrets.example.yaml):
resolveRingBaseUploadType)API перевіряє MIME-типи для поля type. Адаптер мапить:
| Вміст / доступ | type, який надсилається до API |
|---|---|
access: 'private' | document |
image/* | image (повноцінний тип; product — застарілий псевдонім) |
video/* або audio/* | media |
| Усе інше | other |
Необов’язкові перевизначення: ringbaseType, derivativesProfile (none | thumb | gallery | product | news).
| Шаблон | Статус |
|---|---|
{fileId}_v_{variant} наприклад _v_thumb.webp, _v_blur.webp, _v_sync_thumb.jpg | Поточна — єдина схема, яку записує API |
{fileId}_v_video_frame_N.jpg / _v_video_frame_N_480.webp | Поточна — асинхронні HEIC/video frames (_480.webp під _v_ навмисно) |
{fileId}_thumb, {fileId}_thumb_v{N}, {fileId}_thumb_v{N}_480w.webp | Заборонена — ніколи не записуйте; очищайте orphan-и через infrastructure/ring-file-base/scripts/purge-legacy-derivative-keys.sh |
Для raster-файлів надавайте перевагу upload type=image (product — застарілий псевдонім → image). Poll статусу thumbnail: GET /api/v1/files/{fileId}/thumbnail?type=image.
Підключення застосунку (2026-07-15): upload-core і /api/uploads використовують request ladder, коли storage.provider дорівнює ring_filebase (purpose→profile: news→news, product media→product, nft/chat images→gallery, avatar/logos→thumb, docs→none). Відповіді містять fileId + derivatives. Зберігайте їх як MediaImageAsset у news (featuredImageAsset / gallery) і GalleryItem.derivatives у store/NFT. Відображайте через pickImageSrc / pickGalleryDisplayUrl. Застарілу подвійну сумісність Vikka (vikka-field-normalize / NEXT_PUBLIC_NEWS_VIKKA_COMPAT) видалено — лише camelCase JSONB.
Надсилання зображень як media не проходить валідацію (A/V + HEIC дозволені лише чинними правилами API).
Виконайте dry-run на primary, потім на slave FI/UA: ./scripts/purge-legacy-derivative-keys.sh --endpoint https://… --bucket ring-filebase. Додавайте --delete лише після перегляду зразка списку. Команда не зачіпає навмисні _v_video_frame_*_480.webp або _v_thumb.webp.
Задайте env та/або storage.provider у ring-config.json рівним ring_filebase. Після змін env перезапустіть Next.js.
Застосуйте маніфести RingFileBase з infrastructure/ring-file-base/k8s/ring-filebase/ (API Deployment/Service, namespace MinIO, CDN stack). Переконайтеся, що API може дістатися minio-service.ring-filebase-minio.svc.cluster.local:9000, а цільовий bucket існує.
Автентифікація API (services/ring-filebase-api/src/middleware/auth.ts) очікує JWT, чиї декодовані claims містять:
iss = kubernetes/serviceaccountkubernetes.io/serviceaccount/namespacekubernetes.io/serviceaccount/service-account.nameСьогодні middleware декодує claims і не викликає TokenReview та не перевіряє exp. Надавайте перевагу довгоживучому токену з такими claims у Secrets — не вставляйте одногодинний projected ServiceAccount JWT у RINGBASE_API_TOKEN, забуваючи про його строк дії.
Очікуйте JSON із success: true, fileId, url і необов’язковими derivatives під вашим CDN-хостом. Протягом кількох секунд HEAD того самого ключа на slave ingest має повернути 200 (master push).
Browser forms мають використовувати POST /api/uploads (уніфіковане upload core), а не викликати RingFileBase напряму.
| Симптом | Ймовірна причина |
|---|---|
| HTML / 500 від URL завантаження | RINGBASE_API_URL вказує на Next.js (api. ingress) |
401 Invalid ServiceAccount token | Відсутня legacy SA claim shape у токені |
Invalid file type … got: image/png | type=media замість image / other |
| Завантаження успішне, CDN на slave короткочасно повертає 404 | Рідкісна race до push; edge мають зберігати proxy_cache_valid 404 0 |
| Завантаження успішне, CDN повертає 403 | У bucket MinIO немає анонімного GetObject (або неправильно налаштовано CDN Host header) |
Node stream.isDisturbed для Blob | Надавайте перевагу local_storage або ring_filebase; Vercel adapter завантажує Uint8Array |
Propagate завис у failed | POST /api/v1/replication/redrive на primary (максимум 3 повтори, потім зупинка) |
Див. також: повний хаб каталогу інтеграцій.
file()/files/{uuid}Хости api. часто маршрутизуються на ingress застосунку Ring. Завантаження мають потрапляти до ring-filebase-api (внутрішньокластерно) або https://filebase-api.ring-platform.org (публічний запис на primary) — ніколи не до розгортання Next.js. Неправильний URL повертає HTML або HTTP 500 замість JSON з успіхом/fileId/url.
lib/uploads/server/upload-core.tsУніфіковане завантаження, яке використовує POST /api/uploads |
app/api/uploads/route.ts | Точка входу browser/form upload |
infrastructure/ring-file-base/services/ring-filebase-api/ | Джерело API (derivatives + propagate) |
infrastructure/ring-file-base/k8s/ring-filebase/10-api-deployment.yaml | Шаблон розгортання |
infrastructure/k3s-or/ring-filebase/60-propagate-slaves-configmap.yaml | Реєстр slave ingest |
| Змінна | Потрібна для ring_filebase | Примітки |
|---|---|---|
NEXT_PUBLIC_STORAGE_PROVIDER | Так | Задайте ring_filebase (псевдоніми: ringbase, filebase) |
RINGBASE_API_URL | Так | Host або host + /api/v1; адаптер нормалізує до …/api/v1 |
RINGBASE_API_TOKEN | Так | Bearer для middleware автентифікації API |
RINGBASE_PUBLIC_URL | Рекомендовано | Публічна база для URL у відповідях (зазвичай origin CDN) |
NEXT_PUBLIC_RINGBASE_API_URL | Необов’язково | Fallback, якщо RINGBASE_API_URL не задано |
BLOB_READ_WRITE_TOKEN | Ні | Лише для vercel_blob |
NEXT_PUBLIC_LOCAL_STORAGE_URL | Ні | Лише для local_storage |
Приклад ring-config.json:
Шаблон k8s ConfigMap / Secret (див. k8s/secrets.example.yaml):
resolveRingBaseUploadType)API перевіряє MIME-типи для поля type. Адаптер мапить:
| Вміст / доступ | type, який надсилається до API |
|---|---|
access: 'private' | document |
image/* | image (повноцінний тип; product — застарілий псевдонім) |
video/* або audio/* | media |
| Усе інше | other |
Необов’язкові перевизначення: ringbaseType, derivativesProfile (none | thumb | gallery | product | news).
| Шаблон | Статус |
|---|---|
{fileId}_v_{variant} наприклад _v_thumb.webp, _v_blur.webp, _v_sync_thumb.jpg | Поточна — єдина схема, яку записує API |
{fileId}_v_video_frame_N.jpg / _v_video_frame_N_480.webp | Поточна — асинхронні HEIC/video frames (_480.webp під _v_ навмисно) |
{fileId}_thumb, {fileId}_thumb_v{N}, {fileId}_thumb_v{N}_480w.webp | Заборонена — ніколи не записуйте; очищайте orphan-и через infrastructure/ring-file-base/scripts/purge-legacy-derivative-keys.sh |
Для raster-файлів надавайте перевагу upload type=image (product — застарілий псевдонім → image). Poll статусу thumbnail: GET /api/v1/files/{fileId}/thumbnail?type=image.
Підключення застосунку (2026-07-15): upload-core і /api/uploads використовують request ladder, коли storage.provider дорівнює ring_filebase (purpose→profile: news→news, product media→product, nft/chat images→gallery, avatar/logos→thumb, docs→none). Відповіді містять fileId + derivatives. Зберігайте їх як MediaImageAsset у news (featuredImageAsset / gallery) і GalleryItem.derivatives у store/NFT. Відображайте через pickImageSrc / pickGalleryDisplayUrl. Застарілу подвійну сумісність Vikka (vikka-field-normalize / NEXT_PUBLIC_NEWS_VIKKA_COMPAT) видалено — лише camelCase JSONB.
Надсилання зображень як media не проходить валідацію (A/V + HEIC дозволені лише чинними правилами API).
Виконайте dry-run на primary, потім на slave FI/UA: ./scripts/purge-legacy-derivative-keys.sh --endpoint https://… --bucket ring-filebase. Додавайте --delete лише після перегляду зразка списку. Команда не зачіпає навмисні _v_video_frame_*_480.webp або _v_thumb.webp.
Задайте env та/або storage.provider у ring-config.json рівним ring_filebase. Після змін env перезапустіть Next.js.
Застосуйте маніфести RingFileBase з infrastructure/ring-file-base/k8s/ring-filebase/ (API Deployment/Service, namespace MinIO, CDN stack). Переконайтеся, що API може дістатися minio-service.ring-filebase-minio.svc.cluster.local:9000, а цільовий bucket існує.
Автентифікація API (services/ring-filebase-api/src/middleware/auth.ts) очікує JWT, чиї декодовані claims містять:
iss = kubernetes/serviceaccountkubernetes.io/serviceaccount/namespacekubernetes.io/serviceaccount/service-account.nameСьогодні middleware декодує claims і не викликає TokenReview та не перевіряє exp. Надавайте перевагу довгоживучому токену з такими claims у Secrets — не вставляйте одногодинний projected ServiceAccount JWT у RINGBASE_API_TOKEN, забуваючи про його строк дії.
Очікуйте JSON із success: true, fileId, url і необов’язковими derivatives під вашим CDN-хостом. Протягом кількох секунд HEAD того самого ключа на slave ingest має повернути 200 (master push).
Browser forms мають використовувати POST /api/uploads (уніфіковане upload core), а не викликати RingFileBase напряму.
| Симптом | Ймовірна причина |
|---|---|
| HTML / 500 від URL завантаження | RINGBASE_API_URL вказує на Next.js (api. ingress) |
401 Invalid ServiceAccount token | Відсутня legacy SA claim shape у токені |
Invalid file type … got: image/png | type=media замість image / other |
| Завантаження успішне, CDN на slave короткочасно повертає 404 | Рідкісна race до push; edge мають зберігати proxy_cache_valid 404 0 |
| Завантаження успішне, CDN повертає 403 | У bucket MinIO немає анонімного GetObject (або неправильно налаштовано CDN Host header) |
Node stream.isDisturbed для Blob | Надавайте перевагу local_storage або ring_filebase; Vercel adapter завантажує Uint8Array |
Propagate завис у failed | POST /api/v1/replication/redrive на primary (максимум 3 повтори, потім зупинка) |
Див. також: повний хаб каталогу інтеграцій.