Commit Graph

63 Commits

Author SHA1 Message Date
Claudio Ortolina 8fd8dde73d Persist chat history 2026-03-17 13:50:01 +00:00
Claudio Ortolina a00b858226 Add index to speed up records by release date 2026-03-13 16:23:29 +00:00
Claudio Ortolina d3ae3a7381 Fix ScrobbleRule timestamps to use utc_datetime 2026-03-06 09:58:40 +00:00
Claudio Ortolina 9ae63ba055 Add missing FK index on record_set_items.record_id 2026-03-05 14:30:51 +00:00
Claudio Ortolina b35f4aed1d EXP: enrich artist info data via Last.fm and produce better embeddings 2026-03-01 08:22:35 +00:00
Claudio Ortolina 18ac442b2c Install ErrorTracker 2026-02-26 21:31:37 +00:00
Claudio Ortolina 98f901c020 Materialize record releases to improve performance 2026-02-16 12:30:41 +00:00
Claudio Ortolina d6c19d3a40 Improve performance of scrobble activity queries 2026-02-16 12:06:00 +00:00
Claudio Ortolina bcae291cff Support getting artist bios from Wikipedia (experimental) 2026-02-09 15:20:06 +00:00
Claudio Ortolina 419b093101 First pass at record sets 2026-02-05 11:46:52 +00:00
Claudio Ortolina faf8500256 Ensure uniqueness of scrobble rules 2026-02-02 10:32:32 +00:00
Claudio Ortolina 11acec56b2 Remove lotus
Unstable - and it messes with the repo connection, creating other
errors.
2025-11-03 17:29:37 +00:00
Claudio Ortolina a30e1b32d7 Mount data analysis via Lotus packages 2025-10-22 16:33:07 +01:00
Claudio Ortolina ee199272b1 Use sqlite vector 2025-10-12 13:36:42 +02:00
Claudio Ortolina 9cae972bc5 Add similar records
Initial stab by Claude
2025-10-11 21:39:59 +02:00
Claudio Ortolina 57dfd3d33d Remove ErrorTracker
Doesn't work with recent LiveView releases, and seems to be maintained
very slowly despite incoming PRs to fix the issues.
2025-10-03 10:15:23 +03:00
Claudio Ortolina 2e071d24b9 Add index on content size 2025-09-20 09:59:27 +03:00
Claudio Ortolina 74a93e2ee0 Remove obsolete data in artist infos 2025-09-18 21:33:52 +03:00
Claudio Ortolina ea9f8ca9a3 Remove record notes 2025-09-07 15:07:01 +03:00
Claudio Ortolina 55ab648b1c Add MusicLibrary.Notes.Note 2025-09-07 09:24:19 +03:00
Claudio Ortolina 45134d3f96 Add notes field to records 2025-09-05 14:53:06 +03:00
Claudio Ortolina 0564ec95b1 Remove cover_data from records 2025-09-01 16:35:11 +03:00
Claudio Ortolina a605610c9d Add base infra to store assets 2025-09-01 11:59:16 +03:00
Claudio Ortolina 65de5fc833 Add first version of online stores for wishlisted records (claude)
See docs/plans/online_stores.md
2025-07-15 09:42:59 +01:00
Claudio Ortolina d91685b646 First rough implementation of scrobble rules (Claude)
This plan outlines the implementation of functionality to manage
arbitrary rules for fixing data in the `scrobbled_tracks` table. The
system will support two types of transformations:

1. **Album Rule**: Update the album MusicBrainz ID of all tracks
belonging to a specific album (identified by album title)
2. **Artist Rule**: Update the artist MusicBrainz ID of all tracks
belonging to a specific artist (identified by artist name)

- `scrobbled_tracks` table exists with the following structure:
  - `scrobbled_at_uts` (integer, primary key)
  - `musicbrainz_id` (string) - track MusicBrainz ID
  - `title` (string) - track title
  - `cover_url` (string)
  - `scrobbled_at_label` (string)
  - `artist` (map) - embedded artist data with `musicbrainz_id` and
`name`
  - `album` (map) - embedded album data with `musicbrainz_id` and
`title`
  - `last_fm_data` (map) - raw Last.fm API response

- `LastFm.Track` - Schema for scrobbled tracks
- `LastFm.Artist` - Embedded artist schema
- `LastFm.Album` - Embedded album schema

- Main navigation has Stats, Collection, Wishlist sections
- "More" dropdown contains development tools and utilities
- Uses Phoenix LiveView for interactive components

**File**:
`priv/repo/migrations/YYYYMMDDHHMMSS_create_scrobble_rules.exs`

Create `scrobble_rules` table with:

