artutils 0.19.3
New Features
Added
bm_artist_works()inR/db-mcp-data.Ras an experimental MCP query helper. It returns benchmark time-series data for all artworks by an artist by joiningapp.artwork_indexandapp.artwork_benchmark, ordered by artwork start date.Added
style_artist_works()inR/db-mcp-data.Ras an experimental MCP query helper. It returns stylistic evolution data over time for an artist by joiningapp.artwork_index,app.global_styles,app.artist_style_map, andapp.artwork_styles.
artutils 0.19.2
New Features
-
db_art_execute()executes parameterized SQL statements (UPDATE, DELETE, INSERT) usingDBI::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 forget_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()
- Database interface:
get_image_raster()removed - Function deleted; usemagickdirectly for image raster operations.Benchmark functions migrated to artbenchmark -
.parseBenchmarkRow()and benchmark calculation logic moved to the dedicatedartbenchmarkpackage.
artutils 0.18.0
Breaking Changes
-
Function renames to snake_case - All functions now follow snake_case naming convention:
-
dbArtGet()→db_art_get() -
dbArtAppend()→db_art_append() -
dbArtUpdate()→db_art_update() -
getAppdata()→get_appdata() -
getArtistIndex()→get_artist_index() -
getArtistStyleMap()→get_artist_style_map() -
getArtistTags()→get_artist_tags() -
getArtistOpensea()→get_artist_opensea() -
getArtworkIndex()→get_artwork_index() -
getArtworkStats()→get_artwork_stats() -
getArtworkMeta()→get_artwork_meta() -
getArtworkProfile()→get_artwork_profile() -
getArtworkProfileFull()→get_artwork_profile_full() -
getVerificationInfo()→get_verification_info() -
getArtworkOpensea()→get_artwork_opensea() -
artHasNFT()→art_has_nft() -
getFrameAnalytics()→get_frame_analytics() -
getImageRaster()→get_image_raster() -
addArtwork()→add_artwork() -
addCollection()→add_collection() -
updateArtistStats()→update_artist_stats() -
updateArtistBenchmarks()→update_artist_benchmarks() -
deleteCollection()→delete_collection() - All
path*functions →path_*(e.g.,pathArtworkThumb()→path_artwork_thumb()) - All
prefix*functions →prefix_*(e.g.,prefixUploads()→prefix_uploads())
-
- Deprecated functions error immediately - Old function names are still exported but now throw an error directing users to the new names.
New Features
-
delete_collection()now exported - Moved from considering.R to db-modify.R and made available as a public API.
artutils 0.17.0
New features
-
get_artist_tags()retrieves all style tags used across an artist’s artworks. Returns unique tags fromapp.global_stylestable. Used by {artpipelines} for style map updates.
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_indexandartist_statstables 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
- Creates records in both
INTERNAL
- New file
R/db-artist-modify.Rfor 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)
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
-
Demo Mode Guards Removed
- Removed
artcore::is_demo()checks from all database modification functions - Demo mode enforcement now handled at the application layer
- Affected functions:
dbArtAppend(),dbArtUpdate(),addArtwork(),addCollection(),updateArtistStats(),updateArtistBenchmarks(),upsert_artist_preferences(),update_collection_settings()
- Removed
IMPROVEMENTS
-
Database File Reorganization
- Created
db-interface.Rwith low-level database functions (dbArtGet(),dbArtAppend(),dbArtUpdate()) - Refactored
db-modify.Rto contain only data modification functions (addArtwork(),addCollection(),updateArtistStats(),updateArtistBenchmarks()) - Moved
artHasNFT()fromdb-modify.Rtodb-artwork.R(it’s a data-access function) - Each file now contains functions from a single
@familygroup
- Created
-
Test Reorganization
- Created
test-db-interface.Rwith live database tests for read operations - Updated
test-db-modify.Rto only contain data modification tests (mocked) - Added
artHasNFTtest totest-db-artwork.R - Read-only tests use live database queries; write operations use mocks
- Created
-
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 (
@nameblocks) use@keywords internalto 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 undefinedget_artist_preferences()- replaced with inline database query - Fixed R CMD check notes for unused imports (
rlang,shinyremoved from Imports) - Added
@importFrom lifecycle badgeto 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()fromtest-benchmarks.R - Internal functions (prefixed with
.) are not tested directly - Benchmark functionality tested via public
updateArtistBenchmarks()
- Removed tests for
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.ymlconfiguration with function groupings viahas_concept()selectors - Site auto-deploys to https://docs.artalytics.dev/r/artutils on push to main
- Added
.github/workflows/pkgdown.yamlGitHub Actions workflow - Reference page organized into 6 logical groups: Data Access, Data Modifiers, Path Utilities, Application Data, Database Interface, Under Review
- Added
-
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)
get_artist_by_slug()- Retrieve artist by URL-friendly slugget_artist_collections_summary()- Collection info with artwork countsget_artist_recent_works()- Most recent artworks for gallery displayget_artist_stats()- Artist statistics summarygenerate_artist_slug()- Create URL-safe slugs with collision handling
-
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)
-
get_artist_by_slug()now includesfeatured_rankandis_featuredcolumns
-
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
- 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
@familytags for pkgdown grouping -
@familytags generate both concept tags (for pkgdown) and “See Also” cross-references - Fixed
@seealsoreference to unavailableartpipelinespackage - Improved
@paramdocumentation for database interface functions
- All exported functions now have
-
Performance
-
get_artist_stats()optimized with separate COUNT queries (PR #66) - Collections now ordered by most recent artwork upload
-
BUG FIXES
- Fixed
artist_uuidmissing fromget_artist_collections_summary()output (#68) - Fixed class attribute mismatch in
rbindlistfor settings functions - Fixed NA handling in preference joins
- Renamed
blend_rate_normalizedcomponent toave_blend_ratefor consistency
BREAKING CHANGES
-
UI Components Migrated to artshiny (PR #60)
-
mod_statsBox()and related UI functions removed - Use
artshinypackage for Shiny UI components
-
INTERNAL
- Removed
artwork_settingstable references (deprecated) - Moved
calc_percentile()to artcore package - Removed complex mock tests dependent on artshiny
- Cleaned up delete functionality (moved to internal dev package)
artutils 0.13.0
BREAKING CHANGES
-
Frame Analytics Data Structure Change
-
getAppdata()$artwork$brushesDTrenamed toframe_stats - All code must update references:
r$appdata$artwork$brushesDT→r$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_analyticstable with comprehensive temporal, color, and delta metrics - Replaces synthetic
brushes_currydataset 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)
- Added
-
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
- Added UUID validation to
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.Rwith 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)
- Added
MIGRATION GUIDE
Update all code referencing frame data:
# BEFORE (Old)
frames <- r$appdata$artwork$brushesDT
# AFTER (New)
frames <- r$appdata$artwork$frame_statsEnsure 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
-
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 fromartwork_benchmarktable- 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
- Each
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
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
- Time & Effort: Added
Major Changes
- Updated
calcArtworkBenchmarks()to query productionartwork_statstable instead of testartwork_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_statstable:color_generation_rateearly_late_color_ratiostrokes_per_unique_colorframe_color_stabilityframe_color_variancetechnique_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)