diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py
index 06edc09e9e6a3782f71f7390ed390dc0ee4d6266..39165fae8e5bc0893f773be2a2116f221c1b461c 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py
@@ -417,7 +417,7 @@ class Filesystem(NamedCommon):
 
     def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
         if self.directory and not self.directory.endswith('/'):
-            raise ValueError('directory value must end with a trailing slash!')  # todo: ...and needs to start with slash?
+            self.directory += '/'
 
         super().save(force_insert, force_update, using, update_fields)
 
diff --git a/SAS/TMSS/backend/test/t_complex_serializers.sh b/SAS/TMSS/backend/test/t_complex_serializers.sh
index 63ecb0c21ef0f6ae6d8ccc6d0c4d88d826a4189d..a1ebf8e5b3be2a3357f310b5baa582316304e21b 100755
--- a/SAS/TMSS/backend/test/t_complex_serializers.sh
+++ b/SAS/TMSS/backend/test/t_complex_serializers.sh
@@ -1,3 +1,3 @@
 #!/bin/sh
 
-./runctest.sh t_scheduling
\ No newline at end of file
+./runctest.sh t_complex_serializers
\ No newline at end of file
diff --git a/SAS/TMSS/backend/test/t_scheduling.py b/SAS/TMSS/backend/test/t_scheduling.py
index 73892be8d0b9f8c95f1fa9aa0c0e28a2f39b85ef..c18ab360dc3f0e0d68f4d80ba558cef0ec2dca2a 100755
--- a/SAS/TMSS/backend/test/t_scheduling.py
+++ b/SAS/TMSS/backend/test/t_scheduling.py
@@ -555,14 +555,26 @@ class TestWithUC1Specifications(unittest.TestCase):
         # clean all specs/tasks/claims in RADB (cascading delete)
         for spec in tmss_test_env.ra_test_environment.radb.getSpecifications():
             tmss_test_env.ra_test_environment.radb.deleteSpecification(spec['id'])
-        # Set subtask back to 'defined', start_time to now (and no stoptime)
+        # Unschedule subtask, setting it back to 'defined', removing all dataproducts.
         for tb in self.task_blueprints:
             for subtask in tb.subtasks.all():
-                subtask.state = models.SubtaskState.objects.get(value="defined")
+                if subtask.state.value == SubtaskState.Choices.SCHEDULED.value:
+                    unschedule_subtask(subtask)
+                if subtask.state.value == SubtaskState.Choices.ERROR.value:
+                    subtask.state = SubtaskState.objects.get(value=SubtaskState.Choices.DEFINED.value)
+
+                for output in subtask.outputs.all():
+                    # delete all transforms (the producers of the output dataproducts), and the the dataproducts themselves
+                    output.dataproducts.all().select_related('producers').delete()
+                    output.dataproducts.all().delete()
+
+                # start_time to now (and no stoptime)
                 subtask.stop_time = None
                 subtask.start_time = datetime.utcnow()
                 subtask.save()
 
+
+
     def _schedule_subtask_with_failure(self, station_reserved):
         with tmss_test_env.create_tmss_client() as client:
             with self.assertRaises(Exception) as context:
diff --git a/SAS/TMSS/backend/test/t_tmssapp_scheduling_django_API.py b/SAS/TMSS/backend/test/t_tmssapp_scheduling_django_API.py
index fe6cf69a5aa12bf6df9dd788a1f4b4de20732b87..682f22659885f52e3a3632ab288861efa19b3b5e 100755
--- a/SAS/TMSS/backend/test/t_tmssapp_scheduling_django_API.py
+++ b/SAS/TMSS/backend/test/t_tmssapp_scheduling_django_API.py
@@ -448,14 +448,9 @@ class FilesystemTest(unittest.TestCase):
         self.assertLess(before, entry.updated_at)
         self.assertGreater(after, entry.updated_at)
 
-    def test_Filesystem_raises_ValueError_on_invalid_directory_name(self):
-
-        # setup
-        test_data = Filesystem_test_data(directory="/no/trailing/slash")
-
-        # assert
-        with self.assertRaises(ValueError):
-            entry = models.Filesystem.objects.create(**test_data)
+    def test_Filesystem_appends_trailing_slash_to_dirname(self):
+        fs = models.Filesystem.objects.create(**Filesystem_test_data(directory="/no/trailing/slash"))
+        self.assertTrue(fs.directory.endswith('/'))
 
 
 class ClusterTest(unittest.TestCase):
diff --git a/SAS/TMSS/backend/test/t_tmssapp_specification_django_API.py b/SAS/TMSS/backend/test/t_tmssapp_specification_django_API.py
index c07159c9116256563cbbabd1212a679604ecac75..fb612a0416d7b17b3e18e257a5775c6c501be218 100755
--- a/SAS/TMSS/backend/test/t_tmssapp_specification_django_API.py
+++ b/SAS/TMSS/backend/test/t_tmssapp_specification_django_API.py
@@ -341,18 +341,18 @@ class ProjectTest(unittest.TestCase):
         self.assertLess(before, entry.updated_at)
         self.assertGreater(after, entry.updated_at)
 
