We need to create a status function that given a proposalId will return us the current status in which the proposal is and an enum to handle the return.
As the proposal has a uint256 which is the time that it was created by using the global variables we can see in which phase the proposal is:
If block.timestamp - proposal creation time < start vote time then phase = not started yet
After this "time checks" we will check if a vote period is over and we will use an internal function to reach the quorum to see if the function needs to be executed. In the case that the quorum is not reached we will return "Completed" otherwise we should return something like "Queue" or "Pending"
We need an execution function that will check the proposal status function. If it's on pending execution (Queued/Pending check the enum) you will need to run the update internal function and change the status to Executed (you will need to modify the status function and probably add an execution flag)
We need to create a quorum system to decide if a proposal needs to be executed or not, keeping in mind that the eligibility for a vote is owning an NFT it should probably be a % of the active NFT's. Add onlyOwner functions to change the quorum settings.
Check here for more information about the NFT Collection and isActive() #1
NFT collection that has an isActive() check (like ENS registry check for resolution). Basically we need to be able to track the "active" owners of the NFT because there can be NFT holders that won't have rights to vote.
Either NFT minted individually (merkle drop) or sent from one minter address.
We don't have info on the metadata, exact needed features for the NFT yet. Maybe soulbound?
At this stage we should have the data structure for a proposal, an enum with the vote types and a ERC721 with a public function called isEligible and a bunch of internal functions to help you do this task. You need to create a propose function that will just create a proposal data structure and save it, you will need to check that no active proposal exists for that array position that the sender is trying to replace (you can create an internal function to do this check for you). You will also need to create the voting function which will just count the votes inside of the proposal datastructure, get in touch with the "Create voting tracking" issue for a validation if somebody has voted.