feat(product-suite): support temporary item drafts

This commit is contained in:
chengma
2026-07-16 11:10:51 +08:00
parent ec62e34807
commit ecd2ecb758
8 changed files with 767 additions and 27 deletions
+68
View File
@@ -57,6 +57,8 @@ class ImageStudioTests(TempDirMixin, unittest.TestCase):
"account_alias",
"account_slug",
"item_id",
"storage_key",
"binding_state",
"target_main_count",
"target_detail_count",
"suite_settings_json",
@@ -114,6 +116,8 @@ class ImageStudioTests(TempDirMixin, unittest.TestCase):
self.assertEqual("{}", project.suite_settings_json)
self.assertEqual({}, image_studio.project_suite_settings(project))
self.assertEqual("51100639510", project.storage_key)
self.assertEqual(image_studio.PROJECT_BINDING_BOUND, project.binding_state)
self.assert_removed(temp_dir)
@@ -152,6 +156,8 @@ class ImageStudioTests(TempDirMixin, unittest.TestCase):
self.assertEqual("alias_a_slug", project.account_slug)
self.assertEqual("店铺A", project.account_name)
self.assertEqual("初始提示词", project.draft_prompt)
self.assertEqual("51100639510", project.storage_key)
self.assertEqual(image_studio.PROJECT_BINDING_BOUND, project.binding_state)
updated = image_studio.update_project_prompt(project.id, "二次提示词", path=db_path)
self.assertEqual("二次提示词", updated.draft_prompt)
@@ -213,6 +219,68 @@ class ImageStudioTests(TempDirMixin, unittest.TestCase):
self.assert_removed(temp_dir)
def test_draft_projects_bind_in_place_recover_and_conflict_safely(self):
with self.make_temp_dir() as temp_dir:
db_path = os.path.join(temp_dir, "cmshopee.db")
db.init_db(db_path)
account = SimpleNamespace(
alias="alias-a",
account_name="主店",
slug="alias_a",
)
draft = image_studio.create_draft_project(
account,
draft_prompt="临时草稿提示词",
path=db_path,
)
self.assertTrue(draft.item_id.startswith(image_studio.TEMPORARY_ITEM_PREFIX))
self.assertEqual(draft.item_id, draft.storage_key)
self.assertEqual(image_studio.PROJECT_BINDING_DRAFT, draft.binding_state)
self.assertFalse(image_studio.project_has_content(draft.id, path=db_path))
self.assertEqual([], image_studio.list_recoverable_draft_projects(path=db_path))
before_dirs = image_studio.project_image_dirs(os.path.join(temp_dir, "images"), draft)
original = image_studio.add_asset(
draft.id,
image_studio.ASSET_KIND_ORIGINAL,
local_path=os.path.join(temp_dir, "draft.png"),
path=db_path,
)
job = image_studio.create_job(
draft.id,
source_asset_id=original.id,
path=db_path,
)
image_studio.replace_selections(draft.id, "main", [original.id], path=db_path)
self.assertTrue(image_studio.project_has_content(draft.id, path=db_path))
self.assertEqual([draft.id], [project.id for project in image_studio.list_recoverable_draft_projects(path=db_path)])
conflict = image_studio.create_or_get_project(
account,
item_id="51100639510",
path=db_path,
)
image_studio.soft_delete_project(conflict.id, "历史项目", path=db_path)
with self.assertRaises(image_studio.ImageStudioProjectConflictError):
image_studio.bind_draft_project(draft.id, "51100639510", path=db_path)
bound = image_studio.bind_draft_project(draft.id, "51100639511", path=db_path)
self.assertEqual(draft.id, bound.id)
self.assertEqual("51100639511", bound.item_id)
self.assertEqual(image_studio.PROJECT_BINDING_BOUND, bound.binding_state)
self.assertEqual(draft.storage_key, bound.storage_key)
self.assertEqual(before_dirs, image_studio.project_image_dirs(os.path.join(temp_dir, "images"), bound))
self.assertEqual(job.id, image_studio.list_jobs(bound.id, path=db_path)[0].id)
self.assertEqual(original.id, image_studio.list_selections(bound.id, "main", path=db_path)[0].asset_id)
self.assertEqual(bound, image_studio.bind_draft_project(bound.id, "51100639511", path=db_path))
empty = image_studio.create_draft_project(account, path=db_path)
discarded = image_studio.discard_empty_draft_project(empty.id, path=db_path)
self.assertIsNotNone(discarded.deleted_at)
self.assert_removed(temp_dir)
def test_asset_crud_parent_status_and_sorting(self):
with self.make_temp_dir() as temp_dir:
db_path = os.path.join(temp_dir, "cmshopee.db")