forked from MyZubster-Ecosystem/myzubster
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBounty.js
More file actions
111 lines (102 loc) 路 2.26 KB
/
Copy pathBounty.js
File metadata and controls
111 lines (102 loc) 路 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* Bounty Model
* Mongoose schema for bounties with reward assignment and minting support
*/
const mongoose = require('mongoose');
const BountySchema = new mongoose.Schema(
{
title: {
type: String,
required: [true, 'Title is required'],
trim: true
},
description: {
type: String,
required: [true, 'Description is required'],
trim: true
},
reward: {
type: Number,
required: [true, 'Reward amount is required'],
min: [0, 'Reward must be non-negative']
},
currency: {
type: String,
default: 'XMR',
enum: ['XMR', 'BTC', 'ETH', 'USD', 'EUR']
},
status: {
type: String,
enum: ['open', 'assigned', 'completed', 'cancelled'],
default: 'open'
},
// Assignment fields
assignee: {
type: String,
default: null
},
assignedAt: {
type: Date,
default: null
},
// Minting fields
minted: {
type: Boolean,
default: false
},
mintTxHash: {
type: String,
default: null
},
mintedAt: {
type: Date,
default: null
},
walletAddress: {
type: String,
default: null
},
// Optional metadata
tags: {
type: [String],
default: []
},
githubIssueUrl: {
type: String,
default: null
},
createdBy: {
type: String,
default: null
}
},
{
timestamps: true
}
);
// Index for efficient querying
BountySchema.index({ status: 1 });
BountySchema.index({ assignee: 1 });
BountySchema.index({ minted: 1 });
BountySchema.index({ createdAt: -1 });
/**
* Virtual: isEligibleForMinting
* A bounty is eligible for minting if it has an assignee and hasn't been minted yet
*/
BountySchema.virtual('isEligibleForMinting').get(function () {
return !!this.assignee && !this.minted;
});
/**
* Static: findEligibleForAutoMint
* Find all assigned-but-not-yet-minted bounties
*/
BountySchema.statics.findEligibleForAutoMint = function () {
return this.find({ status: 'assigned', minted: false, assignee: { $ne: null } });
};
/**
* Static: findOpenBounties
*/
BountySchema.statics.findOpenBounties = function () {
return this.find({ status: 'open' });
};
module.exports = mongoose.model('Bounty', BountySchema);