jlightner
d8d876e9b8
chore: Download pipeline now reads nfoEnabled from platform_settings pe…
...
- "src/services/download.ts"
- "src/__tests__/download.test.ts"
GSD-Task: S04/T02
2026-04-04 10:00:19 +00:00
jlightner
0f42a4b269
feat: Add Generic platform, per-platform NFO toggle, and default view s…
...
- "src/db/schema/platform-settings.ts"
- "drizzle/0018_platform_settings_nfo_view.sql"
- "src/types/index.ts"
- "src/db/repositories/platform-settings-repository.ts"
- "src/server/routes/platform-settings.ts"
- "src/frontend/src/components/PlatformSettingsForm.tsx"
- "src/frontend/src/pages/Settings.tsx"
- "src/__tests__/platform-settings-api.test.ts"
GSD-Task: S04/T01
2026-04-04 09:56:53 +00:00
jlightner
4cabcfbb4c
feat: Removed the standalone Playlists button from ChannelDetail — scan…
...
- "src/frontend/src/pages/ChannelDetail.tsx"
GSD-Task: S03/T02
2026-04-04 09:46:19 +00:00
jlightner
8ebacba3e1
test: Integrate fetchPlaylists into scheduler checkChannel as best-effo…
...
- "src/services/scheduler.ts"
- "src/__tests__/scheduler.test.ts"
GSD-Task: S03/T01
2026-04-04 09:43:51 +00:00
jlightner
ed901c8240
feat: Moved Add URL button from sidebar footer to channels page header…
...
- "src/frontend/src/components/Sidebar.tsx"
- "src/frontend/src/pages/Channels.tsx"
GSD-Task: S02/T03
2026-04-04 09:37:39 +00:00
jlightner
29e8654b01
feat: Added GET /robots.txt route returning disallow-all and meta robot…
...
- "src/server/routes/health.ts"
- "src/frontend/index.html"
GSD-Task: S02/T02
2026-04-04 09:35:46 +00:00
jlightner
97905039ed
feat: Replaced Search icon with Download icon on Collect All Monitored…
...
- "src/frontend/src/pages/Channels.tsx"
GSD-Task: S02/T01
2026-04-04 09:33:56 +00:00
jlightner
872f092ec4
feat: Added opaque toast-specific background variables and wired Toast.…
...
- "src/frontend/src/styles/theme.css"
- "src/frontend/src/components/Toast.tsx"
GSD-Task: S01/T03
2026-04-04 09:31:08 +00:00
jlightner
243960d249
feat: Reduced back-to-channels link bottom margin from 1.25rem to 0.5re…
...
- "src/frontend/src/pages/ChannelDetail.tsx"
GSD-Task: S01/T02
2026-04-04 09:29:19 +00:00
jlightner
76f0dd882a
feat: Added missing pause/resume mutation hooks and Pause/Play icon imp…
...
- "src/frontend/src/pages/Queue.tsx"
GSD-Task: S01/T01
2026-04-04 09:27:32 +00:00
jlightner
ad16cc6141
fix: direct per-video enrichment and migration statement breakpoints
...
CI / test (push) Successful in 20s
- Rewrote scheduler enrichNewItems to fetch metadata per-video directly
instead of redundantly re-running Phase 1 discovery. Background enrichment
now calls yt-dlp --dump-json per video ID, updating publishedAt and
duration on DB records. Emits scan:complete when enrichment finishes
so clients know to refetch.
- Added missing --> statement-breakpoint markers to migration 0011.
Without them, Drizzle concatenated the three ALTER TABLE statements
and SQLite only executed the first one, leaving embed_thumbnail and
sponsor_block_remove columns missing from format_profiles.
2026-04-04 08:23:23 +00:00
jlightner
8d77ae248a
fix: remove duplicate embed_thumbnail/sponsor_block_remove columns from migration 0013
...
CI / test (push) Failing after 20s
Migration 0011 already adds these columns to format_profiles. The duplicate
ALTER TABLE statements in 0013 cause SQLITE_ERROR on production DB where 0011
was already applied.
2026-04-04 08:03:38 +00:00
jlightner
f37cfde0a0
chore: auto-commit after complete-milestone
...
CI / test (push) Successful in 19s
GSD-Unit: M004
2026-04-04 07:54:04 +00:00
jlightner
54e9041058
feat: Added RSS 2.0 podcast feed at /api/v1/feed/rss and media streamin…
...
- "src/server/routes/feed.ts"
- "src/__tests__/feed-api.test.ts"
- "src/server/middleware/auth.ts"
- "src/server/index.ts"
GSD-Task: S08/T04
2026-04-04 07:38:34 +00:00
jlightner
c012425ceb
fix: Created useTheme hook for App-level theme application, fixed hardc…
...
- "src/frontend/src/hooks/useTheme.ts"
- "src/frontend/src/App.tsx"
- "src/frontend/src/styles/global.css"
- "src/frontend/src/pages/ChannelDetail.tsx"
GSD-Task: S08/T03
2026-04-04 07:31:23 +00:00
jlightner
87cbfe87ee
feat: Created useTimezone hook and timezone-aware format utilities, wir…
...
- "src/frontend/src/hooks/useTimezone.ts"
- "src/frontend/src/utils/format.ts"
- "src/frontend/src/pages/Activity.tsx"
- "src/frontend/src/pages/Queue.tsx"
- "src/frontend/src/pages/ChannelDetail.tsx"
- "src/frontend/src/pages/System.tsx"
- "src/frontend/src/components/HealthStatus.tsx"
GSD-Task: S08/T02
2026-04-04 07:26:04 +00:00
jlightner
98c3d73c69
feat: Added timezone selector and dark/light theme toggle to Settings p…
...
- "src/server/routes/system.ts"
- "src/db/repositories/system-config-repository.ts"
- "src/types/api.ts"
- "src/frontend/src/pages/Settings.tsx"
- "src/frontend/src/styles/theme.css"
- "src/frontend/index.html"
GSD-Task: S08/T01
2026-04-04 07:19:15 +00:00
jlightner
daf892edad
feat: Add pause/resume buttons, paused status badge, and Paused filter…
...
- "src/frontend/src/pages/Queue.tsx"
- "src/frontend/src/api/hooks/useQueue.ts"
- "src/frontend/src/components/StatusBadge.tsx"
GSD-Task: S07/T04
2026-04-04 07:13:13 +00:00
jlightner
bd9e07f878
feat: Added Videos/Streams/Audio tab bar with count badges to channel d…
...
- "src/frontend/src/pages/ChannelDetail.tsx"
- "src/frontend/src/api/hooks/useContent.ts"
GSD-Task: S07/T02
2026-04-04 06:48:10 +00:00
jlightner
69ec5841e7
test: Added getContentCountsByType repository function and GET /api/v1/…
...
- "src/db/repositories/content-repository.ts"
- "src/server/routes/content.ts"
- "src/types/api.ts"
- "src/__tests__/content-api.test.ts"
GSD-Task: S07/T01
2026-04-04 06:44:04 +00:00
jlightner
e6711e91a5
feat: Added missing status badge, Library filter/re-download button, an…
...
- "src/frontend/src/components/StatusBadge.tsx"
- "src/frontend/src/pages/Library.tsx"
- "src/frontend/src/pages/System.tsx"
- "src/frontend/src/api/hooks/useLibrary.ts"
- "src/frontend/src/api/hooks/useSystem.ts"
GSD-Task: S06/T03
2026-04-04 06:39:17 +00:00
jlightner
a11c4c56c5
test: Added missing-scan API (trigger + status) and content requeue end…
...
- "src/server/routes/system.ts"
- "src/server/index.ts"
- "src/index.ts"
- "src/__tests__/missing-scan-api.test.ts"
GSD-Task: S06/T02
2026-04-04 06:35:58 +00:00
jlightner
61da729fa4
feat: Add MissingFileScanner service with cursor-based batched filesyst…
...
- "src/services/missing-file-scanner.ts"
- "src/__tests__/missing-file-scanner.test.ts"
- "src/types/index.ts"
- "src/db/schema/content.ts"
GSD-Task: S06/T01
2026-04-04 06:31:11 +00:00
jlightner
c0ac8cadd5
feat: Added RatingBadge/RatingPicker components, channel and content it…
...
- "src/frontend/src/components/RatingBadge.tsx"
- "src/frontend/src/pages/ChannelDetail.tsx"
- "src/frontend/src/pages/Settings.tsx"
- "src/server/routes/content.ts"
- "src/server/routes/channel.ts"
- "src/server/routes/system.ts"
- "src/types/api.ts"
GSD-Task: S05/T04
2026-04-04 06:24:14 +00:00
jlightner
b4d730d42f
feat: Wired NFO generation into DownloadService with feature flag check…
...
- "src/services/download.ts"
- "src/__tests__/download.test.ts"
GSD-Task: S05/T03
2026-04-04 06:16:03 +00:00
jlightner
7f6f3dcccf
feat: Built NfoGenerator service producing Kodi-compatible NFO XML with…
...
- "src/services/nfo-generator.ts"
- "src/__tests__/nfo-generator.test.ts"
- "src/types/index.ts"
- "src/db/repositories/channel-repository.ts"
- "src/__tests__/sources.test.ts"
GSD-Task: S05/T02
2026-04-04 06:12:35 +00:00
jlightner
e0b6424932
chore: Added nullable contentRating columns to channels and content_ite…
...
- "src/db/schema/channels.ts"
- "src/db/schema/content.ts"
- "src/types/index.ts"
- "src/db/repositories/system-config-repository.ts"
- "src/db/repositories/content-repository.ts"
- "src/__tests__/scheduler.test.ts"
- "drizzle/0017_wild_havok.sql"
GSD-Task: S05/T01
2026-04-04 06:08:16 +00:00
jlightner
01f4a2d38a
test: Built Media Servers settings section with full CRUD, connection t…
...
- "src/frontend/src/api/hooks/useMediaServers.ts"
- "src/frontend/src/components/MediaServerForm.tsx"
- "src/frontend/src/pages/Settings.tsx"
GSD-Task: S04/T04
2026-04-04 06:02:39 +00:00
jlightner
9ef0323480
test: Built media server CRUD routes, connection test/sections endpoint…
...
- "src/server/routes/media-server.ts"
- "src/__tests__/media-server-api.test.ts"
- "src/index.ts"
- "src/server/index.ts"
GSD-Task: S04/T03
2026-04-04 05:57:39 +00:00
jlightner
73c232a845
test: Built stateless MediaServerService with scan triggering, connecti…
...
- "src/services/media-server.ts"
- "src/__tests__/media-server.test.ts"
GSD-Task: S04/T02
2026-04-04 05:53:30 +00:00
jlightner
6aa7e21b90
feat: Added media_servers table, MediaServer type, and CRUD repository…
...
- "src/db/schema/media-servers.ts"
- "src/db/repositories/media-server-repository.ts"
- "src/types/index.ts"
- "drizzle/0016_right_galactus.sql"
GSD-Task: S04/T01
2026-04-04 05:50:33 +00:00
jlightner
9e7d98c7c7
feat: Add collapsible keyword filter UI to channel detail with include/…
...
- "src/frontend/src/pages/ChannelDetail.tsx"
- "src/server/routes/channel.ts"
- "src/frontend/src/api/hooks/useChannels.ts"
GSD-Task: S03/T04
2026-04-04 05:46:46 +00:00
jlightner
05045828d8
feat: Wire keyword filter into scheduler scan flow — exclude/include pa…
...
- "src/services/scheduler.ts"
- "src/__tests__/scheduler.test.ts"
- "src/db/repositories/channel-repository.ts"
GSD-Task: S03/T03
2026-04-04 05:41:55 +00:00
jlightner
cc031a78a9
test: Implement matchesKeywordFilter engine with pipe-separated pattern…
...
- "src/services/keyword-filter.ts"
- "src/__tests__/keyword-filter.test.ts"
GSD-Task: S03/T02
2026-04-04 05:38:37 +00:00
jlightner
8d133024a5
feat: Add includeKeywords and excludeKeywords nullable text columns to…
...
- "src/db/schema/channels.ts"
- "src/types/index.ts"
- "src/db/repositories/channel-repository.ts"
- "drizzle/0015_perfect_lethal_legion.sql"
- "src/__tests__/sources.test.ts"
GSD-Task: S03/T01
2026-04-04 05:35:13 +00:00
jlightner
3bfdb7b634
feat: Add File Organization settings section with output template input…
...
- "src/frontend/src/pages/Settings.tsx"
- "src/frontend/src/components/FormatProfileForm.tsx"
- "src/frontend/src/api/hooks/useFormatProfiles.ts"
- "src/types/api.ts"
- "src/server/routes/system.ts"
GSD-Task: S02/T04
2026-04-04 05:30:34 +00:00
jlightner
fb731377bd
feat: Wire FormatProfile.outputTemplate into DownloadService with conte…
...
- "src/services/download.ts"
- "src/services/file-organizer.ts"
GSD-Task: S02/T03
2026-04-04 05:25:41 +00:00
jlightner
71175198bd
test: Add resolveTemplate and validateTemplate methods to FileOrganizer…
...
- "src/services/file-organizer.ts"
- "src/__tests__/file-organizer.test.ts"
GSD-Task: S02/T02
2026-04-04 05:23:22 +00:00
jlightner
e6371ba196
chore: Add outputTemplate column to format_profiles schema and app.outp…
...
- "src/db/schema/content.ts"
- "src/types/index.ts"
- "src/db/repositories/system-config-repository.ts"
- "src/db/repositories/format-profile-repository.ts"
- "drizzle/0014_adorable_miek.sql"
GSD-Task: S02/T01
2026-04-04 05:20:18 +00:00
jlightner
61105a74b0
feat: Created AddUrlModal with two-step preview/confirm flow, useAdhocD…
...
- "src/frontend/src/components/AddUrlModal.tsx"
- "src/frontend/src/api/hooks/useAdhocDownload.ts"
- "src/frontend/src/components/Sidebar.tsx"
GSD-Task: S01/T04
2026-04-04 05:15:28 +00:00
jlightner
22077e0eb1
feat: Add POST /api/v1/download/url/confirm endpoint for ad-hoc downloa…
...
- "src/server/routes/adhoc-download.ts"
- "src/services/download.ts"
- "src/services/queue.ts"
- "src/__tests__/adhoc-download-api.test.ts"
GSD-Task: S01/T03
2026-04-04 05:12:11 +00:00
jlightner
373a2ee649
test: Created POST /api/v1/download/url/preview endpoint that resolves…
...
- "src/server/routes/adhoc-download.ts"
- "src/__tests__/adhoc-download-api.test.ts"
- "src/server/index.ts"
- "drizzle/0013_flat_lady_deathstrike.sql"
GSD-Task: S01/T02
2026-04-04 05:07:24 +00:00
jlightner
8150b1f6cf
chore: Made content_items.channelId nullable via SQLite table recreatio…
...
- "src/db/schema/content.ts"
- "src/types/index.ts"
- "src/db/repositories/content-repository.ts"
- "src/services/queue.ts"
- "drizzle/0012_adhoc_nullable_channel.sql"
- "drizzle/meta/_journal.json"
GSD-Task: S01/T01
2026-04-04 05:03:40 +00:00
jlightner
9e5033026e
revise issue templates: add location, reproducibility, scope; drop low-signal fields
CI / test (push) Failing after 17s
2026-04-04 04:02:48 +00:00
jlightner
287f0aa068
add issue templates for bug reports and feature requests
CI / test (push) Failing after 19s
2026-04-04 04:00:25 +00:00
jlightner
4fe4986f01
docs: naming templates + metadata embedding design spec
...
CI / test (push) Failing after 17s
Four-slice feature: template engine with {token} syntax, Plex-compatible
metadata embedding via ffmpeg, batch rename tool, live preview UI.
Per-platform and per-channel naming profile support.
Design only — implementation in next milestone.
2026-04-04 03:27:12 +00:00
jlightner
7de71f1062
fix: strip # from filenames — breaks Plex scanner
...
CI / test (push) Failing after 17s
Plex interprets # as a URL fragment delimiter, causing files with # in
the name to be silently skipped during library scans.
- Added # to FORBIDDEN_CHARS in file-organizer.ts sanitizer
- Bulk-renamed 100 existing files on disk
- Updated 100 filePath records in DB to match
2026-04-04 03:15:11 +00:00
jlightner
21a458f500
feat: FormatProfile settings UI + extract ChannelDetail hooks
...
CI / test (push) Failing after 19s
- FormatProfile editor now includes embedChapters, embedThumbnail,
sponsorBlockRemove fields with proper labels and help text
- Extract usePersistedState hook (replaces 7 localStorage try/catch blocks)
- Extract useBulkSelection hook (replaces inline selection state management)
- ChannelDetail.tsx: 1721 → 1672 lines
2026-04-04 02:53:50 +00:00
jlightner
aa09bc089c
feat: Generic platform + YouTube enhancements (chapters, SponsorBlock, thumbnails)
...
Generic Platform:
- New 'generic' platform type — catch-all for any URL yt-dlp supports
- GenericSource resolves channel metadata from any URL via yt-dlp extractors
- Content type auto-detection (video/audio/livestream) from yt-dlp metadata
- Works with Vimeo, Twitch, Bandcamp, Dailymotion, and 1000+ other sites
- Registered in both scheduler registry and channel route registry
- Frontend: indigo badge, URL detection fallback, AddChannelModal support
YouTube Enhancements:
- embedChapters: --embed-chapters flag on FormatProfile
- embedThumbnail: --embed-thumbnail flag on FormatProfile
- sponsorBlockRemove: --sponsorblock-remove with configurable categories
(sponsor, selfpromo, interaction, intro, outro, preview, music_offtopic, filler)
- Migration 0011: adds columns to format_profiles table
- All three configurable per format profile via API and (future) Settings UI
2026-04-04 02:45:02 +00:00
jlightner
b1e90ea8d6
refactor: consolidate format utils, extract route helpers, remove dead code
...
- Consolidate 5 duplicate format functions (formatDuration, formatRelativeTime,
formatFileSize, formatSubscriberCount) into shared utils/format.ts
- Extract parseIdParam() route helper, replacing 22 copy-paste blocks across 9 route files
- Remove dead exports: useScanStatus, useChannelContent (non-paginated),
getContentItemsByStatus, deleteQueueItem, deletePlaylistsByChannelId
- Fix as-any type assertion in system.ts (queueService already typed on FastifyInstance)
- Net: -411 lines, 23 files touched
2026-04-03 22:55:43 +00:00