chore: добавить каркас image-platform
- добавлен базовый pnpm workspace для будущих приложений - добавлена dev-инфраструктура PostgreSQL и MinIO - добавлены env-пример и базовые правила репозитория - зафиксированы архитектура, data model и API-контракт - описан контракт с внешним imgproxy
This commit is contained in:
124
docs/api-contract-draft.md
Normal file
124
docs/api-contract-draft.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# Черновик API Контракта
|
||||
|
||||
Это не реализация API, а фиксация будущего контракта для NestJS backend.
|
||||
|
||||
Backend отдаёт JSON, metadata, statuses и URLs. Он не должен проксировать image bytes на каждый обычный запрос.
|
||||
|
||||
## Allowed Hosts
|
||||
|
||||
```text
|
||||
GET /allowed-hosts
|
||||
POST /allowed-hosts
|
||||
PATCH /allowed-hosts/:id
|
||||
DELETE /allowed-hosts/:id
|
||||
```
|
||||
|
||||
## Assets
|
||||
|
||||
```text
|
||||
GET /assets
|
||||
POST /assets
|
||||
GET /assets/:id
|
||||
DELETE /assets/:id
|
||||
```
|
||||
|
||||
`POST /assets` request:
|
||||
|
||||
```json
|
||||
{
|
||||
"sourceUrl": "https://example.com/photo.jpg"
|
||||
}
|
||||
```
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- validate source URL;
|
||||
- check `allowed_image_hosts`;
|
||||
- create or reuse `image_assets` row;
|
||||
- optionally save original to S3 later.
|
||||
|
||||
## Variants
|
||||
|
||||
```text
|
||||
GET /assets/:id/variants
|
||||
POST /assets/:id/variants
|
||||
POST /variants/:id/regenerate
|
||||
DELETE /variants/:id
|
||||
```
|
||||
|
||||
`POST /assets/:id/variants` request:
|
||||
|
||||
```json
|
||||
{
|
||||
"preset": "card",
|
||||
"format": "webp",
|
||||
"width": 640
|
||||
}
|
||||
```
|
||||
|
||||
Response if ready:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "variant_123",
|
||||
"status": "ready",
|
||||
"url": "http://localhost:8888/images/asset_123/w640_q80_card.webp"
|
||||
}
|
||||
```
|
||||
|
||||
Response if generation is async:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "variant_123",
|
||||
"status": "pending",
|
||||
"url": null
|
||||
}
|
||||
```
|
||||
|
||||
## Image URLs For UI
|
||||
|
||||
Для UI нужен endpoint, который возвращает готовый набор URLs для `<picture>`/`srcset`.
|
||||
|
||||
```text
|
||||
GET /assets/:id/picture?preset=card
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"assetId": "asset_123",
|
||||
"preset": "card",
|
||||
"sources": [
|
||||
{
|
||||
"type": "image/avif",
|
||||
"srcset": "http://localhost:8888/images/asset_123/w320_card.avif 320w, http://localhost:8888/images/asset_123/w640_card.avif 640w"
|
||||
},
|
||||
{
|
||||
"type": "image/webp",
|
||||
"srcset": "http://localhost:8888/images/asset_123/w320_card.webp 320w, http://localhost:8888/images/asset_123/w640_card.webp 640w"
|
||||
}
|
||||
],
|
||||
"fallback": {
|
||||
"src": "http://localhost:8888/images/asset_123/w640_card.jpg",
|
||||
"width": 640,
|
||||
"height": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Worker Lifecycle
|
||||
|
||||
Первый MVP может генерировать sync на request. Если генерация тяжёлая, variant создаётся как `pending`, а worker обрабатывает job.
|
||||
|
||||
PostgreSQL может выступить первой очередью:
|
||||
|
||||
```text
|
||||
SELECT * FROM image_variants
|
||||
WHERE status = 'pending'
|
||||
FOR UPDATE SKIP LOCKED
|
||||
LIMIT 1
|
||||
```
|
||||
|
||||
Позже можно добавить Redis/Valkey или отдельную queue, если PostgreSQL станет узким местом.
|
||||
Reference in New Issue
Block a user