Compare commits

..

3 Commits

Author SHA1 Message Date
11c80a16a3 docs: add Telegram notifications and updated dashboard to README and FEATURES
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 46s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 06:40:34 +01:00
c366b44c54 chore: bump version to 1.24.1 2026-03-22 06:39:23 +01:00
92f80542e6 perf: skip Next.js image re-optimization and stream proxy responses
Thumbnails are already optimized (WebP) by the API, so disable Next.js
image optimization to avoid redundant CPU work. Switch route handlers
from buffering (arrayBuffer) to streaming (response.body) to reduce
memory usage and latency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 06:38:46 +01:00
8 changed files with 69 additions and 33 deletions

10
Cargo.lock generated
View File

@@ -64,7 +64,7 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "api"
version = "1.24.0"
version = "1.24.1"
dependencies = [
"anyhow",
"argon2",
@@ -1233,7 +1233,7 @@ dependencies = [
[[package]]
name = "indexer"
version = "1.24.0"
version = "1.24.1"
dependencies = [
"anyhow",
"axum",
@@ -1667,7 +1667,7 @@ dependencies = [
[[package]]
name = "notifications"
version = "1.24.0"
version = "1.24.1"
dependencies = [
"anyhow",
"reqwest",
@@ -1786,7 +1786,7 @@ dependencies = [
[[package]]
name = "parsers"
version = "1.24.0"
version = "1.24.1"
dependencies = [
"anyhow",
"flate2",
@@ -2923,7 +2923,7 @@ dependencies = [
[[package]]
name = "stripstream-core"
version = "1.24.0"
version = "1.24.1"
dependencies = [
"anyhow",
"serde",

View File

@@ -10,7 +10,7 @@ resolver = "2"
[workspace.package]
edition = "2021"
version = "1.24.0"
version = "1.24.1"
license = "MIT"
[workspace.dependencies]

View File

@@ -110,6 +110,12 @@ The backoffice will be available at http://localhost:7082
- Batch auto-matching and scheduled metadata refresh
- Field locking to protect manual edits from sync
### Notifications
- **Telegram**: real-time notifications via Telegram Bot API
- 12 granular event toggles (scans, thumbnails, conversions, metadata)
- Book thumbnail images included in notifications where applicable
- Test connection from settings
### External Integrations
- **Komga**: import reading progress
- **Prowlarr**: search for missing volumes
@@ -130,9 +136,11 @@ The backoffice will be available at http://localhost:7082
- Rate limiting, token expiration and revocation
### Web UI (Backoffice)
- Dashboard with statistics, charts, and reading progress
- Dashboard with statistics, interactive charts (recharts), and reading progress
- Currently reading & recently read sections
- Library, book, series, author management
- Live job monitoring, metadata search modals, settings panel
- Notification settings with per-event toggle configuration
## Environment Variables

View File

@@ -21,19 +21,16 @@ export async function GET(
const response = await fetch(apiUrl.toString(), {
headers: { Authorization: `Bearer ${token}` },
});
if (!response.ok) {
return new NextResponse(`Failed to fetch image: ${response.status}`, {
status: response.status
return new NextResponse(`Failed to fetch image: ${response.status}`, {
status: response.status
});
}
// Récupérer le content-type et les données
const contentType = response.headers.get("content-type") || "image/webp";
const imageBuffer = await response.arrayBuffer();
// Retourner l'image avec le bon content-type
return new NextResponse(imageBuffer, {
return new NextResponse(response.body, {
headers: {
"Content-Type": contentType,
"Cache-Control": "public, max-age=300",

View File

@@ -6,23 +6,22 @@ export async function GET(
{ params }: { params: Promise<{ bookId: string }> }
) {
const { bookId } = await params;
try {
const { baseUrl, token } = config();
const response = await fetch(`${baseUrl}/books/${bookId}/thumbnail`, {
headers: { Authorization: `Bearer ${token}` },
});
if (!response.ok) {
return new NextResponse(`Failed to fetch thumbnail: ${response.status}`, {
status: response.status
return new NextResponse(`Failed to fetch thumbnail: ${response.status}`, {
status: response.status
});
}
const contentType = response.headers.get("content-type") || "image/webp";
const imageBuffer = await response.arrayBuffer();
return new NextResponse(imageBuffer, {
return new NextResponse(response.body, {
headers: {
"Content-Type": contentType,
"Cache-Control": "public, max-age=31536000, immutable",

View File

@@ -4,6 +4,7 @@ const nextConfig = {
typedRoutes: true,
images: {
minimumCacheTTL: 86400,
unoptimized: true,
},
};

View File

@@ -1,6 +1,6 @@
{
"name": "stripstream-backoffice",
"version": "1.24.0",
"version": "1.24.1",
"private": true,
"scripts": {
"dev": "next dev -p 7082",

View File

@@ -170,6 +170,34 @@
---
## Notifications
### Telegram
- Real-time notifications via Telegram Bot API (`sendMessage` and `sendPhoto`)
- Configuration: bot token, chat ID, enable/disable toggle
- Test connection button in settings
### Granular Event Toggles
12 individually configurable notification events grouped by category:
| Category | Events |
|----------|--------|
| Scans | `scan_completed`, `scan_failed`, `scan_cancelled` |
| Thumbnails | `thumbnail_completed`, `thumbnail_failed`, `thumbnail_cancelled` |
| Conversion | `conversion_completed`, `conversion_failed`, `conversion_cancelled` |
| Metadata | `metadata_approved`, `metadata_batch_completed`, `metadata_refresh_completed` |
### Thumbnail Images in Notifications
- Book cover thumbnails attached to applicable notifications (conversion, metadata approval)
- Uses `sendPhoto` multipart upload with fallback to text-only `sendMessage`
### Implementation
- Shared `crates/notifications` crate used by both API and indexer
- Fire-and-forget: notification failures are logged but never block the main operation
- Messages formatted in HTML with event-specific icons
---
## Page Rendering & Caching
### Page Extraction
@@ -238,13 +266,16 @@
## Backoffice (Web UI)
### Dashboard
- Statistics cards: books, series, authors, libraries
- Donut charts: reading status breakdown, format distribution
- Bar charts: books per language
- Per-library reading progress bars
- Top series by book/page count
- Monthly addition timeline
- Metadata coverage stats
- Statistics cards: books, series, authors, libraries, pages, total size
- Interactive charts (recharts): donut, area, stacked bar, horizontal bar
- Reading status breakdown, format distribution, library distribution
- Currently reading section with progress bars
- Recently read section with cover thumbnails
- Reading activity over time (area chart)
- Books added over time (area chart)
- Per-library stacked reading progress
- Top series by book count
- Metadata coverage and provider breakdown
### Pages
- **Libraries**: list, create, delete, configure monitoring and metadata provider
@@ -253,7 +284,7 @@
- **Authors**: list with book/series counts, detail with author's books
- **Jobs**: history, live progress via SSE, error details
- **Tokens**: create, list, revoke API tokens
- **Settings**: image processing, cache, thumbnails, external services (Prowlarr, qBittorrent)
- **Settings**: image processing, cache, thumbnails, external services (Prowlarr, qBittorrent), notifications (Telegram)
### Interactive Features
- Real-time search with suggestions