14 KiB
Profilarr Architecture Guide
Quick reference for AI assistants working with this codebase.
Overview
Profilarr is a SvelteKit + Deno application for managing configurations across *arr applications (Radarr, Sonarr, etc.). It compiles to standalone binaries.
Stack: SvelteKit 2, Svelte 5 (using Svelte 4 syntax), TypeScript, Tailwind CSS 4, Deno 2, SQLite, Kysely
Svelte Syntax: This codebase uses Svelte 4 syntax (export let for props, $: for reactivity, createEventDispatcher for events). Do not use Svelte 5 runes ($state, $props, $derived) except where explicitly noted.
Key Paths:
src/routes/- SvelteKit pages and API routessrc/lib/server/- Backend logicsrc/lib/client/- Frontend stores and componentsdeno.json- Import aliases and tasks
Backend
1. Database Workflow
SQLite database with WAL mode. DatabaseManager is a singleton handling connections, transactions, and health checks.
Files:
src/lib/server/db/db.ts- DatabaseManager singleton, transaction support, parametrized queriessrc/lib/server/db/queries/- Query files per entity (jobs.ts, arrInstances.ts, notificationServices.ts, etc.)
Pattern: Each entity has a queries file exporting {entity}Queries with create(), getById(), getAll(), update(), delete() methods.
2. Migration System
MigrationRunner manages schema changes. Migrations are tracked in a migrations table with version, name, and applied_at.
Files:
src/lib/server/db/migrations.ts- MigrationRunner class, up/down supportsrc/lib/server/db/migrations/- 16 migration files (001-016)
Key migrations: 004 (jobs), 007 (notifications), 008 (database instances), 011-013 (upgrade configs), 014 (AI settings), 015-016 (sync configs)
3. Jobs System
Background job scheduler checking for due jobs every 60 seconds. Jobs are registered at startup and stored in the database.
Files:
src/lib/server/jobs/scheduler.ts- Scheduler singleton, 60s interval, prevents concurrent executionsrc/lib/server/jobs/runner.ts- Executes jobs, calculates next run time, records historysrc/lib/server/jobs/registry.ts- In-memory registry mapping job names to definitionssrc/lib/server/jobs/init.ts- Registers all jobs at startupsrc/lib/server/jobs/definitions/- Job definitions (syncDatabases.ts, syncArr.ts, upgradeManager.ts, etc.)
Schedule formats: "daily", "hourly", "*/N minutes"
4. Notifications System
Pluggable notification system with builder pattern. Sends to enabled services in parallel, records all attempts in history.
Files:
src/lib/server/notifications/NotificationManager.ts- Central orchestrator, fire-and-forget patternsrc/lib/server/notifications/builder.ts- Fluent API:notify(type).title().message().meta().send()src/lib/server/notifications/types.ts- Notification type constants (job.success, pcd.linked, upgrade.failed, etc.)src/lib/server/notifications/notifiers/DiscordNotifier.ts- Discord webhook implementation with embeds
5. PCDs (Profilarr Compliant Databases)
External git repositories containing configuration profiles. Uses layered SQL operations compiled into an in-memory SQLite cache.
Files:
src/lib/server/pcd/pcd.ts- PCDManager singleton (link, unlink, sync, checkForUpdates)src/lib/server/pcd/manifest.ts- Validates pcd.json manifestssrc/lib/server/pcd/cache.ts- PCDCache class, compiles SQL from layers, file watchingsrc/lib/server/pcd/schema.ts- Kysely schema for PCD database tablessrc/lib/server/pcd/ops.ts- Loads .sql files from layer directoriessrc/lib/server/pcd/deps.ts- Dependency resolution for PCD repossrc/lib/server/pcd/types.ts- TypeScript types for profiles, custom formats, etc.
Layers (in order): schema (from deps) → base (ops/) → tweaks (tweaks/) → user (user_ops/)
SQL helpers: qp(name) (quality profile), cf(name) (custom format), dp(name) (delay profile), tag(name)
6. Sync Engine
Pushes profiles from PCDs to ARR instances. Handles quality profiles, delay profiles, and media management settings.
Files:
src/lib/server/sync/- Sync engine directorysrc/lib/server/jobs/definitions/syncArr.ts- Scheduled sync jobsrc/lib/server/db/queries/syncConfigs.ts- Sync configuration queriessrc/lib/server/db/migrations/015_create_arr_sync.ts- Sync config schemasrc/lib/server/db/migrations/016_add_arr_sync_columns.ts- Additional sync columns
7. ARR API Client
3-tier class hierarchy: BaseHttpClient → BaseArrClient → App-specific clients (RadarrClient, SonarrClient, etc.)
Files:
src/lib/server/utils/http/client.ts- Base HTTP client with retry logic, connection pooling, exponential backoffsrc/lib/server/utils/arr/base.ts- Base ARR client, X-Api-Key auth, connection testing, delay profiles, tagssrc/lib/server/utils/arr/factory.ts- Factory function to create client by typesrc/lib/server/utils/arr/types.ts- TypeScript types for all ARR APIssrc/lib/server/utils/arr/clients/radarr.ts- Full Radarr implementation (movies, quality profiles, files, search, library)src/lib/server/utils/arr/clients/sonarr.ts- Sonarr client stubsrc/lib/server/utils/arr/clients/lidarr.ts- Lidarr client (API v1)
Features: 30s timeout, 3 retries on 5xx, batch operations, custom format scoring
8. Upgrade Manager
Scheduled job that searches for movies based on filters and selection strategies. Uses tag-based cooldowns.
Files:
src/lib/server/upgrades/processor.ts- Main orchestrator for upgrade workflowsrc/lib/server/upgrades/normalize.ts- Converts Radarr responses to normalized formatsrc/lib/server/upgrades/cooldown.ts- Tag-based cooldown (profilarr-searched-YYYY-MM-DD)src/lib/server/upgrades/logger.ts- Structured logging for upgrade runssrc/lib/server/upgrades/types.ts- Type definitionssrc/lib/server/jobs/definitions/upgradeManager.ts- Job definition (every 30 minutes)src/lib/server/jobs/logic/upgradeManager.ts- Job logic, fetches due configssrc/lib/server/db/queries/upgradeConfigs.ts- Upgrade config CRUD
Filter modes: round_robin (cycles through filters), random (picks random filter)
Dry run: Tests workflow without triggering actual searches
9. AI Integration
AI-powered commit message generation using OpenAI-compatible APIs. Generates semantic messages from file diffs.
Files:
src/lib/server/utils/ai/client.ts- Core client:isAIEnabled(),generateCommitMessage(diff)src/lib/server/db/queries/aiSettings.ts- Singleton settings (get, update, reset)src/lib/server/db/migrations/014_create_ai_settings.ts- Schema (enabled, api_url, api_key, model)src/routes/api/ai/status/+server.ts- Check if AI is enabledsrc/routes/api/databases/[id]/generate-commit-message/+server.ts- Generate commit message endpointsrc/routes/settings/general/components/AISettings.svelte- Settings UI
Supports: OpenAI, Ollama, LM Studio, Claude API (any OpenAI-compatible endpoint)
10. Git Integration
Git operations for PCD repositories.
Files:
src/lib/server/utils/git/- Git utilities- Key operations: clone, pull, checkout, status, update detection, private repo support (PAT)
11. Configuration System
Centralized configuration with paths and environment variables.
Files:
src/lib/server/utils/config/config.ts- Paths (database, data, backups, logs), timezone support
12. Logging
Structured logging with source tracking and log levels.
Files:
src/lib/server/utils/logger/- Logger utilities with levels (info, warn, error, debug)
Frontend
13. Accent Variable System
7 color palettes with 11 shades each (50-950). Uses CSS custom properties dynamically set via JavaScript.
Files:
src/app.css- CSS variables for accent colors (lines 7-43), @theme block for Tailwindsrc/lib/client/stores/accent.ts- AccentColor type, color palettes, localStorage persistence,applyAccentColors()src/lib/client/ui/navigation/navbar/accentPicker.svelte- Color picker UI
Colors: blue, yellow, green, orange, teal, purple, rose
Usage: bg-accent-600, text-accent-500, border-accent-300 in Tailwind classes
14. Theme System
Light/dark mode via class-based Tailwind. Uses View Transitions API for smooth switching.
Files:
src/lib/client/stores/theme.ts- Theme store, localStorage persistence, applies class to document.documentElementsrc/lib/client/ui/navigation/navbar/themeToggle.svelte- Toggle button with Sun/Moon icons
Usage: dark:bg-neutral-900, dark:text-white prefixes in Tailwind classes
15. Reusable UI Components
30+ components organized by functionality in src/lib/client/ui/.
Buttons:
src/lib/client/ui/button/Button.svelte- Variants (primary, secondary, danger), sizes (sm, md), icon support
Forms:
src/lib/client/ui/form/FormInput.svelte- Text input + textarea with label, descriptionsrc/lib/client/ui/form/NumberInput.svelte- Numeric with increment/decrement buttonssrc/lib/client/ui/form/TagInput.svelte- Tag entry with Enter key, backspace deletionsrc/lib/client/ui/form/IconCheckbox.svelte- Checkbox with icon, 3 shapes, custom colors
Tables:
src/lib/client/ui/table/Table.svelte- Generic table with TypeScript generics, sorting, custom cell rendererssrc/lib/client/ui/table/ExpandableTable.svelte- Table with row expansionsrc/lib/client/ui/table/ReorderableList.svelte- Drag-and-drop listsrc/lib/client/ui/table/types.ts- Column definitions
Modals:
src/lib/client/ui/modal/Modal.svelte- Base modal with backdrop, Escape key, confirm/cancelsrc/lib/client/ui/modal/SaveTargetModal.svelte- Two-option modal (User/Base layer)src/lib/client/ui/modal/UnsavedChangesModal.svelte- Unsaved changes warningsrc/lib/client/ui/modal/InfoModal.svelte- Information-only modal
Navigation:
src/lib/client/ui/navigation/navbar/navbar.svelte- Top navbar with logo, accent picker, theme togglesrc/lib/client/ui/navigation/pageNav/pageNav.svelte- Left sidebar with hierarchical groupssrc/lib/client/ui/navigation/tabs/Tabs.svelte- Tab navigation
Actions:
src/lib/client/ui/actions/ActionsBar.svelte- Container for inline action buttonssrc/lib/client/ui/actions/ActionButton.svelte- Icon button for toolbarssrc/lib/client/ui/actions/SearchAction.svelte- Search input with debouncingsrc/lib/client/ui/actions/ViewToggle.svelte- Table/card view toggle
Dropdowns:
src/lib/client/ui/dropdown/Dropdown.svelte- Positioned dropdown menusrc/lib/client/ui/dropdown/DropdownItem.svelte- Menu item
State:
src/lib/client/ui/state/EmptyState.svelte- Empty data placeholder
16. Colocation Strategy
Route-based colocation: page-specific components live in route folders, shared UI in src/lib/client/ui/.
Pattern:
src/routes/delay-profiles/[databaseId]/
├── +page.svelte # Page component
├── +page.server.ts # Server-side logic
├── components/ # Page-specific components
│ └── DelayProfileForm.svelte
└── views/ # View variations
├── CardView.svelte
└── TableView.svelte
Examples:
src/routes/delay-profiles/[databaseId]/components/DelayProfileForm.sveltesrc/routes/databases/components/InstanceForm.sveltesrc/routes/quality-profiles/[databaseId]/views/CardView.svelte
17. State Management
Svelte stores for global state with localStorage persistence.
Files:
src/lib/client/stores/theme.ts- Theme (light/dark)src/lib/client/stores/accent.ts- Accent colorsrc/lib/client/stores/search.ts- Search state with debouncing, filters, derived storessrc/lib/client/stores/dataPage.ts-createDataPageStore()combining search + view toggle + filteringsrc/lib/client/stores/libraryCache.ts- Client-side Radarr library cachesrc/lib/client/alerts/store.ts- Toast notifications (success, error, warning, info)
Data Page Pattern:
const { search, view, filtered, setItems } = createDataPageStore(data, {
storageKey: 'delayProfilesView',
searchKeys: ['name']
});
18. Form Enhancement
SvelteKit enhance directive for progressive enhancement with loading states and alerts.
Pattern:
<form method="POST" use:enhance={() => {
isLoading = true;
return async ({ result, update }) => {
if (result.type === 'failure') alertStore.add('error', msg);
else if (result.type === 'redirect') alertStore.add('success', msg);
await update();
isLoading = false;
};
}}>
19. Unsaved Changes Detection
Tracks dirty state and prompts user before navigation.
Files:
src/lib/client/utils/unsavedChanges.svelte.ts- Exception using Svelte 5$staterune; providesmarkDirty(),confirmNavigation(),confirmDiscard(),cancelDiscard()
Architecture
20. Import Aliases
Defined in deno.json for clean imports:
| Alias | Path |
|---|---|
$lib/ |
src/lib/ |
$config |
src/lib/server/utils/config/config.ts |
$logger/ |
src/lib/server/utils/logger/ |
$db/ |
src/lib/server/db/ |
$jobs/ |
src/lib/server/jobs/ |
$arr/ |
src/lib/server/utils/arr/ |
$notifications/ |
src/lib/server/notifications/ |
$pcd/ |
src/lib/server/pcd/ |
$stores/ |
src/lib/client/stores/ |
$ui/ |
src/lib/client/ui/ |
21. Server Initialization
Boot sequence in src/hooks.server.ts:
- Initialize configuration (env vars, paths)
- Log startup banner
- Initialize database connection
- Run database migrations
- Load log settings from database
- Initialize PCD caches
- Initialize job system
- Start job scheduler
22. Build & Deployment
Development:
deno run -A npm:vite dev # Port 6969
Production:
deno run -A npm:vite build
deno compile --target x86_64-unknown-linux-gnu --output dist/linux/profilarr dist/build/mod.ts
deno compile --target x86_64-pc-windows-msvc --output dist/windows/profilarr.exe dist/build/mod.ts
Output: Standalone binaries in dist/linux/ and dist/windows/