As you say, I don't think there is a contrib module available for Backdrop to do this, and yes, it's a process that can break things if not done carefully (especially if you have other contrib modules that create satellite tables or config files around your fields or your entity bundles).
Your steps also are somewhat incomplete (off the top of my head):
You have two options. Option 1 ("cloning" - produces new entity IDs): you can create new entities (e.g. clone nodes), or Option 2 ("switching" bundles - keeps the original entity IDs): you can modify the existing entries in several databases to update the bundle. Option 2 is a bit easier, but has the problem that you may lose all your original entities if something goes wrong (you are not cloning them)
- For Option 2 ("switching"): In the table that stores your entities (e.g. "node" for Content entities), you have to change the value in the column currently used for storing the bundle. This could vary according to entity type. For example, in the table "node", Backdrop uses the column called "type" to store the bundle of each node (e.g. "page", "post"). Paragraph Items (table paragraph_items) uses the column name "bundle". This name, by the way, is defined in hook_entity_info(), under the keys ['entity keys']['bundle'] (also available by running entity_get_info(''ENTITY_TYPE');)
- For both Option 1 and 2, if your entity uses a way to store the definitions of entity bundles (all bundeable entities typically do), you need to be sure that your new bundle has been properly defined and stored. For example, Content Type definitions are stored as json files in "node.type.TYPE.json". This happens to be also the case with Paragraph Items bundle definitions, stored in with the same pattern of file name. BUT other custom entities may actually store those bundle definitions in the database. E.g. in Organic Groups, the og_membership_type table stores OG membership types bundle definitions, so if you want to switch bundles for OG membership entities, you need to be sure that the new OG membership type definition exists in the db. If you are doing all of this programmatically, you must create your bundle definition programmatically as well. If you are doing this manually, you can create your bundle through the UI (e.g. Structure > Paragraph types)
- For both Option 1 and 2: Something you don't list above are field instance definitions. In Backdrop those are stored as config file, with the pattern field.instance.ENTITY_TYPE.BUNDLE_NAME.FIELD_NAME.json. So, in order for your switch to work with fields, you need to be sure to create those field instance definition files (most likely cloning the ones for the source bundle to the target bundle)
- For both Option 1 and 2: In addition, as you list above, all tables storing the data of fields attached to an entity bundle must be either cloned (for Option 1) or modified (for Option 2). In particulars, for Option 2 ("switching") the "bundle" column for field data for those source entities must be switch to the new bundle name (see for example the column "bundle" in the table field_data_body that stores data for the "bundle" field). If you are using Option 1 ("cloning"), you must clone the entries in the field data tables, and be sure the cloned entries have the new bundle AND the correct entity ID
- For Option 1: If your entities use revisions, and if you want to preserve your revisions after cloning, you'll also need to create new entries in your entity revision table . For example, in table node_revision you have to find the nid of the source node, and clone those with the new nid of the switched node after saving it.
- And finally, if you also have field revision data stored in the db (e.g. field_revision_body table), those need to be adjusted as above
I think that covers it, but I may be forgetting stuff related to languages... which I haven't dealt with much.