ktsn-ud commited on
Commit
0349071
·
1 Parent(s): e79e2b5

テキスト情報を承認済みで最新のものから取ってくるように変更

Browse files
SQL_IMPLEMENTATION.md ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ `app/repositories/query.sql`を,以下のように変更してください。
2
+ - 最終的に得られるカラムに「descriptionUpdates」「prSummaryUpdates」「prDetailUpdates」「remarkUpdates」を追加してください。
3
+ - 型:{
4
+ content: string,
5
+ updateStatus: string | null,
6
+ createdAt: DateTime
7
+ }[]
8
+
9
+ なお,本変更のゴールとしては,`app/repositories/projects_repository.py`内の`_transform_row`において,「***Updates」があり,なおかつstatus=APPROVEDとなっている最新のものが存在すればそれのcontentをdescription, prSummary, prDetail, remarkとし,存在しないならば従来のdescription, prSummary, prDetail, remarkを採用することを目指します。description, prSummary, prDetail, remarkは独立に採用を決定してください。要するに,テキストデータが更新される可能性があるので最新のものをピックアップしてください。
10
+
11
+ 実装に当たっては以下のprismaのモデルを参考にしてください。
12
+
13
+ ```prisma
14
+ enum CPUpdateRequestStatus {
15
+ DRAFT
16
+ PENDING_REVIEW
17
+ APPROVED
18
+ REJECTED
19
+ }
20
+
21
+ // 企画に関するテキスト情報(サマリー、説明、PR文)
22
+ model ProjectText {
23
+ id String @id @default(dbgenerated("(UUID())"))
24
+ circleProject CircleProject @relation(name: "circle_project_texts", fields: [circleProjectId], references: [id], onDelete: Cascade)
25
+ circleProjectId String
26
+ textType TextType // DESCRIPTION, PRSUMMARY, PRDETAIL, REMARK
27
+ content String @db.Text // テキスト内容
28
+ updateRequest ProjectMaterialUpdateRequest? @relation("update_request_text")
29
+ createdAt DateTime @default(now())
30
+ updatedAt DateTime @updatedAt @default(now())
31
+ }
32
+
33
+ // 画像情報の管理
34
+ model Image {
35
+ id String @id @default(dbgenerated("(UUID())"))
36
+ filename String
37
+ extension String
38
+ createdAt DateTime @default(now())
39
+ updatedAt DateTime @updatedAt @default(now())
40
+ cproject CircleProject @relation(name: "cproject_image", fields: [cprojectId], references: [id])
41
+ cprojectId String
42
+ order Int
43
+ updateRequest ProjectMaterialUpdateRequest? @relation("update_request_image")
44
+ }
45
+
46
+ // SNSデータ
47
+ model SnsData {
48
+ id String @id @default(dbgenerated("(UUID())"))
49
+ service String // SNSサービス名 (Twitter, Instagram, etc.)
50
+ url String // ユーザー名/ハンドル
51
+ label String?
52
+ circleProject CircleProject @relation(name: "circle_project_sns", fields: [circleProjectId], references: [id], onDelete: Cascade)
53
+ circleProjectId String
54
+ updateRequest ProjectMaterialUpdateRequest? @relation("update_request_snsdata")
55
+ createdAt DateTime @default(now())
56
+ updatedAt DateTime @updatedAt @default(now())
57
+ }
58
+
59
+ model ProjectMaterialUpdateRequest {
60
+ id String @id @default(dbgenerated("(UUID())"))
61
+ targetType CPUpdateRequestType
62
+ targetSns SnsData? @relation(name: "update_request_snsdata", fields: [targetSnsId], references: [id])
63
+ targetSnsId String? @unique
64
+ targetText ProjectText? @relation(name: "update_request_text", fields: [targetTextId], references: [id])
65
+ targetTextId String? @unique
66
+ targetImage Image? @relation(name: "update_request_image", fields: [targetImageId], references: [id])
67
+ targetImageId String? @unique
68
+ status CPUpdateRequestStatus
69
+ requester User @relation(name: "cp_update_requester", fields: [requesterId], references: [id])
70
+ requesterId String
71
+ observer User? @relation(name: "cp_update_observer", fields: [observerId], references: [id])
72
+ observerId String?
73
+ createdAt DateTime @default(now())
74
+ updatedAt DateTime @updatedAt @default(now())
75
+ }
76
+ ```
77
+
app/repositories/projects_repository.py CHANGED
@@ -80,6 +80,25 @@ class ProjectsRepository:
80
  items.append(item)
