feat: add article search index endpoint and category export.zip

- Add GET /api/articleIndex returning the article search index (listSearchIndex)
- Add GET /api/category/export.zip returning a kategorien.zip with a
  Windows-1252 CSV (depth-first, Ebene N columns) plus one AVIF per category image
  (content-addressed, deduplicated) using jszip
This commit is contained in:
seb
2026-08-04 00:30:32 +02:00
parent bfcb073e32
commit c6cb1bc229
19 changed files with 1718 additions and 1 deletions

View File

@@ -0,0 +1,44 @@
# `POST /category/{id}/image`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Add category image
Accepts a full-size AVIF body (`Content-Type: image/avif`).
Full: stored as-is when already AVIF and ≤1000×1000; otherwise scaled to max 1000×1000.
Thumb always scaled to max 200×200. Stores hash/thumbhash, links `categorypic`.
Auth like GET /category/tree — user must be authorized for the category's company.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `id` | yes | integer | Category id |
## Body
Raw binary (`image/avif`).
## Response `201`
Image stored and linked
```json
{
"category": { … }
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | Missing body or invalid image — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Category not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,37 @@
# `DELETE /category/{id}/image`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Delete category image
Removes the category's image. Sets thumbW, thumbH, thumbHash back to null.
Auth like GET /category/tree — user must be authorized for the category's company.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `id` | yes | integer | Category id |
## Response `200`
Image removed
```json
{
"category": { … }
}
```
## Errors
| Status | Description |
|--------|-------------|
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Category or image not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._

View File

@@ -0,0 +1,29 @@
# `GET /category/export.zip`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Export categories as ZIP
Builds a `kategorien.zip` for the authenticated user's selected company.
The ZIP contains `kategorien.csv` (semicolon-separated, Windows-1252,
depth-first in sort order with an `Ebene N` name column per tree depth)
plus one AVIF entry per category image, named `<fullHash>.avif`
(content-addressed, so shared hashes are deduplicated).
## Response `200`
ZIP archive
## Errors
| Status | Description |
|--------|-------------|
| 400 | No company selected — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized — `{"error":"…"}` |
| 404 | Company not found — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._