diff --git a/.gitignore b/.gitignore
index af36aab869b1b17b749f3b607ce1bea22c38243c..3f1d2a8e68a819c621bb2be951a4159ace5fdb30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
 *.csr
 *.key
 *.pem
+
+.ipynb_checkpoints/
diff --git a/backend/app/crud.py b/backend/app/crud.py
index 5afe06ed887f7ba6df7409e52a7e178493d475bf..cbada3362036bfca706d0fb4d06bb1999dfc46ed 100644
--- a/backend/app/crud.py
+++ b/backend/app/crud.py
@@ -320,12 +320,8 @@ def delete_survey_question(db: Session, survey_question_id: int):
     db.commit()
 
 
-def create_survey_response(
-    db: Session, survey_id: int, survey_response: schemas.SurveyResponseCreate
-):
-    db_survey_response = models.SurveyResponse(
-        survey_id=survey_id, **survey_response.dict()
-    )
+def create_survey_response(db: Session, survey_response: schemas.SurveyResponseCreate):
+    db_survey_response = models.SurveyResponse(**survey_response.dict())
     db.add(db_survey_response)
     db.commit()
     db.refresh(db_survey_response)
diff --git a/backend/app/main.py b/backend/app/main.py
index ce99181aee968541a272f2cb9dbc236778760994..db7091947ea174c7d430eec16b8d541f72a18d00 100644
--- a/backend/app/main.py
+++ b/backend/app/main.py
@@ -965,17 +965,13 @@ def delete_survey_question(
 
 @surveyRouter.post("/responses", status_code=status.HTTP_201_CREATED)
 def create_survey_response(
-    survey_id: int,
     response: schemas.SurveyResponseCreate,
     db: Session = Depends(get_db),
 ):
-    if not crud.get_survey(db, survey_id):
-        raise HTTPException(status_code=404, detail="Survey not found")
-
-    return crud.create_survey_response(db, survey_id, response).id
+    return crud.create_survey_response(db, response).id
 
 
-@surveyRouter.get("/responses", response_model=list[schemas.SurveyResponse])
+@surveyRouter.get("/responses/{survey_id}", response_model=list[schemas.SurveyResponse])
 def get_survey_responses(
     survey_id: int,
     db: Session = Depends(get_db),
diff --git a/backend/app/models.py b/backend/app/models.py
index c84fbc1ae46a1dd3ad6864920fc8f77bb5901971..46c127185eeaa41e43468ff0008a354dfd5cc4c7 100644
--- a/backend/app/models.py
+++ b/backend/app/models.py
@@ -187,9 +187,10 @@ class SurveyResponse(Base):
 
     id = Column(Integer, primary_key=True, index=True)
     uuid = Column(String)
+    sid = Column(String)
     created_at = Column(DateTime, default=datetime.datetime.now)
     survey_id = Column(Integer, ForeignKey("survey_surveys.id"))
     group_id = Column(Integer, ForeignKey("survey_groups.id"))
     question_id = Column(Integer, ForeignKey("survey_questions.id"))
-    option = Column(Integer)
+    selected_id = Column(Integer)
     response_time = Column(Float)
diff --git a/backend/app/schemas.py b/backend/app/schemas.py
index 615702156c1812e994ce549ce7235379512d8aa9..2b4ec307efb9d773048653add62c74d67a4715cd 100644
--- a/backend/app/schemas.py
+++ b/backend/app/schemas.py
@@ -204,19 +204,21 @@ class SurveySurveyAddGroup(BaseModel):
 
 class SurveyResponseCreate(BaseModel):
     uuid: str
+    sid: str
     survey_id: int
     group_id: int
     question_id: int
-    option: int
+    selected_id: int
     response_time: float
 
 
 class SurveyResponse(BaseModel):
     id: int
     uuid: str
+    sid: str
     created_at: datetime.datetime
     survey_id: int
     group_id: int
     question_id: int
-    option: int
+    selected_id: int
     response_time: float
diff --git a/frontend/package.json b/frontend/package.json
index 06f92529c194f86f11720db8694479a86c0565e5..352ca2baa2fc12a76287e6564349d05d9ae5f9d9 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -47,7 +47,6 @@
 	"type": "module",
 	"dependencies": {
 		"emoji-picker-element": "^1.21.3",
-		"jquery": "^3.7.1",
 		"svelte-gravatar": "^1.0.3",
 		"svelte-i18n": "^4.0.0",
 		"svelte-material-icons": "^3.0.5",
diff --git a/frontend/src/lib/api/survey.ts b/frontend/src/lib/api/survey.ts
index e2fd5dca12f681a902d742ba35cb696c05fa32c8..8ac70e3b4eae6f900f2af303a3f39232f3a75537 100644
--- a/frontend/src/lib/api/survey.ts
+++ b/frontend/src/lib/api/survey.ts
@@ -14,15 +14,20 @@ export async function getSurveyAPI(survey_id: number) {
 
 export async function sendSurveyResponseAPI(
 	uuid: string,
+	sid: string,
 	survey_id: number,
+	group_id: number,
 	question_id: number,
 	option_id: number,
 	response_time: number
 ) {
-	const response = await axiosInstance.post(`/surveys/${survey_id}/responses`, {
+	const response = await axiosInstance.post(`/surveys/responses`, {
 		uuid,
+		sid,
+		survey_id,
 		question_id,
-		option_id,
+		group_id,
+		selected_id: option_id,
 		response_time
 	});
 
diff --git a/frontend/src/lib/types/surveyOption.ts b/frontend/src/lib/types/surveyOption.ts
deleted file mode 100644
index 2ab3663744f70d623ac398fed4967ddfeaeae544..0000000000000000000000000000000000000000
--- a/frontend/src/lib/types/surveyOption.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { toastAlert } from '$lib/utils/toasts';
-
-export default class SurveyOption {
-	private _id: number;
-	private _question_id: number;
-	private _correct: boolean;
-	private _type: string;
-	private _value: string;
-
-	constructor(id: number, question_id: number, correct: boolean, type: string, value: string) {
-		this._id = id;
-		this._question_id = question_id;
-		this._correct = correct;
-		this._type = type;
-		this._value = value;
-	}
-
-	get id(): number {
-		return this._id;
-	}
-
-	get question_id(): number {
-		return this._question_id;
-	}
-
-	get correct(): boolean {
-		return this._correct;
-	}
-
-	get type(): string {
-		return this._type;
-	}
-
-	get value(): string {
-		return this._value;
-	}
-
-	static parse(data: any): SurveyOption | null {
-		if (data === null) {
-			toastAlert('Failed to parse survey option data');
-			return null;
-		}
-
-		return new SurveyOption(data.id, data.question_id, data.correct, data.type, data.value);
-	}
-
-	static parseAll(data: any): SurveyOption[] {
-		if (data === null) {
-			toastAlert('Failed to parse survey option data');
-			return [];
-		}
-
-		const options: SurveyOption[] = [];
-		for (const option of data) {
-			options.push(SurveyOption.parse(option)!);
-		}
-
-		return options;
-	}
-}
diff --git a/frontend/src/lib/types/surveyQuestion.ts b/frontend/src/lib/types/surveyQuestion.ts
index 1d7e47bcefba59856ed88a7f201769662d90d17e..eb85c8ca384b8bda414bb79f0f4c2c4683892298 100644
--- a/frontend/src/lib/types/surveyQuestion.ts
+++ b/frontend/src/lib/types/surveyQuestion.ts
@@ -1,27 +1,15 @@
 import { toastAlert } from '$lib/utils/toasts';
-import SurveyOption from './surveyOption';
 
 export default class SurveyQuestion {
 	private _id: number;
 	private _group_id: number;
-	private _title: string;
-	private _question_type: string;
-	private _question_value: string;
-	private _options: SurveyOption[];
+	private _question: string;
+	private _options: string[];
 
-	constructor(
-		id: number,
-		group_id: number,
-		title: string,
-		question_type: string,
-		question_value: string,
-		options: SurveyOption[]
-	) {
+	constructor(id: number, group_id: number, question: string, options: string[]) {
 		this._id = id;
 		this._group_id = group_id;
-		this._title = title;
-		this._question_type = question_type;
-		this._question_value = question_value;
+		this._question = question;
 		this._options = options;
 	}
 
@@ -33,19 +21,11 @@ export default class SurveyQuestion {
 		return this._group_id;
 	}
 
-	get title(): string {
-		return this._title;
+	get question(): string {
+		return this._question;
 	}
 
-	get question_type(): string {
-		return this._question_type;
-	}
-
-	get question_value(): string {
-		return this._question_value;
-	}
-
-	get options(): SurveyOption[] {
+	get options(): string[] {
 		return this._options;
 	}
 
@@ -55,16 +35,17 @@ export default class SurveyQuestion {
 			return null;
 		}
 
-		const options = SurveyOption.parseAll(data.options);
+		let options = [];
+		if (data.option1) options.push(data.option1);
+		if (data.option2) options.push(data.option2);
+		if (data.option3) options.push(data.option3);
+		if (data.option4) options.push(data.option4);
+		if (data.option5) options.push(data.option5);
+		if (data.option6) options.push(data.option6);
+		if (data.option7) options.push(data.option7);
+		if (data.option8) options.push(data.option8);
 
-		return new SurveyQuestion(
-			data.id,
-			data.group_id,
-			data.title,
-			data.question_type,
-			data.question_value,
-			options
-		);
+		return new SurveyQuestion(data.id, data.group_id, data.question, options);
 	}
 
 	static parseAll(data: any): SurveyQuestion[] {
diff --git a/frontend/src/routes/surveys/[id]/+layout.server.ts b/frontend/src/routes/surveys/[id]/+layout.server.ts
new file mode 100644
index 0000000000000000000000000000000000000000..073588193a9d322187faea35cc861826b59656b0
--- /dev/null
+++ b/frontend/src/routes/surveys/[id]/+layout.server.ts
@@ -0,0 +1,26 @@
+import { type ServerLoad, redirect } from '@sveltejs/kit';
+
+const publicly_allowed = ['/login', '/register', '/tests/vocabulary', '/surveys'];
+
+const isPublic = (path: string) => {
+	for (const allowed of publicly_allowed) {
+		if (path.startsWith(allowed)) {
+			return true;
+		}
+	}
+	return false;
+};
+
+export const load: ServerLoad = async ({ locals, url }) => {
+	if (locals.user == null || locals.user == undefined) {
+		if (!isPublic(url.pathname)) {
+			redirect(307, `/login`);
+		}
+	}
+
+	return {
+		user: locals.user,
+		session: locals.session,
+		locale: locals.locale
+	};
+};
diff --git a/frontend/src/routes/surveys/[id]/+layout.ts b/frontend/src/routes/surveys/[id]/+layout.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e87df190ee4256ad1c12a6925e66302bf57eeee3
--- /dev/null
+++ b/frontend/src/routes/surveys/[id]/+layout.ts
@@ -0,0 +1,16 @@
+export const ssr = true;
+
+import type { Load } from '@sveltejs/kit';
+import { loadTranslations } from '$lib/services/i18n';
+
+export const load: Load = async ({ url, data }) => {
+	const { user, session, locale } = data;
+	const { pathname } = url;
+
+	await loadTranslations(locale, pathname);
+
+	return {
+		user: user,
+		token: session
+	};
+};
diff --git a/frontend/src/routes/surveys/[id]/+page.svelte b/frontend/src/routes/surveys/[id]/+page.svelte
index b911f1346a4cbcb06d78684b819f411a64978504..151014c4a446224b6603efc75307c066160490bb 100644
--- a/frontend/src/routes/surveys/[id]/+page.svelte
+++ b/frontend/src/routes/surveys/[id]/+page.svelte
@@ -2,7 +2,6 @@
 	import { sendSurveyResponseAPI } from '$lib/api/survey';
 
 	import Survey from '$lib/types/survey.js';
-	import type SurveyOption from '$lib/types/surveyOption';
 	import { t } from '$lib/services/i18n';
 	import { toastWarning } from '$lib/utils/toasts.js';
 	import { get } from 'svelte/store';
@@ -11,12 +10,14 @@
 	export let data;
 
 	const survey: Survey = data.survey!;
-	const user = data.user ? User.parse(data.user) : null;
+	const user = data.user ? User.parse(JSON.parse(data.user)) : null;
 
-	let uuid = user?.email || '';
+	let sid =
+		Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
 	let startTime = new Date().getTime();
 
 	$: step = user ? 1 : 0;
+	$: uuid = user?.email || '';
 
 	$: currentGroupId = 0;
 	$: currentGroup = survey.groups[currentGroupId];
@@ -24,13 +25,15 @@
 	$: currentQuestionId = 0;
 	$: currentQuestion = questionsRandomized[currentQuestionId];
 
-	async function selectOption(option: SurveyOption) {
+	async function selectOption(option: string) {
 		if (
 			!(await sendSurveyResponseAPI(
 				uuid,
+				sid,
 				survey.id,
+				currentGroupId,
 				currentQuestionId,
-				option.id,
+				currentQuestion.options.findIndex((o: string) => o === option),
 				(new Date().getTime() - startTime) / 1000
 			))
 		) {
@@ -94,20 +97,16 @@
 		<button class="button" on:click={() => step++}>{$t('button.next')}</button>
 	</div>
 {:else if step == 2}
-	<h1>Survey: {survey.title}</h1>
-	<p>Group: {currentGroup?.title}</p>
-
+	{@const type = currentQuestion.question.split(':')[0]}
+	{@const value = currentQuestion.question.split(':').slice(1).join(':')}
 	<div class="mx-auto mt-16 text-center">
-		<p class="text-xl mb-4">
-			{currentQuestion?.title}
-		</p>
-		{#if currentQuestion?.question_type == 'text'}
-			<pre>{currentQuestion?.question_value}</pre>
-		{:else if currentQuestion?.question_type == 'image'}
-			<img src={currentQuestion?.question_value} alt="Question" />
-		{:else if currentQuestion?.question_type == 'audio'}
+		{#if type == 'text'}
+			<pre>{value}</pre>
+		{:else if type == 'image'}
+			<img src={value} alt="Question" />
+		{:else if type == 'audio'}
 			<audio controls autoplay class="rounded-lg mx-auto">
-				<source src={currentQuestion?.question_value} type="audio/mpeg" />
+				<source src={value} type="audio/mpeg" />
 				Your browser does not support the audio element.
 			</audio>
 		{/if}
@@ -115,7 +114,9 @@
 
 	<div class="mx-auto mt-16">
 		<div class="flex justify-around min-w-[600px] space-x-10">
-			{#each currentQuestion?.options as option (option.id)}
+			{#each currentQuestion?.options as option (option)}
+				{@const type = option.split(':')[0]}
+				{@const value = option.split(':').slice(1).join(':')}
 				<div
 					class="h-48 w-48 overflow-hidden rounded-lg border border-black"
 					on:click={() => selectOption(option)}
@@ -123,21 +124,21 @@
 					on:keydown={() => selectOption(option)}
 					tabindex="0"
 				>
-					{#if option.type === 'text'}
+					{#if type === 'text'}
 						<span
 							class="flex items-center justify-center h-full w-full text-2xl transition-transform duration-200 ease-in-out transform hover:scale-105"
 						>
-							{option.value}
+							{value}
 						</span>
-					{:else if option.type === 'image'}
+					{:else if type === 'image'}
 						<img
-							src={option.value}
-							alt="Option {option.id}"
+							src={value}
+							alt="Option {option}"
 							class="object-cover h-full w-full transition-transform duration-200 ease-in-out transform hover:scale-105"
 						/>
-					{:else if option.type == 'audio'}
+					{:else if type == 'audio'}
 						<audio controls class="w-full" on:click|preventDefault|stopPropagation>
-							<source src={option.value} type="audio/mpeg" />
+							<source src={value} type="audio/mpeg" />
 							Your browser does not support the audio element.
 						</audio>
 					{/if}
diff --git a/frontend/src/routes/surveys/[id]/+page.ts b/frontend/src/routes/surveys/[id]/+page.ts
index 03742fbe15fa40250a8d5c840b6d8a0fcef5f96a..7ada027448295fe88193014b3e7387c544c24c88 100644
--- a/frontend/src/routes/surveys/[id]/+page.ts
+++ b/frontend/src/routes/surveys/[id]/+page.ts
@@ -1,10 +1,13 @@
 import { getSurveyAPI } from '$lib/api/survey';
 import Survey from '$lib/types/survey';
+import type { Load } from '@sveltejs/kit';
 
 export const ssr = false;
 
-export const load = async ({ params }: { params: Record<string, string> }) => {
+export const load: Load = async ({ params, parent }) => {
+	const data = await parent();
 	const survey_id = parseInt(params.id);
+	const { user, token } = data;
 
 	if (isNaN(survey_id)) {
 		return {
@@ -27,7 +30,9 @@ export const load = async ({ params }: { params: Record<string, string> }) => {
 	}
 
 	return {
-		survey_id: survey_id,
-		survey: survey
+		survey_id,
+		survey,
+		user,
+		token
 	};
 };
diff --git a/scripts/surveys/.ipynb_checkpoints/groups-checkpoint.csv b/scripts/surveys/.ipynb_checkpoints/groups-checkpoint.csv
deleted file mode 100644
index 6d43a0cfef660a5bf7d98893f3d2e4d9085bf9e0..0000000000000000000000000000000000000000
--- a/scripts/surveys/.ipynb_checkpoints/groups-checkpoint.csv
+++ /dev/null
@@ -1,3 +0,0 @@
-group_id,question_id,question,option1,option2
-1,1,,,
-1,2,How old are you?,18-24,25-34
diff --git a/scripts/surveys/.ipynb_checkpoints/survey_maker-checkpoint.ipynb b/scripts/surveys/.ipynb_checkpoints/survey_maker-checkpoint.ipynb
deleted file mode 100644
index de0799cd1ad09017db7264f9f480204bde0640b4..0000000000000000000000000000000000000000
--- a/scripts/surveys/.ipynb_checkpoints/survey_maker-checkpoint.ipynb
+++ /dev/null
@@ -1,366 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 142,
-   "id": "5f682366-5ab6-4418-84b9-b971266af67f",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import requests\n",
-    "import numpy as np\n",
-    "import os"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 145,
-   "id": "e8af376d-ce09-4537-a724-2028777adef3",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "API_URL = 'http://127.0.0.1:8000'\n",
-    "LOCAL_ITEMS_FOLDER = '../../frontend/static/surveys/items'\n",
-    "REMOTE_ITEMS_FOLDER = '/surveys/items'"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 151,
-   "id": "30116c8a-a0a6-4dc7-9b69-8afb50a6252e",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "df_items = pd.read_csv('items.csv',dtype = str)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 152,
-   "id": "265ccfaa-e86d-460c-be36-1bdfbd2c433f",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>id</th>\n",
-       "      <th>question</th>\n",
-       "      <th>correct</th>\n",
-       "      <th>option1</th>\n",
-       "      <th>option2</th>\n",
-       "      <th>option3</th>\n",
-       "      <th>option4</th>\n",
-       "      <th>option5</th>\n",
-       "      <th>option6</th>\n",
-       "      <th>option7</th>\n",
-       "      <th>option8</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>1</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>1</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>2</td>\n",
-       "      <td>How old are you?</td>\n",
-       "      <td>-1</td>\n",
-       "      <td>18-24</td>\n",
-       "      <td>25-34</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "  id          question correct option1 option2 option3 option4 option5  \\\n",
-       "0  1               NaN       1     NaN     NaN     NaN     NaN     NaN   \n",
-       "1  2  How old are you?      -1   18-24   25-34     NaN     NaN     NaN   \n",
-       "\n",
-       "  option6 option7 option8  \n",
-       "0     NaN     NaN     NaN  \n",
-       "1     NaN     NaN     NaN  "
-      ]
-     },
-     "execution_count": 152,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "df_items.head(2)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 219,
-   "id": "93beb77a-7e30-437d-9f7e-e079cd2db029",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "items = []\n",
-    "for i, row in df_items.iterrows():\n",
-    "    row = row.dropna()\n",
-    "    id_ = int(row['id'])\n",
-    "\n",
-    "    o = {'id': id_, 'question': None, 'correct': None}\n",
-    "    items.append(o)\n",
-    "    \n",
-    "    if 'question' in row:\n",
-    "        o['question'] = f'text:{row[\"question\"]}'\n",
-    "    elif os.path.isfile(f'{ITEMS_FOLDER}/{id_}/q.mp3'):\n",
-    "        o['question'] = f'audio:{REMOTE_ITEMS_FOLDER}/{id_}/q.mp3'\n",
-    "    elif os.path.isfile(f'{ITEMS_FOLDER}/{id_}/q.jpeg'):\n",
-    "        o['question'] = f'audio:{REMOTE_ITEMS_FOLDER}/{id_}/q.jpeg'\n",
-    "    else:\n",
-    "        print(f'Failed to find a question for item {id_}')\n",
-    "\n",
-    "    if 'correct' in row:\n",
-    "        o['correct'] = int(row['correct'])\n",
-    "    else:\n",
-    "        print(f'Failed to find corect for item {id_}')\n",
-    "\n",
-    "    for j in range(1,9):\n",
-    "        op = f'option{j}'\n",
-    "        if op in row:\n",
-    "            o[op] = 'text:' + row[op]\n",
-    "        elif os.path.isfile(f'{ITEMS_FOLDER}/{id_}/{j}.mp3'):\n",
-    "            o[op] = f'audio:{REMOTE_ITEMS_FOLDER}/{id_}/{j}.mp3'\n",
-    "        elif os.path.isfile(f'{ITEMS_FOLDER}/{id_}/{j}.jpeg'):\n",
-    "            o[op] = f'audio:{REMOTE_ITEMS_FOLDER}/{id_}/{j}.jpeg'"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 220,
-   "id": "a2bc630b-af5a-4f65-b6f6-4005d2f359f5",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "groups = []\n",
-    "with open('groups.csv') as file:\n",
-    "    file.readline()\n",
-    "    for line in file.read().split('\\n'):\n",
-    "        if not line:\n",
-    "            continue\n",
-    "        id_, title, *its = line.split(',')\n",
-    "        id_ = int(id_)\n",
-    "        its = [int(x) for x in its]\n",
-    "        groups.append({'id': id_, 'title': title, 'items_id': its})"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 221,
-   "id": "0d8fc0ea-6ec9-4c58-8395-2a415d556fea",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "surveys = []\n",
-    "with open('surveys.csv') as file:\n",
-    "    file.readline()\n",
-    "    for line in file.read().split('\\n'):\n",
-    "        if not line:\n",
-    "            continue\n",
-    "        id_, title, *gps = line.split(',')\n",
-    "        id_ = int(id_)\n",
-    "        gps = [int(x) for x in gps]\n",
-    "        surveys.append({'id': id_, 'title': title, 'groups_id': gps})"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 34,
-   "id": "39c018e7-2fb8-4b39-bd9b-fbffb810a823",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdin",
-     "output_type": "stream",
-     "text": [
-      "Username:  admin@admin.tld\n",
-      "Password:  admin\n"
-     ]
-    }
-   ],
-   "source": [
-    "username = input('Username: ')\n",
-    "password = input('Password: ')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 182,
-   "id": "96102efa-019b-4ee3-8c58-02de14b16e0c",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "session = requests.session()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 183,
-   "id": "6eca54d9-ae9a-42c2-a825-33164c0b1591",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "assert session.post(API_URL + '/api/v1/auth/login', data={'email': username, 'password': password}).status_code == 200, 'Wrong username or password'"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 235,
-   "id": "b001af43-1f12-4994-8403-5dd4a165879e",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Successfully created 2 items\n"
-     ]
-    }
-   ],
-   "source": [
-    "for item in items:\n",
-    "    assert session.delete(f'{API_URL}/api/v1/surveys/items/{item[\"id\"]}').status_code in [404, 204], f'Failed to delete item {item[\"id\"]}'\n",
-    "    r = session.post(f'{API_URL}/api/v1/surveys/items', json=item)\n",
-    "    if r.status_code not in [201]:\n",
-    "        print(f'Failed to create item {item[\"id\"]}: {r.text}')\n",
-    "        break\n",
-    "else:\n",
-    "    print(f'Successfully created {len(items)} items')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 241,
-   "id": "31e2bd80-5569-407b-a562-5140d016093e",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Successfully created 2 groups\n"
-     ]
-    }
-   ],
-   "source": [
-    "for group in groups:\n",
-    "    group = group.copy()\n",
-    "    its = group.pop('items_id')\n",
-    "    assert session.delete(f'{API_URL}/api/v1/surveys/groups/{group[\"id\"]}').status_code in [404, 204], f'Failed to delete group {group[\"id\"]}'\n",
-    "    r = session.post(f'{API_URL}/api/v1/surveys/groups', json=group)\n",
-    "    if r.status_code not in [201]:\n",
-    "        print(f'Failed to create group {group[\"id\"]}: {r.text}')\n",
-    "        break\n",
-    "\n",
-    "    for it in its:\n",
-    "        assert session.delete(f'{API_URL}/api/v1/surveys/groups/{group[\"id\"]}/items/{it}').status_code in [404, 204], f'Failed to delete item {it} from group {group[\"id\"]}'\n",
-    "        r = session.post(f'{API_URL}/api/v1/surveys/groups/{group[\"id\"]}/items', json={\"question_id\": it})\n",
-    "        if r.status_code not in [201]:\n",
-    "            print(f'Failed to add item {it} to group {group[\"id\"]}: {r.text}')\n",
-    "            break\n",
-    "\n",
-    "else:\n",
-    "    print(f'Successfully created {len(groups)} groups')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 244,
-   "id": "3520668b-04fb-48f1-acbf-510ff4bc18c4",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Failed to add group 1 to survey 1: {\"detail\":\"Not Found\"}\n",
-      "Failed to add group 2 to survey 2: {\"detail\":\"Not Found\"}\n",
-      "Successfully created 2 surveys\n"
-     ]
-    }
-   ],
-   "source": [
-    "for survey in surveys:\n",
-    "    survey = survey.copy()\n",
-    "    gps = survey.pop('groups_id')\n",
-    "    assert session.delete(f'{API_URL}/api/v1/surveys/{survey[\"id\"]}').status_code in [404, 204], f'Failed to delete survey {survey[\"id\"]}'\n",
-    "    r = session.post(f'{API_URL}/api/v1/surveys', json=survey)\n",
-    "    if r.status_code not in [201]:\n",
-    "        print(f'Failed to create suvey {survey[\"id\"]}: {r.text}')\n",
-    "        break\n",
-    "\n",
-    "    for gp in gps:\n",
-    "        assert session.delete(f'{API_URL}/api/v1/surveys/{survey[\"id\"]}/groups/{gp}').status_code in [404, 204], f'Failed to delete gp {it} from survey {survey[\"id\"]}'\n",
-    "        r = session.post(f'{API_URL}/api/v1/surveys/{survey[\"id\"]}/groups', json={\"group_id\": gp})\n",
-    "        if r.status_code not in [201]:\n",
-    "            print(f'Failed to add group {gp} to survey {survey[\"id\"]}: {r.text}')\n",
-    "            break\n",
-    "\n",
-    "else:\n",
-    "    print(f'Successfully created {len(groups)} surveys')"
-   ]
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.11.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/scripts/surveys/survey_maker.ipynb b/scripts/surveys/survey_maker.ipynb
index 5dcd6c4b0e52848b4b94ecf43b86820f45c86454..b79c5dfbb95f73957486d201138c5e74406b0d67 100644
--- a/scripts/surveys/survey_maker.ipynb
+++ b/scripts/surveys/survey_maker.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 142,
+   "execution_count": 1,
    "id": "5f682366-5ab6-4418-84b9-b971266af67f",
    "metadata": {},
    "outputs": [],
@@ -15,7 +15,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 145,
+   "execution_count": 2,
    "id": "e8af376d-ce09-4537-a724-2028777adef3",
    "metadata": {},
    "outputs": [],
@@ -27,7 +27,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 151,
+   "execution_count": 3,
    "id": "30116c8a-a0a6-4dc7-9b69-8afb50a6252e",
    "metadata": {},
    "outputs": [],
@@ -37,7 +37,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 152,
+   "execution_count": 4,
    "id": "265ccfaa-e86d-460c-be36-1bdfbd2c433f",
    "metadata": {},
    "outputs": [
@@ -118,7 +118,7 @@
        "1     NaN     NaN     NaN  "
       ]
      },
-     "execution_count": 152,
+     "execution_count": 4,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -129,7 +129,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 219,
+   "execution_count": 5,
    "id": "93beb77a-7e30-437d-9f7e-e079cd2db029",
    "metadata": {},
    "outputs": [],
@@ -144,10 +144,10 @@
     "    \n",
     "    if 'question' in row:\n",
     "        o['question'] = f'text:{row[\"question\"]}'\n",
-    "    elif os.path.isfile(f'{ITEMS_FOLDER}/{id_}/q.mp3'):\n",
+    "    elif os.path.isfile(f'{LOCAL_ITEMS_FOLDER}/{id_}/q.mp3'):\n",
     "        o['question'] = f'audio:{REMOTE_ITEMS_FOLDER}/{id_}/q.mp3'\n",
-    "    elif os.path.isfile(f'{ITEMS_FOLDER}/{id_}/q.jpeg'):\n",
-    "        o['question'] = f'audio:{REMOTE_ITEMS_FOLDER}/{id_}/q.jpeg'\n",
+    "    elif os.path.isfile(f'{LOCAL_ITEMS_FOLDER}/{id_}/q.jpeg'):\n",
+    "        o['question'] = f'image:{REMOTE_ITEMS_FOLDER}/{id_}/q.jpeg'\n",
     "    else:\n",
     "        print(f'Failed to find a question for item {id_}')\n",
     "\n",
@@ -160,15 +160,15 @@
     "        op = f'option{j}'\n",
     "        if op in row:\n",
     "            o[op] = 'text:' + row[op]\n",
-    "        elif os.path.isfile(f'{ITEMS_FOLDER}/{id_}/{j}.mp3'):\n",
+    "        elif os.path.isfile(f'{LOCAL_ITEMS_FOLDER}/{id_}/{j}.mp3'):\n",
     "            o[op] = f'audio:{REMOTE_ITEMS_FOLDER}/{id_}/{j}.mp3'\n",
-    "        elif os.path.isfile(f'{ITEMS_FOLDER}/{id_}/{j}.jpeg'):\n",
-    "            o[op] = f'audio:{REMOTE_ITEMS_FOLDER}/{id_}/{j}.jpeg'"
+    "        elif os.path.isfile(f'{LOCAL_ITEMS_FOLDER}/{id_}/{j}.jpeg'):\n",
+    "            o[op] = f'image:{REMOTE_ITEMS_FOLDER}/{id_}/{j}.jpeg'"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 220,
+   "execution_count": 6,
    "id": "a2bc630b-af5a-4f65-b6f6-4005d2f359f5",
    "metadata": {},
    "outputs": [],
@@ -187,7 +187,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 221,
+   "execution_count": 7,
    "id": "0d8fc0ea-6ec9-4c58-8395-2a415d556fea",
    "metadata": {},
    "outputs": [],
@@ -206,7 +206,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
+   "execution_count": 8,
    "id": "39c018e7-2fb8-4b39-bd9b-fbffb810a823",
    "metadata": {},
    "outputs": [
@@ -226,7 +226,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 182,
+   "execution_count": 9,
    "id": "96102efa-019b-4ee3-8c58-02de14b16e0c",
    "metadata": {},
    "outputs": [],
@@ -236,7 +236,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 183,
+   "execution_count": 10,
    "id": "6eca54d9-ae9a-42c2-a825-33164c0b1591",
    "metadata": {},
    "outputs": [],
@@ -271,7 +271,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 253,
+   "execution_count": 12,
    "id": "31e2bd80-5569-407b-a562-5140d016093e",
    "metadata": {},
    "outputs": [
@@ -306,7 +306,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 254,
+   "execution_count": 13,
    "id": "3520668b-04fb-48f1-acbf-510ff4bc18c4",
    "metadata": {},
    "outputs": [