示例#1
0
def disable_account_recovery_token():
    token_id = request.form['tokenId']
    token = database.token.account_recovery.disable(token_id)
    response = {
        'message': 'WebUserResetPasswordToken {id} disabled.'.format(id=token.id)
    }
    return Success(status_code=201,
                   headers={'Location': '/account-recovery/deactivate'},
                   resource_type='DeactivateNewSurveyToken',
                   body=response)
 def post(self):
     survey = database.survey.get(current_identity.survey_id)
     response = {
         'token':
         database.web_user.create_invite_researcher_token(survey).token
     }
     return Success(status_code=201,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body=response)
示例#3
0
 def get(self):
     survey = database.survey.get(current_identity.survey_id)
     response = {
         'stations': to_prompts_geojson(survey.subway_stops),
         'bufferSize': survey.trip_subway_buffer
     }
     return Success(status_code=200,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body=response)
    def post(self):
        json_data = json.loads(request.data.decode('utf-8'))
        data = rename_json_keys(json_data, camelcase_to_underscore)
        survey_name = data['survey_name'].lower().strip()

        survey = database.survey.find_by_name(survey_name)
        if not survey:
            return Error(status_code=410,
                         headers=self.headers,
                         resource_type=self.resource_type,
                         errors=['Specified survey not found'])

        user = database.user.create(survey=survey, user_data=data['user'])

        if user:
            survey_json = database.survey.formatted_survey_questions(survey)
            prompts_json = database.survey.formatted_survey_prompts(survey)
            # supply a default max_prompts value of 0 if no prompts are set instead of None
            max_prompts = survey.max_prompts if len(prompts_json) > 0 else 0
            response = {
                'user': '******',
                'uuid': data['user']['uuid'],
                'contact_email': survey.contact_email,
                'default_avatar': get_default_avatar_path(),
                'avatar': survey.avatar_uri,
                'survey': survey_json,
                'prompt': {
                    'max_days': survey.max_survey_days,
                    'max_prompts': max_prompts,
                    'num_prompts': len(prompts_json),
                    'prompts': prompts_json
                },
                'lang': survey.language,
                'about_text': survey.about_text,
                'terms_of_service': survey.terms_of_service,
                'survey_name': survey.pretty_name,
                'record_acceleration': survey.record_acceleration,
                'record_mode': survey.record_mode
            }

            # add in deprecation warning for v1 api
            return Success(
                status_code=201,
                headers=self.headers,
                resource_type=self.resource_type,
                status=
                'Warning (deprecated): API v1 will soon be phased out. Please refer to documentation for v2 calls.',
                body=rename_json_keys(response, underscore_to_camelcase))

        return Error(status_code=400,
                     headers=self.headers,
                     resource_type=self.resource_type,
                     errors=['Could not register new user.'])
示例#5
0
 def delete(self, email):
     survey = database.survey.get(current_identity.survey_id)
     user = survey.web_users.filter_by(email=email).one_or_none()
     if user:
         database.web_user.delete(user)
         return Success(status_code=201,
                        headers=self.headers,
                        resource_type=self.resource_type,
                        body={})
     return Error(status_code=401,
                  headers=self.headers,
                  resource_type=self.resource_type,
                  errors=['Web user could not be deleted from survey.'])
示例#6
0
 def get(self):
     survey = database.survey.get(current_identity.survey_id)
     prompts = database.prompts.formatted_prompt_questions(survey)
     response = {
         'survey_id': survey.id,
         'prompts': prompts,
         'started':
         True if database.survey.get_start_time(survey) else False
     }
     return Success(status_code=200,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body=make_keys_camelcase(response))
示例#7
0
 def put(self):
     email = request.json.get('email')
     password = request.json.get('password')
     token = request.json.get('token')
     user = database.web_user.update_password(email, password, token)
     if user:
         return Success(status_code=201,
                        headers=self.headers,
                        resource_type=self.resource_type,
                        body={})
     return Error(status_code=401,
                  headers=self.headers,
                  resource_type=self.resource_type,
                  errors=[])
