From f3369d8a8b172f8b887d7392664ed80c8996fb89 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Thu, 17 Dec 2020 07:48:27 +0300 Subject: Adds Timestamp Field Adds timestamp field to user form responses on generation. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- backend/models/form_response.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'backend/models') diff --git a/backend/models/form_response.py b/backend/models/form_response.py index f3296cd..b6570e5 100644 --- a/backend/models/form_response.py +++ b/backend/models/form_response.py @@ -1,6 +1,7 @@ +import datetime import typing as t -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, validator from .antispam import AntiSpam from .discord_user import DiscordUser @@ -14,6 +15,11 @@ class FormResponse(BaseModel): antispam: t.Optional[AntiSpam] response: dict[str, t.Any] form_id: str + timestamp: str = datetime.datetime.now(tz=datetime.timezone.utc).isoformat() + + @validator("timestamp") + def set_timestamp(cls, _: str) -> str: + return datetime.datetime.now(tz=datetime.timezone.utc).isoformat() class Config: allow_population_by_field_name = True -- cgit v1.2.3 From d2427c7d3c3a1e877e99a724106b8d01d356e84c Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Thu, 17 Dec 2020 09:38:13 +0300 Subject: Fixes DB Timestamp on Return As pointed out by @ks129, fetching the responses would cause an error in the timestamp, as the validation was returning the current time at fetching, instead of the stored value. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- SCHEMA.md | 15 ++++++++------- backend/models/form_response.py | 15 +++++++++++---- backend/routes/forms/submit.py | 2 ++ 3 files changed, 21 insertions(+), 11 deletions(-) (limited to 'backend/models') diff --git a/SCHEMA.md b/SCHEMA.md index b37ed1d..59b6c33 100644 --- a/SCHEMA.md +++ b/SCHEMA.md @@ -127,13 +127,14 @@ Textareas require no additional configuration. ## Form response -| Field | Type | Description | -| ---------- | ---------------------------------------------------- | --------------------------------------------------------------------------- | -| `_id`/`id` | MongoDB ObjectID | Random identifier used for the response | -| `user` | Optional [user details object](#user-details-object) | An object describing the user that submitted if the form is not anonymous | -| `antispam` | Optional [anti spam object](#anti-spam-object) | An object containing information about the anti-spam on the form submission | -| `response` | Object | Object containing question IDs mapping to the users answer | -| `form_id` | String | ID of the form that the user is submitting to | +| Field | Type | Description | +| ----------- | ---------------------------------------------------- | --------------------------------------------------------------------------- | +| `_id`/`id` | MongoDB ObjectID | Random identifier used for the response | +| `user` | Optional [user details object](#user-details-object) | An object describing the user that submitted if the form is not anonymous | +| `antispam` | Optional [anti spam object](#anti-spam-object) | An object containing information about the anti-spam on the form submission | +| `response` | Object | Object containing question IDs mapping to the users answer | +| `form_id` | String | ID of the form that the user is submitting to | +| `timestamp` | String | ISO formatted string of submission time. | ### User details object diff --git a/backend/models/form_response.py b/backend/models/form_response.py index b6570e5..8a4da28 100644 --- a/backend/models/form_response.py +++ b/backend/models/form_response.py @@ -15,11 +15,18 @@ class FormResponse(BaseModel): antispam: t.Optional[AntiSpam] response: dict[str, t.Any] form_id: str - timestamp: str = datetime.datetime.now(tz=datetime.timezone.utc).isoformat() + timestamp: str - @validator("timestamp") - def set_timestamp(cls, _: str) -> str: - return datetime.datetime.now(tz=datetime.timezone.utc).isoformat() + @validator("timestamp", pre=True) + def set_timestamp(cls, iso_string: str) -> str: + if iso_string is None: + return datetime.datetime.now(tz=datetime.timezone.utc).isoformat() + + elif not isinstance(iso_string, str): + raise ValueError("Submission timestamp must be a string.") + + # Convert to datetime and back to ensure string is valid + return datetime.datetime.fromisoformat(iso_string).isoformat() class Config: allow_population_by_field_name = True diff --git a/backend/routes/forms/submit.py b/backend/routes/forms/submit.py index 3ecbda0..48ae4f6 100644 --- a/backend/routes/forms/submit.py +++ b/backend/routes/forms/submit.py @@ -34,6 +34,8 @@ class SubmitForm(Route): async def post(self, request: Request) -> JSONResponse: data = await request.json() + data["timestamp"] = None + if form := await request.state.db.forms.find_one( {"_id": request.path_params["form_id"], "features": "OPEN"} ): -- cgit v1.2.3 From 1d28213cccbac6e300781ab2fc30affa480242ac Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Thu, 17 Dec 2020 09:44:07 +0300 Subject: Update backend/models/form_response.py Co-authored-by: ks129 <45097959+ks129@users.noreply.github.com> --- backend/models/form_response.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backend/models') diff --git a/backend/models/form_response.py b/backend/models/form_response.py index 8a4da28..0da7b15 100644 --- a/backend/models/form_response.py +++ b/backend/models/form_response.py @@ -18,7 +18,7 @@ class FormResponse(BaseModel): timestamp: str @validator("timestamp", pre=True) - def set_timestamp(cls, iso_string: str) -> str: + def set_timestamp(cls, iso_string: t.Optional[str]) -> t.Optional[str]: if iso_string is None: return datetime.datetime.now(tz=datetime.timezone.utc).isoformat() -- cgit v1.2.3