-    def test_Project_raises_ValueError_on_invalid_archive_subdirectory_name(self):
-
+class FileSystemTest(unittest.TestCase):
+    def test_directory_always_ends_with_slash(self):
         # setup
-        test_data_1 = Project_test_data(archive_subdirectory="no/trailing/slash")
-        test_data_2 = Project_test_data(archive_subdirectory="/with/leading/slash/")
+        test_data_1 = Filesystem_test_data(directory="/no/trailing/slash")
+        test_data_2 = Filesystem_test_data(directory="/with/trailing/slash/")
 
         # assert
-        with self.assertRaises(ValueError):
-            entry = models.Project.objects.create(**test_data_1)
+        entry1 = models.Filesystem.objects.create(**test_data_1)
+        self.assertTrue(entry1.directory.endswith('/'))
 
-        with self.assertRaises(ValueError):
-            entry = models.Project.objects.create(**test_data_2)
+        entry2 = models.Filesystem.objects.create(**test_data_2)
+        self.assertTrue(entry2.directory.endswith('/'))
 
 
 class ProjectQuotaTest(unittest.TestCase):
@@ -366,6 +366,36 @@ class ProjectQuotaTest(unittest.TestCase):
             models.ProjectQuota.objects.create(**test_data)
 
 
+class ProjectQuotaArchiveLocationTest(unittest.TestCase):
+    def test_archive_location_must_be_archive_site(self):
+        with self.assertRaises(ValueError):
+            test_data = dict(ProjectQuotaArchiveLocation_test_data(archive_location=models.Filesystem.objects.create(**Filesystem_test_data(cluster=models.Cluster.objects.create(**Cluster_test_data(archive_site=False))))))
+            models.ProjectQuotaArchiveLocation.objects.create(**test_data)
+
+        test_data = dict(ProjectQuotaArchiveLocation_test_data(archive_location=models.Filesystem.objects.create(**Filesystem_test_data(cluster=models.Cluster.objects.create(**Cluster_test_data(archive_site=True))))))
+        models.ProjectQuotaArchiveLocation.objects.create(**test_data)
+
+    def test_quota_must_be_bytes(self):
+        with self.assertRaises(ValueError):
+            test_data = dict(ProjectQuotaArchiveLocation_test_data(project_quota = models.ProjectQuota.objects.create(**ProjectQuota_test_data(resource_type=models.ResourceType.objects.create(**ResourceType_test_data(quantity=models.Quantity.objects.get(value=models.Quantity.Choices.NUMBER.value)))))))
+            models.ProjectQuotaArchiveLocation.objects.create(**test_data)
+
+        test_data = dict(ProjectQuotaArchiveLocation_test_data(project_quota=models.ProjectQuota.objects.create(**ProjectQuota_test_data(resource_type=models.ResourceType.objects.create(**ResourceType_test_data(quantity=models.Quantity.objects.get(value=models.Quantity.Choices.BYTES.value)))))))
+        models.ProjectQuotaArchiveLocation.objects.create(**test_data)
+
+    def test_uri(self):
+        PROJECT_NAME = "TestProject"
+        SURL = "srm://my.srm.site:1234/path/to/data"
+        project = models.Project.objects.create(**Project_test_data(name=PROJECT_NAME))
+        archive_location = models.Filesystem.objects.create(**Filesystem_test_data(directory=SURL))
+        quota = models.ProjectQuota.objects.create(**ProjectQuota_test_data(project=project))
+
+        pqal = models.ProjectQuotaArchiveLocation.objects.create(**ProjectQuotaArchiveLocation_test_data(project_quota=quota, archive_location=archive_location))
+        self.assertEqual(PROJECT_NAME.lower(), pqal.archive_subdirectory)
+        self.assertEqual(SURL+'/'+PROJECT_NAME.lower()+'/', pqal.full_archive_uri)
+
+
+
 class SchedulingSetTest(unittest.TestCase):
 
     def test_SchedulingSet_gets_created_with_correct_creation_timestamp(self):
diff --git a/SAS/TMSS/backend/test/tmss_test_data_django_models.py b/SAS/TMSS/backend/test/tmss_test_data_django_models.py
index 8035afbcfc136067fe9d5da53e8362c4c4063742..7d3e065be36e697dd96a80777a6a9c9044fce46d 100644
--- a/SAS/TMSS/backend/test/tmss_test_data_django_models.py
+++ b/SAS/TMSS/backend/test/tmss_test_data_django_models.py
@@ -117,7 +117,7 @@ def Cycle_test_data() -> dict:
             "start": datetime.utcnow().isoformat(),
             "stop": datetime.utcnow().isoformat()}
 
-def Project_test_data(name: str=None, priority_rank: int = 1, archive_subdirectory="my_project/", auto_pin=False) -> dict:
+def Project_test_data(name: str=None, priority_rank: int = 1, auto_pin=False) -> dict:
     if name is None:
         name = 'my_project_' + str(uuid.uuid4())
 
