Commit Graph
302 Commits
Author SHA1 Message Date
adminandClaude Sonnet 5 90be365c7f Implement backup.sh: pg_dump + tdlib tar + restic backup/forget + Kuma reporting
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 00:58:29 +02:00
admin 7e21a41615 Add backup service image (Dockerfile, entrypoint, crontab) 2026-07-23 00:53:34 +02:00
admin f3d62c68fb Add implementation plan for NAS-backed Postgres + TDLib backups
Six tasks: backup image, backup.sh, repo compose wiring, CI build
step, production compose wiring (gated on NAS/Kuma details from the
user), deploy + restore-drill verification.
2026-07-23 00:47:47 +02:00
admin 412e3066bc Add design spec for NAS-backed Postgres + TDLib backups
Restic-based backup container, encrypted daily backups to a Synology
NFS share, 14-day retention, Uptime Kuma alerting.
2026-07-23 00:41:06 +02:00
admin ffe5c920c6 Fix backup service restart handling 2026-07-22 10:04:18 +02:00
admin c533d034f9 fix: restrict backup restore paths 2026-07-22 09:44:08 +02:00
admin 03822e0763 fix: narrow backup scope to database and telegram sessions 2026-07-22 09:31:07 +02:00
admin 3536089d52 docs: add monthly backup verification owner
Align the approved backup design and implementation plan on the monthly full Restic integrity check and disposable restore rehearsal without adding production code.

Constraint: PostgreSQL logical dump plus tdlib_state and tdlib_bot_state only

Rejected: Add a second production timer or backup script changes | outside requested docs-only scope

Confidence: high

