How to verify typed struct data with EIP712Upgradeable.sol

Im trying to use the proposed example of _signTypedData coming from Ethers docs. I basically enter my data like this on the client:

const signers = await hre.ethers.getSigners();

  // All properties on a domain are optional
  const domain = {
    name: "name7",
    version: "1",
    chainId: 8545,
    verifyingContract: organizerProxy
  };

  // The named list of all type definitions
  const types = {
    Proxy: [
      { name: "series", type: "bytes32" },
      { name: "creator", type: "address" },
      { name: "minter", type: "address" },
      { name: "Contract", type: "address" },
      { name: "proxyState", type: "uint8" },
      { name: "exist", type: "bool" },
      { name: "numberEvents", type: "uint8" }
    ]
  };

  // The data to sign
  const value = {
    series: evSeries,
    creator: ethers.utils.getAddress(organizerProxy),
    minter: ethers.utils.getAddress(minterTemplate.address),
    Contract: ethers.utils.getAddress(organizerProxy),
    proxyState: proxyState,
    exist: true,
    numberEvents: numberEvents
  };

  let signature = await signers[0]._signTypedData(domain, types, value);

  const expectedSignerAddress = signers[0].address;
  const recoveredAddress = ethers.utils.verifyTypedData(
    domain,
    types,
    value,
    signature
  );

  console.log(recoveredAddress === expectedSignerAddress); // returns TRUE

And when I send it to the contracts like this:

let signature = await signers[0]._signTypedData(domain, types, value);

I try to verify the signature in this way:

import "./EIP712Upgradeable.sol";
...


...
bytes32 constant EVENTPROXY_TYPEHASH = keccak256(
        "Proxy(bytes32 series,address creator,address minter,address Contract,uint8 proxyState,bool exist,uint8 numberEvents"); 
        //NOTICE THE uint8 FIX FOR THE PROXYSTATE ENUM

enum ProxyState {
    deactivated,
    onMarketPlace,
    onSecondMarket,
    unlisted
  }

  struct EventProxy {
    bytes32 seriesName;
    address creator;
    address minter;
    address Contract;
    ProxyState proxyState;
    bool exist;
    uint8 numberEvents;
  }

function getStructHash(
    EventProxy memory structToHash
  ) external pure returns (bytes32) {
    bytes32 _typeHash = 
    keccak256(
      abi.encode(
        EVENTPROXY_TYPEHASH,
        structToHash.seriesName,
        structToHash.creator,
        structToHash.minter,
        structToHash.Contract,
        uint8(structToHash.proxyState),
        structToHash.exist,
        structToHash.numberEvents
      ));
    return _typeHash;

  } 

function checkHashSignature(Proxy memory _structToHash, bytes memory signature) public view returns (bytes32) {
    bytes32 structTypedHash =getStructHash(_structToHash);

    bytes32 finalStructHash = EIP712Upgradeable._hashTypedDataV4(structTypedHash);    
    address signer = ECDSAUpgradeable.recover(finalStructHash,signature);
    console.log(signer); // THIS IS GIVING A DIFFERENT SIGNER!!!!!!!!
    require (hasRole(DEFAULT_ADMIN_ROLE, signer),"Transaction: Invalid signature");
    require (signer != address(0),"Origin: Invalid signature");
    return finalStructHash;
  }

Im suspecting the encode is not the same or maybe is the way Im using the functions in the contract to get the hashes.

Any help will be really appreciated. I have looked this up everywhere but OZ docs don't explain much on the details of the encoding considered for the contract Im importing.

The code works perfect. I was just missing a parenthesis within my struct "hardcoding", i.e while describing my struct:

  bytes32 constant PROXY_TYPEHASH = keccak256(
        "Proxy(bytes32 series,address creator,address minter,address Contract,uint8 proxyState,bool exist,uint8 numberEvents)"); 

Always make sure your struct definition has the right types as used within your client function and be sure not to put unnecessary spaces or miss parenthesis (duh!).