Optimize code quality

Refactor questionnaire handler and questionnaire model.
This commit is contained in:
Marcus Kammer 2025-02-19 15:59:42 +01:00
parent 965e1be803
commit f0042b2f43
Signed by: marcuskammer
GPG key ID: C374817BE285268F
3 changed files with 70 additions and 45 deletions

View file

@ -12,7 +12,15 @@
#:survey-properties-description #:survey-properties-description
#:survey-html #:survey-html
#:questionnaire #:questionnaire
#:questionnaire-uid
#:questionnaire-name #:questionnaire-name
#:questionnaire-type #:questionnaire-type
#:questionnaire-lang #:questionnaire-lang
#:questionnaire-timestamp-created
#:questionnaire-post-params
#:questionnaire-to-list
#:questionnaire-survey-uid
#:questionnaire-data-file
#:questionnaire-write-file
#:make-questionnaire
#:create-questionnaire-data)) #:create-questionnaire-data))

View file

@ -1,13 +1,55 @@
;;; -*- mode: lisp; coding: utf-8; -*- ;;; -*- mode: lisp; coding: utf-8; -*-
(in-package :ml-survey/models) (in-package :ml-survey/models)
(defclass questionnaire () (defclass questionnaire ()
((name :initarg :name :reader questionnaire-name) ((uid :initarg :uid
(type :initarg :type :reader questionnaire-type) :reader questionnaire-uid
(lang :initarg :lang :reader questionnaire-lang))) :documentation "Unique identifier for this questionnaire instance (auto-generated).")
(name :initarg :name
:reader questionnaire-name
:documentation "The display name of the questionnaire.")
(type :initarg :type
:reader questionnaire-type
:documentation "The questionnaire type. (e.g. likert, mixed)")
(lang :initarg :lang
:reader questionnaire-lang
:documentation "Language code for the questionnaire.")
(data-file :initarg :data-file
:accessor questionnaire-data-file
:documentation "Location of data file as pathname.")
(survey-uid :initarg :survey-uid
:reader questionnaire-survey-uid
:documentation "Unique identifier for the survey.")
(post-params :initarg :post-params
:accessor questionnaire-post-params
:documentation "Additional parameters for post-processing.")
(timestamp-created :initarg :timestamp-created
:reader questionnaire-timestamp-created
:documentation "Creation/modification time (auto-generated).")))
(defmethod create-questionnaire-data ((q questionnaire) post-params) (defmethod initialize-instance :after ((q questionnaire) &key)
(list :type (questionnaire-type q) (with-slots (timestamp-created uid data-file survey-uid) q
:name (questionnaire-name q) (setf timestamp-created (ml-survey/app:today+now))
:timestamp (ml-survey/app:today+now) (setf uid (ml-survey/app:generate-uuid))
:post-data post-params)) (setf data-file (pathname (format nil "~a~a/~a.lisp"
(ml-survey/fileops:ensure-surveys-dir)
survey-uid
uid)))))
(defmethod make-questionnaire (&rest initargs &key &allow-other-keys)
"Create a new questionnaire instance.
Accepts all valid initargs for questionnaire class."
(apply #'make-instance 'questionnaire initargs))
(defmethod questionnaire-to-list ((q questionnaire))
(loop for slot in (closer-mop:class-slots (class-of q))
for slot-name = (closer-mop:slot-definition-name slot)
when (slot-boundp q slot-name)
nconc (list (intern (symbol-name slot-name) :keyword)
(slot-value q slot-name))))
(defmethod questionnaire-write-file ((q questionnaire))
(ml-survey/fileops:write-to-file (questionnaire-data-file q)
(questionnaire-to-list q)))

View file

@ -1,4 +1,5 @@
;;; -*- mode: lisp; coding: utf-8; -*- ;;; -*- mode: lisp; coding: utf-8; -*-
(in-package :ml-survey/questionnaire) (in-package :ml-survey/questionnaire)
(defun questionnaire-uri-p (uri) (defun questionnaire-uri-p (uri)
@ -12,53 +13,27 @@
(defun questionnaire-uri (request) (defun questionnaire-uri (request)
(questionnaire-uri-p (hunchentoot:request-uri request))) (questionnaire-uri-p (hunchentoot:request-uri request)))
(defvar *likert-scale*
'(:sus :nps :ueq :mecue :seq :umux :pwu :smeq :intui :visawi))
(defun likert-p (q)
(let ((q-keyword (if (stringp q) (intern (string-upcase q) :keyword) q)))
(if (member q-keyword *likert-scale*)
t
nil)))
(defun process-questionnaire-get (q) (defun process-questionnaire-get (q)
(declare (type questionnaire q)) (declare (type questionnaire q))
(view q)) (view q))
(defun determine-questionnaire-type (q-name) (defun process-questionnaire-post (post-params q)
"Determine the type of questionnaire based on its name."
(if (likert-p q-name) "likert" "mixed"))
(defun questionnaire-write-to-file (data-file post-params q)
(ml-survey/fileops:write-to-file data-file (create-questionnaire-data q post-params)))
(defun process-questionnaire-post (post-params survey q)
(declare (type questionnaire q)) (declare (type questionnaire q))
(let* ((survey-id (survey-id survey)) (setf (questionnaire-post-params q) post-params)
(questionnaire-id (ml-survey/app:generate-uuid)) (questionnaire-write-to-file q)
(questionnaire-data-file (ml-survey/fileops:ensure-data-file-exist survey-id questionnaire-id))) (view-submit q))
(questionnaire-write-to-file questionnaire-data-file post-params q)
(view-submit q)))
(defun extract-uri-param (param) (defun extract-uri-param (param)
(ml-survey/app:extract-from (hunchentoot:request-uri*) param)) (ml-survey/app:extract-from (hunchentoot:request-uri*) param))
(defun create-survey (survey-id) (defun process-request (questionnaire)
(make-instance 'survey :id survey-id))
(defun process-request (survey questionnaire)
(ecase (hunchentoot:request-method*) (ecase (hunchentoot:request-method*)
(:get (process-questionnaire-get questionnaire)) (:get (process-questionnaire-get questionnaire))
(:post (process-questionnaire-post (hunchentoot:post-parameters*) survey questionnaire)))) (:post (process-questionnaire-post (hunchentoot:post-parameters*) questionnaire))))
(define-easy-handler (questionnaire-handler :uri #'questionnaire-uri) () (define-easy-handler (questionnaire-handler :uri #'questionnaire-uri) ()
(let* ((survey-id (extract-uri-param :survey-id)) (let* ((survey-uid (parse-integer (extract-uri-param :survey-id)))
(lang (extract-uri-param :lang)) (questionnaire (make-questionnaire :survey-uid survey-id
(name (extract-uri-param :questionnaire)) :lang (extract-uri-param :lang)
(type (determine-questionnaire-type name)) :name (extract-uri-param :questionnaire))))
(survey (create-survey survey-id)) (process-request questionnaire)))
(questionnaire (make-instance 'questionnaire
:name name
:type type
:lang lang)))
(process-request survey questionnaire)))