Scope-risk: narrow
2026-07-22 09:19:15 +02:00
admin a8818dcf0c docs: correct backup scope to database and sessions
Clarify that PostgreSQL logical dumps and TDLib session volumes are protected, while STL binaries remain in Telegram and manual uploads stay excluded.
2026-07-22 09:10:19 +02:00
admin d57ec0458f docs: harden disposable restore rehearsal 2026-07-22 03:57:39 +02:00
admin 6763af731f docs: document disposable restore rehearsal 2026-07-22 03:49:02 +02:00
admin d5ba4fd4fd fix: close backup review findings 2026-07-22 03:40:35 +02:00
admin def8edb029 docs: document Synology backup and recovery 2026-07-22 02:54:44 +02:00
admin 68742d682d fix: harden backup restore safety 2026-07-22 02:49:06 +02:00
admin f8bc737214 feat: retain uploaded STL files for recovery 2026-07-22 02:24:59 +02:00
admin 238ec17155 docs: amend backup design for durable STL retention 2026-07-22 02:13:11 +02:00
admin a2b7e77cc4 feat: add guarded backup restore workflow 2026-07-22 00:55:24 +02:00
admin 2beac6d62f feat: schedule nightly off-host backups 2026-07-22 00:41:32 +02:00
admin 897cd3d95e feat: implement encrypted database and volume snapshots 2026-07-22 00:30:56 +02:00
admin 34e88a8cf5 feat: add backup compose service 2026-07-22 00:22:56 +02:00
admin 5e7807b056 chore: ignore local worktrees 2026-07-21 23:49:33 +02:00
admin 7693ed6f02 docs: plan database and file backup implementation 2026-07-21 23:32:41 +02:00
admin 75c67b2036 docs: design database and file backups 2026-07-21 23:23:52 +02:00
adminandClaude Opus 4.8 6178ff3b08 docs: add Task 3 (creator filter combobox) to plan
continuous-integration/drone/push Build is passing
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 09:42:37 +02:00
admin 57842c6d95 Merge feat/send-all-from-creator: send-all-from-creator button + searchable creator filter 2026-07-04 09:42:08 +02:00
admin b3c49c3794 feat(stls): add searchable creator filter combobox to toolbar 2026-07-04 09:36:51 +02:00
admin 20e60bc6af feat(stls): add 'send all from creator' toolbar button 2026-07-04 09:26:36 +02:00
admin 50e89719bb feat(stls): add sendAllFromCreatorAction server action 2026-07-04 09:20:36 +02:00
adminandClaude Opus 4.8 1cae855c26 docs: implementation plan for send-all-from-creator button
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 09:15:58 +02:00
adminandClaude Opus 4.8 b0baf72f0a docs: spec for send-all-from-creator button on STL page
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 09:14:33 +02:00
adminandClaude Opus 4.8 0cf5fcd3a7 fix(stls): stop loading preview blobs in list queries (OOM fix)
continuous-integration/drone/push Build is passing
The STLs list queries selected the full previewData JPEG bytes (avg
~700KB, up to 2MB, and every group member's preview) only to compute a
hasPreview boolean. Under concurrent page loads this piled blobs into
the Node heap, exceeded the 512MB container limit, crashed the process,
and surfaced as repeated connection errors while browsing.

Replace the byte-loading select with a fetchPreviewFlags() helper that
checks `previewData IS NOT NULL` in SQL (IDs only, no bytes). Applied to
listPackages, listDisplayItems, searchPackages, and listUngroupedPackages.

Verified: same concurrent load that drove memory to 508/512MB and forced
a restart now peaks at 156MB (30%) with zero failed requests and no restart.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 19:05:34 +02:00
adminandClaude Opus 4.8 3b7202a662 harden(telegram): reject non-positive topic id in disableActiveTopic
continuous-integration/drone/push Build is passing
BigInt("") / BigInt("0") don't throw; guard against them since the
action is exported and admin-callable independent of the UI button.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 12:15:03 +02:00
adminandClaude Opus 4.8 23f8e91c50 feat(telegram): add "skip & disable topic" on the live worker panel
Track the forum topic currently being processed on IngestionRun
(currentTopicId + currentAccountChannelMapId; additive migration) and
expose it on the live status. processArchiveSets gains an optional
shouldStop callback polled before each archive set; the forum branch
passes a live isTopicFetchEnabled check, so disabling a topic mid-run
lets the in-flight file finish, then skips the rest of that topic.

A new disableActiveTopic server action sets the topic's fetchEnabled
false (upsert), and the worker status panel shows a "Skip & disable
this topic" button while a topic is being processed. Future runs skip
the topic via the existing live per-topic read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 12:10:56 +02:00
admin c749d03376 Merge fix/topics-drawer-scroll-and-filter: topics drawer scroll + title filter
continuous-integration/drone/push Build is passing
2026-06-22 09:05:46 +02:00
adminandClaude Opus 4.8 d7771887a1 fix(worker): silence false-positive integrity-test notifications
The pre-upload integrity test is advisory (never blocks upload), but it
raised a WARNING SystemNotification whenever `7z t` failed — most often
because large 7z archives OOM-kill the test process (SIGKILL / exit 137)
in the memory-limited worker container, which is a tool limitation, not
corruption. Classify failures as encrypted | corrupt | inconclusive;
suppress notifications for inconclusive (debug log only) while still
proceeding with the upload as before. Genuine corruption now uses the
INTEGRITY_AUDIT notification type instead of the misleading HASH_MISMATCH;
encrypted archives still notify.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 08:57:25 +02:00
adminandClaude Opus 4.8 26bc43299a fix(telegram): make topics drawer scrollable + add topic title filter
The Radix ScrollArea viewport did not get a bounded height inside the
flex-column, max-h, vertically-centred dialog, so a long topic list
overflowed the dialog instead of scrolling (last topics unreachable).
Switch to a native flex-1 min-h-0 overflow-y-auto container, which is
the canonical touch-friendly flex-scroll pattern.

Also add a "Filter topics..." input (matches by topic title) so any
topic can be reached regardless of list length; reset the filter on
close; and add a toast fallback message on toggle failure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 08:50:10 +02:00
adminandClaude Opus 4.8 8b500a1610 feat(stls): enlarge candidate images in preview picker
continuous-integration/drone/push Build is passing
Each loaded candidate gets an enlarge button that opens the ImageLightbox
without changing selection, so the right preview is easier to choose.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 04:57:40 +02:00
adminandClaude Opus 4.8 f0a9d3b4da feat(stls): click-to-enlarge preview in package files drawer
The drawer preview image opens the ImageLightbox; replacing the image
stays available via the existing Upload/Pick Preview buttons. No-preview
upload affordance unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 04:48:13 +02:00
adminandClaude Opus 4.8 b90317c007 feat(stls): click-to-enlarge package preview thumbnail in table
Package preview thumbnails open the ImageLightbox on click (hover shows a
maximize affordance). No-preview cells unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 04:44:52 +02:00
adminandClaude Opus 4.8 6f8ddcca81 feat(stls): add reusable ImageLightbox for full-size preview viewing
Radix Dialog-based lightbox (Esc / overlay / close button to dismiss),
image shown object-contain capped to the viewport. No new dependencies.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 04:17:42 +02:00
adminandClaude Opus 4.8 25ff067ea0 feat(telegram): add Topics action to forum channels in Channels tab
Forum source channels get a Topics menu item that opens the TopicsDrawer.
Non-forum channels are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 04:15:46 +02:00
adminandClaude Opus 4.8 7e58cc29fa feat(telegram): add TopicsDrawer for per-topic fetch toggles
Lists a channel's topics with an enable/disable Switch each (optimistic,
revert on failure). Empty state explains topics appear after the next scan.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:24:57 +02:00
adminandClaude Opus 4.8 5a4e358eee feat(telegram): add setTopicFetchEnabled server action
Admin-guarded toggle of TopicProgress.fetchEnabled by row id. Persists
immediately; the worker honours it on its next live per-topic read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:22:45 +02:00
adminandClaude Opus 4.8 c31afc5b92 feat(telegram): add GET /api/telegram/channels/[channelId]/topics
Returns per-topic fetch state for a channel, mirroring the existing
account-links route auth pattern.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:19:46 +02:00
adminandClaude Opus 4.8 6324d64870 feat(telegram): expose isForum on ChannelRow and add listChannelTopics
ChannelRow now carries isForum so the UI can show the Topics action for
forum channels only. listChannelTopics returns per-topic fetch state for
a channel from TopicProgress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:16:42 +02:00
adminandClaude Opus 4.8 974769350b feat(worker): honour per-topic fetch toggle live in scan loop
Eager-persist a TopicProgress row for every discovered topic at run
start, and read the live fetchEnabled flag per topic so a mid-run
disable skips topics not yet started. Disabled topics are skipped
before any TDLib scan or fetch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 01:13:10 +02:00
adminandClaude Opus 4.8 f9b82f1654 feat(worker): add ensureTopicProgressRows + isTopicFetchEnabled helpers
ensureTopicProgressRows inserts missing topic rows only (skipDuplicates),
leaving watermarks/scan-state/fetchEnabled untouched. isTopicFetchEnabled
reads the live per-topic flag for mid-run skip decisions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 00:27:24 +02:00
adminandClaude Opus 4.8 7146a5cf0d feat(db): add fetchEnabled flag to TopicProgress
Additive Postgres migration (default true) that backs the per-topic
fetch enable/disable toggle. Existing rows backfill to enabled, so
current behaviour is unchanged. Migration applied to the live DB via
CI prisma migrate deploy (deferred, per environment).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 00:25:21 +02:00
adminandClaude Opus 4.7 4f6a6f0f75 feat(worker): forum-topic scan-skip + getForumTopic short-circuit
continuous-integration/drone/push Build is passing
Mirror of the non-forum guards from 1a4bc6f, scoped to forum topics
inside the topic loop:

  - Top-of-topic-loop recency/backoff skip
  - getForumTopic short-circuit after the SkippedPackage retry pass
  - upsertTopicScanState for end-of-scan persistence (both the
    archives-found path and the no-archives path)

