Extend the media post-processing subsystem (APP-101) to video, sharing
the media_process_task table via the media_type discriminator but running
on its own dedicated queue so a long transcode never blocks image work.
- Upload hook (enqueueMediaProcessIfEligible) now branches by mime: image/*
and video/* each gate on their own master switch + per-user opt-in +
min_size, then Enqueue with the matching MediaType.
- Cron runs two independent lanes (enqueueMediaProcessLane): images ->
MediaProcessQueue, videos -> MediaVideoQueue.
- New dedicated MediaVideoQueue (dependency.go), MediaCompressVideoTaskType,
started in application.go, live-reloaded via mediaVideoQueuePostProcessor,
metric in GetQueueMetrics.
- MediaCompressTask.compress branches by media_type; new compressVideo builds
the ffmpeg command (codec/CRF/preset, videoScaleFilter cap without upscale,
audio, -threads, optional nice on non-Windows); normalizeVideoContainer
defaults to "keep" so the file is not renamed.
- Settings block media_compress_video_* + MediaProcessVideo(ctx) getter;
engine is always ffmpeg for video. cpu_num virtual key in GetSetting feeds
the frontend threads selector. AutoCompressVideos user opt-in + Codec added
to the JSON props (no schema/migration/BackendVersion bump).
- Tests: TestMediaProcessEnqueueVideo (discriminator isolation),
TestNormalizeVideoContainer + TestVideoScaleFilter (ffmpeg arg building).
Bumps the assets submodule pointer to the APP-103 frontend.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a media post-processing pipeline that compresses images off the upload
path, in batches, to save storage:
- New media_process_task ent table (media_type discriminator; image now,
video later) + inventory client with idempotent Enqueue/ListPending.
- CompleteUpload enqueues the primary entity when the global switch and the
owner's auto_compress_images opt-in are on and mime/size gates pass.
- A configurable cron enqueues a bounded batch onto a dedicated
MediaProcessQueue (default 1 worker) that compresses each blob via vips
(default) or ffmpeg using EntitySource, then writes the result back as a
new version through manager.Update (quota handled by StorageDiff). A
context guard prevents the write-back from re-enqueueing itself.
- BackendVersion 4.14.1 -> 4.14.2 to fire the migration; new default
settings are idempotently backfilled.
BusyWorkers/metrics expose the queue in /admin/task; result mode 'version'
is the MVP (replace/auto are follow-ups).
* refactor(captcha): update Cap backend to 2.0.0 API format
* feat(captcha): add Cap version config for 1.x/2.x compatibility
* fix(captcha): change Cap default version to 1.x for backward compatibility
* refactor(captcha): remove Cap 1.x compatibility, keep only 2.x support
* feat(captcha): update field names to Cap 2.0 standard - Site Key and Secret Key
* fix(captcha): update Cap field names in defaults configuration
* Add Cap Captcha support
- Add CaptchaCap type constant in types.go
- Add Cap struct with InstanceURL, KeyID, and KeySecret fields
- Add CapCaptcha method in provider.go to return Cap settings
- Add default settings for Cap captcha in setting.go
- Implement Cap captcha verification logic in middleware
- Expose Cap captcha settings in site API
This adds support for Cap captcha service as an alternative
captcha option alongside existing reCAPTCHA, Turnstile and
built-in captcha options.
* update cap json tags