Skip to content
This repository was archived by the owner on Apr 6, 2022. It is now read-only.

Commit d390713

Browse files
authored
Merge pull request #309 from orbiting/questionnaire-improvements
Questionnaire improvements
2 parents 1d880d3 + cadc154 commit d390713

25 files changed

+623
-49
lines changed

packages/dataloader/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module.exports = (loader, options = {}, find = defaultFind) =>
4343
,
4444
{
4545
cacheKeyFn: getCacheKey,
46+
maxBatchSize: 1000,
4647
...options
4748
}
4849
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const run = require('../run.js')
2+
3+
const dir = 'packages/voting/migrations/sqls/'
4+
const file = '20190907043631-questionnaire-improvements'
5+
6+
exports.up = (db) =>
7+
run(db, dir, `${file}-up.sql`)
8+
9+
exports.down = (db) =>
10+
run(db, dir, `${file}-down.sql`)

packages/translate/translations.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1619,4 +1619,4 @@
16191619
"value": "Ihr Profil ist im Moment einer Kandidatur zugeordnet und kann im Moment nicht zurückgenommen werden."
16201620
}
16211621
]
1622-
}
1622+
}

packages/voting/graphql/resolvers/Election.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ module.exports = {
1616
async userIsEligible (entity, args, { pgdb, user: me }) {
1717
return isEligible(me && me.id, entity, pgdb)
1818
},
19-
async userHasSubmitted (entity, args, { pgdb, user: me }) {
20-
return userHasSubmitted(entity.id, me && me.id, pgdb)
19+
async userHasSubmitted (entity, args, context) {
20+
const { user: me } = context
21+
return userHasSubmitted(entity.id, me && me.id, context)
2122
},
22-
async userSubmitDate (entity, args, { pgdb, user: me }) {
23-
return userSubmitDate(entity.id, me && me.id, pgdb)
23+
async userSubmitDate (entity, args, context) {
24+
const { user: me } = context
25+
return userSubmitDate(entity.id, me && me.id, context)
2426
},
2527
async turnout (election, args, { pgdb }) {
2628
if (election.result && election.result.turnout) { // after counting

packages/voting/graphql/resolvers/QuestionInterface.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ module.exports = {
44
__resolveType (question) {
55
return `QuestionType${question.type}`
66
},
7-
userAnswer: (question, args, { req, user: me, pgdb, t }) => {
7+
userAnswer: (question, args, { req, user: me, pgdb, t, loaders }) => {
88
if (!me) {
99
return null
1010
}
1111
if (question.userAnswer !== undefined) {
1212
return question.userAnswer
1313
}
14-
return pgdb.public.answers.findOne({
14+
return loaders.Answer.byKeyObj.load({
1515
questionId: question.id,
1616
userId: me.id
1717
})

packages/voting/graphql/resolvers/Questionnaire.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ module.exports = {
99
async userIsEligible (entity, args, { pgdb, user: me }) {
1010
return isEligible(me && me.id, entity, pgdb)
1111
},
12-
async userHasSubmitted (entity, args, { pgdb, user: me }) {
13-
return userHasSubmitted(entity.id, me && me.id, pgdb)
12+
async userHasSubmitted (entity, args, context) {
13+
const { user: me } = context
14+
return userHasSubmitted(entity.id, me && me.id, context)
1415
},
15-
async userSubmitDate (entity, args, { pgdb, user: me }) {
16-
return userSubmitDate(entity.id, me && me.id, pgdb)
16+
async userSubmitDate (entity, args, context) {
17+
const { user: me } = context
18+
return userSubmitDate(entity.id, me && me.id, context)
1719
},
1820
async questions (entity, args, { pgdb, user: me }) {
1921
return getQuestions(entity, args, pgdb)

packages/voting/graphql/resolvers/Voting.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ module.exports = {
2323
async userIsEligible (entity, args, { pgdb, user: me }) {
2424
return isEligible(me && me.id, entity, pgdb)
2525
},
26-
async userHasSubmitted (entity, args, { pgdb, user: me }) {
27-
return userHasSubmitted(entity.id, me && me.id, pgdb)
26+
async userHasSubmitted (entity, args, context) {
27+
const { user: me } = context
28+
return userHasSubmitted(entity.id, me && me.id, context)
2829
},
29-
async userSubmitDate (entity, args, { pgdb, user: me }) {
30-
return userSubmitDate(entity.id, me && me.id, pgdb)
30+
async userSubmitDate (entity, args, context) {
31+
const { user: me } = context
32+
return userSubmitDate(entity.id, me && me.id, context)
3133
},
3234
async turnout (voting, args, { pgdb }) {
3335
if (voting.result && voting.result.turnout) { // after counting
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
const { ensureSignedIn } = require('@orbiting/backend-modules-auth')
2+
const {
3+
findById,
4+
ensureReadyToSubmit
5+
} = require('../../../lib/Questionnaire')
6+
const uuid = require('uuid/v4')
7+
8+
module.exports = async (_, { questionnaireId }, context) => {
9+
const { pgdb, user: me, t, req, loaders } = context
10+
ensureSignedIn(req, t)
11+
12+
const transaction = await pgdb.transactionBegin()
13+
try {
14+
const now = new Date()
15+
16+
const questionnaire = await findById(questionnaireId, transaction)
17+
await ensureReadyToSubmit(questionnaire, me.id, now, { ...context, pgdb: transaction })
18+
19+
await transaction.public.questionnaireSubmissions.insert({
20+
questionnaireId,
21+
userId: me.id
22+
})
23+
24+
await loaders.QuestionnaireSubmissions.byKeyObj.clear({
25+
userId: me.id,
26+
questionnaireId
27+
})
28+
29+
await transaction.public.answers.update(
30+
{
31+
userId: me.id,
32+
questionnaireId: questionnaire.id
33+
},
34+
{
35+
userId: null,
36+
pseudonym: uuid()
37+
}
38+
)
39+
40+
await transaction.transactionCommit()
41+
42+
return questionnaire
43+
} catch (e) {
44+
await transaction.transactionRollback()
45+
throw e
46+
}
47+
}

packages/voting/graphql/resolvers/_mutations/resetQuestionnaire.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ module.exports = async (_, { id: questionnaireId }, context) => {
1313
const now = new Date()
1414

1515
const questionnaire = await findById(questionnaireId, transaction)
16-
await ensureReadyToSubmit(questionnaire, me.id, now, transaction, t)
16+
17+
await ensureReadyToSubmit(questionnaire, me.id, now, { ...context, pgdb: transaction })
1718

1819
await pgdb.public.answers.delete({
1920
questionnaireId,
20-
userId: me.id
21+
userId: me.id,
22+
submitted: false
2123
})
2224

2325
await transaction.transactionCommit()

packages/voting/graphql/resolvers/_mutations/submitAnswer.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ const { ensureSignedIn } = require('@orbiting/backend-modules-auth')
22
const {
33
findById,
44
ensureReadyToSubmit,
5-
transformQuestion
5+
transformQuestion,
6+
updateResultIncrementally
67
} = require('../../../lib/Questionnaire')
78
const {
89
validateAnswer
910
} = require('../../../lib/Question')
1011

11-
module.exports = async (_, { answer: { id, questionId, payload } }, context) => {
12+
module.exports = async (_, { answer }, context) => {
1213
const { pgdb, user: me, t, req } = context
1314
ensureSignedIn(req, t)
1415

16+
const { id, questionId, payload } = answer
17+
1518
const transaction = await pgdb.transactionBegin()
1619
try {
1720
const now = new Date()
@@ -21,7 +24,7 @@ module.exports = async (_, { answer: { id, questionId, payload } }, context) =>
2124
}
2225

2326
const questionnaire = await findById(question.questionnaireId, transaction)
24-
await ensureReadyToSubmit(questionnaire, me.id, now, transaction, t)
27+
await ensureReadyToSubmit(questionnaire, me.id, now, { ...context, pgdb: transaction })
2528

2629
// check client generated ID
2730
const existingAnswer = await transaction.public.answers.findOne({ id })
@@ -38,6 +41,12 @@ module.exports = async (_, { answer: { id, questionId, payload } }, context) =>
3841
userId: me.id,
3942
questionId
4043
})
44+
if (
45+
(existingAnswer && existingAnswer.submitted) ||
46+
(sameAnswer && sameAnswer.submitted)
47+
) {
48+
throw new Error(t('api/questionnaire/answer/immutable'))
49+
}
4150
if (sameAnswer) {
4251
await transaction.public.answers.deleteOne({ id: sameAnswer.id })
4352
}
@@ -63,6 +72,19 @@ module.exports = async (_, { answer: { id, questionId, payload } }, context) =>
6372
)
6473
}
6574

75+
if (emptyAnswer && questionnaire.noEmptyAnswers) {
76+
throw new Error(t('api/questionnaire/answer/empty'))
77+
}
78+
79+
if (questionnaire.updateResultIncrementally) {
80+
await updateResultIncrementally(
81+
questionnaire.id,
82+
answer,
83+
transaction,
84+
context
85+
)
86+
}
87+
6688
// write
6789
const findQuery = { id }
6890
if (emptyAnswer) {
@@ -85,7 +107,8 @@ module.exports = async (_, { answer: { id, questionId, payload } }, context) =>
85107
questionId,
86108
questionnaireId: questionnaire.id,
87109
userId: me.id,
88-
payload
110+
payload,
111+
submitted: questionnaire.submitAnswersImmediately
89112
})
90113
}
91114
}

0 commit comments

Comments
 (0)