Merge pull request #468 from ZcashFoundation/develop

Release 1.6.0
This commit is contained in:
Daniel Ternyak 2019-08-05 23:33:57 -05:00 committed by GitHub
commit 7a85a89c78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 32 deletions

View File

@ -309,17 +309,6 @@ class Proposal(db.Model):
payout_total += p
try:
present = datetime.datetime.today().replace(day=1)
if present > milestone.date_estimated:
raise ValidationException("Milestone date estimate must be in the future ")
except Exception as e:
current_app.logger.warn(
f"Unexpected validation error - client prohibits {e}"
)
raise ValidationException("Date estimate is not a valid datetime")
if payout_total != 100.0:
raise ValidationException("Payout percentages of milestones must add up to exactly 100%")
@ -358,6 +347,14 @@ class Proposal(db.Model):
# Then run through regular validation
Proposal.simple_validate(vars(self))
# only do this when user submits for approval, there is a chance the dates will
# be passed by the time admin approval / user publishing occurs
def validate_milestone_dates(self):
present = datetime.datetime.today().replace(day=1, hour=0, minute=0, second=0, microsecond=0)
for milestone in self.milestones:
if present > milestone.date_estimated:
raise ValidationException("Milestone date estimate must be in the future ")
@staticmethod
def create(**kwargs):
Proposal.simple_validate(kwargs)
@ -475,6 +472,7 @@ class Proposal(db.Model):
# state: status (DRAFT || REJECTED) -> (PENDING || STAKING)
def submit_for_approval(self):
self.validate_publishable()
self.validate_milestone_dates()
allowed_statuses = [ProposalStatus.DRAFT, ProposalStatus.REJECTED]
# specific validation
if self.status not in allowed_statuses:

View File

@ -56,6 +56,7 @@ typings/
# dotenv environment variables file
.env
.env.testnet
# next.js build output
.next

View File

@ -161,7 +161,9 @@ const MilestoneFields = ({
}
format="MMMM YYYY"
allowClear={false}
onChange={time => onChange(index, { ...milestone, dateEstimated: time.unix() })}
onChange={time =>
onChange(index, { ...milestone, dateEstimated: time.startOf('month').unix() })
}
disabled={milestone.immediatePayout}
disabledDate={current => {
if (!previousMilestoneDateEstimate) {

View File

@ -1,4 +1,11 @@
import { ProposalDraft, STATUS, MILESTONE_STAGE, PROPOSAL_ARBITER_STATUS } from 'types';
import {
ProposalDraft,
STATUS,
MILESTONE_STAGE,
PROPOSAL_ARBITER_STATUS,
CreateMilestone,
} from 'types';
import moment from 'moment';
import { User } from 'types';
import {
getAmountError,
@ -127,23 +134,9 @@ export function getCreateErrors(
// Milestones
if (milestones) {
let cumulativeMilestonePct = 0;
let lastMsEst: CreateMilestone['dateEstimated'] = 0;
const milestoneErrors = milestones.map((ms, idx) => {
if (!ms.title) {
return 'Title is required';
} else if (ms.title.length > 40) {
return 'Title length can only be 40 characters maximum';
}
if (!ms.content) {
return 'Description is required';
} else if (ms.content.length > 200) {
return 'Description can only be 200 characters maximum';
}
if (!ms.dateEstimated) {
return 'Estimate date is required';
}
// check payout first so we collect the cumulativePayout even if other fields are invalid
if (!ms.payoutPercent) {
return 'Payout percent is required';
} else if (Number.isNaN(parseInt(ms.payoutPercent, 10))) {
@ -158,6 +151,37 @@ export function getCreateErrors(
// Last one shows percentage errors
cumulativeMilestonePct += parseInt(ms.payoutPercent, 10);
if (!ms.title) {
return 'Title is required';
} else if (ms.title.length > 40) {
return 'Title length can only be 40 characters maximum';
}
if (!ms.content) {
return 'Description is required';
} else if (ms.content.length > 200) {
return 'Description can only be 200 characters maximum';
}
if (!ms.dateEstimated) {
return 'Estimate date is required';
} else {
// FE validation on milestone estimation
if (
ms.dateEstimated <
moment(Date.now())
.startOf('month')
.unix()
) {
return 'Estimate date should be in the future';
}
if (ms.dateEstimated <= lastMsEst) {
return 'Estimate date should be later than previous estimate date';
}
lastMsEst = ms.dateEstimated;
}
if (
idx === milestones.length - 1 &&
cumulativeMilestonePct !== 100 &&

View File

@ -1,5 +1,9 @@
# Contact Us
* You may reach out to the Zcash Foundation by emailing us at contact@zfnd.org
* You can find us on twitter at https://twitter.com/zcashfoundation
* You can contribute or report issues at https://github.com/ZcashFoundation/zcash-grant-system/issues
Reach out to [contact@zfnd.org](mailto:contact@zfnd.org) for user support and general inquiries.
The Zcash Foundation can provide feedback on grant ideas, but we encourage you to start with conversations on the [Zcash Community Forum](https://forum.zcashcommunity.com/c/community-collaboration) or the [Zcash Community Chat](https://chat.zcashcommunity.com/channel/the-zcash-foundation).
**Security or privacy issues should be sent to contact@zfnd.org _and_ contact@grant.io to alert the development team immediately.** If you discover a software bug or vulnerability on ZF Grants, please follow the [Responsible Disclosure Policy](https://github.com/ZcashFoundation/zcash-grant-system/blob/develop/DISCLOSURE.md).
Noncritical bugs or feature suggestions can be [submitted as issues in the GitHub repo](https://github.com/ZcashFoundation/zcash-grant-system/issues).