Added logic for quizz, need to connect everything
This commit is contained in:
parent
001ff8b5cb
commit
be01c925a3
44
ERD-Misael.erd
Normal file
44
ERD-Misael.erd
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<diagram version="1" name="ERD-Misael.erd">
|
||||||
|
<entities>
|
||||||
|
<data-source id="postgres-jdbc-195261858a3-67acab6d92533937">
|
||||||
|
<entity id="1" name="answers" fq-name="misael.answers" order="0" font="Segoe UI:9:0" x="40" y="50">
|
||||||
|
<path name="misael"/>
|
||||||
|
<path name="misael"/>
|
||||||
|
</entity>
|
||||||
|
<entity id="2" name="questions" fq-name="misael.questions" order="1" font="Segoe UI:9:0" x="279" y="40">
|
||||||
|
<path name="misael"/>
|
||||||
|
<path name="misael"/>
|
||||||
|
</entity>
|
||||||
|
<entity id="3" name="quizz" fq-name="misael.quizz" order="2" font="Segoe UI:9:0" x="510" y="127">
|
||||||
|
<path name="misael"/>
|
||||||
|
<path name="misael"/>
|
||||||
|
</entity>
|
||||||
|
<entity id="4" name="quizzf" fq-name="misael.quizzf" order="3" font="Segoe UI:9:0" x="279" y="224">
|
||||||
|
<path name="misael"/>
|
||||||
|
<path name="misael"/>
|
||||||
|
</entity>
|
||||||
|
<entity id="5" name="roles" fq-name="misael.roles" order="4" font="Segoe UI:9:0" x="709" y="418">
|
||||||
|
<path name="misael"/>
|
||||||
|
<path name="misael"/>
|
||||||
|
</entity>
|
||||||
|
<entity id="6" name="users" fq-name="misael.users" order="5" font="Segoe UI:9:0" x="709" y="254">
|
||||||
|
<path name="misael"/>
|
||||||
|
<path name="misael"/>
|
||||||
|
</entity>
|
||||||
|
<entity id="7" name="users_roles" fq-name="misael.users_roles" order="6" font="Segoe UI:9:0" x="510" y="352">
|
||||||
|
<path name="misael"/>
|
||||||
|
<path name="misael"/>
|
||||||
|
</entity>
|
||||||
|
</data-source>
|
||||||
|
</entities>
|
||||||
|
<relations>
|
||||||
|
<relation name="fk54dobrdq2u51m4u8s7kg0as8v" fq-name="misael.answers.fk54dobrdq2u51m4u8s7kg0as8v" type="fk" pk-ref="2" fk-ref="1"/>
|
||||||
|
<relation name="fkq12h25ynjok1m497gwos511te" fq-name="misael.questions.fkq12h25ynjok1m497gwos511te" type="fk" pk-ref="3" fk-ref="2"/>
|
||||||
|
<relation name="fk4ukbg2yaa93gs5nx1s5d9rqu4" fq-name="misael.quizzf.fk4ukbg2yaa93gs5nx1s5d9rqu4" type="fk" pk-ref="3" fk-ref="4"/>
|
||||||
|
<relation name="fkj6m8fwv7oqv74fcehir1a9ffy" fq-name="misael.users_roles.fkj6m8fwv7oqv74fcehir1a9ffy" type="fk" pk-ref="5" fk-ref="7"/>
|
||||||
|
<relation name="fkfeoogns8m4m4hvno1ttqb30wm" fq-name="misael.quizz.fkfeoogns8m4m4hvno1ttqb30wm" type="fk" pk-ref="6" fk-ref="3"/>
|
||||||
|
<relation name="fkuj3h8r3i4lnxukdqobapwbuq" fq-name="misael.quizzf.fkuj3h8r3i4lnxukdqobapwbuq" type="fk" pk-ref="6" fk-ref="4"/>
|
||||||
|
<relation name="fk2o0jvgh89lemvvo17cbqvdxaa" fq-name="misael.users_roles.fk2o0jvgh89lemvvo17cbqvdxaa" type="fk" pk-ref="6" fk-ref="7"/>
|
||||||
|
</relations>
|
||||||
|
</diagram>
|
||||||
@ -1,6 +1,10 @@
|
|||||||
package com.bernard.misael;
|
package com.bernard.misael;
|
||||||
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -21,10 +25,14 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|||||||
import com.bernard.misael.model.User;
|
import com.bernard.misael.model.User;
|
||||||
import com.bernard.misael.service.UserService;
|
import com.bernard.misael.service.UserService;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
public class SpringSecurity {
|
public class SpringSecurity {
|
||||||
|
|
||||||
|
public static final Logger LOG = Logger.getLogger(SpringSecurity.class.getName());
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserDetailsService userDetailsService;
|
private UserDetailsService userDetailsService;
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,10 @@ public class Answer {
|
|||||||
@JoinColumn(name = "question",nullable = false)
|
@JoinColumn(name = "question",nullable = false)
|
||||||
private Question question;
|
private Question question;
|
||||||
|
|
||||||
@Lob
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "form",nullable = false)
|
||||||
|
private QuizzForm form;
|
||||||
|
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
package com.bernard.misael.model;
|
package com.bernard.misael.model;
|
||||||
|
|
||||||
|
import com.bernard.misael.questions.QTypes;
|
||||||
|
import com.bernard.misael.questions.QuestionType;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -19,6 +25,9 @@ public class Question {
|
|||||||
@Column(name="id")
|
@Column(name="id")
|
||||||
private long id;
|
private long id;
|
||||||
|
|
||||||
|
@Column(nullable=false)
|
||||||
|
QTypes type;
|
||||||
|
|
||||||
@Column(nullable=false)
|
@Column(nullable=false)
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
@ -26,7 +35,21 @@ public class Question {
|
|||||||
@JoinColumn(name = "quizz",nullable = false)
|
@JoinColumn(name = "quizz",nullable = false)
|
||||||
private Quizz quizz;
|
private Quizz quizz;
|
||||||
|
|
||||||
@Lob
|
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
|
transient QuestionType qtype = null;
|
||||||
|
public QuestionType getQT() {
|
||||||
|
if(qtype==null){
|
||||||
|
ObjectMapper om = new ObjectMapper();
|
||||||
|
JsonNode jsNode;
|
||||||
|
try {
|
||||||
|
jsNode = om.readTree(value);
|
||||||
|
qtype = type.getConstructor().apply(jsNode);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return qtype;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
79
src/main/java/com/bernard/misael/questions/DccQuestion.java
Normal file
79
src/main/java/com/bernard/misael/questions/DccQuestion.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package com.bernard.misael.questions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
|
||||||
|
public class DccQuestion implements QuestionType{
|
||||||
|
|
||||||
|
String text;
|
||||||
|
String goodAnswer;
|
||||||
|
String[] wrongAnswers;
|
||||||
|
|
||||||
|
public DccQuestion(JsonNode data){
|
||||||
|
text = data.get("text").asText();
|
||||||
|
goodAnswer = data.get("good").asText();
|
||||||
|
JsonNode wrong = data.get("wrong");
|
||||||
|
wrongAnswers = new String[wrong.size()];
|
||||||
|
for(int i = 0; i<wrong.size();i++)
|
||||||
|
wrongAnswers[i] = wrong.get(i).asText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonNode clientQuestionData(int step, JsonNode answer) {
|
||||||
|
ObjectNode o = JsonNodeFactory.instance.objectNode();
|
||||||
|
switch (step) {
|
||||||
|
case 0:
|
||||||
|
o.put("text", this.text);
|
||||||
|
return o;
|
||||||
|
case 1:
|
||||||
|
Random r = new Random();
|
||||||
|
int k = answer.get("type").asInt();
|
||||||
|
switch(k) {
|
||||||
|
case 0:
|
||||||
|
return o;
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
List<String> answers = new ArrayList<>(k);
|
||||||
|
answers.add(goodAnswer);
|
||||||
|
for(int i = 0;i<k;i++)
|
||||||
|
answers.add(wrongAnswers[i]);
|
||||||
|
Collections.shuffle(answers, r);
|
||||||
|
o.putArray("answers").addAll(answers.stream().map(JsonNodeFactory.instance::textNode).collect(Collectors.toList()));
|
||||||
|
return o;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Invalid Answer type");
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Question step invalid : "+step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnswerResult clientAnswers(int step, JsonNode oldAnswer, JsonNode clientAnswer) {
|
||||||
|
ObjectNode o = JsonNodeFactory.instance.objectNode();
|
||||||
|
switch (step) {
|
||||||
|
case 0:
|
||||||
|
int answerType = clientAnswer.asInt();
|
||||||
|
if(answerType != 0 && answerType != 2 && answerType != 4)
|
||||||
|
throw new IllegalArgumentException("Illegal answer type: "+answerType);
|
||||||
|
o.put("type", answerType);
|
||||||
|
return new AnswerResult(o, false, 1);
|
||||||
|
case 1:
|
||||||
|
String answer = clientAnswer.asText();
|
||||||
|
o = oldAnswer.deepCopy();
|
||||||
|
o.put("answer", answer);
|
||||||
|
return new AnswerResult(o, true, -1);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Question step invalid : "+step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
27
src/main/java/com/bernard/misael/questions/QTypes.java
Normal file
27
src/main/java/com/bernard/misael/questions/QTypes.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package com.bernard.misael.questions;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum QTypes {
|
||||||
|
|
||||||
|
DCC(1,DccQuestion.class,DccQuestion::new);
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private Class<? extends QuestionType> type;
|
||||||
|
private Function<JsonNode,QuestionType> constructor;
|
||||||
|
|
||||||
|
public static QTypes findById(final int id) {
|
||||||
|
for(QTypes value : QTypes.values())
|
||||||
|
if (value.id == id)
|
||||||
|
return value;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
22
src/main/java/com/bernard/misael/questions/QuestionType.java
Normal file
22
src/main/java/com/bernard/misael/questions/QuestionType.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package com.bernard.misael.questions;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
public interface QuestionType {
|
||||||
|
|
||||||
|
JsonNode clientQuestionData(int step, JsonNode answer);
|
||||||
|
|
||||||
|
AnswerResult clientAnswers(int step, JsonNode oldAnswer, JsonNode clientAnswer);
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public static class AnswerResult {
|
||||||
|
private JsonNode newAnswer;
|
||||||
|
private boolean nextQuestion;
|
||||||
|
private int nextStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.bernard.misael.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Answer;
|
||||||
|
import com.bernard.misael.model.Question;
|
||||||
|
import com.bernard.misael.model.QuizzForm;
|
||||||
|
|
||||||
|
public interface AnswerRepository extends JpaRepository<Answer,Long> {
|
||||||
|
|
||||||
|
public Answer findByFormAndQuestion(QuizzForm qf, Question q);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.bernard.misael.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Question;
|
||||||
|
import com.bernard.misael.model.Quizz;
|
||||||
|
|
||||||
|
|
||||||
|
public interface QuestionRepository extends JpaRepository<Question,Long> {
|
||||||
|
|
||||||
|
public Question findByQuizzAndIndex(Quizz quizz, int index);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.bernard.misael.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Quizz;
|
||||||
|
import com.bernard.misael.model.QuizzForm;
|
||||||
|
import com.bernard.misael.model.User;
|
||||||
|
|
||||||
|
public interface QuizzFormRepository extends JpaRepository<QuizzForm,Long> {
|
||||||
|
|
||||||
|
public QuizzForm findByUserAndQuizz(User u, Quizz q);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.bernard.misael.repository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Quizz;
|
||||||
|
|
||||||
|
public interface QuizzRepository extends JpaRepository<Quizz,Long> {
|
||||||
|
|
||||||
|
public @NonNull Optional<Quizz> findById(@NonNull Long id);
|
||||||
|
|
||||||
|
}
|
||||||
11
src/main/java/com/bernard/misael/service/QuizzManager.java
Normal file
11
src/main/java/com/bernard/misael/service/QuizzManager.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package com.bernard.misael.service;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.User;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
|
||||||
|
public interface QuizzManager {
|
||||||
|
|
||||||
|
public JsonNode answer(User user, long quizzId,JsonNode data);
|
||||||
|
public JsonNode next(User user, long quizzId);
|
||||||
|
|
||||||
|
}
|
||||||
115
src/main/java/com/bernard/misael/service/QuizzManagerImpl.java
Normal file
115
src/main/java/com/bernard/misael/service/QuizzManagerImpl.java
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
package com.bernard.misael.service;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Answer;
|
||||||
|
import com.bernard.misael.model.Question;
|
||||||
|
import com.bernard.misael.model.Quizz;
|
||||||
|
import com.bernard.misael.model.QuizzForm;
|
||||||
|
import com.bernard.misael.model.User;
|
||||||
|
import com.bernard.misael.questions.QuestionType.AnswerResult;
|
||||||
|
import com.bernard.misael.repository.AnswerRepository;
|
||||||
|
import com.bernard.misael.repository.QuestionRepository;
|
||||||
|
import com.bernard.misael.repository.QuizzFormRepository;
|
||||||
|
import com.bernard.misael.repository.QuizzRepository;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class QuizzManagerImpl implements QuizzManager {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
QuizzFormRepository qfRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
QuizzRepository qRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
QuestionRepository questionRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AnswerRepository answerRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonNode answer(User user, long quizzId, JsonNode data) {
|
||||||
|
//TODO replace conversions String <-> JsonNode to Answer type
|
||||||
|
Quizz quizz = qRepository.findById(quizzId).get();
|
||||||
|
QuizzForm qf = qfRepository.findByUserAndQuizz(user, quizz);
|
||||||
|
|
||||||
|
if(qf.isDone())
|
||||||
|
throw new UnsupportedOperationException();//TODO add more precise exceptions here
|
||||||
|
int qindex = qf.getCurrentQuestion();
|
||||||
|
Question q = questionRepository.findByQuizzAndIndex(quizz,qindex);
|
||||||
|
int step = qf.getAnswerStep();
|
||||||
|
Answer answer = answerRepository.findByFormAndQuestion(qf, q);
|
||||||
|
|
||||||
|
ObjectMapper om = new ObjectMapper();
|
||||||
|
JsonNode answerData;
|
||||||
|
try {
|
||||||
|
answerData = om.readTree(answer.getValue());
|
||||||
|
AnswerResult result = q.getQT().clientAnswers(step, answerData, data);
|
||||||
|
if(result.isNextQuestion()) {
|
||||||
|
qf.setCurrentQuestion(qindex+1);
|
||||||
|
} else {
|
||||||
|
qf.setAnswerStep(result.getNextStep());
|
||||||
|
}
|
||||||
|
answer.setValue(om.writeValueAsString(result.getNewAnswer()));
|
||||||
|
//XXX Persist QF ?
|
||||||
|
ObjectNode out = JsonNodeFactory.instance.objectNode();
|
||||||
|
out.set("result", JsonNodeFactory.instance.textNode("ok"));
|
||||||
|
return out;
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
//TODO autogenerated
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonNode next(User user, long quizzId) {
|
||||||
|
Quizz quizz = qRepository.findById(quizzId).get();
|
||||||
|
QuizzForm qf = qfRepository.findByUserAndQuizz(user, quizz);
|
||||||
|
if(qf == null){
|
||||||
|
// We should create the quizzform
|
||||||
|
qf = newQuizzForm(user, quizz);
|
||||||
|
}
|
||||||
|
if(qf.isDone())
|
||||||
|
throw new UnsupportedOperationException();//TODO add more precise exceptions here
|
||||||
|
int qindex = qf.getCurrentQuestion();
|
||||||
|
Question q = questionRepository.findByQuizzAndIndex(quizz,qindex);
|
||||||
|
int step = qf.getAnswerStep();
|
||||||
|
Answer answer = answerRepository.findByFormAndQuestion(qf, q);
|
||||||
|
|
||||||
|
ObjectMapper om = new ObjectMapper();
|
||||||
|
JsonNode answerData;
|
||||||
|
try {
|
||||||
|
answerData = om.readTree(answer.getValue());
|
||||||
|
JsonNode qdata = q.getQT().clientQuestionData(step, answerData);
|
||||||
|
|
||||||
|
ObjectNode out = JsonNodeFactory.instance.objectNode();
|
||||||
|
out.set("index", JsonNodeFactory.instance.numberNode(qindex));
|
||||||
|
out.set("step", JsonNodeFactory.instance.numberNode(step));
|
||||||
|
out.set("index", qdata);
|
||||||
|
return out;
|
||||||
|
} catch (JsonProcessingException e){
|
||||||
|
//XXX autogenerated
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public QuizzForm newQuizzForm(User user, Quizz quizz) {
|
||||||
|
QuizzForm qf = new QuizzForm();
|
||||||
|
qf.setUser(user);
|
||||||
|
qf.setQuizz(quizz);
|
||||||
|
qf.setDone(false);
|
||||||
|
qf.setCurrentQuestion(0);
|
||||||
|
qf.setAnswerStep(0);
|
||||||
|
//XXX Persist QF ?
|
||||||
|
return qf;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package com.bernard.misael.service.exception;
|
||||||
|
|
||||||
|
public class ShouldNotAnswerNowException extends Exception{
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,5 +1,14 @@
|
|||||||
package com.bernard.misael.web;
|
package com.bernard.misael.web;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.HttpStatusCode;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
@ -17,6 +26,7 @@ import jakarta.validation.Valid;
|
|||||||
@Controller
|
@Controller
|
||||||
public class AuthController {
|
public class AuthController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
public AuthController(UserService userService) {
|
public AuthController(UserService userService) {
|
||||||
@ -71,4 +81,19 @@ public class AuthController {
|
|||||||
userService.saveUser(userDto);
|
userService.saveUser(userDto);
|
||||||
return "redirect:/adduser?success";
|
return "redirect:/adduser?success";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/create-mysaa-user")
|
||||||
|
public ResponseEntity<String> checkMysaaExists() {
|
||||||
|
if(userService.findUserByName("mysaa") == null) {
|
||||||
|
UserDto u = new UserDto();
|
||||||
|
Random r = new Random();
|
||||||
|
UUID pass = new UUID(r.nextLong(),r.nextLong());
|
||||||
|
u.setName("mysaa");
|
||||||
|
u.setPassword(pass.toString());
|
||||||
|
userService.saveUser(u);
|
||||||
|
Logger.getLogger(AuthController.class.getName()).warning("Created user mysaa with password "+pass.toString());
|
||||||
|
}
|
||||||
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,15 +3,22 @@ package com.bernard.misael.web;
|
|||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
import com.bernard.misael.model.User;
|
import com.bernard.misael.model.User;
|
||||||
import com.bernard.misael.repository.UserRepository;
|
import com.bernard.misael.repository.UserRepository;
|
||||||
import com.bernard.misael.service.UserService;
|
import com.bernard.misael.service.QuizzManager;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ -21,6 +28,9 @@ public class QuestionsController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
UserRepository ur;
|
UserRepository ur;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
QuizzManager qm;
|
||||||
|
|
||||||
@GetMapping("/quizz")
|
@GetMapping("/quizz")
|
||||||
/*
|
/*
|
||||||
* List all quizz
|
* List all quizz
|
||||||
@ -45,4 +55,35 @@ public class QuestionsController {
|
|||||||
return "forms.html";
|
return "forms.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/form/{q}")
|
||||||
|
public String formpage(@PathVariable("q") long quizzId, Principal p, Model m) {
|
||||||
|
User u = null;
|
||||||
|
if (p!=null)
|
||||||
|
u = ur.findByName(p.getName());
|
||||||
|
//XXX test that user can answer quizz
|
||||||
|
m.addAttribute("formid", quizzId);
|
||||||
|
|
||||||
|
return "form";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/question/{q}")
|
||||||
|
public ResponseEntity<JsonNode> question(@PathVariable("q") long quizzId, Principal p) {
|
||||||
|
User u = null;
|
||||||
|
if (p!=null)
|
||||||
|
u = ur.findByName(p.getName());
|
||||||
|
JsonNode out = qm.next(u, quizzId);
|
||||||
|
return new ResponseEntity<>(out, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/answer/{q}")
|
||||||
|
public JsonNode answer(@PathVariable("q") long quizzId, @RequestBody JsonNode data, Principal p) {
|
||||||
|
User u = null;
|
||||||
|
if (p!=null)
|
||||||
|
u = ur.findByName(p.getName());
|
||||||
|
JsonNode out = qm.answer(u, quizzId, data);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
spring:
|
spring:
|
||||||
datasource:
|
datasource:
|
||||||
url: jdbc:mysql://127.0.0.1:10051/misael
|
url: jdbc:postgres://127.0.0.1:10051/misael
|
||||||
username: misael
|
username: misael
|
||||||
password: misael-dev
|
password: misael-dev
|
||||||
hikari:
|
hikari:
|
||||||
@ -10,18 +10,25 @@ spring:
|
|||||||
locations: classpath:db/migration/structure, classpath:db/migration/data
|
locations: classpath:db/migration/structure, classpath:db/migration/data
|
||||||
validate-on-migrate: true
|
validate-on-migrate: true
|
||||||
default-schema: misael
|
default-schema: misael
|
||||||
|
create-schemas: true
|
||||||
|
session:
|
||||||
|
jdbc:
|
||||||
|
initialize-schema: always
|
||||||
|
security:
|
||||||
|
user:
|
||||||
|
name: mysaa
|
||||||
|
|
||||||
# jpa:
|
jpa:
|
||||||
# properties:
|
properties:
|
||||||
# javax:
|
javax:
|
||||||
# persistence:
|
persistence:
|
||||||
# schema-generation:
|
schema-generation:
|
||||||
# create-source: metadata
|
create-source: metadata
|
||||||
# scripts:
|
scripts:
|
||||||
# action: update
|
action: update
|
||||||
# create-target: db-migration.sql
|
create-target: db-migration.sql
|
||||||
# database:
|
database:
|
||||||
# action: none
|
action: none
|
||||||
# hibernate:
|
hibernate:
|
||||||
# ddl-auto: none
|
ddl-auto: none
|
||||||
# generate-ddl: true
|
generate-ddl: true
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
create table answers (id bigint generated by default as identity, value oid, question bigint not null, primary key (id));
|
create table answers (id bigint generated by default as identity, value varchar(255), form bigint not null, question bigint not null, primary key (id));
|
||||||
create table questions (id bigint generated by default as identity, index integer not null, value oid, quizz bigint not null, primary key (id));
|
create table questions (id bigint generated by default as identity, index integer not null, type smallint not null check (type between 0 and 0), value varchar(255), quizz bigint not null, primary key (id));
|
||||||
create table quizz (id bigint generated by default as identity, is_public boolean default false not null, name varchar(255) not null, question_count integer default 0 not null, owner bigint, primary key (id));
|
create table quizz (id bigint generated by default as identity, is_public boolean default false not null, name varchar(255) not null, question_count integer default 0 not null, owner bigint, primary key (id));
|
||||||
create table quizzf (id bigint generated by default as identity, answer_step integer not null, current_question integer not null, done boolean not null, quizz bigint not null, answerer bigint not null, primary key (id));
|
create table quizzf (id bigint generated by default as identity, answer_step integer not null, current_question integer not null, done boolean not null, quizz bigint not null, answerer bigint not null, primary key (id));
|
||||||
alter table if exists quizz drop constraint if exists UKc1plspc0ecmwqqpfaf24avb4c;
|
alter table if exists quizz drop constraint if exists UKc1plspc0ecmwqqpfaf24avb4c;
|
||||||
alter table if exists quizz add constraint UKc1plspc0ecmwqqpfaf24avb4c unique (name);
|
alter table if exists quizz add constraint UKc1plspc0ecmwqqpfaf24avb4c unique (name);
|
||||||
|
alter table if exists answers add constraint FKjtutlsv5n10071rq261lcjovm foreign key (form) references quizzf;
|
||||||
alter table if exists answers add constraint FK54dobrdq2u51m4u8s7kg0as8v foreign key (question) references questions;
|
alter table if exists answers add constraint FK54dobrdq2u51m4u8s7kg0as8v foreign key (question) references questions;
|
||||||
alter table if exists questions add constraint FKq12h25ynjok1m497gwos511te foreign key (quizz) references quizz;
|
alter table if exists questions add constraint FKq12h25ynjok1m497gwos511te foreign key (quizz) references quizz;
|
||||||
alter table if exists quizz add constraint FKfeoogns8m4m4hvno1ttqb30wm foreign key (owner) references users;
|
alter table if exists quizz add constraint FKfeoogns8m4m4hvno1ttqb30wm foreign key (owner) references users;
|
||||||
alter table if exists quizzf add constraint FK4ukbg2yaa93gs5nx1s5d9rqu4 foreign key (quizz) references quizz;
|
alter table if exists quizzf add constraint FK4ukbg2yaa93gs5nx1s5d9rqu4 foreign key (quizz) references quizz;
|
||||||
alter table if exists quizzf add constraint FKuj3h8r3i4lnxukdqobapwbuq foreign key (answerer) references users;
|
alter table if exists quizzf add constraint FK7gvxodb5t2n68ot577ig9u3w6 foreign key (answerer) references users;
|
||||||
13
src/main/resources/templates/form.html
Normal file
13
src/main/resources/templates/form.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<div th:replace="~{html-head}"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div th:replace="~{header}"/>
|
||||||
|
<main>
|
||||||
|
Youhou ! (Y devrait y avoir le form ici ^^) <span th:text="${formid}"/>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -9,7 +9,7 @@
|
|||||||
<main>
|
<main>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Premier item ?</li>
|
<li>Premier item ?</li>
|
||||||
<li th:each="q : ${quizz}"><a th:href="@{/questions/newform/{id}(id=${q.id})}">Quizz <span th:text="${q.name}"/></a></li>
|
<li th:each="q : ${quizz}"><a th:href="@{/questions/form/{id}(id=${q.id})}">Quizz <span th:text="${q.name}"/></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user