Same trulyIdle definition throughout: no archives this scan, no
failures this scan, no retryable SkippedPackage rows pending. Topics
with chronic failures stay out of backoff because their counter
never increments.

For MPE specifically (1,086 forum topics), per-cycle searchChatMessages
calls drop from ~1,086 to roughly the count of topics with new
activity in the last 5 minutes — typically <50.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 19:58:44 +02:00
adminandClaude Opus 4.7 1a4bc6f9f3 feat(worker): non-forum channel-scan-skip + getChat short-circuit
For non-forum channels in runWorkerForAccount, three guards:

  1. Top-of-loop recency/backoff skip — if recently scanned with no
     pending work, or in backoff and not its turn, skip entirely.
     Bypassed when retryable SkippedPackages exist.

  2. After the SkippedPackage retry pass, a getChat short-circuit —
     if TDLib's local cache says the channel's last_message.id <= our
     effective watermark, skip the paginated searchChatMessages.

  3. End-of-scan persists lastScannedAt + lastScanFoundArchives +
     consecutiveEmptyScans via the new upsertChannelScanState helper.
     trulyIdle requires: no archives, no failures, no retryable pending.

scheduler.ts exposes getCurrentCycle() so the backoff "every Nth cycle"
modulo can be applied.

Forum-topic branch lands in the next commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 19:56:54 +02:00