- `id` (primary key)
- `type` (string) - "album" or "artist"
- `match_value` (string) - album title or artist name to match
- `target_musicbrainz_id` (string) - MusicBrainz ID to set
- `enabled` (boolean) - whether rule is active
- `description` (text) - optional description for the rule
- `inserted_at` (timestamp)
- `updated_at` (timestamp)

Indexes:

- `type, match_value` (compound index for efficient matching)
- `enabled` (for filtering active rules)

**File**: `lib/music_library/scrobble_rules/scrobble_rule.ex`

Create Ecto schema with:

- Field definitions matching migration
- Validations:
  - `type` must be "album" or "artist"
  - `match_value` required and non-empty
  - `target_musicbrainz_id` required and non-empty
  - `enabled` defaults to true
- Changeset functions for create/update operations

**File**: `lib/music_library/scrobble_rules.ex`

Implement context functions:

- `list_scrobble_rules(opts \\ [])` - list all rules with optional
filtering
- `get_scrobble_rule!(id)` - get specific rule by ID
- `create_scrobble_rule(attrs)` - create new rule
- `update_scrobble_rule(rule, attrs)` - update existing rule
- `delete_scrobble_rule(rule)` - delete rule
- `change_scrobble_rule(rule, attrs \\ %{})` - create changeset
- `list_enabled_rules()` - get only enabled rules for worker
- `apply_album_rule(rule)` - apply album transformation
- `apply_artist_rule(rule)` - apply artist transformation
- `apply_all_rules()` - apply all enabled rules

**File**: `lib/music_library_web/components/layouts/app.html.heex`

Add new navigation link in the "More" dropdown:

- Icon: `hero-adjustments-horizontal`
- Label: "Scrobble Rules"
- Route: `/scrobble-rules`
- Position: After "Oban" link, before separator

**File**: `lib/music_library_web/router.ex`

Add new LiveView routes in the authenticated scope:

- `/scrobble-rules` - index page
- `/scrobble-rules/new` - create new rule
- `/scrobble-rules/:id/edit` - edit existing rule

**File**: `lib/music_library_web/live/scrobble_rules_live/index.ex`

Implement LiveView with:

- List view showing all rules with status indicators
- Create/Edit forms with validation
- Delete confirmation
- Filter controls (by type, enabled/disabled)
- Manual rule application triggers
- Real-time updates via PubSub

**Template**:
`lib/music_library_web/live/scrobble_rules_live/index.html.heex`

- Table layout with rule details
- Action buttons (Edit, Delete, Apply)
- Form components for create/edit
- Status indicators for enabled/disabled rules

**File**:
`lib/music_library_web/live/scrobble_rules_live/form_component.ex`

Create reusable form component:

- Type selection (album/artist)
- Match value input with validation
- Target MusicBrainz ID input
- Description textarea
- Enable/disable toggle
- Save/Cancel actions

Where possible, use the components available at
<https://docs.fluxonui.com/1.1.4/overview.html>.

**File**: `lib/music_library/scrobble_rules/worker.ex`

Implement Oban worker:

- Scheduled to run periodically (e.g., every 30 minutes)
- Fetches all enabled rules
- Applies each rule in sequence
- Logs application results
- Handles errors gracefully
- Tracks last application time

**File**: `test/music_library/scrobble_rules_test.exs`

- Test all context functions
- Test rule application logic
- Test edge cases and error handling

**File**: `test/music_library/scrobble_rules/scrobble_rule_test.exs`

- Test schema validations
- Test changeset functions
- Test constraint validations

**File**: `test/music_library_web/live/scrobble_rules_live_test.exs`

- Test LiveView interactions
- Test form submissions
- Test real-time updates
- Test navigation and routing

**File**: `test/music_library/scrobble_rules/worker_test.exs`

- Test job execution
- Test rule application
- Test error handling
- Test scheduling

- Ensure atomic operations when applying rules
- Validate MusicBrainz IDs before applying
- Log all transformations for audit trail

- Index optimization for rule matching
- Batch processing for large datasets
- Rate limiting for external API calls

- Clear feedback on rule application
- Preview mode to show what would change
- Bulk operations for managing multiple rules
- Export/import functionality for rule sets

- Input validation and sanitization
- Rate limiting on rule creation
- Audit logging for all changes

```sql
-- scrobble_rules table
CREATE TABLE scrobble_rules (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  type TEXT NOT NULL CHECK (type IN ('album', 'artist')),
  match_value TEXT NOT NULL,
  target_musicbrainz_id TEXT NOT NULL,
  enabled BOOLEAN NOT NULL DEFAULT TRUE,
  description TEXT,
  inserted_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL
);

CREATE INDEX idx_scrobble_rules_type_match ON scrobble_rules(type,
match_value);
CREATE INDEX idx_scrobble_rules_enabled ON scrobble_rules(enabled);
```

