The privacy tooling that arrived in core 4.9.6 and WooCommerce 3.4 covers the standard data, and everything a custom plugin stored is yours to declare.
add_filter( 'wp_privacy_personal_data_exporters', function ( $exporters ) {
$exporters['turkerdev-quotes'] = array(
'exporter_friendly_name' => __( 'Saved quotes', 'turkerdev' ),
'callback' => 'turkerdev_export_quotes',
);
return $exporters;
} );
// the callback returns [ 'data' => [...], 'done' => true|false ]
// and is called repeatedly with an incrementing page number
The pagination in the callback exists because an export runs in a request and a customer with four thousand orders will not fit in one — returning done => false means it is called again. The eraser side has the same shape and an extra decision: what has to be retained for accounting rather than deleted. Getting the export right is a day; deciding what may be erased is a conversation with somebody who is not an engineer.