Skip to contents

artutils 0.19.3

New Features

  • Added bm_artist_works() in R/db-mcp-data.R as an experimental MCP query helper. It returns benchmark time-series data for all artworks by an artist by joining app.artwork_index and app.artwork_benchmark, ordered by artwork start date.

  • Added style_artist_works() in R/db-mcp-data.R as an experimental MCP query helper. It returns stylistic evolution data over time for an artist by joining app.artwork_index, app.global_styles, app.artist_style_map, and app.artwork_styles.


artutils 0.19.2

New Features

  • db_art_execute() executes parameterized SQL statements (UPDATE, DELETE, INSERT) using DBI::dbExecute(). This is the preferred method for executing statements with dynamic values as it prevents SQL injection attacks. Returns the number of affected rows.

    # Example: parameterized UPDATE
    n_updated <- db_art_execute(
      qry = "UPDATE app.artwork_index SET purchase_url = $1 WHERE art_uuid = $2",
      params = list(url, artwork_uuid)
    )

artutils 0.19.1

New Features

  • get_art_print_url() retrieves the external print store URL for an artwork to enable e-commerce integration with print marketplaces.

  • get_art_opensea_url() retrieves the direct OpenSea listing URL for NFT artworks to enable one-click marketplace navigation.

  • get_art_purchase_urls() retrieves print and OpenSea URLs for all artworks by an artist in a single efficient query. Bulk version optimized for get_appdata().

  • get_appdata() now includes $artist$urlsDT — a data.table of purchase URLs (print and OpenSea) for all artist artworks, eliminating extra queries in consuming modules.


artutils 0.19.0

Breaking Changes

  • Deprecated function aliases removed - The following camelCase function stubs that threw errors directing users to snake_case equivalents have been removed entirely:

    • Database interface: dbArtGet(), dbArtAppend(), dbArtUpdate()
    • Path functions: pathImageAsset(), pathArtCanvas(), pathArtworkThumb(), pathArtistThumb(), pathGalleryAsset(), pathCertFrameAsset(), pathCertTemplAsset(), pathArtMainImage(), pathReplayFrame(), pathReplayGraph(), pathArtworkCert()
    • Prefix functions: prefixUploads(), prefixGallery(), prefixReplay()
    • Data access: getAppdata(), getArtistIndex(), getArtistStyleMap(), getArtistTags(), getArtistOpensea(), getArtworkIndex(), getArtworkStats(), getArtworkMeta(), getArtworkProfile(), getArtworkProfileFull(), getVerificationInfo(), getArtworkOpensea(), artHasNFT(), getFrameAnalytics(), getImageRaster()
    • Modifiers: addArtwork(), addCollection(), updateArtistStats(), updateArtistBenchmarks(), deleteCollection()
  • get_image_raster() removed - Function deleted; use magick directly for image raster operations.

  • Benchmark functions migrated to artbenchmark - .parseBenchmarkRow() and benchmark calculation logic moved to the dedicated artbenchmark package.

Removed

  • R/deprecate.R - All deprecated function stubs removed (see Breaking Changes above)
  • R/benchmarks.R - Migrated to artbenchmark package
  • R/getImageRaster.R - get_image_raster() function removed

Internal

  • R/considering.R moved to R/.dev/considering.R (internal development only)
  • R/settings.R renamed to R/app-settings.R for clarity
  • Removed ~1,200 lines of deprecated/migrated code
  • Updated NAMESPACE exports

artutils 0.18.0

Breaking Changes

New Features

  • delete_collection() now exported - Moved from considering.R to db-modify.R and made available as a public API.

Dependencies

  • Updated to use artcore 1.2.0 with renamed dbc()/dbd() functions

artutils 0.17.0

New features

  • get_artist_tags() retrieves all style tags used across an artist’s artworks. Returns unique tags from app.global_styles table. Used by {artpipelines} for style map updates.

Internal


artutils 0.16.0