```
lib/music_library/
├── scrobble_rules/
│   ├── scrobble_rule.ex          # Schema
│   └── worker.ex                 # Oban worker
└── scrobble_rules.ex             # Context

lib/music_library_web/
└── live/
    └── scrobble_rules_live/
        ├── index.ex              # LiveView
        ├── index.html.heex       # Template
        └── form_component.ex     # Form component

priv/repo/migrations/
└── YYYYMMDDHHMMSS_create_scrobble_rules.exs

test/
├── music_library/
│   ├── scrobble_rules_test.exs
│   └── scrobble_rules/
│       ├── scrobble_rule_test.exs
│       └── worker_test.exs
└── music_library_web/
    └── live/
        └── scrobble_rules_live_test.exs
```

1. Database migration and schema
2. Context module with basic CRUD operations
3. LiveView interface for rule management
4. Navigation and routing updates
5. Periodic worker implementation
6. Comprehensive testing
7. Documentation and deployment

This plan ensures a robust, maintainable solution that integrates
seamlessly with the existing Music Library application architecture.
2025-07-03 16:47:08 +01:00
Claudio Ortolina c5e47cbc8c Display dominant colors from the db 2025-06-07 20:07:23 +01:00
Claudio Ortolina a63f2de60b Use ->> instead of json_extract in queries
Improves readability of queries.
2025-06-06 21:05:44 +01:00
Claudio Ortolina b191d87dfd Fix scrobble tracks schema
Remove the primary key, and just set a unique index on scrobbled time
and title, which allows skipping duplicates.
2025-05-31 20:54:37 +01:00
Claudio Ortolina d01d16f1ae Add infrastructure to persist scrobble tracks to database
Unused for now.
2025-05-31 08:16:32 +01:00
Claudio Ortolina 423d1e7764 Can sort wishlisted records by insertion 2025-05-26 23:12:34 +01:00
Claudio Ortolina ad29b8f96d Normalized search index
So that one can search for 'bjorn' and find 'Bjørn'
2025-05-25 09:26:01 +01:00
Claudio Ortolina 95f71519d3 Store Last.fm API key with encrypted secret 2025-05-06 15:18:14 +01:00
Claudio Ortolina 3e7341d4ca Support choosing a selected release 2025-05-01 17:42:40 +01:00
Claudio Ortolina d8bc26da4c Fix migration to be schema independent 2025-05-01 14:12:53 +01:00
Claudio Ortolina e083950138 Rename record.release to record.release_date
Includes changes to dependent tables (i.e. the record search index) and
related functions.
2025-05-01 14:04:57 +01:00
Claudio Ortolina ece877086f Store artist infos 2025-04-26 13:57:43 +01:00
Claudio Ortolina 16b19de163 Remove unique index from records 2025-02-26 10:56:29 +00:00
Claudio Ortolina 1f973bcd1d Remove error tracker tables from main repo 2025-01-23 10:52:42 +00:00
Claudio Ortolina 3b3b9cf7a5 Restore missing migration with amended rollback task 2025-01-23 10:52:29 +00:00
Claudio Ortolina eeaaf8b542 Move ErrorTracker to its own repo and file
Note that the SQlite adapter supports version 2 onwards.
2025-01-23 10:40:36 +00:00
Claudio Ortolina 5cd57fdde4 Install Error Tracker to track production issues 2025-01-01 17:11:17 +00:00
Claudio Ortolina b63b3a633a Can fetch records by a specific artist 2024-12-02 10:55:12 +00:00
Claudio Ortolina b2e1f1f8d1 Index records by type to improve query perf 2024-11-23 23:16:24 +00:00
Claudio Ortolina 2e2000fe01 Introduce separate search index
Uses a fts5 virtual table, kept up to date via triggers on the records
table.
2024-11-22 19:37:13 +00:00
Claudio Ortolina 659894aaee Materialize included release group ids 2024-11-17 11:52:47 +00:00
Claudio Ortolina 97c7be7b0c Store release ids when importing a record 2024-11-12 15:01:17 +00:00
Claudio Ortolina 74a11ca10f Prevent importing the same record twice 2024-11-05 11:40:01 +00:00
Claudio Ortolina 79edd6eade Add missing index to records table
Updates a relevant test to remove flakyness
2024-10-22 22:15:13 +01:00
Claudio Ortolina 54f8da81b6 Insert default purchased_at date when importing a record 2024-10-19 19:22:43 +01:00
Claudio Ortolina 6f7f0fed79 Add record indexes to optimize search 2024-10-14 15:18:47 +01:00