Voting System API
Design the APIs for a voting system, answering in code: a VotingService whose methods stand in for the endpoints and return HTTP-style status objects.
createPoll(pollId, options)→POST /polls.{ status: 201, options }with the options sorted;{ status: 409 }if the poll exists;{ status: 422 }if the options are empty or repeat.castVote(pollId, voter, option)→PUT /polls/{id}/votes/{voter}— a PUT, so a retried request cannot double-count.{ status: 404 }for an unknown poll,{ status: 409 }if it is closed,{ status: 422 }for an unknown option,{ status: 201, result: "recorded" }for a voter's first vote,{ status: 200, result: "unchanged" }for the same vote again,{ status: 200, result: "changed" }when the voter switches.closePoll(pollId)→{ status: 204 }, or{ status: 404 }.results(pollId)→{ status: 200, results: [[option, count], ...] }for options with at least one vote, sorted by count descending then option ascending;{ status: 404 }for an unknown poll. Results stay readable after the poll closes.audit()→ every successful mutation, in order:["createPoll", pollId, options](as requested),["vote", pollId, voter, previousOption | null, option],["closePoll", pollId].
svc.createPoll("p1", ["b", "a"]) -> { status: 201, options: ["a", "b"] }
svc.castVote("p1", "v1", "a") -> { status: 201, result: "recorded" }
svc.castVote("p1", "v1", "a") -> { status: 200, result: "unchanged" } // safe retry
svc.castVote("p1", "v1", "b") -> { status: 200, result: "changed" }
svc.results("p1") -> { status: 200, results: [["b", 1]] }Hints
Hint 1
Key the vote store by (pollId, voter). A cast looks up the previous option: none means recorded, the same means unchanged, different means changed — decrement the old tally and increment the new one so the read model stays consistent.
Hint 2
Keep the tally as its own structure updated on every write, so reads never rescan votes, and append one audit entry per successful mutation before returning.