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

hicommonwealth / commonwealth / 14907162975

08 May 2025 01:04PM UTC coverage: 42.961% (-0.2%) from 43.119%
14907162975

push

github

web-flow
Merge pull request #12070 from hicommonwealth/rotorsoft/11975-weighted-voting-polls

Weighted voting polls

1683 of 4323 branches covered (38.93%)

Branch coverage included in aggregate %.

0 of 33 new or added lines in 5 files covered. (0.0%)

3047 of 6687 relevant lines covered (45.57%)

37.6 hits per line

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

9.09
/libs/model/src/aggregates/poll/createPollVote.command.ts
1
import { Command, InvalidState } from '@hicommonwealth/core';
2
import * as schemas from '@hicommonwealth/schemas';
3
import dayjs from 'dayjs';
4
import utc from 'dayjs/plugin/utc';
5
import { models } from '../../database';
6
import { authPoll } from '../../middleware';
7
import { mustBeAuthorizedPoll } from '../../middleware/guards';
8
import { getVotingWeight } from '../../services/stakeHelper';
9

10
dayjs.extend(utc);
33✔
11

12
export const CreateVotePollErrors = {
33✔
13
  InvalidOption: 'Invalid response option',
14
  PollingClosed: 'Polling already finished',
15
};
16

17
export function CreatePollVote(): Command<typeof schemas.CreatePollVote> {
18
  return {
×
19
    ...schemas.CreatePollVote,
20
    auth: [
21
      authPoll({
22
        action: 'UPDATE_POLL',
23
      }),
24
    ],
25
    body: async ({ actor, payload, context }) => {
NEW
26
      const { poll, address, thread } = mustBeAuthorizedPoll(actor, context);
×
27
      if (!poll.ends_at && dayjs(poll.ends_at).utc().isBefore(dayjs().utc())) {
×
28
        throw new InvalidState(CreateVotePollErrors.PollingClosed);
×
29
      }
30

31
      // TODO: migrate this to be JSONB array of strings in the DB
32
      const options = JSON.parse(poll.options);
×
33
      if (!options.includes(payload.option)) {
×
34
        throw new InvalidState(CreateVotePollErrors.InvalidOption);
×
35
      }
36

NEW
37
      const calculated_voting_weight = await getVotingWeight(
×
38
        thread.topic_id,
39
        address.address,
40
      );
41

42
      // findOrCreate doesn't work because `poll_id` and `option` not
43
      // optional in the Vote schema
44
      let vote = await models.Vote.findOne({
×
45
        where: {
46
          poll_id: payload.poll_id,
47
          address: address.address,
48
        },
49
      });
50
      if (!vote) {
×
51
        vote = await models.Vote.create({
×
52
          poll_id: payload.poll_id,
53
          address: address.address,
54
          author_community_id: address.community_id,
55
          community_id: poll.community_id,
56
          calculated_voting_weight: calculated_voting_weight?.toString(),
57
          option: payload.option,
58
        });
59
      }
60

61
      return vote.toJSON();
×
62
    },
63
  };
64
}
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

© 2026 Coveralls, Inc