81
  return items
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  return Project(
84
  projectId=row["projectId"],
85
  circleName=row["circleName"],
@@ -91,10 +110,10 @@ class ProjectsRepository:
91
  day2=row["day2"],
92
  day3=row["day3"],
93
  location=row["location"],
94
- description=row["description"],
95
- prSummary=row["prSummary"],
96
- prDetail=row["prDetail"],
97
- remark=row.get("remark") or None,
98
  images=[Image(**img) for img in _coerce_dict_list(row.get("images"))],
99
  socialMedia=[
100
  Sns(**url) for url in _coerce_dict_list(row.get("socialMedia"))
 
80
  items.append(item)
81
  return items
82
 
83
+ def _resolve_text(default_key: str, updates_key: str) -> str | None:
84
+ updates = sorted(
85
+ _coerce_dict_list(row.get(updates_key)),
86
+ key=lambda item: item.get("createdAt") or "",
87
+ reverse=True,
88
+ )
89
+ for update in updates:
90
+ status = update.get("updateStatus")
91
+ if isinstance(status, str) and status.upper() == "APPROVED":
92
+ content = update.get("content")
93
+ if isinstance(content, str):
94
+ return content
95
+ return row.get(default_key)
96
+
97
+ description_value = _resolve_text("description", "descriptionUpdates")
98
+ pr_summary_value = _resolve_text("prSummary", "prSummaryUpdates")
99
+ pr_detail_value = _resolve_text("prDetail", "prDetailUpdates")
100
+ remark_value = _resolve_text("remark", "remarkUpdates")
101
+
102
  return Project(
103
  projectId=row["projectId"],
104
  circleName=row["circleName"],
 
110
  day2=row["day2"],
111
  day3=row["day3"],
112
  location=row["location"],
113
+ description=description_value,
114
+ prSummary=pr_summary_value,
115
+ prDetail=pr_detail_value,
116
+ remark=remark_value or None,
117
  images=[Image(**img) for img in _coerce_dict_list(row.get("images"))],
118
  socialMedia=[
119
  Sns(**url) for url in _coerce_dict_list(row.get("socialMedia"))
app/repositories/query.sql CHANGED
@@ -13,6 +13,10 @@ SELECT
13
  texts.prSummary AS `prSummary`,
14
  texts.prDetail AS `prDetail`,
15
  texts.remark AS `remark`,
 
 
 
 
16
  COALESCE(images.`images`, '[]') AS `images`,
17
  COALESCE(sns.socialMedia, '[]') AS `socialMedia`,
18
  COALESCE(tags.tags, '[]') AS `tags`
@@ -45,6 +49,34 @@ LEFT JOIN (
45
  ) AS texts
46
  ON texts.circleProjectId = cp.id
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  -- 画像情報を結合
49
  LEFT JOIN (
50
  SELECT
 
13
  texts.prSummary AS `prSummary`,
14
  texts.prDetail AS `prDetail`,
15
  texts.remark AS `remark`,
16
+ COALESCE(textUpdates.descriptionUpdates, '[]') AS `descriptionUpdates`,
17
+ COALESCE(textUpdates.prSummaryUpdates, '[]') AS `prSummaryUpdates`,
18
+ COALESCE(textUpdates.prDetailUpdates, '[]') AS `prDetailUpdates`,
19
+ COALESCE(textUpdates.remarkUpdates, '[]') AS `remarkUpdates`,
20
  COALESCE(images.`images`, '[]') AS `images`,
21
  COALESCE(sns.socialMedia, '[]') AS `socialMedia`,
22
  COALESCE(tags.tags, '[]') AS `tags`
 
49
  ) AS texts
50
  ON texts.circleProjectId = cp.id
51
 
52
+ -- テキストの更新履歴を結合
53
+ LEFT JOIN (
54
+ SELECT
55
+ typed.circleProjectId,
56
+ MAX(CASE WHEN typed.textType = 'DESCRIPTION' THEN typed.updates END) AS descriptionUpdates,
57
+ MAX(CASE WHEN typed.textType = 'PRSUMMARY' THEN typed.updates END) AS prSummaryUpdates,
58
+ MAX(CASE WHEN typed.textType = 'PRDETAIL' THEN typed.updates END) AS prDetailUpdates,
59
+ MAX(CASE WHEN typed.textType = 'REMARK' THEN typed.updates END) AS remarkUpdates
60
+ FROM (
61
+ SELECT
62
+ pt.circleProjectId,
63
+ pt.textType,
64
+ JSON_ARRAYAGG(
65
+ JSON_OBJECT(
66
+ 'content', pt.content,
67
+ 'updateStatus', pmur.status,
68
+ 'createdAt', pt.createdAt
69
+ )
70
+ ) AS updates
71
+ FROM `ProjectText` AS pt
72
+ LEFT JOIN `ProjectMaterialUpdateRequest` AS pmur
73
+ ON pmur.targetTextId = pt.id
74
+ GROUP BY pt.circleProjectId, pt.textType
75
+ ) AS typed
76
+ GROUP BY typed.circleProjectId
77
+ ) AS textUpdates
78
+ ON textUpdates.circleProjectId = cp.id
79
+
80
  -- 画像情報を結合
81
  LEFT JOIN (
82
  SELECT