示例#8
0
    def get(self):
        survey = database.survey.get(current_identity.survey_id)
        uri = survey.avatar_uri

        # use default avatar if a custom one is not set
        if not uri:
            with current_app.app_context():
                uri = '{base}/static/{avatar}'.format(
                    base=current_app.config['ASSETS_ROUTE'],
                    avatar=current_app.config['DEFAULT_AVATAR_FILENAME'])
        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body={'avatarUri': uri})
示例#9
0
    def get(self):
        survey = database.survey.get(current_identity.survey_id)
        sort_fields = json.loads(request.values.get('sorting', '{}'))
        page_index = int(request.values.get('pageIndex'))
        items_per_page = int(request.values.get('itemsPerPage'))

        response = database.web_user.paginated_table(
            survey=survey,
            page_index=page_index,
            items_per_page=items_per_page,
            sort_fields=sort_fields)
        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=response)
示例#10
0
    def post(self):
        data = json.loads(request.data)
        survey_name = data['survey_name'].lower()

        survey = database.survey.find_by_name(survey_name)
        if not survey:
            return Error(status_code=400,
                         headers=self.headers,
                         resource_type=self.resource_type,
                         errors=['Specified survey not found'])

        user = database.user.create(survey=survey, user_data=data['user'])

        if user:
            survey_json = database.survey.formatted_survey_questions(survey)
            prompts_json = database.survey.formatted_survey_prompts(survey)
            # supply a default max_prompts value of 0 if no prompts are set instead of None
            max_prompts = survey.max_prompts if len(prompts_json) > 0 else 0
            response = {
                'survey_id': survey.id,
                'user': '******',
                'uuid': data['user']['uuid'],
                'default_avatar': get_default_avatar_path(),
                'avatar': survey.avatar_uri,
                'survey': survey_json,
                'prompt': {
                    'max_days': survey.max_survey_days,
                    'max_prompts': max_prompts,
                    'num_prompts': len(prompts_json),
                    'prompts': prompts_json
                },
                'lang': survey.language,
                'about_text': survey.about_text,
                'terms_of_service': survey.terms_of_service,
                'survey_name': survey.pretty_name,
                'record_acceleration': survey.record_acceleration,
                'record_mode': survey.record_mode
            }
            return Success(status_code=201,
                           headers=self.headers,
                           resource_type=self.resource_type,
                           body=make_keys_camelcase(response))

        return Error(status_code=400,
                     headers=self.headers,
                     resource_type=self.resource_type,
                     errors=['Could not register new user.'])
示例#11
0
def upload_survey_schema_json():
    if not request.json.get('surveyName'):
        return Error(status_code=400,
                     headers={'Location': '/manage-surveys/schema'},
                     resource_type='NewSurveySchema',
                     errors=['A unique survey name must be provided.'])
    errors = None
    if request.json.get('schema'):
        survey_name = request.json['surveyName']
        error = database.survey_admin.create_from_schema(
            survey_name=survey_name,
            admin_email=request.json['schema']['adminEmail'],
            admin_password=request.json['schema']['adminPassword'],
            language=request.json['schema']['language'],
            survey_questions=request.json['schema']['surveyQuestions'],
            survey_prompts=request.json['schema']['surveyPrompts'])
        if not error:
            # format the same as jinja2 renders the template
            response = {
                'recent_signups': [],
                'message': 'Survey "{}" created.'.format(survey_name)
            }
            for survey in database.survey_admin.get_recent_signups(10):
                response['recent_signups'].append({
                    'name':
                    survey.name,
                    'pretty_name':
                    survey.pretty_name,
                    'created_at':
                    str(survey.created_at.replace(microsecond=0)),
                    'active':
                    'True' if survey.mobile_coordinates.first() else 'False'
                })

            return Success(status_code=201,
                           headers={'Location': '/manage-surveys/schema'},
                           resource_type='NewSurveySchema',
                           body=response)
        errors = [error]

    if not errors:
        errors = ['New survey schema could not be uploaded.']
    return Error(status_code=400,
                 headers={'Location': '/manage-surveys/schema'},
                 resource_type='NewSurveySchema',
                 errors=errors)
示例#12
0
    def delete(self):
        survey = database.survey.get(current_identity.survey_id)
        if survey.avatar_uri:
            filehandler.delete(survey.avatar_uri)

        # reset to default avatar
        with current_app.app_context():
            default_avatar_uri = '{base}/user/{avatar}'.format(
                base=current_app.config['ASSETS_ROUTE'],
                avatar=current_app.config['DEFAULT_AVATAR_FILENAME'])
            survey.avatar_uri = default_avatar_uri
            database.survey.update(survey)

        return Success(status_code=202,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body={'avatarUri': default_avatar_uri})
示例#13
0
 def get(self):
     survey = database.survey.get(current_identity.survey_id)
     response = {
         'language': survey.language,
         'about_text': survey.about_text,
         'terms_of_service': survey.terms_of_service,
         'max_days': survey.max_survey_days,
         'max_prompts': survey.max_prompts,
         'survey': database.survey.get_survey_questions_json(survey),
         'survey_id': survey.id,
         'started':
         True if database.survey.get_start_time(survey) else False
     }
     return Success(status_code=200,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    body=make_keys_camelcase(response))
    def get(self):
        survey = database.survey.get(current_identity.survey_id)
        start = database.survey.get_start_time(survey)

        response = {
            'message': 'Survey has not begun.',
            'start_time': None,
            'last_export': None
        }

        if start:
            response['message'] = 'Survey has started'
            response['start_time'] = start.isoformat()
            response['last_export'] = survey.last_export

        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=make_keys_camelcase(response))
    def get(self):
        survey_id = current_identity.survey_id
        start = ciso8601.parse_datetime(request.values.get('start'))
        end = ciso8601.parse_datetime(request.values.get('end'))
        timezone = request.values.get('timezone')
        sse_channel = request.values.get('channel')
        # sse.publish({'msg': 'starting exports...', 'type': 'request-ack'},
        #             channel=sse_channel)

        mobile_data_dump.queue(survey_id, start, end, timezone, sse_channel)
        # mobile_data_dump(survey_id, start, end, timezone, sse_channel)

        response = {
            'start': start.isoformat(),
            'end': end.isoformat()
        }
        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=response)
示例#16
0
def generate_new_survey_token():
    database.token.new_survey.create()
    response = {
        'recent_tokens': [],
        'message': 'New survey sign-up token successfully created.'
    }

    # format the same as jinja2 renders the template
    for token in database.token.new_survey.get_recent(10):
        response['recent_tokens'].append({
            'token': token.token,
            'created_at': str(token.created_at.replace(microsecond=0)),
            'active': str(token.active),
            'usages': token.usages
        })

    return Success(status_code=201,
                   headers={'Location': '/signup-tokens/token'},
                   resource_type='NewSurveyToken',
                   body=response)
示例#17
0
    def get(self):
        survey = database.survey.get(current_identity.survey_id)
        start = request.values.get('start')
        end = request.values.get('end')
        period = request.values.get('period')
        get_counts_overview = request.values.get(
            'countsTable').lower() == 'true'
        response = {
            'installationsBarGraph':
            mobile_installations_bargraph(survey, start, end, period),
            'activeUsersLineGraph':
            active_users_linegraph(survey)
        }
        if get_counts_overview is True:
            response['overview'] = survey_overview(survey)

        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=response)
示例#18
0
    def post(self):
        email = request.json.get('email')
        base_url = request.json.get('baseUrl')

        token = database.web_user.create_reset_password_token(email)
        if token:
            email_password_token.queue(current_app.config['MAILGUN_DOMAIN'],
                                       current_app.config['MAILGUN_API_KEY'],
                                       base_url, email, token.token)
            # email_password_token(current_app.config['MAILGUN_DOMAIN'],
            #                      current_app.config['MAILGUN_API_KEY'],
            #                      base_url, email, token.token)

            return Success(status_code=201,
                           headers=self.headers,
                           resource_type=self.resource_type,
                           body={})
        return Error(status_code=401,
                     headers=self.headers,
                     resource_type=self.resource_type,
                     errors=['Email not found.'])
    def get(self):
        if current_identity.has_role('admin') or current_identity.has_role('researcher'):
            survey = database.survey.get(current_identity.survey_id)
            survey_users = []

            users_with_coordinates = (survey.mobile_users.filter(
                db.exists().where(MobileUser.id == MobileCoordinate.mobile_id)))

            for user in users_with_coordinates:
                survey_users.append({
                    'uuid': user.uuid,
                    'created_at': user.created_at.isoformat()
                })
        else:
            survey_users = [{
                'uuid': current_identity.participant_uuid,
                'created_at': current_identity.created_at.isoformat()
            }]
        return Success(status_code=200,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=survey_users)            
示例#20
0
    def post(self):
        validations = [{
            'uuid': {
                'key': 'uuid',
                'validator': value_exists,
                'response': Error,
                'error': 'UUID must be supplied. No action taken.'
            },
            'survey_answers': {
                'key': 'survey',
                'validator': None
            },
            'coordinates': {
                'key': 'coordinates',
                'validator': None
            },
            'prompts_answers': {
                'key': 'prompts',
                'validator': None
            },
            'cancelled_prompts': {
                'key': 'cancelledPrompts',
                'validator': None
            }
        }]
        validated = validate_json(validations, self.headers, self.resource_type)
        user = database.user.find_by_uuid(validated['uuid'])

        if user:
            survey_answers, coordinates, prompts_answers, cancelled_prompts = None, None, None, None
            response = {
                'survey': 'No new survey data supplied.',
                'coordinates': 'No new coordinates data supplied.',
                'prompts': 'No new prompt answers supplied.',
                'cancelledPrompts': 'No cancelled prompts supplied.'
            }
            if validated['survey_answers']:
                survey_answers = database.survey.upsert(user=user,
                                                        answers=validated['survey_answers'])
                if survey_answers:
                    response['survey'] = 'Survey answer for {} upserted.'.format(user.uuid)
            if validated['coordinates']:
                coordinates = database.coordinates.insert(user=user,
                                                          coordinates=validated['coordinates'])
                if coordinates:
                    response['coordinates'] = (
                        'New coordinates for {} inserted.'.format(user.uuid))
            
            # upsert prompts answers and remove any existing conflicting cancelled prompt responses
            if validated['prompts_answers']:
                prompts_answers = database.prompts.upsert(user=user,
                                                          prompts=validated['prompts_answers'])
                prompts_uuids = [p.prompt_uuid for p in prompts_answers]
                database.cancelled_prompts.delete(prompts_uuids)

                if prompts_answers:
                    response['prompts'] = (
                        'New prompt answers for {} inserted.'.format(user.uuid))

            # filter cancelled prompts which conflict with a provided response by uuid and insert cancelled prompts
            if validated['cancelled_prompts']:
                if validated['prompts_answers']:
                    answers_uuids = {p['uuid'] for p in validated['prompts_answers']}
                    filtered_cancelled_prompts = []
                    for c in validated['cancelled_prompts']:
                        if c['uuid'] not in answers_uuids:
                            filtered_cancelled_prompts.append(c)
                else:
                    filtered_cancelled_prompts = validated['cancelled_prompts']
                cancelled_prompts = database.cancelled_prompts.insert(user=user,
                                                                      cancelled_prompts=filtered_cancelled_prompts)
                if cancelled_prompts:
                    response['cancelledPrompts'] = (
                        'New cancelled prompts for {} inserted.'.format(user.uuid))

            status = None
            if any([survey_answers, coordinates, prompts_answers, cancelled_prompts]):
                database.commit()
                status = 201
            else:
                status = 200

            return Success(status_code=status,
                           headers=self.headers,
                           resource_type=self.resource_type,
                           body=response)

        return Error(status_code=400,
                     headers=self.headers,
                     resource_type=self.resource_type,
                     errors=['Could not find survey for {}.'.format(validated['uuid'])])
    def post(self):
        validations = [{
            'email': {
                'key': 'email',
                'validator': value_exists,
                'response': Error,
                'error': 'Email cannot be blank.',
            },
            'password': {
                'key': 'password',
                'validator': value_exists,
                'response': Error,
                'error': 'Password cannot be blank.',
            },
            'survey_name': {
                'key': 'surveyName',
                'validator': value_exists,
                'response': Error,
                'error': 'Survey name cannot be blank.',
            }
        }]
        validated = validate_json(validations, self.headers,
                                  self.resource_type)
        survey = database.survey.find_by_name(validated['survey_name'])

        # create a researcher user if a signup token is provided
        researcherToken = request.json.get('registrationToken', '').strip()
        if researcherToken:
            user = database.web_user.create_researcher(
                survey=survey,
                email=validated['email'],
                password=validated['password'],
                token=researcherToken)

            if user is False:
                return Error(status_code=400,
                             headers=self.headers,
                             resource_type=self.resource_type,
                             errors=['Web user already exists for email.'])
            elif user is None:
                return Error(status_code=403,
                             headers=self.headers,
                             resource_type=self.resource_type,
                             errors=['Researcher user could not be created.'])

        else:
            mobile_user = database.mobile_user.find_by_email(
                email=validated['email'])
            if not mobile_user:
                return Error(
                    status_code=404,
                    headers=self.headers,
                    resource_type=self.resource_type,
                    errors=[
                        'Participant email not found in any survey response.'
                    ])
            else:
                user = database.web_user.create_participant(
                    survey,
                    email=validated['email'],
                    password=validated['password'],
                    uuid=mobile_user.uuid)
                if user is False:
                    return Error(
                        status_code=400,
                        headers=self.headers,
                        resource_type=self.resource_type,
                        errors=['Participant user could not be created.'])
        return Success(status_code=201,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=make_keys_camelcase(validated))
示例#22
0
 def get(self):
     return Success(status_code=200,
                    headers=self.headers,
                    resource_type='BaseIndex',
                    body=None)
示例#23
0
    def post(self):
        validations = [{
            'about_text': {
                'key': 'aboutText',
                'validator': None,
            },
            'terms_of_service': {
                'key': 'termsOfService',
                'validator': None
            },
            'contact_email': {
                'key': 'contactEmail',
                'validator': value_exists,
                'response': Error,
                'error': 'A contact email address must be specified.'
            },
            'survey_max_days': {
                'key': 'surveyMaxDays',
                'validator': value_exists,
                'response': Error,
                'error':
                'A maximum number of survey prompt days must be entered.',
            },
            'survey_max_prompts': {
                'key': 'surveyMaxPrompts',
                'validator': value_exists,
                'response': Error,
                'error': 'A maximum number of survey prompts must be entered.',
            },
            'gps_accuracy_meters': {
                'key':
                'gpsAccuracyThresholdMeters',
                'validator':
                value_exists,
                'response':
                Error,
                'error':
                'A minimum GPS accuracy threshold must be specified. (Higher threshold is lower accuracy)'
            },
            'tripbreaker_interval_seconds': {
                'key': 'tripbreakerIntervalSeconds',
                'validator': value_exists,
                'response': Error,
                'error': 'Trip breaking interval must be provided.'
            },
            'tripbreaker_cold_start_meters': {
                'key': 'tripbreakerColdStartDistanceMeters',
                'validator': value_exists,
                'response': Error,
                'error': 'Trip breaking cold start distance must be provided.'
            },
            'tripbreaker_subway_buffer_meters': {
                'key': 'tripbreakerSubwayBufferMeters',
                'validator': value_exists,
                'response': Error,
                'error': 'Trip breaking subway buffer must be provided.'
            }
        }]
        validated = validate_json(validations, self.headers,
                                  self.resource_type)
        survey = database.survey.get(current_identity.survey_id)
        survey.about_text = validated['about_text']
        survey.terms_of_service = validated['terms_of_service']
        survey.contact_email = validated['contact_email']
        survey.max_survey_days = validated['survey_max_days']
        survey.max_prompts = validated['survey_max_prompts']
        survey.gps_accuracy_threshold = validated['gps_accuracy_meters']
        survey.trip_break_interval = validated['tripbreaker_interval_seconds']
        survey.trip_break_cold_start_distance = validated[
            'tripbreaker_cold_start_meters']
        survey.trip_subway_buffer = validated[
            'tripbreaker_subway_buffer_meters']
        db.session.commit()

        return Success(status_code=201,
                       headers=self.headers,
                       resource_type=self.resource_type,
                       body=make_keys_camelcase(validated))
