Programmatically, How does Bitcoin core differentiate transactions category?
Bitcoin Core has three types of transaction categories: send, receive, and move.

It differentiates between these as follows:


move - This tx is not an onchain one, and has no transaction id. It is simply moving BTC from one wallet account to another (accounts are not addresses, but groupings of addresses). This is done using the move RPC call
send - A send tx is one where an utxo from your wallet is used as the input to a transaction. This usually have a fee, since the fee is debited from the total sum of the utxos.
receive - A receive tx is one where a new utxo spendable (or watched) by your wallet is created. These don't have a fee as you don't pay anything to receive Bitcoin.


You can see the ListTransaction code here.