@@ -132,24 +132,47 @@ def Project_test_data(name: str=None, priority_rank: int = 1, archive_subdirecto
                "private_data": True,
                "expert": True,
                "filler": False,
-               "archive_subdirectory": archive_subdirectory,
                "auto_pin": auto_pin}
 
-def ResourceType_test_data() -> dict:
+def ResourceType_test_data(quantity: models.Quantity=None) -> dict:
+    if quantity is None:
+        quantity = models.Quantity.objects.get(value=models.Quantity.Choices.BYTES.value)
+
     return  {
         "tags": [],
         "description": 'my description ' + str(uuid.uuid4()),
         "name": 'my_resource_type_' + str(uuid.uuid4()),
-        "quantity": models.Quantity.objects.get(value=models.Quantity.Choices.NUMBER.value)
+        "quantity": quantity
      }
 
-def ProjectQuota_test_data() -> dict:
-   return  { 
-        "value": '1000',
-        "project": models.Project.objects.create(**Project_test_data()),
-        "resource_type": models.ResourceType.objects.create(**ResourceType_test_data())
+
+def ProjectQuota_test_data(value: int=1000, project: models.Project=None, resource_type: models.ResourceType=None) -> dict:
+    if project is None:
+        project = models.Project.objects.create(**Project_test_data())
+
+    if resource_type is None:
+        resource_type = models.ResourceType.objects.create(**ResourceType_test_data())
+
+    return {
+        "value": value,
+        "project": project,
+        "resource_type": resource_type
     }
-  
+
+
+def ProjectQuotaArchiveLocation_test_data(project_quota: models.ProjectQuota=None, archive_location: models.Filesystem=None) -> dict:
+    if project_quota is None:
+        project_quota = models.ProjectQuota.objects.create(**ProjectQuota_test_data())
+
+    if archive_location is None:
+        archive_location = models.Filesystem.objects.create(**Filesystem_test_data())
+
+    return {
+        "project_quota": project_quota,
+        "archive_location": archive_location
+    }
+
+
 def SchedulingSet_test_data(name="my_scheduling_set", project: models.Project=None) -> dict:
     if project is None:
         project = models.Project.objects.create(**Project_test_data())
@@ -404,8 +427,8 @@ def Subtask_test_data(task_blueprint: models.TaskBlueprint=None, subtask_templat
              "global_identifier": models.SIPidentifier.objects.create(source="TMSS")}
 
 def Dataproduct_test_data(producer: models.SubtaskOutput=None,
-                          filename: str="my_file.ext",
-                          directory: str="/data/test-projects",
+                          filename: str=None,
+                          directory: str=None,
                           dataformat: models.Dataformat=None,
                           datatype: models.Datatype=None,
                           specifications_doc: object=None,
@@ -413,6 +436,12 @@ def Dataproduct_test_data(producer: models.SubtaskOutput=None,
                           feedback_doc: object = None,
                           feedback_template: models.DataproductFeedbackTemplate = None) -> dict:
 
+    if filename is None:
+        filename = "my_file_%s.ext" % uuid.uuid4()
+
+    if directory is None:
+        directory = "/tmp/test_data/%s/" % uuid.uuid4()
+
     if producer is None:
         producer = models.SubtaskOutput.objects.create(**SubtaskOutput_test_data())
 
@@ -466,16 +495,19 @@ def DataproductTransform_test_data() -> dict:
                         "identity": True,
                         "tags": ['tmss', 'testing']}
 
-def Filesystem_test_data(directory="/") -> dict:
+def Filesystem_test_data(directory: str="/", cluster: models.Cluster=None) -> dict:
+    if cluster is None:
+        cluster = models.Cluster.objects.create(**Cluster_test_data())
+
     return {"capacity": 1111111111,
-                        "cluster": models.Cluster.objects.create(**Cluster_test_data()),
+                        "cluster": cluster,
                         "directory": directory,
                         "tags": ['tmss', 'testing']}
 
-def Cluster_test_data(name="default cluster") -> dict:
+def Cluster_test_data(name: str="default cluster", archive_site: bool=True) -> dict:
     return {"name": name,
             "location": "upstairs",
-            "archive_site": True,
+            "archive_site": archive_site,
             "tags": ['tmss', 'testing']}
 
 def DataproductArchiveInfo_test_data() -> dict:
diff --git a/SAS/TMSS/backend/test/tmss_test_data_rest.py b/SAS/TMSS/backend/test/tmss_test_data_rest.py
index bc90c5ac03346f5226a834a7922545223a37b81d..44a4cf68156c45053fe0624cacfc7139b1fdb12a 100644
--- a/SAS/TMSS/backend/test/tmss_test_data_rest.py
+++ b/SAS/TMSS/backend/test/tmss_test_data_rest.py
@@ -251,7 +251,6 @@ class TMSSRESTTestDataCreator():
                 "can_trigger": False,
                 "private_data": True,
                 "cycles": cycle_urls,
-                "archive_subdirectory": 'my_project/',
                 "auto_pin": auto_pin}
 
     @property