github.com/decred/politeia@v1.4.0/politeiawww/api/cms/v1/v1.go (about)

     1  package v1
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/decred/dcrd/dcrutil/v3"
     7  	"github.com/decred/politeia/politeiad/backend/gitbe/cmsplugin"
     8  	www "github.com/decred/politeia/politeiawww/api/www/v1"
     9  )
    10  
    11  type ErrorStatusT int
    12  type InvoiceStatusT int
    13  type LineItemTypeT int
    14  type PaymentStatusT int
    15  type DomainTypeT int
    16  type ContractorTypeT int
    17  type DCCTypeT int
    18  type DCCStatusT int
    19  type DCCVoteStatusT int
    20  
    21  const (
    22  	APIVersion = 1
    23  
    24  	// Contractor Management Routes
    25  	RouteInviteNewUser          = "/invite"
    26  	RouteRegisterUser           = "/register"
    27  	RouteCMSUsers               = "/cmsusers"
    28  	RouteNewInvoice             = "/invoices/new"
    29  	RouteEditInvoice            = "/invoices/edit"
    30  	RouteInvoiceDetails         = "/invoices/{token:[A-z0-9]{64}}"
    31  	RouteSetInvoiceStatus       = "/invoices/{token:[A-z0-9]{64}}/status"
    32  	RouteUserInvoices           = "/user/invoices"
    33  	RouteUserSubContractors     = "/user/subcontractors"
    34  	RouteNewDCC                 = "/dcc/new"
    35  	RouteDCCDetails             = "/dcc/{token:[A-z0-9]{64}}"
    36  	RouteGetDCCs                = "/dcc"
    37  	RouteSupportOpposeDCC       = "/dcc/supportoppose"
    38  	RouteNewCommentDCC          = "/dcc/newcomment"
    39  	RouteDCCComments            = "/dcc/{token:[A-z0-9]{64}}/comments"
    40  	RouteSetDCCStatus           = "/dcc/{token:[A-z0-9]{64}}/status"
    41  	RouteCastVoteDCC            = "/dcc/vote"
    42  	RouteVoteDetailsDCC         = "/dcc/votedetails"
    43  	RouteActiveVotesDCC         = "/dcc/activevotes"
    44  	RouteStartVoteDCC           = "/dcc/startvote"
    45  	RouteInvoices               = "/invoices"
    46  	RouteManageCMSUser          = "/admin/managecms"
    47  	RouteAdminUserInvoices      = "/admin/userinvoices"
    48  	RouteGeneratePayouts        = "/admin/generatepayouts"
    49  	RouteInvoicePayouts         = "/admin/invoicepayouts"
    50  	RoutePayInvoices            = "/admin/payinvoices"
    51  	RouteInvoiceComments        = "/invoices/{token:[A-z0-9]{64}}/comments"
    52  	RouteInvoiceExchangeRate    = "/invoices/exchangerate"
    53  	RouteProposalOwner          = "/proposals/owner"
    54  	RouteProposalBilling        = "/proposals/billing"
    55  	RouteProposalBillingSummary = "/proposals/spendingsummary"
    56  	RouteProposalBillingDetails = "/proposals/spendingdetails"
    57  	RouteUserCodeStats          = "/user/codestats"
    58  
    59  	// Invoice status codes
    60  	InvoiceStatusInvalid  InvoiceStatusT = 0 // Invalid status
    61  	InvoiceStatusNotFound InvoiceStatusT = 1 // Invoice not found
    62  	InvoiceStatusNew      InvoiceStatusT = 2 // Invoice has not been reviewed
    63  	InvoiceStatusUpdated  InvoiceStatusT = 3 // Invoice has unreviewed changes
    64  	InvoiceStatusDisputed InvoiceStatusT = 4 // Invoice has been disputed for some reason
    65  	InvoiceStatusRejected InvoiceStatusT = 5 // Invoice fully rejected and closed
    66  	InvoiceStatusApproved InvoiceStatusT = 6 // Invoice has been approved
    67  	InvoiceStatusPaid     InvoiceStatusT = 7 // Invoice has been paid
    68  
    69  	// Line item types
    70  	LineItemTypeInvalid  LineItemTypeT = 0 // Invalid type
    71  	LineItemTypeLabor    LineItemTypeT = 1 // Labor line items
    72  	LineItemTypeExpense  LineItemTypeT = 2 // Expenses incurred line items
    73  	LineItemTypeMisc     LineItemTypeT = 3 // Catch all for anything else
    74  	LineItemTypeSubHours LineItemTypeT = 4 // Line items for subcontractor billing
    75  
    76  	// Domain types
    77  	DomainTypeInvalid   DomainTypeT = 0 // Invalid Domain type
    78  	DomainTypeDeveloper DomainTypeT = 1 // Developer domain
    79  	DomainTypeMarketing DomainTypeT = 2 // Marketing domain
    80  	DomainTypeResearch  DomainTypeT = 4 // Research domain
    81  	DomainTypeDesign    DomainTypeT = 5 // Design domain
    82  
    83  	// Contractor types
    84  	ContractorTypeInvalid         ContractorTypeT = 0 // Invalid contractor type
    85  	ContractorTypeDirect          ContractorTypeT = 1 // Direct contractor
    86  	ContractorTypeSupervisor      ContractorTypeT = 2 // Supervisor contractor
    87  	ContractorTypeSubContractor   ContractorTypeT = 3 // SubContractor
    88  	ContractorTypeNominee         ContractorTypeT = 4 // Nominated DCC user
    89  	ContractorTypeRevoked         ContractorTypeT = 5 // Revoked CMS User
    90  	ContractorTypeTemp            ContractorTypeT = 6 // Temporary Contractor (only allowed 1 invoice)
    91  	ContractorTypeTempDeactivated ContractorTypeT = 7 // Temporary Contractor that has been deactivated
    92  	ContractorTypeProposal        ContractorTypeT = 8 // Contractor appproved by proposal, but not DCC
    93  
    94  	// Payment information status types
    95  	PaymentStatusInvalid  PaymentStatusT = 0 // Invalid status
    96  	PaymentStatusWatching PaymentStatusT = 1 // Payment currently watching
    97  	PaymentStatusPaid     PaymentStatusT = 2 // Payment fully paid
    98  
    99  	// DCC types
   100  	DCCTypeInvalid    DCCTypeT = 0 // Invalid DCC type
   101  	DCCTypeIssuance   DCCTypeT = 1 // Issuance DCC type
   102  	DCCTypeRevocation DCCTypeT = 2 // Revocation DCC type
   103  
   104  	// DCC status types
   105  	DCCStatusInvalid  DCCStatusT = 0 // Invalid issuance/revocation status
   106  	DCCStatusActive   DCCStatusT = 1 // Currently active issuance/revocation (awaiting sponsors)
   107  	DCCStatusApproved DCCStatusT = 2 // Fully approved DCC proposal
   108  	DCCStatusRejected DCCStatusT = 3 // Rejected DCC proposal
   109  
   110  	// DCC vote status codes
   111  	DCCVoteStatusInvalid    DCCVoteStatusT = 0
   112  	DCCVoteStatusNotStarted DCCVoteStatusT = 1
   113  	DCCVoteStatusStarted    DCCVoteStatusT = 2
   114  	DCCVoteStatusFinished   DCCVoteStatusT = 3
   115  
   116  	InvoiceInputVersion = 1
   117  
   118  	// PolicyMaxImages is the maximum number of images accepted
   119  	// when creating a new invoice
   120  	PolicyMaxImages = 20
   121  
   122  	// PolicyMaxImageSize is the maximum image file size (in bytes)
   123  	// accepted when creating a new invoice
   124  	PolicyMaxImageSize = 512 * 1024
   125  
   126  	// PolicyMaxMDs is the maximum number of markdown files accepted
   127  	// when creating a new invoice
   128  	PolicyMaxMDs = 1
   129  
   130  	// PolicyMaxMDSize is the maximum markdown file size (in bytes)
   131  	// accepted when creating a new invoice
   132  	PolicyMaxMDSize = 512 * 1024
   133  
   134  	// PolicyMaxNameLength is the max length of a contractor name
   135  	PolicyMaxNameLength = 50
   136  
   137  	// PolicyMinNameLength is the min length of a contractor name
   138  	PolicyMinNameLength = 3
   139  
   140  	// PolicyMaxLocationLength is the max length of a contractor location
   141  	PolicyMaxLocationLength = 100
   142  
   143  	// PolicyMinLocationLength is the min length of a contractor location
   144  	PolicyMinLocationLength = 0
   145  
   146  	// PolicyMaxContactLength is the max length of a contractor contact
   147  	PolicyMaxContactLength = 100
   148  
   149  	// PolicyMinContactLength is the min length of a contractor contact
   150  	PolicyMinContactLength = 3
   151  
   152  	// PolicyInvoiceCommentChar is the character which, when used as the first
   153  	// character of a line, denotes that entire line as a comment.
   154  	PolicyInvoiceCommentChar rune = '#'
   155  
   156  	// PolicyInvoiceFieldDelimiterChar is the character that delimits field
   157  	// values for each line item in the CSV.
   158  	PolicyInvoiceFieldDelimiterChar rune = ','
   159  
   160  	// PolicyInvoiceLineItemCount is the number of expected fields in the raw
   161  	// csv line items
   162  	PolicyInvoiceLineItemCount = 9
   163  
   164  	// PolicyMinLineItemColLength is the minimun length for the strings in
   165  	// each column field of the lineItem structure.
   166  	PolicyMinLineItemColLength = 3
   167  
   168  	// PolicyMaxLineItemColLength is the maximum length for the strings in
   169  	// each column field of the lineItem structure.
   170  	PolicyMaxLineItemColLength = 500
   171  
   172  	// PolicyMinSponsorStatementLength is the minimum length for the sponsor
   173  	// statement contained within a DCC
   174  	PolicyMinSponsorStatementLength = 0
   175  
   176  	// PolicyMaxSponsorStatementLength is the maximum length for the sponsor
   177  	// statement contained within a DCC
   178  	PolicyMaxSponsorStatementLength = 5000
   179  
   180  	// ProposalBillingListPageSize is the maximum number of proposal billing
   181  	// summaries returned for the routes that return lists of proposal billing
   182  	// summaries.
   183  	ProposalBillingListPageSize = 50
   184  
   185  	// InvoiceListPageSize is the maximum number of invoices returned by the
   186  	// Invoices request, the date range should just be updated to return them
   187  	// all.
   188  	InvoiceListPageSize = 50
   189  
   190  	ErrorStatusMalformedName                  www.ErrorStatusT = 1001
   191  	ErrorStatusMalformedLocation              www.ErrorStatusT = 1002
   192  	ErrorStatusInvoiceNotFound                www.ErrorStatusT = 1003
   193  	ErrorStatusInvalidMonthYearRequest        www.ErrorStatusT = 1004
   194  	ErrorStatusMalformedInvoiceFile           www.ErrorStatusT = 1005
   195  	ErrorStatusInvalidInvoiceStatusTransition www.ErrorStatusT = 1006
   196  	ErrorStatusReasonNotProvided              www.ErrorStatusT = 1007
   197  	ErrorStatusInvoiceDuplicate               www.ErrorStatusT = 1008
   198  	ErrorStatusInvalidPaymentAddress          www.ErrorStatusT = 1009
   199  	ErrorStatusMalformedLineItem              www.ErrorStatusT = 1010
   200  	ErrorStatusInvoiceMissingName             www.ErrorStatusT = 1011
   201  	ErrorStatusInvoiceMissingContact          www.ErrorStatusT = 1013
   202  	ErrorStatusInvoiceMissingRate             www.ErrorStatusT = 1014
   203  	ErrorStatusInvoiceInvalidRate             www.ErrorStatusT = 1015
   204  	ErrorStatusInvoiceMalformedContact        www.ErrorStatusT = 1016
   205  	ErrorStatusMalformedProposalToken         www.ErrorStatusT = 1017
   206  	ErrorStatusMalformedDomain                www.ErrorStatusT = 1018
   207  	ErrorStatusMalformedSubdomain             www.ErrorStatusT = 1019
   208  	ErrorStatusMalformedDescription           www.ErrorStatusT = 1020
   209  	ErrorStatusWrongInvoiceStatus             www.ErrorStatusT = 1021
   210  	ErrorStatusInvoiceRequireLineItems        www.ErrorStatusT = 1022
   211  	ErrorStatusInvalidInvoiceMonthYear        www.ErrorStatusT = 1024
   212  	ErrorStatusInvalidExchangeRate            www.ErrorStatusT = 1025
   213  	ErrorStatusInvalidLineItemType            www.ErrorStatusT = 1026
   214  	ErrorStatusInvalidLaborExpense            www.ErrorStatusT = 1027
   215  	ErrorStatusDuplicatePaymentAddress        www.ErrorStatusT = 1028
   216  	ErrorStatusInvalidDatesRequested          www.ErrorStatusT = 1029
   217  	ErrorStatusInvalidInvoiceEditMonthYear    www.ErrorStatusT = 1030
   218  	ErrorStatusInvalidDCCType                 www.ErrorStatusT = 1031
   219  	ErrorStatusInvalidNominatingDomain        www.ErrorStatusT = 1032
   220  	ErrorStatusMalformedSponsorStatement      www.ErrorStatusT = 1033
   221  	ErrorStatusMalformedDCCFile               www.ErrorStatusT = 1034
   222  	ErrorStatusInvalidDCCComment              www.ErrorStatusT = 1035
   223  	ErrorStatusInvalidDCCStatusTransition     www.ErrorStatusT = 1036
   224  	ErrorStatusDuplicateEmail                 www.ErrorStatusT = 1037
   225  	ErrorStatusInvalidUserNewInvoice          www.ErrorStatusT = 1038
   226  	ErrorStatusInvalidDCCNominee              www.ErrorStatusT = 1039
   227  	ErrorStatusDCCNotFound                    www.ErrorStatusT = 1040
   228  	ErrorStatusWrongDCCStatus                 www.ErrorStatusT = 1041
   229  	ErrorStatusInvalidSupportOppose           www.ErrorStatusT = 1042
   230  	ErrorStatusDuplicateSupportOppose         www.ErrorStatusT = 1043
   231  	ErrorStatusUserIsAuthor                   www.ErrorStatusT = 1044
   232  	ErrorStatusInvalidUserDCC                 www.ErrorStatusT = 1045
   233  	ErrorStatusInvalidDCCContractorType       www.ErrorStatusT = 1046
   234  	ErrorStatusInvalidTypeSubHoursLineItem    www.ErrorStatusT = 1047
   235  	ErrorStatusMissingSubUserIDLineItem       www.ErrorStatusT = 1048
   236  	ErrorStatusInvalidSubUserIDLineItem       www.ErrorStatusT = 1049
   237  	ErrorStatusInvalidSupervisorUser          www.ErrorStatusT = 1050
   238  	ErrorStatusMalformedDCC                   www.ErrorStatusT = 1051
   239  	ErrorStatusInvalidDCCVoteStatus           www.ErrorStatusT = 1052
   240  	ErrorStatusInvalidDCCAllVoteUserWeight    www.ErrorStatusT = 1053
   241  	ErrorStatusDCCVoteEnded                   www.ErrorStatusT = 1054
   242  	ErrorStatusDCCVoteStillLive               www.ErrorStatusT = 1055
   243  	ErrorStatusDCCDuplicateVote               www.ErrorStatusT = 1056
   244  	ErrorStatusMissingCodeStatsUsername       www.ErrorStatusT = 1057
   245  	ErrorStatusTrackerNotStarted              www.ErrorStatusT = 1058
   246  
   247  	ProposalsMainnet = "https://proposals.decred.org"
   248  	ProposalsTestnet = "https://test-proposals.decred.org"
   249  )
   250  
   251  var (
   252  	// APIRoute is the route prefix for the cms v1 API
   253  	APIRoute = fmt.Sprintf("/v%v", APIVersion)
   254  
   255  	// PolicyValidMimeTypes is the accepted mime types of attachments
   256  	// in invoices
   257  	PolicyValidMimeTypes = []string{
   258  		"image/png",
   259  	}
   260  
   261  	// PolicyInvoiceFieldSupportedChars is the regular expression of a valid
   262  	// invoice fields.
   263  	PolicyInvoiceFieldSupportedChars = []string{
   264  		"A-z", "0-9", "&", ".", ",", ":", ";", "-", " ", "@", "+", "#", "/",
   265  		"(", ")", "!", "?", "\"", "'"}
   266  
   267  	// PolicyCMSNameLocationSupportedChars is the regular expression of a valid
   268  	// name or location for registering users on cms.
   269  	PolicyCMSNameLocationSupportedChars = []string{
   270  		"A-z", "0-9", ".", "-", " ", ","}
   271  
   272  	// PolicyCMSContactSupportedChars is the regular expression of a valid
   273  	// contact for registering users on cms.
   274  	PolicyCMSContactSupportedChars = []string{
   275  		"A-z", "0-9", "&", ".", ":", "-", "_", "@", "+", ",", " "}
   276  
   277  	// PolicySponsorStatementSupportedChars is the regular expression of a valid
   278  	// sponsor statement for DCC in cms.
   279  	PolicySponsorStatementSupportedChars = []string{
   280  		"A-z", "0-9", "&", ".", ",", ":", ";", "-", " ", "@", "+", "#", "/",
   281  		"(", ")", "!", "?", "\"", "'", "\n"}
   282  
   283  	// PolicySupportedCMSDomains supplies the currently available domain types
   284  	// and descriptions of them.
   285  	PolicySupportedCMSDomains = []AvailableDomain{
   286  		{
   287  			Description: "development",
   288  			Type:        DomainTypeDeveloper,
   289  		},
   290  		{
   291  			Description: "marketing",
   292  			Type:        DomainTypeMarketing,
   293  		},
   294  		{
   295  			Description: "research",
   296  			Type:        DomainTypeResearch,
   297  		},
   298  		{
   299  			Description: "design",
   300  			Type:        DomainTypeDesign,
   301  		},
   302  	}
   303  
   304  	// PolicyCMSSupportedLineItemTypes supplies the currently available invoice types
   305  	// and descriptions of them.
   306  	PolicyCMSSupportedLineItemTypes = []AvailableLineItemType{
   307  		{
   308  			Description: "labor",
   309  			Type:        LineItemTypeLabor,
   310  		},
   311  		{
   312  			Description: "expense",
   313  			Type:        LineItemTypeExpense,
   314  		},
   315  		{
   316  			Description: "misc",
   317  			Type:        LineItemTypeMisc,
   318  		},
   319  		{
   320  			Description: "subhours",
   321  			Type:        LineItemTypeSubHours,
   322  		},
   323  	}
   324  
   325  	// ErrorStatus converts error status codes to human readable text.
   326  	ErrorStatus = map[www.ErrorStatusT]string{
   327  		ErrorStatusMalformedName:                  "malformed name",
   328  		ErrorStatusMalformedLocation:              "malformed location",
   329  		ErrorStatusInvoiceNotFound:                "invoice cannot be found",
   330  		ErrorStatusInvalidMonthYearRequest:        "month or year was set, while the other was not",
   331  		ErrorStatusInvalidInvoiceStatusTransition: "invalid invoice status transition",
   332  		ErrorStatusReasonNotProvided:              "reason for action not provided",
   333  		ErrorStatusMalformedInvoiceFile:           "submitted invoice file is malformed",
   334  		ErrorStatusInvoiceDuplicate:               "submitted invoice is a duplicate of an existing invoice",
   335  		ErrorStatusInvalidPaymentAddress:          "invalid payment address",
   336  		ErrorStatusMalformedLineItem:              "malformed line item submitted",
   337  		ErrorStatusInvoiceMissingName:             "invoice missing contractor name",
   338  		ErrorStatusInvoiceMissingContact:          "invoice missing contractor contact",
   339  		ErrorStatusInvoiceMalformedContact:        "invoice has malformed contractor contact",
   340  		ErrorStatusInvoiceMissingRate:             "invoice missing contractor rate",
   341  		ErrorStatusInvoiceInvalidRate:             "invoice has invalid contractor rate",
   342  		ErrorStatusMalformedProposalToken:         "line item has malformed proposal token",
   343  		ErrorStatusMalformedDomain:                "line item has malformed domain",
   344  		ErrorStatusMalformedSubdomain:             "line item has malformed subdomain",
   345  		ErrorStatusMalformedDescription:           "line item has malformed description",
   346  		ErrorStatusWrongInvoiceStatus:             "invoice is an wrong status to be editted (approved, rejected or paid)",
   347  		ErrorStatusInvoiceRequireLineItems:        "invoices require at least 1 line item",
   348  		ErrorStatusInvalidInvoiceMonthYear:        "an invalid month/year was submitted on an invoice",
   349  		ErrorStatusInvalidExchangeRate:            "exchange rate was invalid or didn't match expected result",
   350  		ErrorStatusInvalidLineItemType:            "line item has an invalid type",
   351  		ErrorStatusInvalidLaborExpense:            "line item has an invalid labor or expense field",
   352  		ErrorStatusDuplicatePaymentAddress:        "a duplicate payment address was used",
   353  		ErrorStatusInvalidDatesRequested:          "invalid dates were requested",
   354  		ErrorStatusInvalidInvoiceEditMonthYear:    "invalid attempt to edit invoice month/year",
   355  		ErrorStatusInvalidDCCType:                 "invalid DCC type was included",
   356  		ErrorStatusInvalidNominatingDomain:        "non-matching domain was attempt",
   357  		ErrorStatusMalformedSponsorStatement:      "DCC sponsor statement was malformed",
   358  		ErrorStatusMalformedDCCFile:               "submitted DCC file was malformed according to standards",
   359  		ErrorStatusInvalidDCCComment:              "submitted DCC comment must either be aye or nay",
   360  		ErrorStatusInvalidDCCStatusTransition:     "invalid status transition for a DCC",
   361  		ErrorStatusDuplicateEmail:                 "another user already has that email registered",
   362  		ErrorStatusInvalidUserNewInvoice:          "current contractor status does not allow new invoices to be created",
   363  		ErrorStatusInvalidDCCNominee:              "invalid nominee user was submitted for a DCC",
   364  		ErrorStatusDCCNotFound:                    "a requested dcc was not found",
   365  		ErrorStatusWrongDCCStatus:                 "cannot comment/approve/oppose DCC if it's not active state",
   366  		ErrorStatusInvalidSupportOppose:           "invalid support or opposition vote was included in the request, must be aye or nay",
   367  		ErrorStatusDuplicateSupportOppose:         "user has already supported or opposed the given DCC",
   368  		ErrorStatusUserIsAuthor:                   "user cannot support or oppose their own sponsored DCC",
   369  		ErrorStatusInvalidUserDCC:                 "user is not authorized to complete the DCC request",
   370  		ErrorStatusInvalidDCCContractorType:       "DCC must have a valid contractor type",
   371  		ErrorStatusInvalidTypeSubHoursLineItem:    "must be a Supervisor Contractor to submit a subcontractor hours line item",
   372  		ErrorStatusMissingSubUserIDLineItem:       "must supply a userid for a subcontractor hours line item",
   373  		ErrorStatusInvalidSubUserIDLineItem:       "the userid supplied for the subcontractor hours line item is invalid",
   374  		ErrorStatusInvalidSupervisorUser:          "attempted input of an invalid supervisor user id",
   375  		ErrorStatusMalformedDCC:                   "malformed dcc detected",
   376  		ErrorStatusInvalidDCCVoteStatus:           "the DCC to be voted isn't currently up for an all user vote",
   377  		ErrorStatusInvalidDCCAllVoteUserWeight:    "the user does not have a corresponding user weight for this vote",
   378  		ErrorStatusDCCVoteEnded:                   "the all contractor voting period has ended",
   379  		ErrorStatusDCCVoteStillLive:               "cannot update status of a DCC while a vote is still live",
   380  		ErrorStatusDCCDuplicateVote:               "user has already submitted a vote for the given dcc",
   381  		ErrorStatusMissingCodeStatsUsername:       "codestats site username is required to receive code stats",
   382  		ErrorStatusTrackerNotStarted:              "code tracker required for attempted request, check token setting in config",
   383  	}
   384  )
   385  
   386  // AvailableDomain contains a domain type and it's corresponding description.
   387  type AvailableDomain struct {
   388  	Description string      `json:"description"`
   389  	Type        DomainTypeT `json:"type"`
   390  }
   391  
   392  // AvailableLineItemType contains a line item type and it's description
   393  type AvailableLineItemType struct {
   394  	Description string        `json:"description"`
   395  	Type        LineItemTypeT `json:"type"`
   396  }
   397  
   398  /// Contractor Management System Routes
   399  
   400  // InviteNewUser is used to request that a new user invitation be sent via email.
   401  // If successful, the user will require verification before being able to login.
   402  type InviteNewUser struct {
   403  	Email     string `json:"email"`
   404  	Temporary bool   `json:"temp"` // This denotes if the user is a temporary user (only allowed to submit 1 invoice).
   405  }
   406  
   407  // InviteNewUserReply responds with the verification token for the user
   408  // (if an email server is not set up).
   409  type InviteNewUserReply struct {
   410  	VerificationToken string `json:"verificationtoken"`
   411  }
   412  
   413  // RegisterUser is used by an contractor that has been invited to join the
   414  // Contractor Management System
   415  type RegisterUser struct {
   416  	Email             string `json:"email"`
   417  	Username          string `json:"username"`
   418  	Password          string `json:"password"`
   419  	VerificationToken string `json:"verificationtoken"`
   420  	PublicKey         string `json:"publickey"`
   421  }
   422  
   423  // RegisterUserReply replies to Register with no properties, if successful.
   424  type RegisterUserReply struct{}
   425  
   426  // NewInvoice attempts to submit a new invoice.
   427  type NewInvoice struct {
   428  	Month     uint       `json:"month"`
   429  	Year      uint       `json:"year"`
   430  	Files     []www.File `json:"files"`     // Invoice file and any attachments along with it
   431  	PublicKey string     `json:"publickey"` // Key used to verify signature
   432  	Signature string     `json:"signature"` // Signature of file hash
   433  }
   434  
   435  // NewInvoiceReply is used to reply to the NewInvoiceReply command.
   436  type NewInvoiceReply struct {
   437  	CensorshipRecord www.CensorshipRecord `json:"censorshiprecord"`
   438  }
   439  
   440  // EditInvoice attempts to edit a proposal
   441  type EditInvoice struct {
   442  	Token     string     `json:"token"`
   443  	Files     []www.File `json:"files"`
   444  	PublicKey string     `json:"publickey"`
   445  	Signature string     `json:"signature"`
   446  }
   447  
   448  // EditInvoiceReply is used to reply to the EditInvoice command
   449  type EditInvoiceReply struct {
   450  	Invoice InvoiceRecord `json:"invoice"`
   451  }
   452  
   453  // InvoiceRecord is an entire invoice and its content.
   454  type InvoiceRecord struct {
   455  	Status             InvoiceStatusT       `json:"status"`                       // Current status of invoice
   456  	StatusChangeReason string               `json:"statuschangereason,omitempty"` // Reason (if any) for the current status
   457  	Timestamp          int64                `json:"timestamp"`                    // Last update of invoice
   458  	UserID             string               `json:"userid"`                       // ID of user who submitted invoice
   459  	Username           string               `json:"username"`                     // Username of user who submitted invoice
   460  	PublicKey          string               `json:"publickey"`                    // User's public key, used to verify signature.
   461  	Signature          string               `json:"signature"`                    // Signature of file digest
   462  	Files              []www.File           `json:"file"`                         // Actual invoice file
   463  	Version            string               `json:"version"`                      // Record version
   464  	Input              InvoiceInput         `json:"input"`                        // Decoded invoice from invoice.json file
   465  	Payment            PaymentInformation   `json:"payment"`                      // Payment information for the Invoice
   466  	Total              int64                `json:"total"`                        // Total amount that the invoice is billing
   467  	CensorshipRecord   www.CensorshipRecord `json:"censorshiprecord"`
   468  }
   469  
   470  // InvoiceDetails is used to retrieve a invoice by it's token.
   471  type InvoiceDetails struct {
   472  	Token   string `json:"token"`             // Censorship token
   473  	Version string `json:"version,omitempty"` // Invoice version
   474  }
   475  
   476  // InvoiceDetailsReply is used to reply to a invoice details command.
   477  type InvoiceDetailsReply struct {
   478  	Invoice InvoiceRecord `json:"invoice"`
   479  	Payout  Payout        `json:"payout"` // Calculated payout from the InvoiceRecord
   480  }
   481  
   482  // InvoiceInput is the expected structure of the invoice.json file being added to InvoiceRecords.
   483  // Users' raw csv will be inputted and parsed to help in their creation.
   484  type InvoiceInput struct {
   485  	Version            uint             `json:"version"`            // Version of the invoice input
   486  	Month              uint             `json:"month"`              // Month of Invoice
   487  	Year               uint             `json:"year"`               // Year of Invoice
   488  	ExchangeRate       uint             `json:"exchangerate"`       // Exchange rate of a given month/year in USD cents
   489  	ContractorName     string           `json:"contractorname"`     // IRL name of contractor
   490  	ContractorLocation string           `json:"contractorlocation"` // IRL location of contractor
   491  	ContractorContact  string           `json:"contractorcontact"`  // Contractor email or other contact
   492  	ContractorRate     uint             `json:"contractorrate"`     // Contractor Pay Rate in USD cents
   493  	PaymentAddress     string           `json:"paymentaddress"`     //  DCR payment address
   494  	LineItems          []LineItemsInput `json:"lineitems"`
   495  }
   496  
   497  // LineItemsInput is the expected struct of line items contained within an users'
   498  // invoice input.
   499  type LineItemsInput struct {
   500  	Type          LineItemTypeT `json:"type"`          // Type of work performed
   501  	Domain        string        `json:"domain"`        // Domain of work performed
   502  	Subdomain     string        `json:"subdomain"`     // Subdomain of work performed
   503  	Description   string        `json:"description"`   // Description of work performed
   504  	ProposalToken string        `json:"proposaltoken"` // Link to politeia proposal that work is associated with
   505  	SubUserID     string        `json:"subuserid"`     // UserID of the associated Subcontractor
   506  	SubRate       uint          `json:"subrate"`       // The payrate of the subcontractor
   507  	Labor         uint          `json:"labor"`         // Number of minutes (if labor)
   508  	Expenses      uint          `json:"expenses"`      // Total cost (in USD cents) of line item (if expense or misc)
   509  }
   510  
   511  // PolicyReply returns the various policy information while in CMS mode.
   512  type PolicyReply struct {
   513  	MinPasswordLength             uint                    `json:"minpasswordlength"`
   514  	MinUsernameLength             uint                    `json:"minusernamelength"`
   515  	MaxUsernameLength             uint                    `json:"maxusernamelength"`
   516  	MaxImages                     uint                    `json:"maximages"`
   517  	MaxImageSize                  uint                    `json:"maximagesize"`
   518  	MaxMDs                        uint                    `json:"maxmds"`
   519  	MaxMDSize                     uint                    `json:"maxmdsize"`
   520  	ValidMIMETypes                []string                `json:"validmimetypes"`
   521  	MaxNameLength                 uint                    `json:"maxnamelength"`
   522  	MinNameLength                 uint                    `json:"minnamelength"`
   523  	MaxLocationLength             uint                    `json:"maxlocationlength"`
   524  	MinLocationLength             uint                    `json:"minlocationlength"`
   525  	MaxContactLength              uint                    `json:"maxcontactlength"`
   526  	MinContactLength              uint                    `json:"mincontactlength"`
   527  	MaxLineItemColLength          uint                    `json:"maxlineitemcollength"`
   528  	MinLineItemColLength          uint                    `json:"minlineitemcollength"`
   529  	InvoiceCommentChar            rune                    `json:"invoicecommentchar"`
   530  	InvoiceFieldDelimiterChar     rune                    `json:"invoicefielddelimiterchar"`
   531  	InvoiceLineItemCount          uint                    `json:"invoicelineitemcount"`
   532  	InvoiceFieldSupportedChars    []string                `json:"invoicefieldsupportedchars"`
   533  	UsernameSupportedChars        []string                `json:"usernamesupportedchars"`
   534  	CMSNameLocationSupportedChars []string                `json:"cmsnamelocationsupportedchars"`
   535  	CMSContactSupportedChars      []string                `json:"cmscontactsupportedchars"`
   536  	CMSStatementSupportedChars    []string                `json:"cmsstatementsupportedchars"`
   537  	CMSSupportedLineItemTypes     []AvailableLineItemType `json:"supportedlineitemtypes"`
   538  	CMSSupportedDomains           []AvailableDomain       `json:"supporteddomains"`
   539  }
   540  
   541  // UserInvoices is used to get all of the invoices by userID.
   542  type UserInvoices struct{}
   543  
   544  // UserInvoicesReply is used to reply to a user invoices commands.
   545  type UserInvoicesReply struct {
   546  	Invoices []InvoiceRecord `json:"invoices"`
   547  }
   548  
   549  // Invoices is used to get all invoices from all users (if no userid is
   550  // given).
   551  type Invoices struct {
   552  	Month     uint16         `json:"month"`  // Month of Invoice
   553  	Year      uint16         `json:"year"`   // Year of Invoice
   554  	Status    InvoiceStatusT `json:"status"` // Current status of invoice
   555  	UserID    string         `json:"userid"` // User ID for invoices to return
   556  	StartTime int64          `json:"start"`  // Start time for range of invoice submission
   557  	EndTime   int64          `json:"end"`    // End time for range of invoice submission
   558  }
   559  
   560  // InvoicesReply is used to reply to an admin invoices command.
   561  type InvoicesReply struct {
   562  	Invoices []InvoiceRecord `json:"invoices"`
   563  }
   564  
   565  // AdminUserInvoices is used to get all invoices from a given user
   566  type AdminUserInvoices struct {
   567  	UserID string `json:"userid"` // Invoices from a given user
   568  }
   569  
   570  // AdminUserInvoicesReply is used to reply to a user invoices commands.
   571  type AdminUserInvoicesReply struct {
   572  	Invoices []InvoiceRecord `json:"invoices"`
   573  }
   574  
   575  // SetInvoiceStatus is used to approve or reject an unreviewed invoice.
   576  type SetInvoiceStatus struct {
   577  	Token     string         `json:"token"`
   578  	Status    InvoiceStatusT `json:"status"`
   579  	Reason    string         `json:"reason"`
   580  	Signature string         `json:"signature"` // Signature of Token+Version+Reason(InvoiceStatus)
   581  	PublicKey string         `json:"publickey"` // Public key of admin
   582  }
   583  
   584  // SetInvoiceStatusReply is used to reply to a SetInvoiceStatus command.
   585  type SetInvoiceStatusReply struct {
   586  	Invoice InvoiceRecord `json:"invoice"`
   587  }
   588  
   589  // GeneratePayouts is used to generate a list of addresses and amounts of
   590  // approved invoices that need to be paid.
   591  type GeneratePayouts struct {
   592  }
   593  
   594  // GeneratePayoutsReply is used to replay to a GeneratePayouts command.
   595  type GeneratePayoutsReply struct {
   596  	Payouts []Payout `json:"payouts"`
   597  }
   598  
   599  // Payout contains an address and an amount to be paid
   600  type Payout struct {
   601  	ContractorName string         `json:"contractorname"`
   602  	ContractorRate uint           `json:"contractorrate"` // in USD cents
   603  	Username       string         `json:"username"`
   604  	Month          uint           `json:"month"`        // Invoice month
   605  	Year           uint           `json:"year"`         // Invoice year
   606  	Token          string         `json:"token"`        // Invoice token
   607  	Address        string         `json:"address"`      // User provided payment address
   608  	LaborTotal     uint           `json:"labortotal"`   // in USD cents
   609  	ExpenseTotal   uint           `json:"expensetotal"` // in USD cents
   610  	Total          uint           `json:"total"`        // in USD cents
   611  	DCRTotal       dcrutil.Amount `json:"dcrtotal"`     // in DCR atoms
   612  	ExchangeRate   uint           `json:"exchangerate"` // in USD cents
   613  	ApprovedTime   int64          `json:"approvedtime"` // Time of invoice approval (in Unix seconds)
   614  }
   615  
   616  // InvoiceExchangeRate contains the request to receive a monthly exchange rate
   617  type InvoiceExchangeRate struct {
   618  	Month uint `json:"month"`
   619  	Year  uint `json:"year"`
   620  }
   621  
   622  // InvoiceExchangeRateReply returns the calculated monthly exchange rate
   623  type InvoiceExchangeRateReply struct {
   624  	ExchangeRate uint `json:"exchangerate"` // in USD cents
   625  }
   626  
   627  // PayInvoices temporarily allows the administrator to set all approved invoices
   628  // to paid status.
   629  type PayInvoices struct{}
   630  
   631  // PayInvoicesReply will be empty if no errors have occurred.
   632  type PayInvoicesReply struct{}
   633  
   634  // InvoicePayouts contains the request to receive invoices that have been paid
   635  // within a start and end date.
   636  type InvoicePayouts struct {
   637  	StartTime int64 `json:"starttime"` // Start time for range (in unix seconds)
   638  	EndTime   int64 `json:"endtime"`   // End time for range (in unix seconds)
   639  }
   640  
   641  // InvoicePayoutsReply returns an array of invoices within the requested
   642  // date range.
   643  type InvoicePayoutsReply struct {
   644  	Invoices []InvoiceRecord `json:"invoices"` // Invoices within the requested date range.
   645  }
   646  
   647  // PaymentInformation contains information for each invoice's payout. A payout
   648  // might be a single transaction or it might include multiple transactions.
   649  type PaymentInformation struct {
   650  	Token           string         `json:"token"`
   651  	Address         string         `json:"address"`
   652  	TxIDs           []string       `json:"txids"`
   653  	TimeStarted     int64          `json:"timestarted"`
   654  	TimeLastUpdated int64          `json:"timelastupdated"`
   655  	AmountNeeded    dcrutil.Amount `json:"amountneeded"`
   656  	AmountReceived  dcrutil.Amount `json:"amountreceived"`
   657  	Status          PaymentStatusT `json:"status"`
   658  }
   659  
   660  // User represents a CMS user. It contains the standard politeiawww user
   661  // fields as well as CMS specific user fields.
   662  type User struct {
   663  	ID                              string             `json:"id"`
   664  	Email                           string             `json:"email"`
   665  	Username                        string             `json:"username"`
   666  	Admin                           bool               `json:"isadmin"`
   667  	Identities                      []www.UserIdentity `json:"identities"`
   668  	LastLoginTime                   int64              `json:"lastlogintime"`
   669  	FailedLoginAttempts             uint64             `json:"failedloginattempts"`
   670  	Deactivated                     bool               `json:"isdeactivated"`
   671  	Locked                          bool               `json:"islocked"`
   672  	EmailNotifications              uint64             `json:"emailnotifications"` // Notify the user via emails
   673  	NewUserVerificationToken        []byte             `json:"newuserverificationtoken"`
   674  	NewUserVerificationExpiry       int64              `json:"newuserverificationexpiry"`
   675  	UpdateKeyVerificationToken      []byte             `json:"updatekeyverificationtoken"`
   676  	UpdateKeyVerificationExpiry     int64              `json:"updatekeyverificationexpiry"`
   677  	ResetPasswordVerificationToken  []byte             `json:"resetpasswordverificationtoken"`
   678  	ResetPasswordVerificationExpiry int64              `json:"resetpasswordverificationexpiry"`
   679  
   680  	// CMS Information
   681  	Domain             DomainTypeT     `json:"domain"` // Contractor domain
   682  	GitHubName         string          `json:"githubname"`
   683  	MatrixName         string          `json:"matrixname"`
   684  	ContractorType     ContractorTypeT `json:"contractortype"`
   685  	ContractorName     string          `json:"contractorname"`
   686  	ContractorLocation string          `json:"contractorlocation"`
   687  	ContractorContact  string          `json:"contractorcontact"`
   688  	SupervisorUserIDs  []string        `json:"supervisoruserids"`
   689  	ProposalsOwned     []string        `json:"proposalsowned"`
   690  }
   691  
   692  // UserDetails fetches a cms user's details by their id.
   693  type UserDetails struct {
   694  	UserID string `json:"userid"` // User id
   695  }
   696  
   697  // UserDetailsReply returns a cms user's details.
   698  type UserDetailsReply struct {
   699  	User User `json:"user"`
   700  }
   701  
   702  // EditUser edits a user's CMS information.
   703  type EditUser struct {
   704  	GitHubName         string `json:"githubname,omitempty"`
   705  	MatrixName         string `json:"matrixname,omitempty"`
   706  	ContractorName     string `json:"contractorname,omitempty"`
   707  	ContractorLocation string `json:"contractorlocation,omitempty"`
   708  	ContractorContact  string `json:"contractorcontact,omitempty"`
   709  }
   710  
   711  // EditUserReply is the reply for the EditUser command.
   712  type EditUserReply struct{}
   713  
   714  // CMSManageUser updates the various fields for a given user.
   715  type CMSManageUser struct {
   716  	UserID            string          `json:"userid"`
   717  	Domain            DomainTypeT     `json:"domain,omitempty"`
   718  	ContractorType    ContractorTypeT `json:"contractortype,omitempty"`
   719  	SupervisorUserIDs []string        `json:"supervisoruserids,omitempty"`
   720  	ProposalsOwned    []string        `json:"proposalsowned,omitempty"`
   721  }
   722  
   723  // CMSManageUserReply is the reply for the CMSManageUserReply command.
   724  type CMSManageUserReply struct{}
   725  
   726  // DCCInput contains all of the information concerning a DCC object that
   727  // will be submitted as a Record to the politeiad backend.
   728  type DCCInput struct {
   729  	Type             DCCTypeT        `json:"type"`           // Type of DCC object
   730  	NomineeUserID    string          `json:"nomineeuserid"`  // UserID of the DCC nominee (issuance or revocation)
   731  	SponsorStatement string          `json:"statement"`      // Statement from sponsoring user about why DCC should be approved
   732  	Domain           DomainTypeT     `json:"domain"`         // Domain of proposed contractor issuance
   733  	ContractorType   ContractorTypeT `json:"contractortype"` // The Contractor Type of the nominee for when they are approved
   734  }
   735  
   736  // DCCRecord is what will be decoded from a Record for a DCC object to the
   737  // politeiad backend.
   738  type DCCRecord struct {
   739  	Status             DCCStatusT `json:"status"`             // Current status of the DCC
   740  	StatusChangeReason string     `json:"statuschangereason"` // The reason for changing the DCC status.
   741  	Timestamp          int64      `json:"timestamp"`          // Last update of dcc
   742  	TimeSubmitted      int64      `json:"timesubmitted"`      // Submission time stamp
   743  	TimeReviewed       int64      `json:"timereviewed"`       // Approval/Rejection time stamp
   744  	DCC                DCCInput   `json:"dccpayload"`         // DCC payload for the given object
   745  	File               www.File   `json:"file"`               // Actual DCC file (dcc.json, etc)
   746  	PublicKey          string     `json:"publickey"`          // Sponsoring user's public key, used to verify signature.
   747  	Signature          string     `json:"signature"`          // Signature of file digest
   748  
   749  	NomineeUsername string `json:"nomineeusername"` // The username of the nominated user.
   750  	SponsorUserID   string `json:"sponsoruserid"`   // The userid of the sponsoring user.
   751  	SponsorUsername string `json:"sponsorusername"` // The username of the sponsoring user.
   752  
   753  	SupportUserIDs    []string `json:"supportuserids"` // List of UserIDs for those that have shown support of the DCC.
   754  	OppositionUserIDs []string `json:"againstuserids"` // List of UserIDs for those that have shown opposition of the DCC.
   755  
   756  	SupportUsernames    []string `json:"supportusernames"` // List of Usernames for those that have shown support of the DCC.
   757  	OppositionUsernames []string `json:"againstusernames"` // List of Usernames for those that have shown opposition of the DCC.
   758  
   759  	CensorshipRecord www.CensorshipRecord `json:"censorshiprecord"`
   760  }
   761  
   762  // DCCWeight contains a user id and their assigned weight for a given DCC all
   763  // contractor vote.
   764  type DCCWeight struct {
   765  	UserID string // User ID
   766  	Weight int64  // User Weight of the vote (as calculated at the start of the vote).
   767  }
   768  
   769  // NewDCC is a request for submitting a new DCC proposal.
   770  type NewDCC struct {
   771  	File      www.File `json:"file"`      // Issuance/Revocation file (i.e DCCInput)
   772  	PublicKey string   `json:"publickey"` // Pubkey of the sponsoring user
   773  	Signature string   `json:"signature"` // Signature of the issuance struct by the sponsoring user.
   774  }
   775  
   776  // NewDCCReply returns the censorship record when the DCC is successfully
   777  // submitted to the backend.
   778  type NewDCCReply struct {
   779  	CensorshipRecord www.CensorshipRecord `json:"censorshiprecord"`
   780  }
   781  
   782  // DCCDetails request finds a DCC with a matching token.
   783  type DCCDetails struct {
   784  	Token string `json:"token"` // Token of requested DCC
   785  }
   786  
   787  // DCCDetailsReply returns the DCC details if found.
   788  type DCCDetailsReply struct {
   789  	DCC         DCCRecord   `json:"dcc"`         // DCCRecord of requested token
   790  	VoteSummary VoteSummary `json:"votesummary"` // Vote summary of the DCC
   791  }
   792  
   793  // VoteOption describes a single vote option.
   794  type VoteOption struct {
   795  	Id          string `json:"id"`          // Single unique word identifying vote (e.g. yes)
   796  	Description string `json:"description"` // Longer description of the vote.
   797  	Bits        uint64 `json:"bits"`        // Bits used for this option
   798  }
   799  
   800  // Vote represents the vote options for vote that is identified by its token.
   801  type Vote struct {
   802  	Token            string       `json:"token"`            // Token that identifies vote
   803  	Mask             uint64       `json:"mask"`             // Valid votebits
   804  	Duration         uint32       `json:"duration"`         // Duration in blocks
   805  	QuorumPercentage uint32       `json:"quorumpercentage"` // Percent of eligible votes required for quorum
   806  	PassPercentage   uint32       `json:"passpercentage"`   // Percent of total votes required to pass
   807  	Options          []VoteOption `json:"options"`          // Vote options
   808  }
   809  
   810  // VoteResults retrieves a single proposal vote results from the server. If the
   811  // voting period has not yet started for the given proposal a reply is returned
   812  // with all fields set to their zero value.
   813  type VoteResults struct{}
   814  
   815  // VoteResultsReply returns the original proposal vote and the associated cast
   816  // votes.
   817  type VoteResultsReply struct {
   818  	StartVote      StartVote      `json:"startvote"`      // Original vote
   819  	CastVotes      []CastVote     `json:"castvotes"`      // Vote results
   820  	StartVoteReply StartVoteReply `json:"startvotereply"` // Eligible tickets and other details
   821  }
   822  
   823  // ActiveVote obtains all dccs that have active votes.
   824  type ActiveVote struct{}
   825  
   826  // VoteTuple is the proposal, vote and vote details.
   827  type VoteTuple struct {
   828  	DCC            DCCRecord      `json:"dcc"`            // DCC
   829  	StartVote      StartVote      `json:"startvote"`      // Vote bits and mask
   830  	StartVoteReply StartVoteReply `json:"startvotereply"` // Eligible user weights and other details
   831  }
   832  
   833  // ActiveVoteReply returns all proposals that have active votes.
   834  type ActiveVoteReply struct {
   835  	Votes []VoteTuple `json:"votes"` // Active votes
   836  }
   837  
   838  type StartVote struct {
   839  	Vote      Vote   `json:"vote"`
   840  	PublicKey string `json:"publickey"` // Key used for signature
   841  	Signature string `json:"signature"` // Signature of Vote hash
   842  }
   843  
   844  // StartVoteReply is the reply to the StartVote command.
   845  type StartVoteReply struct {
   846  	StartBlockHeight uint32   `json:"startblockheight"` // Block height of vote start
   847  	StartBlockHash   string   `json:"startblockhash"`   // Block hash of vote start
   848  	EndBlockHeight   uint32   `json:"endblockheight"`   // Block height of vote end
   849  	UserWeights      []string `json:"userweights"`      // Snapshot of users and their given weights
   850  }
   851  
   852  // VoteDetails returns the votes details for the specified proposal.
   853  type VoteDetails struct {
   854  	Token string `json:"token"` // Proposal token
   855  }
   856  
   857  // VoteDetailsReply is the reply to the VoteDetails command. It contains all
   858  // of the information from a StartVote and StartVoteReply
   859  //
   860  // Vote contains a JSON encoded Vote and needs to be decoded according to the
   861  // Version.
   862  type VoteDetailsReply struct {
   863  	Version          uint32   `json:"version"`          // StartVote version
   864  	Vote             string   `json:"vote"`             // JSON encoded Vote struct
   865  	PublicKey        string   `json:"publickey"`        // Key used for signature
   866  	Signature        string   `json:"signature"`        // Start vote signature
   867  	StartBlockHeight uint32   `json:"startblockheight"` // Block height
   868  	StartBlockHash   string   `json:"startblockhash"`   // Block hash
   869  	EndBlockHeight   uint32   `json:"endblockheight"`   // Height of vote end
   870  	UserWeights      []string `json:"userweights"`      // Snapshot of users and their given weights
   871  }
   872  
   873  // VoteSummary contains a summary of the vote information for a specific
   874  // dcc.
   875  type VoteSummary struct {
   876  	Status           DCCStatusT         `json:"status"`                     // Vote status
   877  	UserWeights      []DCCWeight        `json:"userweights"`                // User weights that is populated for all contractor votes.
   878  	Duration         uint32             `json:"duration,omitempty"`         // Duration of vote
   879  	EndHeight        uint32             `json:"endheight,omitempty"`        // Vote end height
   880  	QuorumPercentage uint32             `json:"quorumpercentage,omitempty"` // Percent of eligible votes required for quorum
   881  	PassPercentage   uint32             `json:"passpercentage,omitempty"`   // Percent of total votes required to pass
   882  	Results          []VoteOptionResult `json:"results,omitempty"`          // Vote results
   883  }
   884  
   885  // VoteOptionResult is a structure that describes a VotingOption along with the
   886  // number of votes it has received
   887  type VoteOptionResult struct {
   888  	Option        VoteOption `json:"option"`        // Vote Option
   889  	VotesReceived uint64     `json:"votesreceived"` // Number of votes received by the option
   890  }
   891  
   892  // GetDCCs request finds all DCCs that have matching status (if used).
   893  type GetDCCs struct {
   894  	Status DCCStatusT `json:"status"` // Return all DCCs of this status
   895  }
   896  
   897  // GetDCCsReply returns the DCCs if found.
   898  type GetDCCsReply struct {
   899  	DCCs []DCCRecord `json:"dccs"` // DCCRecords of matching status
   900  }
   901  
   902  // SupportOpposeDCC request allows a user to support a given DCC issuance or
   903  // revocation.
   904  type SupportOpposeDCC struct {
   905  	Vote      string `json:"vote"`      // Vote must be "aye" or "nay"
   906  	Token     string `json:"token"`     // The censorship token of the given DCC issuance or revocation.
   907  	PublicKey string `json:"publickey"` // Pubkey of the submitting user
   908  	Signature string `json:"signature"` // Signature of the Token+Vote by the submitting user.
   909  }
   910  
   911  // SupportOpposeDCCReply returns an empty response when successful.
   912  type SupportOpposeDCCReply struct{}
   913  
   914  // SetDCCStatus is an admin request that updates the status of a DCC
   915  type SetDCCStatus struct {
   916  	Token     string     `json:"token"`     // Token of the DCC iss/rev
   917  	Reason    string     `json:"reason"`    // Reason for approval
   918  	Status    DCCStatusT `json:"status"`    // New status
   919  	Signature string     `json:"signature"` // Client Signature of Token+Status+Reason
   920  	PublicKey string     `json:"publickey"` // Pubkey used for Signature
   921  }
   922  
   923  // SetDCCStatusReply returns an empty response when successful.
   924  type SetDCCStatusReply struct{}
   925  
   926  // UserSubContractors is a request for a logged in Supervisor to return a
   927  // list of UserIDs/Usernames
   928  type UserSubContractors struct{}
   929  
   930  // UserSubContractorsReply returns a list of Users that are considered
   931  // sub contractors of the logged in user making the request.
   932  type UserSubContractorsReply struct {
   933  	Users []User `json:"users"`
   934  }
   935  
   936  // AbridgedCMSUser is a shortened version of CMS User that's used for the
   937  // CMSUsers reply.
   938  type AbridgedCMSUser struct {
   939  	ID             string          `json:"id"`
   940  	Domain         DomainTypeT     `json:"domain"`
   941  	ContractorType ContractorTypeT `json:"contractortype"`
   942  	Username       string          `json:"username"`
   943  }
   944  
   945  // CMSUsers is used to request a list of CMS users given a filter.
   946  type CMSUsers struct {
   947  	Domain         DomainTypeT     `json:"domain"`
   948  	ContractorType ContractorTypeT `json:"contractortype"`
   949  }
   950  
   951  // CMSUsersReply returns a list of Users that are currently
   952  type CMSUsersReply struct {
   953  	Users []AbridgedCMSUser `json:"users"`
   954  }
   955  
   956  // ProposalOwner is a request for determining the current owners of a given
   957  // proposal.
   958  type ProposalOwner struct {
   959  	ProposalToken string `json:"proposaltoken"`
   960  }
   961  
   962  // ProposalOwnerReply returns the users that are currently associated with
   963  // the requested proposal token.
   964  type ProposalOwnerReply struct {
   965  	Users []AbridgedCMSUser `json:"users"`
   966  }
   967  
   968  // ProposalBilling collects information for administrators or proposal owners
   969  // for a given proposal.
   970  type ProposalBilling struct {
   971  	Token string `json:"token"`
   972  }
   973  
   974  // ProposalBillingReply returns all line items that have been billed to the
   975  // proposal token.
   976  type ProposalBillingReply struct {
   977  	BilledLineItems []ProposalLineItems `json:"lineitems"`
   978  }
   979  
   980  // ProposalLineItems includes all information required for a proper billing
   981  // history of line items from a given proposal token.
   982  type ProposalLineItems struct {
   983  	// User information
   984  	UserID   string `json:"userid"`
   985  	Username string `json:"username"`
   986  
   987  	// Invoice Information
   988  	Month int `json:"month"`
   989  	Year  int `json:"year"`
   990  
   991  	// Contractor rate
   992  	ContractorRate uint `json:"contractorrate"`
   993  
   994  	// Line Item Information
   995  	LineItem LineItemsInput `json:"lineitem"`
   996  }
   997  
   998  // CastVote is a signed vote.
   999  type CastVote struct {
  1000  	VoteBit   string `json:"votebit"`   // Vote bit that was selected, this is encode in hex
  1001  	Token     string `json:"token"`     // The censorship token of the given DCC issuance or revocation.
  1002  	UserID    string `json:"userid"`    // UserID of the submitting user
  1003  	PublicKey string `json:"publickey"` // Pubkey of the submitting user
  1004  	Signature string `json:"signature"` // Signature of the Token+VoteBit+UserID by the submitting user.
  1005  }
  1006  
  1007  // CastVoteReply is the answer to the CastVote command. The Error and
  1008  // ErrorStatus fields will only be populated if something went wrong while
  1009  // attempting to cast the vote.
  1010  type CastVoteReply struct {
  1011  	ClientSignature string                 `json:"clientsignature"`       // Signature that was sent in
  1012  	Signature       string                 `json:"signature"`             // Signature of the ClientSignature
  1013  	Error           string                 `json:"error"`                 // Error status message
  1014  	ErrorStatus     cmsplugin.ErrorStatusT `json:"errorstatus,omitempty"` // Error status code
  1015  }
  1016  
  1017  // ProposalBillingSummary allows for all proposal spending to be returned for
  1018  // an admin to review.
  1019  type ProposalBillingSummary struct {
  1020  	Offset int `json:"offset"` // Amount to offset for pagination
  1021  	Count  int `json:"count"`  // Size of page for pagination
  1022  }
  1023  
  1024  // ProposalBillingSummaryReply returns an array of proposal spending based on
  1025  // the list of approved invoices returned from the respective proposals site.
  1026  type ProposalBillingSummaryReply struct {
  1027  	Proposals []ProposalSpending `json:"proposals"`
  1028  }
  1029  
  1030  // ProposalSpending contains all the information about a given proposal's
  1031  // spending.
  1032  type ProposalSpending struct {
  1033  	Token       string          `json:"token"`
  1034  	Title       string          `json:"title"`
  1035  	TotalBilled int64           `json:"totalbilled"`
  1036  	Invoices    []InvoiceRecord `json:"invoices"`
  1037  }
  1038  
  1039  // ProposalBillingDetails returns all the information about the given proposal's
  1040  // spending.
  1041  type ProposalBillingDetails struct {
  1042  	Token string `json:"token"`
  1043  }
  1044  
  1045  // ProposalBillingDetailsReply returns the spending information about the
  1046  // requested proposal.
  1047  type ProposalBillingDetailsReply struct {
  1048  	Details ProposalSpending `json:"details"`
  1049  }
  1050  
  1051  // UserCodeStats is a request that other members of the requested user's domain
  1052  // may attempt to view the given month/year of code changes
  1053  type UserCodeStats struct {
  1054  	UserID    string `json:"userid"`
  1055  	StartTime int64  `json:"starttime"`
  1056  	EndTime   int64  `json:"endtime"`
  1057  }
  1058  
  1059  // UserCodeStatsReply responds with an array of code stats per repo for the
  1060  // given user, month and year.
  1061  type UserCodeStatsReply struct {
  1062  	RepoStats []CodeStats `json:"repostats"`
  1063  }
  1064  
  1065  // CodeStats contains various pieces of information for user's code
  1066  // contributions per repo over a period of time.
  1067  type CodeStats struct {
  1068  	Month            int      `json:"month"`
  1069  	Year             int      `json:"year"`
  1070  	Repository       string   `json:"repository"`
  1071  	MergedAdditions  int64    `json:"mergedadditions"`
  1072  	MergedDeletions  int64    `json:"mergeddeletions"`
  1073  	UpdatedAdditions int64    `json:"updatedadditions"`
  1074  	UpdatedDeletions int64    `json:"updateddeletions"`
  1075  	ReviewAdditions  int64    `json:"reviewadditions"`
  1076  	ReviewDeletions  int64    `json:"reviewdeletions"`
  1077  	CommitAdditions  int64    `json:"commitadditions"`
  1078  	CommitDeletions  int64    `json:"commitdeletions"`
  1079  	PRs              []string `json:"prs"`
  1080  	Reviews          []string `json:"reviews"`
  1081  	Commits          []string `json:"commits"`
  1082  }