• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vocdoni / saas-backend / 17557469823

08 Sep 2025 04:25PM UTC coverage: 58.777% (-0.06%) from 58.841%
17557469823

Pull #213

github

altergui
fix
Pull Request #213: api: standardize parameters ProcessID, CensusID, GroupID, JobID, UserID, BundleID

254 of 345 new or added lines in 22 files covered. (73.62%)

19 existing lines in 7 files now uncovered.

5652 of 9616 relevant lines covered (58.78%)

32.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.33
/db/jobs.go
1
package db
2

3
import (
4
        "context"
5
        "fmt"
6
        "time"
7

8
        "github.com/ethereum/go-ethereum/common"
9
        "github.com/vocdoni/saas-backend/internal"
10
        "go.mongodb.org/mongo-driver/bson"
11
        "go.mongodb.org/mongo-driver/mongo"
12
        "go.mongodb.org/mongo-driver/mongo/options"
13
        "go.vocdoni.io/dvote/log"
14
)
15

16
// SetJob creates a new job record in the database or updates an existing one.
17
func (ms *MongoStorage) SetJob(job *Job) error {
6✔
18
        ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
6✔
19
        defer cancel()
6✔
20

6✔
21
        ms.keysLock.Lock()
6✔
22
        defer ms.keysLock.Unlock()
6✔
23

6✔
24
        // If no ID is set, create a new one
6✔
25
        if job.ID == internal.NilObjectID {
6✔
NEW
26
                job.ID = internal.NewObjectID()
×
UNCOV
27
        }
×
28

29
        // Create update document
30
        updateDoc, err := dynamicUpdateDocument(job, nil)
6✔
31
        if err != nil {
6✔
32
                return fmt.Errorf("failed to create update document: %w", err)
×
33
        }
×
34

35
        // Upsert the job
36
        filter := bson.M{"_id": job.ID}
6✔
37
        opts := options.Update().SetUpsert(true)
6✔
38
        _, err = ms.jobs.UpdateOne(ctx, filter, updateDoc, opts)
6✔
39
        if err != nil {
6✔
40
                return fmt.Errorf("failed to upsert job: %w", err)
×
41
        }
×
42

43
        return nil
6✔
44
}
45

46
// Job retrieves a job by its jobId.
47
func (ms *MongoStorage) Job(jobID internal.ObjectID) (*Job, error) {
5✔
48
        ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
5✔
49
        defer cancel()
5✔
50

5✔
51
        var job Job
5✔
52
        filter := bson.M{"_id": jobID}
5✔
53
        err := ms.jobs.FindOne(ctx, filter).Decode(&job)
5✔
54
        if err != nil {
6✔
55
                if err == mongo.ErrNoDocuments {
2✔
56
                        return nil, ErrNotFound
1✔
57
                }
1✔
58
                return nil, fmt.Errorf("failed to get job: %w", err)
×
59
        }
60

61
        return &job, nil
4✔
62
}
63

64
// CreateJob creates a new job record with initial data.
65
func (ms *MongoStorage) CreateJob(jobID internal.ObjectID, jobType JobType, orgAddress common.Address, total int) error {
4✔
66
        job := &Job{
4✔
67
                ID:         jobID,
4✔
68
                Type:       jobType,
4✔
69
                OrgAddress: orgAddress,
4✔
70
                Total:      total,
4✔
71
                Added:      0,
4✔
72
                Errors:     []string{},
4✔
73
                CreatedAt:  time.Now(),
4✔
74
        }
4✔
75

4✔
76
        return ms.SetJob(job)
4✔
77
}
4✔
78

79
// CompleteJob updates a job with final results when it completes.
80
func (ms *MongoStorage) CompleteJob(jobID internal.ObjectID, added int, errors []string) error {
4✔
81
        ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
4✔
82
        defer cancel()
4✔
83

4✔
84
        ms.keysLock.Lock()
4✔
85
        defer ms.keysLock.Unlock()
4✔
86

4✔
87
        filter := bson.M{"_id": jobID}
4✔
88
        update := bson.M{
4✔
89
                "$set": bson.M{
4✔
90
                        "added":       added,
4✔
91
                        "errors":      errors,
4✔
92
                        "completedAt": time.Now(),
4✔
93
                },
4✔
94
        }
4✔
95

4✔
96
        _, err := ms.jobs.UpdateOne(ctx, filter, update)
4✔
97
        if err != nil {
4✔
98
                return fmt.Errorf("failed to complete job: %w", err)
×
99
        }
×
100

101
        return nil
4✔
102
}
103

104
// Jobs retrieves paginated jobs for an organization from the database.
105
func (ms *MongoStorage) Jobs(orgAddress common.Address, page, pageSize int, jobType *JobType) (int, []Job, error) {
11✔
106
        if orgAddress.Cmp(common.Address{}) == 0 {
11✔
107
                return 0, nil, ErrInvalidData
×
108
        }
×
109

110
        ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
11✔
111
        defer cancel()
11✔
112

11✔
113
        // Create filter
11✔
114
        filter := bson.M{
11✔
115
                "orgAddress": orgAddress,
11✔
116
        }
11✔
117

11✔
118
        // Add job type filter if specified
11✔
119
        if jobType != nil {
15✔
120
                filter["type"] = *jobType
4✔
121
        }
4✔
122

123
        // Count total documents
124
        totalCount, err := ms.jobs.CountDocuments(ctx, filter)
11✔
125
        if err != nil {
11✔
126
                return 0, nil, fmt.Errorf("failed to count jobs: %w", err)
×
127
        }
×
128

129
        // Calculate total pages
130
        totalPages := int((totalCount + int64(pageSize) - 1) / int64(pageSize))
11✔
131

11✔
132
        // Calculate skip value based on page and pageSize
11✔
133
        skip := (page - 1) * pageSize
11✔
134

11✔
135
        // Set up options for pagination - sort by creation date descending (newest first)
11✔
136
        findOptions := options.Find().
11✔
137
                SetSort(bson.D{{Key: "createdAt", Value: -1}}).
11✔
138
                SetSkip(int64(skip)).
11✔
139
                SetLimit(int64(pageSize))
11✔
140

11✔
141
        // Execute the find operation with pagination
11✔
142
        cursor, err := ms.jobs.Find(ctx, filter, findOptions)
11✔
143
        if err != nil {
11✔
144
                return 0, nil, fmt.Errorf("failed to get jobs: %w", err)
×
145
        }
×
146
        defer func() {
22✔
147
                if err := cursor.Close(ctx); err != nil {
11✔
148
                        log.Warnw("error closing cursor", "error", err)
×
149
                }
×
150
        }()
151

152
        // Decode results
153
        var jobs []Job
11✔
154
        if err = cursor.All(ctx, &jobs); err != nil {
11✔
155
                return 0, nil, fmt.Errorf("failed to decode jobs: %w", err)
×
156
        }
×
157

158
        return totalPages, jobs, nil
11✔
159
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc