From b88cb4734426c6aba0dfcfd2d66cc655cbfeb441 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Fri, 24 Mar 2023 13:36:34 -0400 Subject: [PATCH 01/19] DB changes for th barcode bulk_scan --- microsetta_private_api/admin/admin_impl.py | 13 +++++ .../api/microsetta_private_api.yaml | 52 +++++++++++++++++++ microsetta_private_api/db/patches/0107.sql | 9 ++++ microsetta_private_api/repo/admin_repo.py | 38 ++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 microsetta_private_api/db/patches/0107.sql diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index d4c889cbc..38393387b 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -859,3 +859,16 @@ def get_vioscreen_sample_to_user(token_info): st_repo = SurveyTemplateRepo(t) data = st_repo.get_vioscreen_sample_to_user() return jsonify(data), 200 + + +def map_to_rack(token_info, sample_barcode, body): + validate_admin_access(token_info) + + with Transaction() as t: + admin_repo = AdminRepo(t) + scan_id = admin_repo.map_to_rack(sample_barcode, body) + t.commit() + + response = jsonify({"scan_id": scan_id}) + response.status_code = 201 + return response \ No newline at end of file diff --git a/microsetta_private_api/api/microsetta_private_api.yaml b/microsetta_private_api/api/microsetta_private_api.yaml index 423cbe337..c629a745a 100644 --- a/microsetta_private_api/api/microsetta_private_api.yaml +++ b/microsetta_private_api/api/microsetta_private_api.yaml @@ -2125,6 +2125,37 @@ paths: schema: type: object + '/admin/rack/{sample_barcode}/add': + post: + # Note: We might want to be able to differentiate system administrator operations + # from technician operations in the future by user accounts and the routes they post to + operationId: microsetta_private_api.admin.admin_impl.map_to_rack + tags: + - Admin + summary: Set sample processing information for a barcode + description: Set sample processing information for a barcode + parameters: + - $ref: '#/components/parameters/sample_barcode' + requestBody: + content: + application/json: + schema: + type: object + properties: + rack_id: + type: string + location_col: + type: string + location_row: + type: string + responses: + '201': + description: Successfully mapped new barcode scan to rack + content: + application/json: + schema: + type: object + '/admin/metadata/samples/{sample_barcode}/surveys/{survey_template_id}': get: operationId: microsetta_private_api.admin.admin_impl.sample_pulldown_single_survey @@ -2961,6 +2992,15 @@ components: items: type: string example: "https://wherever.com" + rack_id: + type: string + example: "0000" + location_col: + type: string + example: "1" + location_row: + type: string + example: "A" sample: type: object @@ -2988,6 +3028,18 @@ components: accession_urls: $ref: '#/components/schemas/accession_urls' + scanned_sample: + type: object + properties: + rack_id: + $ref: '#/components/schemas/rack_id' + location_col: + $ref: '#/components/schemas/location_col' + location_row: + $ref: '#/components/schemas/location_row' + sample_datetime: + $ref: '#/components/schemas/sample_datetime' + preparation: type: object properties: diff --git a/microsetta_private_api/db/patches/0107.sql b/microsetta_private_api/db/patches/0107.sql new file mode 100644 index 000000000..6bcbbb5a2 --- /dev/null +++ b/microsetta_private_api/db/patches/0107.sql @@ -0,0 +1,9 @@ +CREATE TABLE barcodes.rack_samples ( + location_id uuid NOT NULL DEFAULT uuid_generate_v4(), + rack_id varchar NOT NULL, + sample_id varchar NOT NULL, + location_row varchar NOT NULL, + location_col varchar NOT NULL, + date_time TIMESTAMP WITH TIME ZONE NOT NULL, + PRIMARY KEY (location_id) +); \ No newline at end of file diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index b94cd8072..c6838757a 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -1128,6 +1128,44 @@ def search_barcode(self, sql_cond, cond_params): ) return [r[0] for r in cur.fetchall()] + def map_to_rack(self, sample_barcode, scan_info): + with self._transaction.cursor() as cur: + + # not actually using the result, just checking there IS one + # to ensure this is a valid barcode + cur.execute( + "SELECT barcode FROM barcodes.barcode WHERE barcode=%s", + (sample_barcode,) + ) + + if cur.rowcount == 0: + raise NotFound("No such barcode: %s" % sample_barcode) + elif cur.rowcount > 1: + # Note: This "can't" happen. + raise RepoException("ERROR: Multiple barcode entries would be " + "affected by scan; failing out") + + # put a new row in the barcodes.barcode_scans table + new_uuid = str(uuid.uuid4()) + scan_args = ( + new_uuid, + scan_info['rack_id'], + sample_barcode, + scan_info['location_row'], + scan_info['location_col'], + datetime.datetime.now() + ) + + cur.execute( + "INSERT INTO barcodes.rack_samples " + "(location_id, rack_id, sample_id, " + "location_row, location_col, date_time) " + "VALUES (%s, %s, %s, %s, %s, %s)", + scan_args + ) + + return new_uuid + def get_survey_metadata(self, sample_barcode, survey_template_id=None): ids = self._get_ids_relevant_to_barcode(sample_barcode) From 55112b497cc782b6c729ec690d65b0b3f8130cf3 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Fri, 24 Mar 2023 14:01:01 -0400 Subject: [PATCH 02/19] fix lint errors --- microsetta_private_api/admin/admin_impl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index 38393387b..b66e10d62 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -871,4 +871,4 @@ def map_to_rack(token_info, sample_barcode, body): response = jsonify({"scan_id": scan_id}) response.status_code = 201 - return response \ No newline at end of file + return response From 8581e56bab88307ea002830d59d1a6437cc7a68a Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Fri, 24 Mar 2023 14:27:49 -0400 Subject: [PATCH 03/19] resolve conflict of db patch name --- microsetta_private_api/db/patches/{0107.sql => 0115.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename microsetta_private_api/db/patches/{0107.sql => 0115.sql} (100%) diff --git a/microsetta_private_api/db/patches/0107.sql b/microsetta_private_api/db/patches/0115.sql similarity index 100% rename from microsetta_private_api/db/patches/0107.sql rename to microsetta_private_api/db/patches/0115.sql From 426c52d6c72d1195500e934f3a7bc04974340a50 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Mon, 27 Mar 2023 23:33:34 -0400 Subject: [PATCH 04/19] test cases --- .../admin/tests/test_admin_api.py | 15 ++++++++++ .../admin/tests/test_admin_repo.py | 30 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/microsetta_private_api/admin/tests/test_admin_api.py b/microsetta_private_api/admin/tests/test_admin_api.py index 9560de097..eb7fa0888 100644 --- a/microsetta_private_api/admin/tests/test_admin_api.py +++ b/microsetta_private_api/admin/tests/test_admin_api.py @@ -1096,3 +1096,18 @@ def mock_func(*args, **kwargs): data=json.dumps(info), headers=MOCK_HEADERS) self.assertEqual(204, response.status_code) + + def test_sample_map_to_rack(self): + barcode= "000001024" + scan_info= { + 'rack_id': '005', + 'location_row': 'B', + 'location_col': '01' + } + + response = self.client.post( + '/apo/admin/rack/{0}/add'.format(barcode), + content_type="application/json", + data=json.dumps(scan_info)) + + self.assertEquals(201, response.status_code) \ No newline at end of file diff --git a/microsetta_private_api/admin/tests/test_admin_repo.py b/microsetta_private_api/admin/tests/test_admin_repo.py index d406822ba..59493be9e 100644 --- a/microsetta_private_api/admin/tests/test_admin_repo.py +++ b/microsetta_private_api/admin/tests/test_admin_repo.py @@ -1219,3 +1219,33 @@ def test_set_kit_uuids_for_dak_order(self): self.assertEqual(len(curr_records), 2) for expected_record in expected_records: self.assertIn(expected_record, curr_records) + + def test_map_to_rack_fail(self): + scan_info = { + 'rack_id': '001', + 'location_row': 'A', + 'location_col': '02' + } + + with Transaction() as t: + barcode = '00000000' + + admin_repo = AdminRepo(t) + with self.assertRaises(NotFound): + admin_repo.map_to_rack(barcode, scan_info) + + def test_map_to_rack_success(self): + scan_info = { + 'rack_id': '001', + 'location_row': 'A', + 'location_col': '02' + } + + uuid = "" + with Transaction() as t: + barcode = '000001024' + + admin_repo = AdminRepo(t) + uuid = admin_repo.map_to_rack(barcode, scan_info) + + self.assertTrue(len(uuid) > 0) From 798f3169af194c8e08e07f8f8f7f9d2dd2cd945a Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Mon, 27 Mar 2023 23:50:59 -0400 Subject: [PATCH 05/19] fix lint errors --- microsetta_private_api/admin/tests/test_admin_api.py | 7 ++++--- microsetta_private_api/admin/tests/test_admin_repo.py | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/microsetta_private_api/admin/tests/test_admin_api.py b/microsetta_private_api/admin/tests/test_admin_api.py index 2dd2f9a14..c003ff7d4 100644 --- a/microsetta_private_api/admin/tests/test_admin_api.py +++ b/microsetta_private_api/admin/tests/test_admin_api.py @@ -1271,19 +1271,20 @@ def mock_func(*args, **kwargs): self.assertEqual(204, response.status_code) def test_sample_map_to_rack(self): - barcode= "000001024" - scan_info= { + barcode = "000001024" + scan_info = { 'rack_id': '005', 'location_row': 'B', 'location_col': '01' } response = self.client.post( - '/apo/admin/rack/{0}/add'.format(barcode), + '/api/admin/rack/{0}/add'.format(barcode), content_type="application/json", data=json.dumps(scan_info)) self.assertEquals(201, response.status_code) + def test_generate_ffq_codes(self): input_json = json.dumps({"code_quantity": 2}) diff --git a/microsetta_private_api/admin/tests/test_admin_repo.py b/microsetta_private_api/admin/tests/test_admin_repo.py index 03147936d..7e304141e 100644 --- a/microsetta_private_api/admin/tests/test_admin_repo.py +++ b/microsetta_private_api/admin/tests/test_admin_repo.py @@ -1353,6 +1353,7 @@ def test_map_to_rack_success(self): uuid = admin_repo.map_to_rack(barcode, scan_info) self.assertTrue(len(uuid) > 0) + def test_create_ffq_code(self): with Transaction() as t: admin_repo = AdminRepo(t) From 6e893fe9a539eb40cff0e1584b6782203be87f02 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Tue, 28 Mar 2023 00:04:17 -0400 Subject: [PATCH 06/19] fix test error --- microsetta_private_api/admin/tests/test_admin_api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/microsetta_private_api/admin/tests/test_admin_api.py b/microsetta_private_api/admin/tests/test_admin_api.py index c003ff7d4..7a3b77ac8 100644 --- a/microsetta_private_api/admin/tests/test_admin_api.py +++ b/microsetta_private_api/admin/tests/test_admin_api.py @@ -1281,7 +1281,9 @@ def test_sample_map_to_rack(self): response = self.client.post( '/api/admin/rack/{0}/add'.format(barcode), content_type="application/json", - data=json.dumps(scan_info)) + data=json.dumps(scan_info), + headers=MOCK_HEADERS + ) self.assertEquals(201, response.status_code) From ce8aeb3ef3e01dff697527cdbcb40473f9f8f85a Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Tue, 25 Apr 2023 13:28:28 -0400 Subject: [PATCH 07/19] remove lines from DB patch as requested --- microsetta_private_api/db/patches/0114.sql | 4 ---- 1 file changed, 4 deletions(-) diff --git a/microsetta_private_api/db/patches/0114.sql b/microsetta_private_api/db/patches/0114.sql index f24c11791..86cbae812 100644 --- a/microsetta_private_api/db/patches/0114.sql +++ b/microsetta_private_api/db/patches/0114.sql @@ -33,10 +33,6 @@ UPDATE ag.survey_question SET american = 'In the past month, have you been expos UPDATE ag.survey_question SET american = 'In the past month, have you been suspected of having Coronavirus/COVID-19 infection?' WHERE survey_question_id = 212; UPDATE ag.survey_question SET american = 'In the past 6 weeks, have you had any of the following symptoms? (check all that apply)' WHERE survey_question_id = 214; --- Adjust the options for question 214 --- First, let's fix the typo in "Loss of appetite" - we'll leave the old option in the database so as to not break existing records -INSERT INTO ag.survey_response (american, spanish, spain_spanish) VALUES ('Lack of appetite', 'Falta de apetito', 'Falta de apetito'); -UPDATE ag.survey_question_response SET response = 'Lack of appetite' WHERE response = 'Lack of appetitie'; -- Now let's add new options. First, we'll add the options to the database INSERT INTO ag.survey_response (american) VALUES ('Shortness of breath or difficulty breathing'), From 6595d566ed8b62ab6cacd5be3ddf06d59216bec1 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Tue, 2 May 2023 12:29:25 -0400 Subject: [PATCH 08/19] code changes for temp db --- microsetta_private_api/admin/admin_impl.py | 16 +++++++++ .../api/microsetta_private_api.yaml | 36 +++++++++++++++++-- microsetta_private_api/repo/admin_repo.py | 22 ++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index 732ce48e9..76b0a7192 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -930,3 +930,19 @@ def map_to_rack(token_info, sample_barcode, body): response = jsonify({"scan_id": scan_id}) response.status_code = 201 return response + + +def get_sample_from_rack(token_info, rack_id): + validate_admin_access(token_info) + + with Transaction() as t: + admin_repo = AdminRepo(t) + row = admin_repo.get_rack_sample(rack_id) + if row is None: + response = jsonify({"message": "sample does not exist!"}) + response.status_code = 404 + return response + else: + response = jsonify(row) + response.status_code = 201 + return response \ No newline at end of file diff --git a/microsetta_private_api/api/microsetta_private_api.yaml b/microsetta_private_api/api/microsetta_private_api.yaml index 98bcd09b7..9176ed90a 100644 --- a/microsetta_private_api/api/microsetta_private_api.yaml +++ b/microsetta_private_api/api/microsetta_private_api.yaml @@ -2373,8 +2373,8 @@ paths: operationId: microsetta_private_api.admin.admin_impl.map_to_rack tags: - Admin - summary: Set sample processing information for a barcode - description: Set sample processing information for a barcode + summary: Add sample to rack for a barcode + description: Add sample to rack for a barcode parameters: - $ref: '#/components/parameters/sample_barcode' requestBody: @@ -2396,6 +2396,29 @@ paths: application/json: schema: type: object + + '/admin/rack/sample/{rack_id}': + get: + operationId: microsetta_private_api.admin.admin_impl.get_sample_from_rack + tags: + - Admin + summary: Get sample details from rack by rack id + description: Get sample details from rack by rack id + parameters: + - $ref: '#/components/parameters/rack_id' + responses: + '201': + description: Successfully fetched sample details from rack by rack id + content: + application/json: + schema: + type: object + '404': + description: Sample does not exist + content: + application/json: + schema: + type: object '/admin/metadata/samples/{sample_barcode}/surveys/{survey_template_id}': get: @@ -2980,6 +3003,12 @@ components: description: Type of consent schema: $ref: '#/components/schemas/consent_type' + rack_id: + name: rack_id + in: path + description: Rack id for a particular sample placed in rack + schema: + $ref: '#/components/schemas/rack_id' # query parameters activation_code: @@ -3304,6 +3333,9 @@ components: location_row: type: string example: "A" + rack_id: + type: string + example: "aaaaaaaa-bbbb-cccc-dddd-eeeeffffffff" sample: type: object diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index e53b80f1e..2be8df0ab 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -1174,6 +1174,28 @@ def map_to_rack(self, sample_barcode, scan_info): return new_uuid + def get_rack_sample(self, rack_id): + with self._transaction.dict_cursor() as cur: + + # not actually using the result, just checking there IS one + # to ensure this is a valid barcode + cur.execute( + "SELECT sample_id, location_row, location_col " + "FROM barcodes.rack_samples WHERE rack_id=%s", + (rack_id,) + ) + + row = cur.fetchone() + + if row is None: + raise NotFound("No such barcode with rack id: %s" % rack_id) + + data_to_return = {} + data_to_return["location_row"] = row["location_row"] + data_to_return["location_col"] = row["location_col"] + data_to_return["barcode"] = row["sample_id"] + return data_to_return + def get_survey_metadata(self, sample_barcode, survey_template_id=None): ''' Return all surveys associated with a given barcode. From 4da556e44f1e692cfaaf14c583bbb5ec79514bd2 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Tue, 2 May 2023 12:47:45 -0400 Subject: [PATCH 09/19] fix lints --- microsetta_private_api/admin/admin_impl.py | 2 +- microsetta_private_api/repo/admin_repo.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index 76b0a7192..40cb5930b 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -945,4 +945,4 @@ def get_sample_from_rack(token_info, rack_id): else: response = jsonify(row) response.status_code = 201 - return response \ No newline at end of file + return response diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index 2be8df0ab..c776a2bd0 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -1189,7 +1189,7 @@ def get_rack_sample(self, rack_id): if row is None: raise NotFound("No such barcode with rack id: %s" % rack_id) - + data_to_return = {} data_to_return["location_row"] = row["location_row"] data_to_return["location_col"] = row["location_col"] From 70b4848d6553ad7342bbd939b207d4c1d4f7a3f8 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Tue, 16 May 2023 15:42:31 -0400 Subject: [PATCH 10/19] fix sample repetition --- microsetta_private_api/admin/admin_impl.py | 7 +++++-- microsetta_private_api/repo/admin_repo.py | 23 ++++++++++++---------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index 40cb5930b..448b5d2ca 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -922,6 +922,8 @@ def get_vioscreen_sample_to_user(token_info): def map_to_rack(token_info, sample_barcode, body): validate_admin_access(token_info) + print(str(body)) + with Transaction() as t: admin_repo = AdminRepo(t) scan_id = admin_repo.map_to_rack(sample_barcode, body) @@ -931,7 +933,8 @@ def map_to_rack(token_info, sample_barcode, body): response.status_code = 201 return response - +#TO DO: CHANGE CODE TO HANDLE O-T-M RESPONSE +#CHECK IF CHANGE NEEDED IN YAML def get_sample_from_rack(token_info, rack_id): validate_admin_access(token_info) @@ -943,6 +946,6 @@ def get_sample_from_rack(token_info, rack_id): response.status_code = 404 return response else: - response = jsonify(row) + response = jsonify({"result":row}) response.status_code = 201 return response diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index c776a2bd0..9caf4abbf 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -1185,16 +1185,19 @@ def get_rack_sample(self, rack_id): (rack_id,) ) - row = cur.fetchone() - - if row is None: - raise NotFound("No such barcode with rack id: %s" % rack_id) - - data_to_return = {} - data_to_return["location_row"] = row["location_row"] - data_to_return["location_col"] = row["location_col"] - data_to_return["barcode"] = row["sample_id"] - return data_to_return + sample_rows = cur.fetchall() + + if len(sample_rows) == 0: + raise NotFound("No barcode with rack id: %s" % rack_id) + + result = [] + for row in sample_rows: + data_to_return = {} + data_to_return["location_row"] = row["location_row"] + data_to_return["location_col"] = row["location_col"] + data_to_return["barcode"] = row["sample_id"] + result.append(data_to_return) + return result def get_survey_metadata(self, sample_barcode, survey_template_id=None): ''' From 7190611ec29f896361fb4925c1d17982a198b52d Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Tue, 16 May 2023 16:08:06 -0400 Subject: [PATCH 11/19] fix lints erros --- microsetta_private_api/admin/admin_impl.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index 448b5d2ca..a039270e8 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -933,8 +933,7 @@ def map_to_rack(token_info, sample_barcode, body): response.status_code = 201 return response -#TO DO: CHANGE CODE TO HANDLE O-T-M RESPONSE -#CHECK IF CHANGE NEEDED IN YAML + def get_sample_from_rack(token_info, rack_id): validate_admin_access(token_info) @@ -946,6 +945,6 @@ def get_sample_from_rack(token_info, rack_id): response.status_code = 404 return response else: - response = jsonify({"result":row}) + response = jsonify({"result": row}) response.status_code = 201 return response From 1a41df8593c99ce4cfe9cc02275c426e1d8fbaa5 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Thu, 1 Jun 2023 13:40:05 -0400 Subject: [PATCH 12/19] PR feedback --- microsetta_private_api/admin/admin_impl.py | 8 +++----- .../admin/tests/test_admin_repo.py | 9 ++++++++- .../api/microsetta_private_api.yaml | 16 ++++++++++++++-- microsetta_private_api/db/patches/0115.sql | 5 ++++- microsetta_private_api/repo/admin_repo.py | 18 +++++++++--------- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index a039270e8..7b156f8d2 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -922,8 +922,6 @@ def get_vioscreen_sample_to_user(token_info): def map_to_rack(token_info, sample_barcode, body): validate_admin_access(token_info) - print(str(body)) - with Transaction() as t: admin_repo = AdminRepo(t) scan_id = admin_repo.map_to_rack(sample_barcode, body) @@ -934,12 +932,12 @@ def map_to_rack(token_info, sample_barcode, body): return response -def get_sample_from_rack(token_info, rack_id): +def get_samples_from_rack(token_info, rack_id, bulk_scan_id): validate_admin_access(token_info) - + with Transaction() as t: admin_repo = AdminRepo(t) - row = admin_repo.get_rack_sample(rack_id) + row = admin_repo.get_rack_samples(rack_id, bulk_scan_id) if row is None: response = jsonify({"message": "sample does not exist!"}) response.status_code = 404 diff --git a/microsetta_private_api/admin/tests/test_admin_repo.py b/microsetta_private_api/admin/tests/test_admin_repo.py index 7e304141e..40ac1e9c8 100644 --- a/microsetta_private_api/admin/tests/test_admin_repo.py +++ b/microsetta_private_api/admin/tests/test_admin_repo.py @@ -1339,20 +1339,27 @@ def test_map_to_rack_fail(self): admin_repo.map_to_rack(barcode, scan_info) def test_map_to_rack_success(self): + bulk_scan_id = str(uuid.uuid4()) scan_info = { 'rack_id': '001', 'location_row': 'A', - 'location_col': '02' + 'location_col': '02', + 'bulk_scan_id': bulk_scan_id } uuid = "" + samples = None with Transaction() as t: barcode = '000001024' admin_repo = AdminRepo(t) uuid = admin_repo.map_to_rack(barcode, scan_info) + rack_id = '001' + samples = admin_repo.get_rack_samples(rack_id, bulk_scan_id) + self.assertTrue(len(uuid) > 0) + self.assertEquals(len(samples), 1) def test_create_ffq_code(self): with Transaction() as t: diff --git a/microsetta_private_api/api/microsetta_private_api.yaml b/microsetta_private_api/api/microsetta_private_api.yaml index 9176ed90a..717550651 100644 --- a/microsetta_private_api/api/microsetta_private_api.yaml +++ b/microsetta_private_api/api/microsetta_private_api.yaml @@ -2389,6 +2389,8 @@ paths: type: string location_row: type: string + bulk_scan_id: + type: string responses: '201': description: Successfully mapped new barcode scan to rack @@ -2397,15 +2399,16 @@ paths: schema: type: object - '/admin/rack/sample/{rack_id}': + '/admin/rack/{bulk_scan_id}/sample/{rack_id}': get: - operationId: microsetta_private_api.admin.admin_impl.get_sample_from_rack + operationId: microsetta_private_api.admin.admin_impl.get_samples_from_rack tags: - Admin summary: Get sample details from rack by rack id description: Get sample details from rack by rack id parameters: - $ref: '#/components/parameters/rack_id' + - $ref: '#/components/parameters/bulk_scan_id' responses: '201': description: Successfully fetched sample details from rack by rack id @@ -3009,6 +3012,12 @@ components: description: Rack id for a particular sample placed in rack schema: $ref: '#/components/schemas/rack_id' + bulk_scan_id: + name: bulk_scan_id + in: path + description: Unique identifier for each bulk scan cycle + schema: + $ref: '#/components/schemas/bulk_scan_id' # query parameters activation_code: @@ -3336,6 +3345,9 @@ components: rack_id: type: string example: "aaaaaaaa-bbbb-cccc-dddd-eeeeffffffff" + bulk_scan_id: + type: string + example: "aaaaaaaa-bbbb-cccc-dddd-eeeeffffffff" sample: type: object diff --git a/microsetta_private_api/db/patches/0115.sql b/microsetta_private_api/db/patches/0115.sql index 6bcbbb5a2..65d9467c3 100644 --- a/microsetta_private_api/db/patches/0115.sql +++ b/microsetta_private_api/db/patches/0115.sql @@ -6,4 +6,7 @@ CREATE TABLE barcodes.rack_samples ( location_col varchar NOT NULL, date_time TIMESTAMP WITH TIME ZONE NOT NULL, PRIMARY KEY (location_id) -); \ No newline at end of file +); + +ALTER TABLE barcodes.rack_samples +ADD COLUMN scan_id varchar NOT NULL; \ No newline at end of file diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index 9caf4abbf..68f69c420 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -1161,28 +1161,28 @@ def map_to_rack(self, sample_barcode, scan_info): sample_barcode, scan_info['location_row'], scan_info['location_col'], - datetime.datetime.now() + datetime.datetime.now(), + scan_info['bulk_scan_id'] ) cur.execute( "INSERT INTO barcodes.rack_samples " "(location_id, rack_id, sample_id, " - "location_row, location_col, date_time) " - "VALUES (%s, %s, %s, %s, %s, %s)", + "location_row, location_col, date_time, scan_id) " + "VALUES (%s, %s, %s, %s, %s, %s, %s)", scan_args ) return new_uuid - def get_rack_sample(self, rack_id): + def get_rack_samples(self, rack_id, bulk_scan_id): with self._transaction.dict_cursor() as cur: - # not actually using the result, just checking there IS one - # to ensure this is a valid barcode cur.execute( - "SELECT sample_id, location_row, location_col " - "FROM barcodes.rack_samples WHERE rack_id=%s", - (rack_id,) + "SELECT DISTINCT ON (sample_id) sample_id, location_row, location_col " + "FROM barcodes.rack_samples WHERE rack_id=%s AND scan_id=%s " + "ORDER BY sample_id, date_time DESC", + (rack_id,bulk_scan_id,) ) sample_rows = cur.fetchall() From 831cb4eb10fbe1cb397ee207047649882ce92864 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Thu, 1 Jun 2023 13:48:19 -0400 Subject: [PATCH 13/19] fix lint --- microsetta_private_api/admin/admin_impl.py | 2 +- microsetta_private_api/admin/tests/test_admin_repo.py | 7 ++++--- microsetta_private_api/repo/admin_repo.py | 9 +++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/microsetta_private_api/admin/admin_impl.py b/microsetta_private_api/admin/admin_impl.py index 7b156f8d2..ff62c9ada 100644 --- a/microsetta_private_api/admin/admin_impl.py +++ b/microsetta_private_api/admin/admin_impl.py @@ -934,7 +934,7 @@ def map_to_rack(token_info, sample_barcode, body): def get_samples_from_rack(token_info, rack_id, bulk_scan_id): validate_admin_access(token_info) - + with Transaction() as t: admin_repo = AdminRepo(t) row = admin_repo.get_rack_samples(rack_id, bulk_scan_id) diff --git a/microsetta_private_api/admin/tests/test_admin_repo.py b/microsetta_private_api/admin/tests/test_admin_repo.py index 40ac1e9c8..435bd2350 100644 --- a/microsetta_private_api/admin/tests/test_admin_repo.py +++ b/microsetta_private_api/admin/tests/test_admin_repo.py @@ -4,6 +4,7 @@ import psycopg2 import psycopg2.extras from dateutil.relativedelta import relativedelta +import uuid import microsetta_private_api.model.project as p @@ -1347,18 +1348,18 @@ def test_map_to_rack_success(self): 'bulk_scan_id': bulk_scan_id } - uuid = "" + id = "" samples = None with Transaction() as t: barcode = '000001024' admin_repo = AdminRepo(t) - uuid = admin_repo.map_to_rack(barcode, scan_info) + id = admin_repo.map_to_rack(barcode, scan_info) rack_id = '001' samples = admin_repo.get_rack_samples(rack_id, bulk_scan_id) - self.assertTrue(len(uuid) > 0) + self.assertTrue(len(id) > 0) self.assertEquals(len(samples), 1) def test_create_ffq_code(self): diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index 68f69c420..1dec368a5 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -1179,10 +1179,11 @@ def get_rack_samples(self, rack_id, bulk_scan_id): with self._transaction.dict_cursor() as cur: cur.execute( - "SELECT DISTINCT ON (sample_id) sample_id, location_row, location_col " - "FROM barcodes.rack_samples WHERE rack_id=%s AND scan_id=%s " - "ORDER BY sample_id, date_time DESC", - (rack_id,bulk_scan_id,) + "SELECT DISTINCT ON (sample_id) sample_id, location_row, " + "location_col FROM barcodes.rack_samples WHERE rack_id=%s " + "AND scan_id=%s " + "ORDER BY sample_id, date_time DESC", + (rack_id,bulk_scan_id, ) ) sample_rows = cur.fetchall() From 573eb4506927b733d64daf4e9b7987d94fb90a1a Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Thu, 1 Jun 2023 13:54:25 -0400 Subject: [PATCH 14/19] fix lint --- microsetta_private_api/repo/admin_repo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/microsetta_private_api/repo/admin_repo.py b/microsetta_private_api/repo/admin_repo.py index 1dec368a5..572c5c7c1 100644 --- a/microsetta_private_api/repo/admin_repo.py +++ b/microsetta_private_api/repo/admin_repo.py @@ -1182,8 +1182,8 @@ def get_rack_samples(self, rack_id, bulk_scan_id): "SELECT DISTINCT ON (sample_id) sample_id, location_row, " "location_col FROM barcodes.rack_samples WHERE rack_id=%s " "AND scan_id=%s " - "ORDER BY sample_id, date_time DESC", - (rack_id,bulk_scan_id, ) + "ORDER BY sample_id, date_time DESC", + (rack_id, bulk_scan_id, ) ) sample_rows = cur.fetchall() From 49954489351c31e83daf6370a97d6af7bc69e896 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Thu, 1 Jun 2023 14:03:23 -0400 Subject: [PATCH 15/19] Fixed Tests for Bulk Scan --- microsetta_private_api/admin/tests/test_admin_api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/microsetta_private_api/admin/tests/test_admin_api.py b/microsetta_private_api/admin/tests/test_admin_api.py index 7a3b77ac8..11955bc29 100644 --- a/microsetta_private_api/admin/tests/test_admin_api.py +++ b/microsetta_private_api/admin/tests/test_admin_api.py @@ -1,6 +1,7 @@ import pytest from unittest import TestCase from unittest.mock import patch +import uuid from flask import Response import json import microsetta_private_api.server @@ -1275,7 +1276,8 @@ def test_sample_map_to_rack(self): scan_info = { 'rack_id': '005', 'location_row': 'B', - 'location_col': '01' + 'location_col': '01', + 'bulk_scan_id': str(uuid.uuid4()) } response = self.client.post( From 6e1d42417f3377555516d6359f0874f1c22b4c17 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Thu, 8 Jun 2023 13:17:39 -0400 Subject: [PATCH 16/19] update the DB file name to avoid conflict --- microsetta_private_api/db/patches/0115.sql | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 microsetta_private_api/db/patches/0115.sql diff --git a/microsetta_private_api/db/patches/0115.sql b/microsetta_private_api/db/patches/0115.sql deleted file mode 100644 index 65d9467c3..000000000 --- a/microsetta_private_api/db/patches/0115.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE barcodes.rack_samples ( - location_id uuid NOT NULL DEFAULT uuid_generate_v4(), - rack_id varchar NOT NULL, - sample_id varchar NOT NULL, - location_row varchar NOT NULL, - location_col varchar NOT NULL, - date_time TIMESTAMP WITH TIME ZONE NOT NULL, - PRIMARY KEY (location_id) -); - -ALTER TABLE barcodes.rack_samples -ADD COLUMN scan_id varchar NOT NULL; \ No newline at end of file From f7d26bffbd18a81a2e8ebb16277d30df6bc08988 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Thu, 8 Jun 2023 13:34:37 -0400 Subject: [PATCH 17/19] change file name --- microsetta_private_api/db/patches/0116.sql | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 microsetta_private_api/db/patches/0116.sql diff --git a/microsetta_private_api/db/patches/0116.sql b/microsetta_private_api/db/patches/0116.sql new file mode 100644 index 000000000..65d9467c3 --- /dev/null +++ b/microsetta_private_api/db/patches/0116.sql @@ -0,0 +1,12 @@ +CREATE TABLE barcodes.rack_samples ( + location_id uuid NOT NULL DEFAULT uuid_generate_v4(), + rack_id varchar NOT NULL, + sample_id varchar NOT NULL, + location_row varchar NOT NULL, + location_col varchar NOT NULL, + date_time TIMESTAMP WITH TIME ZONE NOT NULL, + PRIMARY KEY (location_id) +); + +ALTER TABLE barcodes.rack_samples +ADD COLUMN scan_id varchar NOT NULL; \ No newline at end of file From a7e58c87cba87509f321af5a1af032a1ea3ed4b2 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Thu, 8 Jun 2023 14:07:33 -0400 Subject: [PATCH 18/19] update 0114 to undo changes --- microsetta_private_api/db/patches/0114.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/microsetta_private_api/db/patches/0114.sql b/microsetta_private_api/db/patches/0114.sql index 86cbae812..471b660d2 100644 --- a/microsetta_private_api/db/patches/0114.sql +++ b/microsetta_private_api/db/patches/0114.sql @@ -32,7 +32,8 @@ UPDATE ag.group_questions SET survey_group = -14, display_index = 37 WHERE surve UPDATE ag.survey_question SET american = 'In the past month, have you been exposed to someone likely to have Coronavirus/COVID-19? (check all that apply)' WHERE survey_question_id = 211; UPDATE ag.survey_question SET american = 'In the past month, have you been suspected of having Coronavirus/COVID-19 infection?' WHERE survey_question_id = 212; UPDATE ag.survey_question SET american = 'In the past 6 weeks, have you had any of the following symptoms? (check all that apply)' WHERE survey_question_id = 214; - +INSERT INTO ag.survey_response (american, spanish, spain_spanish) VALUES ('Lack of appetite', 'Falta de apetito', 'Falta de apetito'); +UPDATE ag.survey_question_response SET response = 'Lack of appetite' WHERE response = 'Lack of appetitie'; -- Now let's add new options. First, we'll add the options to the database INSERT INTO ag.survey_response (american) VALUES ('Shortness of breath or difficulty breathing'), From fb6de2e6087f6da221fb149c8d17e44295c81f23 Mon Sep 17 00:00:00 2001 From: ragini7913 Date: Thu, 8 Jun 2023 14:30:03 -0400 Subject: [PATCH 19/19] fix 0114 --- microsetta_private_api/db/patches/0114.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/microsetta_private_api/db/patches/0114.sql b/microsetta_private_api/db/patches/0114.sql index 471b660d2..f24c11791 100644 --- a/microsetta_private_api/db/patches/0114.sql +++ b/microsetta_private_api/db/patches/0114.sql @@ -32,6 +32,9 @@ UPDATE ag.group_questions SET survey_group = -14, display_index = 37 WHERE surve UPDATE ag.survey_question SET american = 'In the past month, have you been exposed to someone likely to have Coronavirus/COVID-19? (check all that apply)' WHERE survey_question_id = 211; UPDATE ag.survey_question SET american = 'In the past month, have you been suspected of having Coronavirus/COVID-19 infection?' WHERE survey_question_id = 212; UPDATE ag.survey_question SET american = 'In the past 6 weeks, have you had any of the following symptoms? (check all that apply)' WHERE survey_question_id = 214; + +-- Adjust the options for question 214 +-- First, let's fix the typo in "Loss of appetite" - we'll leave the old option in the database so as to not break existing records INSERT INTO ag.survey_response (american, spanish, spain_spanish) VALUES ('Lack of appetite', 'Falta de apetito', 'Falta de apetito'); UPDATE ag.survey_question_response SET response = 'Lack of appetite' WHERE response = 'Lack of appetitie'; -- Now let's add new options. First, we'll add the options to the database