cannot achieve this structure (custom posts VS categories VS ??)

This is fairly straightforward with a custom post type and custom taxonomy.

First, register a custom taxonomy worktype, with rewrite parameter set to works:

'rewrite' => array( 'slug' => 'works' )

Next, register a custom post type with rewrite set to works/%worktype%:

'rewrite' => array( 'slug' => 'works/%worktype%' )

You’ll also need to set with_front to false if your posts have a static prefix, like blog.

Next, add a filter to post_type_link to swap the %worktype% tag with your selected worktype for individual works posts whenever WordPress outputs a link to an individual work:

function wpa_works_post_link( $post_link, $id = 0 ){
    $post = get_post($id);  
    if ( is_object( $post ) && $post->post_type == 'works' ){
        $terms = wp_get_object_terms( $post->ID, 'worktype' );
        if( $terms ){
            return str_replace ( '%worktype%' , $terms[0]->slug , $post_link );
        }
    }
    return $post_link;
}
add_filter( 'post_type_link', 'wpa_works_post_link', 1, 3 );