Files
FrozenFriendsYume/packages/backend/built/services/note/polls/vote.js
T
2026-07-26 18:25:37 +09:00

83 lines
2.5 KiB
JavaScript

import { publishNoteStream } from "../../stream.js";
import { PollVotes, NoteWatchings, Polls, Blockings } from "../../../models/index.js";
import { Not } from "typeorm";
import { genId } from "../../../misc/gen-id.js";
import { createNotification } from "../../create-notification.js";
export default async function(user, note, choice) {
const poll = await Polls.findOneBy({
noteId: note.id
});
if (poll == null) throw new Error("poll not found");
// Check whether is valid choice
if (poll.choices[choice] == null) throw new Error("invalid choice param");
// Check blocking
if (note.userId !== user.id) {
const blocked = await Blockings.exist({
where: [
{
blockerId: note.userId,
blockeeId: user.id,
groupId: null
},
...note.groupId ? [
{
groupId: note.groupId,
blockeeId: user.id
}
] : []
]
});
if (blocked) {
throw new Error("blocked");
}
}
// if already voted
const exist = await PollVotes.findBy({
noteId: note.id,
userId: user.id
});
if (poll.multiple) {
if (exist.some((x)=>x.choice === choice)) {
throw new Error("already voted");
}
} else if (exist.length !== 0) {
throw new Error("already voted");
}
// Create vote
await PollVotes.insert({
id: genId(),
createdAt: new Date(),
noteId: note.id,
userId: user.id,
choice: choice
});
// Increment votes count
const index = choice + 1; // In SQL, array index is 1 based
await Polls.query(`UPDATE poll SET votes[${index}] = votes[${index}] + 1 WHERE "noteId" = '${poll.noteId}'`);
publishNoteStream(note.id, "pollVoted", {
choice: choice,
userId: user.id
});
// Notify
createNotification(note.userId, "pollVote", {
notifierId: user.id,
note: note,
noteId: note.id,
choice: choice
});
// Fetch watchers
NoteWatchings.findBy({
noteId: note.id,
userId: Not(user.id)
}).then((watchers)=>{
for (const watcher of watchers){
createNotification(watcher.userId, "pollVote", {
notifierId: user.id,
note: note,
noteId: note.id,
choice: choice
});
}
});
}