示例#24
0
    def post(self):
        validations = [{
            'uuid': {
                'key': 'uuid',
                'validator': value_exists,
                'response': Error,
                'error': 'UUID must be supplied. No action taken.'
            },
            'survey_answers': {
                'key': 'survey',
                'validator': None
            },
            'coordinates': {
                'key': 'coordinates',
                'validator': None
            },
            'prompts_answers': {
                'key': 'prompts',
                'validator': None
            },
            'cancelled_prompts': {
                'key': 'cancelledPrompts',
                'validator': None
            }
        }]
        validated = validate_json(validations, self.headers,
                                  self.resource_type)
        user = database.user.find_by_uuid(validated['uuid'])

        if user:
            survey_answers, coordinates, prompts_answers, cancelled_prompts = None, None, None, None
            response = {
                'survey': 'No new survey data supplied.',
                'coordinates': 'No new coordinates data supplied.',
                'prompts': 'No new prompt answers supplied.',
                'cancelledPrompts': 'No cancelled prompts supplied.'
            }
            if validated['survey_answers']:
                survey_answers = database.survey.upsert(
                    user=user, answers=validated['survey_answers'])
                if survey_answers:
                    response[
                        'survey'] = 'Survey answer for {} upserted.'.format(
                            user.uuid)
            if validated['coordinates']:
                coordinates = rename_json_keys(validated['coordinates'],
                                               camelcase_to_underscore)
                coordinates = database.coordinates.insert(
                    user=user, coordinates=coordinates)
                if coordinates:
                    response['coordinates'] = (
                        'New coordinates for {} inserted.'.format(user.uuid))

            # upsert prompts answers and remove any existing conflicting cancelled prompt responses
            if validated['prompts_answers']:
                formatted_prompts = rename_json_keys(
                    validated['prompts_answers'], camelcase_to_underscore)
                error = self._fail_on_deprecated_prompts(formatted_prompts)
                if error:
                    return error
                prompts_answers = database.prompts.upsert(
                    user=user, prompts=formatted_prompts)
                prompts_uuids = {p.prompt_uuid for p in prompts_answers}
                database.cancelled_prompts.delete(prompts_uuids)

                if prompts_answers:
                    response['prompts'] = (
                        'New prompt answers for {} inserted.'.format(
                            user.uuid))

            # filter cancelled prompts which conflict with a provided response by uuid and insert cancelled prompts
            if validated['cancelled_prompts']:
                formatted_cancelled_prompts = rename_json_keys(
                    validated['cancelled_prompts'], camelcase_to_underscore)

                # fail gracefully on older version of mobile app that do not provide a prompt uuid
                error = self._fail_on_deprecated_prompts(
                    formatted_cancelled_prompts)
                if error:
                    return error

                if validated['prompts_answers']:
                    answers_uuids = {
                        p['uuid']
                        for p in validated['prompts_answers']
                    }
                    filtered_cancelled_prompts = []
                    for c in formatted_cancelled_prompts:
                        if c['uuid'] not in answers_uuids:
                            filtered_cancelled_prompts.append(c)
                else:
                    filtered_cancelled_prompts = formatted_cancelled_prompts
                cancelled_prompts = database.cancelled_prompts.insert(
                    user=user, cancelled_prompts=filtered_cancelled_prompts)
                if cancelled_prompts:
                    response['cancelledPrompts'] = (
                        'New cancelled prompts for {} inserted.'.format(
                            user.uuid))

            status = None
            if any([
                    survey_answers, coordinates, prompts_answers,
                    cancelled_prompts
            ]):
                database.commit()
                status = 201
            else:
                status = 200

            # add in deprecation warning for v1 api
            return Success(
                status_code=status,
                headers=self.headers,
                resource_type=self.resource_type,
                status=
                'Warning (deprecated): API v1 will soon be phased out. Please refer to documentation for v2 calls.',
                body=response)

        return Error(
            status_code=410,
            headers=self.headers,
            resource_type=self.resource_type,
            errors=['Could not find survey for {}.'.format(validated['uuid'])])