New features

  • add_artist() creates new artist profile with transactional database inserts for onboarding workflows (PR #73).
    • Creates records in both artist_index and artist_stats tables atomically
    • Generates unique URL-friendly slugs with collision handling
    • Optional CDN directory creation for artist assets
    • Supports test mode with override UUID for testing/migration

INTERNAL

  • New file R/db-artist-modify.R for artist modification functions
  • Internal helpers .gen_artist_slug() and .slug_exists() for slug generation
  • Comprehensive unit tests in test-db-artist-modify.R
  • Demo mode check removed (handled at application layer per 0.15.0 pattern)

TODO

  • addArtist() pending integration with artist onboarding pipeline

artutils 0.15.0

Documentation & Code Cleanup Release

This release focuses on documentation improvements, removal of demo mode guards, test cleanup, file reorganization, and codebase hygiene.

BREAKING CHANGES

IMPROVEMENTS

  • Database File Reorganization
    • Created db-interface.R with low-level database functions (dbArtGet(), dbArtAppend(), dbArtUpdate())
    • Refactored db-modify.R to contain only data modification functions (addArtwork(), addCollection(), updateArtistStats(), updateArtistBenchmarks())
    • Moved artHasNFT() from db-modify.R to db-artwork.R (it’s a data-access function)
    • Each file now contains functions from a single @family group
  • Test Reorganization
    • Created test-db-interface.R with live database tests for read operations
    • Updated test-db-modify.R to only contain data modification tests (mocked)
    • Added artHasNFT test to test-db-artwork.R
    • Read-only tests use live database queries; write operations use mocks
  • Roxygen Documentation Quality
    • Updated function titles to explain WHY (not just WHAT) for all exported functions
    • Reference index now shows actionable descriptions like “Resolve URL slug to artist profile for page routing”
    • Topic pages (@name blocks) use @keywords internal to prevent duplicate entries in reference
  • pkgdown Reference Organization
    • Topic pages no longer appear as separate entries in the reference index
    • Functions grouped cleanly by family without organizational noise

BUG FIXES

  • Fixed is_collection_visible() calling undefined get_artist_preferences() - replaced with inline database query
  • Fixed R CMD check notes for unused imports (rlang, shiny removed from Imports)
  • Added @importFrom lifecycle badge to properly import lifecycle package

REMOVED

  • Stub Files Deleted
    • R/calcArtworkBenchmarks.R - was just a redirect comment
    • R/settings-artist-prefs.R - was just a redirect comment
    • R/settings-visibility.R - empty topic page with no functions
  • Internal Function Tests Removed
    • Removed tests for .calc_benchmarks() and .parseBenchmarkRow() from test-benchmarks.R
    • Internal functions (prefixed with .) are not tested directly
    • Benchmark functionality tested via public updateArtistBenchmarks()

INTERNAL

  • Code coverage: 59.61%
    • db-artwork.R: 100%
    • db-frame-analytics.R: 100%
    • db-interface.R: 100%
    • getImageRaster.R: 100%
    • db-artist.R: 89%
    • app-data.R: 87%

DEPENDENCIES

  • Removed rlang and shiny from Imports (only used in .dev/ files)
  • Removed unused rdstools references from demo mode guards

artutils 0.14.0

pkgdown Documentation Infrastructure

This release introduces comprehensive pkgdown documentation with automatic GitHub Pages deployment, lifecycle tagging for unused functions, and improved function organization.

NEW FEATURES

  • pkgdown Documentation Site
    • Added _pkgdown.yml configuration with function groupings via has_concept() selectors
    • Site auto-deploys to https://docs.artalytics.dev/r/artutils on push to main
    • Added .github/workflows/pkgdown.yaml GitHub Actions workflow
    • Reference page organized into 6 logical groups: Data Access, Data Modifiers, Path Utilities, Application Data, Database Interface, Under Review
  • Vignettes
    • vignettes/artutils.Rmd - Get Started guide with package overview, environment setup, quick start
    • vignettes/data-access-patterns.Rmd - End-to-end query workflows (artist discovery, gallery views, frame analysis)
    • vignettes/data-modification-workflows.Rmd - WRITE operations (addArtist, addCollection, updateArtistStats)
  • Artist Profile Data Functions (PR #66)
  • Artist Settings & Visibility Functions (PR #63)
    • filter_visible_collections() - Privacy-aware collection filtering
    • Settings functions for artist preferences and collection visibility
  • Featured Artist Support (PR #68)

LIFECYCLE CHANGES

  • 37 Functions Moved to R/considering.R (lifecycle: questioning)
    • Functions with no external callers in the platform codebase
    • Tagged with lifecycle::deprecate_soft() - warns once per session
    • Functions remain exported to avoid breaking unknown callers
    • If you depend on any of these functions, please file an issue
    Affected functions include:
    • Benchmark calculations: calcArtworkBenchmarks(), calcArtworkBenchmarks_p()
    • Artist data: getArtistStats(), getArtistName(), getArtistBenchmarks(), getCollectionSummary(), list_artists(), list_collections(), getArtistSummary(), listArtworkUUIDs(), getArtworksTable(), getAllArtistData(), updateArtist()
    • Artwork data: getArtworkPaths(), getArtworkColors(), getArtworkStyles(), getArtworkHash(), getArtworkCOA()
    • Collections: getCollections(), deleteCollection()
    • Asset paths: pathArtVaultImage(), pathCanvasSign(), pathLottieJSON(), pathPackageCSS()
    • Counts: getCountFrames(), getCountVariants(), getCountCarousel()
    • Settings: get_artist_preferences(), upsert_artist_preferences(), get_collection_settings(), update_collection_settings(), is_collection_visible()
    • Other: update_has_nft()

IMPROVEMENTS

  • Documentation Quality
    • All exported functions now have @family tags for pkgdown grouping
    • @family tags generate both concept tags (for pkgdown) and “See Also” cross-references
    • Fixed @seealso reference to unavailable artpipelines package
    • Improved @param documentation for database interface functions
  • Performance
    • get_artist_stats() optimized with separate COUNT queries (PR #66)
    • Collections now ordered by most recent artwork upload

BUG FIXES

  • Fixed artist_uuid missing from get_artist_collections_summary() output (#68)
  • Fixed class attribute mismatch in rbindlist for settings functions
  • Fixed NA handling in preference joins
  • Renamed blend_rate_normalized component to ave_blend_rate for consistency

BREAKING CHANGES

  • UI Components Migrated to artshiny (PR #60)
    • mod_statsBox() and related UI functions removed
    • Use artshiny package for Shiny UI components

INTERNAL

  • Removed artwork_settings table references (deprecated)
  • Moved calc_percentile() to artcore package
  • Removed complex mock tests dependent on artshiny
  • Cleaned up delete functionality (moved to internal dev package)

DEPENDENCIES

  • Added lifecycle to Imports (for deprecation warnings)
  • Added knitr, rmarkdown to Suggests (for vignettes)
  • Added VignetteBuilder: knitr to DESCRIPTION

artutils 0.13.0

BREAKING CHANGES

  • Frame Analytics Data Structure Change
    • getAppdata()$artwork$brushesDT renamed to frame_stats
    • All code must update references: r$appdata$artwork$brushesDTr$appdata$artwork$frame_stats
    • Reason: Transition from synthetic brush stroke data to real per-frame analytics
    • Affected packages: modFrames (PR #19), artpipelines (updated)
  • Removed Lenient NULL Handling - Strict Fail-Fast Enforcement
    • ..getArtworkStyles() no longer returns empty data.table for missing data
    • Missing style data now throws immediate errors
    • Philosophy: Missing data indicates pipeline failure requiring immediate fix
    • Migration: Ensure all artworks have style data before deploying

NEW FEATURES

  • Frame Analytics Database Infrastructure
    • Added getFrameAnalytics() - Retrieve 21-column per-frame analytics from database
    • New app.artwork_frame_analytics table with comprehensive temporal, color, and delta metrics
    • Replaces synthetic brushes_curry dataset with real production data
    • Columns include: temporal metrics (elapsed_minutes, cumulative_strokes, estimated_bpm), color composition (unique_colors, dominant_hex, color_diversity), delta metrics (colors_added, pixels_added, palette_change_score), and phase detection (technique_phase)
  • Security Hardening
    • Added UUID validation to getFrameAnalytics() to prevent SQL injection
    • Uses artcore::validate_uuid() for strict format validation
    • Rejects invalid UUIDs before database query execution

IMPROVEMENTS

  • Fail-Fast Data Integrity
    • All artworks now use real frame analytics instead of synthetic data
    • Missing frame analytics data throws errors immediately (no silent failures)
    • Removed lenient NULL handling from style/analytics functions
    • Database FK constraints enforce referential integrity (CASCADE deletes)

TESTING

  • Comprehensive Test Coverage for Frame Analytics
    • Added test-db-frame-analytics.R with 6 test suites
    • SQL injection protection tests (6 test cases)
    • Data structure validation (21-column schema verification)
    • Monotonic temporal metrics validation
    • Edge case testing (frame 1 baseline values)
    • Connection parameter testing (with cn and without)

MIGRATION GUIDE

Update all code referencing frame data:

# BEFORE (Old)
frames <- r$appdata$artwork$brushesDT

# AFTER (New)
frames <- r$appdata$artwork$frame_stats

Ensure data pipeline has processed all artworks:

If you see errors about missing frame analytics, run:

artpipelines::createFrameAnalytics(artist, artwork)

artutils 0.12.0

BREAKING CHANGES

  • Removed Fallback Behavior for Missing Benchmarks
    • .parseBenchmarkRow() now throws errors for NULL benchmark values instead of defaulting to 50%
    • getAppdata() now throws errors when benchmarks are missing from database
    • Provides clear error messages with instructions to run updateArtistBenchmarks()
    • Philosophy: Fail fast in development, fix issues permanently at the source

Why This Breaking Change?

Silent fallbacks were masking real data issues. We discovered benchmark rows from June 2025 with NULL values that went undetected for months because the code was defaulting to 50%. This change ensures data integrity issues are caught and fixed immediately.


artutils 0.11.0

New Features

  • Batch Benchmark Calculation: Added updateArtistBenchmarks() for efficient batch recalculation
    • Replaces N individual calculations with single batch operation
    • Integrated into artwork upload pipeline via artpipelines::updateArtistData()
    • Uses transaction-wrapped DELETE + INSERT for atomicity
    • Comprehensive logging for debugging and observability
  • Database-First Benchmark Reading: getAppdata() now reads from artwork_benchmark table
    • 10-20x performance improvement (5ms vs 50-100ms per artwork)
    • Graceful fallback to dynamic calculation when DB data unavailable
    • Eliminates duplicate getArtistBenchmarks() calls

Internal Functions

  • Added .parseBenchmarkRow() helper to convert DB rows to benchmark structure
    • Handles NA values with sensible defaults (50 for scores, “low” for confidence)
    • Returns empty numeric(5) for components (DB stores only summary scores)
    • Comprehensive input validation and logging

Performance Notes

  • Known Issue: updateArtistBenchmarks() has N+1 query pattern (documented in code)
    • Each calcArtworkBenchmarks() call queries artwork_stats independently
    • For 50 artworks = 50 duplicate queries
    • TODO: Refactor to fetch once and pass to calc function
    • Current implementation prioritizes code reuse over query optimization

Bug Fixes

  • Restored URL and BugReports fields to DESCRIPTION (removed by automated check)
  • Fixed codecov.io redirect in README.md badges
  • Updated .Rbuildignore to exclude README.md from build warnings

Documentation

  • Added comprehensive roxygen2 docs for updateArtistBenchmarks()
  • Documented N+1 query issue with TODO for future optimization
  • Added CHECK_FIX_REPORT.md and CHECK_SUMMARY.md for R CMD check results

Testing

  • 274/274 tests passing (100% pass rate)
  • Added comprehensive test coverage for new functions
  • R CMD check: 0 errors, 0 warnings, 0 notes

artutils 0.10.0

Breaking Changes

  • 15-Metric Benchmark System: calcArtworkBenchmarks() now returns 5 metrics per category instead of 3
    • Time & Effort: Added color_generation_rate, early_late_color_ratio
    • Skill & Artistry: Added strokes_per_unique_color, frame_color_stability
    • Complexity & Detail: Added frame_color_variance, technique_phase_count
    • Migration Required: Applications expecting 3 components per category must be updated
    • Benchmark scores will change as they now average 5 metrics instead of 3

Major Changes

  • Updated calcArtworkBenchmarks() to query production artwork_stats table instead of test artwork_stats2
  • Added database schema validation with warnings for missing metrics
  • Enhanced NULL/NA handling with user notifications
  • Improved test coverage for benchmark calculations

New Features

  • Database schema validation automatically handles missing columns
  • Transparent NA metric reporting for debugging
  • Comprehensive unit tests for 15-metric framework

Bug Fixes

  • Fixed incorrect benchmark scores in modGallery (was showing 99%, 16%, 66% instead of correct values)
  • Resolved issue with test table query causing stale data

Documentation

  • Updated AGENTS.md with complete 15-metric framework documentation
  • Added migration guide for applications using benchmark data
  • Enhanced function documentation with metric descriptions

Performance

  • No performance degradation despite additional metrics
  • Query optimization notes added for large portfolios (100+ artworks)

Dependencies

  • Requires artcore >= 0.2.0
  • Database requires 7 new columns in app.artwork_stats table:
    • color_generation_rate
    • early_late_color_ratio
    • strokes_per_unique_color
    • frame_color_stability
    • frame_color_variance
    • technique_phase_count

Migration Guide

Applications using calcArtworkBenchmarks() must be updated:

Before (3 metrics per category):

benchmarks$time_effort$components  # length = 3
# c(drawing_hours, brush_strokes, ave_bpm)

After (5 metrics per category):

benchmarks$time_effort$components  # length = 5
# c(drawing_hours, brush_strokes, ave_bpm, color_generation_rate, early_late_color_ratio)

Compatibility Check

To check if your code needs updating:

benchmarks <- calcArtworkBenchmarks(artist, artwork)
if (length(benchmarks$time_effort$components) != 5) {
  warning("Using old version of artutils - please update")
}

artutils 0.9.3

Performance Improvements

  • Major optimization of getAppdata() function, reducing execution time by 31.2%
  • Enhanced data.table operations for better memory efficiency

Bug Fixes

  • Fixed test edge case in getAllArtistData() for non-existent artists

Development

  • Added IDE directories to .gitignore
  • Improved test clarity with better documentation