@spfn/cms 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +490 -0
  3. package/dist/actions.d.ts +9 -0
  4. package/dist/actions.d.ts.map +1 -0
  5. package/dist/actions.js +11 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/client.d.ts +138 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +62 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/cms.config.d.ts +77 -0
  12. package/dist/cms.config.d.ts.map +1 -0
  13. package/dist/cms.config.js +111 -0
  14. package/dist/cms.config.js.map +1 -0
  15. package/dist/entities/cms-audit-logs.d.ts +213 -0
  16. package/dist/entities/cms-audit-logs.d.ts.map +1 -0
  17. package/dist/entities/cms-audit-logs.js +103 -0
  18. package/dist/entities/cms-audit-logs.js.map +1 -0
  19. package/dist/entities/cms-draft-cache.d.ts +188 -0
  20. package/dist/entities/cms-draft-cache.d.ts.map +1 -0
  21. package/dist/entities/cms-draft-cache.js +112 -0
  22. package/dist/entities/cms-draft-cache.js.map +1 -0
  23. package/dist/entities/cms-label-values.d.ts +192 -0
  24. package/dist/entities/cms-label-values.d.ts.map +1 -0
  25. package/dist/entities/cms-label-values.js +105 -0
  26. package/dist/entities/cms-label-values.js.map +1 -0
  27. package/dist/entities/cms-label-versions.d.ts +207 -0
  28. package/dist/entities/cms-label-versions.d.ts.map +1 -0
  29. package/dist/entities/cms-label-versions.js +80 -0
  30. package/dist/entities/cms-label-versions.js.map +1 -0
  31. package/dist/entities/cms-labels.d.ts +189 -0
  32. package/dist/entities/cms-labels.d.ts.map +1 -0
  33. package/dist/entities/cms-labels.js +48 -0
  34. package/dist/entities/cms-labels.js.map +1 -0
  35. package/dist/entities/cms-published-cache.d.ts +199 -0
  36. package/dist/entities/cms-published-cache.d.ts.map +1 -0
  37. package/dist/entities/cms-published-cache.js +103 -0
  38. package/dist/entities/cms-published-cache.js.map +1 -0
  39. package/dist/entities/index.d.ts +10 -0
  40. package/dist/entities/index.d.ts.map +1 -0
  41. package/dist/entities/index.js +10 -0
  42. package/dist/entities/index.js.map +1 -0
  43. package/dist/generators/index.d.ts +19 -0
  44. package/dist/generators/index.d.ts.map +1 -0
  45. package/dist/generators/index.js +19 -0
  46. package/dist/generators/index.js.map +1 -0
  47. package/dist/generators/label-sync-generator.d.ts +33 -0
  48. package/dist/generators/label-sync-generator.d.ts.map +1 -0
  49. package/dist/generators/label-sync-generator.js +86 -0
  50. package/dist/generators/label-sync-generator.js.map +1 -0
  51. package/dist/helpers/locale.actions.d.ts +132 -0
  52. package/dist/helpers/locale.actions.d.ts.map +1 -0
  53. package/dist/helpers/locale.actions.js +210 -0
  54. package/dist/helpers/locale.actions.js.map +1 -0
  55. package/dist/helpers/locale.constants.d.ts +10 -0
  56. package/dist/helpers/locale.constants.d.ts.map +1 -0
  57. package/dist/helpers/locale.constants.js +10 -0
  58. package/dist/helpers/locale.constants.js.map +1 -0
  59. package/dist/helpers/locale.d.ts +17 -0
  60. package/dist/helpers/locale.d.ts.map +1 -0
  61. package/dist/helpers/locale.js +20 -0
  62. package/dist/helpers/locale.js.map +1 -0
  63. package/dist/helpers/sync.d.ts +41 -0
  64. package/dist/helpers/sync.d.ts.map +1 -0
  65. package/dist/helpers/sync.js +309 -0
  66. package/dist/helpers/sync.js.map +1 -0
  67. package/dist/index.d.ts +20 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +24 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/init.d.ts +31 -0
  72. package/dist/init.d.ts.map +1 -0
  73. package/dist/init.js +36 -0
  74. package/dist/init.js.map +1 -0
  75. package/dist/labels/helpers.d.ts +31 -0
  76. package/dist/labels/helpers.d.ts.map +1 -0
  77. package/dist/labels/helpers.js +60 -0
  78. package/dist/labels/helpers.js.map +1 -0
  79. package/dist/labels/index.d.ts +7 -0
  80. package/dist/labels/index.d.ts.map +1 -0
  81. package/dist/labels/index.js +7 -0
  82. package/dist/labels/index.js.map +1 -0
  83. package/dist/repositories/cms-draft-cache.repository.d.ts +62 -0
  84. package/dist/repositories/cms-draft-cache.repository.d.ts.map +1 -0
  85. package/dist/repositories/cms-draft-cache.repository.js +56 -0
  86. package/dist/repositories/cms-draft-cache.repository.js.map +1 -0
  87. package/dist/repositories/cms-label-values.repository.d.ts +32 -0
  88. package/dist/repositories/cms-label-values.repository.d.ts.map +1 -0
  89. package/dist/repositories/cms-label-values.repository.js +72 -0
  90. package/dist/repositories/cms-label-values.repository.js.map +1 -0
  91. package/dist/repositories/cms-labels.repository.d.ts +53 -0
  92. package/dist/repositories/cms-labels.repository.d.ts.map +1 -0
  93. package/dist/repositories/cms-labels.repository.js +77 -0
  94. package/dist/repositories/cms-labels.repository.js.map +1 -0
  95. package/dist/repositories/cms-published-cache.repository.d.ts +53 -0
  96. package/dist/repositories/cms-published-cache.repository.d.ts.map +1 -0
  97. package/dist/repositories/cms-published-cache.repository.js +54 -0
  98. package/dist/repositories/cms-published-cache.repository.js.map +1 -0
  99. package/dist/repositories/index.d.ts +8 -0
  100. package/dist/repositories/index.d.ts.map +1 -0
  101. package/dist/repositories/index.js +9 -0
  102. package/dist/repositories/index.js.map +1 -0
  103. package/dist/routes/labels/[id]/contract.d.ts +68 -0
  104. package/dist/routes/labels/[id]/contract.d.ts.map +1 -0
  105. package/dist/routes/labels/[id]/contract.js +84 -0
  106. package/dist/routes/labels/[id]/contract.js.map +1 -0
  107. package/dist/routes/labels/[id]/index.d.ts +10 -0
  108. package/dist/routes/labels/[id]/index.d.ts.map +1 -0
  109. package/dist/routes/labels/[id]/index.js +96 -0
  110. package/dist/routes/labels/[id]/index.js.map +1 -0
  111. package/dist/routes/labels/by-key/[key]/contract.d.ts +24 -0
  112. package/dist/routes/labels/by-key/[key]/contract.d.ts.map +1 -0
  113. package/dist/routes/labels/by-key/[key]/contract.js +28 -0
  114. package/dist/routes/labels/by-key/[key]/contract.js.map +1 -0
  115. package/dist/routes/labels/by-key/[key]/index.d.ts +8 -0
  116. package/dist/routes/labels/by-key/[key]/index.d.ts.map +1 -0
  117. package/dist/routes/labels/by-key/[key]/index.js +32 -0
  118. package/dist/routes/labels/by-key/[key]/index.js.map +1 -0
  119. package/dist/routes/labels/contract.d.ts +59 -0
  120. package/dist/routes/labels/contract.d.ts.map +1 -0
  121. package/dist/routes/labels/contract.js +75 -0
  122. package/dist/routes/labels/contract.js.map +1 -0
  123. package/dist/routes/labels/index.d.ts +10 -0
  124. package/dist/routes/labels/index.d.ts.map +1 -0
  125. package/dist/routes/labels/index.js +73 -0
  126. package/dist/routes/labels/index.js.map +1 -0
  127. package/dist/routes/published-cache/contract.d.ts +25 -0
  128. package/dist/routes/published-cache/contract.d.ts.map +1 -0
  129. package/dist/routes/published-cache/contract.js +35 -0
  130. package/dist/routes/published-cache/contract.js.map +1 -0
  131. package/dist/routes/published-cache/index.d.ts +8 -0
  132. package/dist/routes/published-cache/index.d.ts.map +1 -0
  133. package/dist/routes/published-cache/index.js +33 -0
  134. package/dist/routes/published-cache/index.js.map +1 -0
  135. package/dist/routes/sync/contract.d.ts +33 -0
  136. package/dist/routes/sync/contract.d.ts.map +1 -0
  137. package/dist/routes/sync/contract.js +34 -0
  138. package/dist/routes/sync/contract.js.map +1 -0
  139. package/dist/routes/sync/index.d.ts +13 -0
  140. package/dist/routes/sync/index.d.ts.map +1 -0
  141. package/dist/routes/sync/index.js +241 -0
  142. package/dist/routes/sync/index.js.map +1 -0
  143. package/dist/routes/values/[labelId]/[version]/contract.d.ts +29 -0
  144. package/dist/routes/values/[labelId]/[version]/contract.d.ts.map +1 -0
  145. package/dist/routes/values/[labelId]/[version]/contract.js +33 -0
  146. package/dist/routes/values/[labelId]/[version]/contract.js.map +1 -0
  147. package/dist/routes/values/[labelId]/[version]/index.d.ts +8 -0
  148. package/dist/routes/values/[labelId]/[version]/index.d.ts.map +1 -0
  149. package/dist/routes/values/[labelId]/[version]/index.js +45 -0
  150. package/dist/routes/values/[labelId]/[version]/index.js.map +1 -0
  151. package/dist/routes/values/[labelId]/contract.d.ts +38 -0
  152. package/dist/routes/values/[labelId]/contract.d.ts.map +1 -0
  153. package/dist/routes/values/[labelId]/contract.js +59 -0
  154. package/dist/routes/values/[labelId]/contract.js.map +1 -0
  155. package/dist/routes/values/[labelId]/index.d.ts +8 -0
  156. package/dist/routes/values/[labelId]/index.d.ts.map +1 -0
  157. package/dist/routes/values/[labelId]/index.js +42 -0
  158. package/dist/routes/values/[labelId]/index.js.map +1 -0
  159. package/dist/server.d.ts +99 -0
  160. package/dist/server.d.ts.map +1 -0
  161. package/dist/server.js +256 -0
  162. package/dist/server.js.map +1 -0
  163. package/dist/store.d.ts +87 -0
  164. package/dist/store.d.ts.map +1 -0
  165. package/dist/store.js +205 -0
  166. package/dist/store.js.map +1 -0
  167. package/dist/sync.d.ts +11 -0
  168. package/dist/sync.d.ts.map +1 -0
  169. package/dist/sync.js +179 -0
  170. package/dist/sync.js.map +1 -0
  171. package/dist/types.d.ts +74 -0
  172. package/dist/types.d.ts.map +1 -0
  173. package/dist/types.js +7 -0
  174. package/dist/types.js.map +1 -0
  175. package/package.json +95 -0
@@ -0,0 +1,188 @@
1
+ /**
2
+ * CMS Draft Cache Entity
3
+ *
4
+ * 관리자별 Draft 콘텐츠를 캐싱합니다.
5
+ * - 사용자별 격리 (userId)
6
+ * - 실시간 미리보기 지원
7
+ * - 동시 편집 가능
8
+ *
9
+ * 핵심 기능:
10
+ * - 여러 관리자가 같은 섹션을 동시에 편집
11
+ * - 각자의 변경사항은 자신의 미리보기에만 표시
12
+ * - 충돌 없이 안전하게 작업
13
+ */
14
+ export declare const cmsDraftCache: import("drizzle-orm/pg-core").PgTableWithColumns<{
15
+ name: "draft_cache";
16
+ schema: string;
17
+ columns: {
18
+ id: import("drizzle-orm/pg-core").PgColumn<{
19
+ name: "id";
20
+ tableName: "draft_cache";
21
+ dataType: "number";
22
+ columnType: "PgSerial";
23
+ data: number;
24
+ driverParam: number;
25
+ notNull: true;
26
+ hasDefault: true;
27
+ isPrimaryKey: true;
28
+ isAutoincrement: false;
29
+ hasRuntimeDefault: false;
30
+ enumValues: undefined;
31
+ baseColumn: never;
32
+ identity: undefined;
33
+ generated: undefined;
34
+ }, {}, {}>;
35
+ section: import("drizzle-orm/pg-core").PgColumn<{
36
+ name: "section";
37
+ tableName: "draft_cache";
38
+ dataType: "string";
39
+ columnType: "PgText";
40
+ data: string;
41
+ driverParam: string;
42
+ notNull: true;
43
+ hasDefault: false;
44
+ isPrimaryKey: false;
45
+ isAutoincrement: false;
46
+ hasRuntimeDefault: false;
47
+ enumValues: [string, ...string[]];
48
+ baseColumn: never;
49
+ identity: undefined;
50
+ generated: undefined;
51
+ }, {}, {}>;
52
+ locale: import("drizzle-orm/pg-core").PgColumn<{
53
+ name: "locale";
54
+ tableName: "draft_cache";
55
+ dataType: "string";
56
+ columnType: "PgText";
57
+ data: string;
58
+ driverParam: string;
59
+ notNull: true;
60
+ hasDefault: false;
61
+ isPrimaryKey: false;
62
+ isAutoincrement: false;
63
+ hasRuntimeDefault: false;
64
+ enumValues: [string, ...string[]];
65
+ baseColumn: never;
66
+ identity: undefined;
67
+ generated: undefined;
68
+ }, {}, {}>;
69
+ userId: import("drizzle-orm/pg-core").PgColumn<{
70
+ name: "user_id";
71
+ tableName: "draft_cache";
72
+ dataType: "string";
73
+ columnType: "PgText";
74
+ data: string;
75
+ driverParam: string;
76
+ notNull: true;
77
+ hasDefault: false;
78
+ isPrimaryKey: false;
79
+ isAutoincrement: false;
80
+ hasRuntimeDefault: false;
81
+ enumValues: [string, ...string[]];
82
+ baseColumn: never;
83
+ identity: undefined;
84
+ generated: undefined;
85
+ }, {}, {}>;
86
+ content: import("drizzle-orm/pg-core").PgColumn<{
87
+ name: "content";
88
+ tableName: "draft_cache";
89
+ dataType: "json";
90
+ columnType: "PgJsonb";
91
+ data: unknown;
92
+ driverParam: unknown;
93
+ notNull: true;
94
+ hasDefault: false;
95
+ isPrimaryKey: false;
96
+ isAutoincrement: false;
97
+ hasRuntimeDefault: false;
98
+ enumValues: undefined;
99
+ baseColumn: never;
100
+ identity: undefined;
101
+ generated: undefined;
102
+ }, {}, {}>;
103
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
104
+ name: "updated_at";
105
+ tableName: "draft_cache";
106
+ dataType: "date";
107
+ columnType: "PgTimestamp";
108
+ data: Date;
109
+ driverParam: string;
110
+ notNull: true;
111
+ hasDefault: true;
112
+ isPrimaryKey: false;
113
+ isAutoincrement: false;
114
+ hasRuntimeDefault: false;
115
+ enumValues: undefined;
116
+ baseColumn: never;
117
+ identity: undefined;
118
+ generated: undefined;
119
+ }, {}, {}>;
120
+ };
121
+ dialect: "pg";
122
+ }>;
123
+ export type CmsDraftCache = typeof cmsDraftCache.$inferSelect;
124
+ export type NewCmsDraftCache = typeof cmsDraftCache.$inferInsert;
125
+ /**
126
+ * 사용 예시:
127
+ *
128
+ * // Draft 초기화 (편집 시작)
129
+ * await db.insert(cmsDraftCache)
130
+ * .values({
131
+ * section: 'home',
132
+ * locale: 'ko',
133
+ * userId: 'user-a@futureplay.com',
134
+ * content: publishedContent // 발행 버전 복사
135
+ * });
136
+ *
137
+ * // Draft 업데이트 (값 수정 시)
138
+ * const cache = await db.select()
139
+ * .from(cmsDraftCache)
140
+ * .where(and(
141
+ * eq(cmsDraftCache.section, 'home'),
142
+ * eq(cmsDraftCache.locale, 'ko'),
143
+ * eq(cmsDraftCache.userId, userId)
144
+ * ))
145
+ * .limit(1);
146
+ *
147
+ * const updatedContent = {
148
+ * ...cache[0].content,
149
+ * 'home.hero.title': newValue // 부분 업데이트
150
+ * };
151
+ *
152
+ * await db.update(cmsDraftCache)
153
+ * .set({ content: updatedContent, updatedAt: new Date() })
154
+ * .where(eq(cmsDraftCache.id, cache[0].id));
155
+ *
156
+ * // Draft 조회 (미리보기)
157
+ * const draft = await db.select()
158
+ * .from(cmsDraftCache)
159
+ * .where(and(
160
+ * eq(cmsDraftCache.section, 'home'),
161
+ * eq(cmsDraftCache.locale, 'ko'),
162
+ * eq(cmsDraftCache.userId, session.user.id)
163
+ * ))
164
+ * .limit(1);
165
+ *
166
+ * // 사용자의 모든 작업 중인 섹션 조회
167
+ * const userDrafts = await db.select()
168
+ * .from(cmsDraftCache)
169
+ * .where(eq(cmsDraftCache.userId, userId))
170
+ * .orderBy(desc(cmsDraftCache.updatedAt));
171
+ *
172
+ * // 오래된 Draft 정리 (30일 이상)
173
+ * const stale = await db.delete(cmsDraftCache)
174
+ * .where(lt(
175
+ * cmsDraftCache.updatedAt,
176
+ * new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
177
+ * ))
178
+ * .returning();
179
+ *
180
+ * // Draft 폐기 (변경사항 버리기)
181
+ * await db.delete(cmsDraftCache)
182
+ * .where(and(
183
+ * eq(cmsDraftCache.section, 'home'),
184
+ * eq(cmsDraftCache.locale, 'ko'),
185
+ * eq(cmsDraftCache.userId, userId)
186
+ * ));
187
+ */
188
+ //# sourceMappingURL=cms-draft-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-draft-cache.d.ts","sourceRoot":"","sources":["../../src/entities/cms-draft-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCxB,CAAC;AAGH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,YAAY,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,OAAO,aAAa,CAAC,YAAY,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * CMS Draft Cache Entity
3
+ *
4
+ * 관리자별 Draft 콘텐츠를 캐싱합니다.
5
+ * - 사용자별 격리 (userId)
6
+ * - 실시간 미리보기 지원
7
+ * - 동시 편집 가능
8
+ *
9
+ * 핵심 기능:
10
+ * - 여러 관리자가 같은 섹션을 동시에 편집
11
+ * - 각자의 변경사항은 자신의 미리보기에만 표시
12
+ * - 충돌 없이 안전하게 작업
13
+ */
14
+ import { serial, text, jsonb, timestamp, index, unique } from 'drizzle-orm/pg-core';
15
+ import { createFunctionSchema } from '@spfn/core/db';
16
+ // Create isolated schema for @spfn/cms
17
+ const schema = createFunctionSchema('@spfn/cms');
18
+ export const cmsDraftCache = schema.table('draft_cache', {
19
+ // Primary Key
20
+ id: serial('id').primaryKey(),
21
+ // 섹션 (페이지 단위)
22
+ section: text('section').notNull(),
23
+ // "home" | "why-futureplay" | "team" | "our-companies" | "apply"
24
+ // 언어
25
+ locale: text('locale').notNull(),
26
+ // "ko" | "en" | "ja"
27
+ // 사용자 ID (핵심 필드!)
28
+ userId: text('user_id').notNull(),
29
+ // 각 관리자의 독립적인 작업 공간
30
+ // Draft 콘텐츠 (JSONB)
31
+ content: jsonb('content').notNull(),
32
+ // Record<string, LabelValue>
33
+ // {
34
+ // "home.hero.title": { type: "text", content: "수정 중..." },
35
+ // "home.hero.subtitle": { type: "text", content: "새로운 문구" },
36
+ // ...
37
+ // }
38
+ // 최종 수정 시각
39
+ updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
40
+ }, (table) => [
41
+ // UNIQUE 제약: section + locale + userId 조합은 유일
42
+ unique('cms_draft_cache_unique')
43
+ .on(table.section, table.locale, table.userId),
44
+ // 인덱스: section으로 조회 최적화
45
+ index('cms_draft_cache_section_idx').on(table.section),
46
+ // 인덱스: userId로 사용자의 모든 draft 조회 최적화
47
+ index('cms_draft_cache_user_idx').on(table.userId),
48
+ ]);
49
+ /**
50
+ * 사용 예시:
51
+ *
52
+ * // Draft 초기화 (편집 시작)
53
+ * await db.insert(cmsDraftCache)
54
+ * .values({
55
+ * section: 'home',
56
+ * locale: 'ko',
57
+ * userId: 'user-a@futureplay.com',
58
+ * content: publishedContent // 발행 버전 복사
59
+ * });
60
+ *
61
+ * // Draft 업데이트 (값 수정 시)
62
+ * const cache = await db.select()
63
+ * .from(cmsDraftCache)
64
+ * .where(and(
65
+ * eq(cmsDraftCache.section, 'home'),
66
+ * eq(cmsDraftCache.locale, 'ko'),
67
+ * eq(cmsDraftCache.userId, userId)
68
+ * ))
69
+ * .limit(1);
70
+ *
71
+ * const updatedContent = {
72
+ * ...cache[0].content,
73
+ * 'home.hero.title': newValue // 부분 업데이트
74
+ * };
75
+ *
76
+ * await db.update(cmsDraftCache)
77
+ * .set({ content: updatedContent, updatedAt: new Date() })
78
+ * .where(eq(cmsDraftCache.id, cache[0].id));
79
+ *
80
+ * // Draft 조회 (미리보기)
81
+ * const draft = await db.select()
82
+ * .from(cmsDraftCache)
83
+ * .where(and(
84
+ * eq(cmsDraftCache.section, 'home'),
85
+ * eq(cmsDraftCache.locale, 'ko'),
86
+ * eq(cmsDraftCache.userId, session.user.id)
87
+ * ))
88
+ * .limit(1);
89
+ *
90
+ * // 사용자의 모든 작업 중인 섹션 조회
91
+ * const userDrafts = await db.select()
92
+ * .from(cmsDraftCache)
93
+ * .where(eq(cmsDraftCache.userId, userId))
94
+ * .orderBy(desc(cmsDraftCache.updatedAt));
95
+ *
96
+ * // 오래된 Draft 정리 (30일 이상)
97
+ * const stale = await db.delete(cmsDraftCache)
98
+ * .where(lt(
99
+ * cmsDraftCache.updatedAt,
100
+ * new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
101
+ * ))
102
+ * .returning();
103
+ *
104
+ * // Draft 폐기 (변경사항 버리기)
105
+ * await db.delete(cmsDraftCache)
106
+ * .where(and(
107
+ * eq(cmsDraftCache.section, 'home'),
108
+ * eq(cmsDraftCache.locale, 'ko'),
109
+ * eq(cmsDraftCache.userId, userId)
110
+ * ));
111
+ */
112
+ //# sourceMappingURL=cms-draft-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-draft-cache.js","sourceRoot":"","sources":["../../src/entities/cms-draft-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,uCAAuC;AACvC,MAAM,MAAM,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;AAEjD,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE;IACrD,cAAc;IACd,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE;IAE7B,cAAc;IACd,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;IAClC,iEAAiE;IAEjE,KAAK;IACL,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE;IAChC,qBAAqB;IAErB,kBAAkB;IAClB,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;IACjC,oBAAoB;IAEpB,oBAAoB;IACpB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;IACnC,6BAA6B;IAC7B,IAAI;IACJ,6DAA6D;IAC7D,+DAA+D;IAC/D,QAAQ;IACR,IAAI;IAEJ,WAAW;IACX,SAAS,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE;CACpF,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;IACV,8CAA8C;IAC9C,MAAM,CAAC,wBAAwB,CAAC;SAC/B,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IAE9C,wBAAwB;IACxB,KAAK,CAAC,6BAA6B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;IAEtD,oCAAoC;IACpC,KAAK,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;CACrD,CAAC,CAAC;AAMH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * CMS Label Values Entity
3
+ *
4
+ * 라벨의 실제 값을 저장합니다.
5
+ * - 다국어 지원 (locale)
6
+ * - 반응형 지원 (breakpoint)
7
+ * - 버전 관리 (version)
8
+ * - JSONB로 유연한 값 저장
9
+ */
10
+ export declare const cmsLabelValues: import("drizzle-orm/pg-core").PgTableWithColumns<{
11
+ name: "label_values";
12
+ schema: string;
13
+ columns: {
14
+ id: import("drizzle-orm/pg-core").PgColumn<{
15
+ name: "id";
16
+ tableName: "label_values";
17
+ dataType: "number";
18
+ columnType: "PgSerial";
19
+ data: number;
20
+ driverParam: number;
21
+ notNull: true;
22
+ hasDefault: true;
23
+ isPrimaryKey: true;
24
+ isAutoincrement: false;
25
+ hasRuntimeDefault: false;
26
+ enumValues: undefined;
27
+ baseColumn: never;
28
+ identity: undefined;
29
+ generated: undefined;
30
+ }, {}, {}>;
31
+ labelId: import("drizzle-orm/pg-core").PgColumn<{
32
+ name: "label_id";
33
+ tableName: "label_values";
34
+ dataType: "number";
35
+ columnType: "PgInteger";
36
+ data: number;
37
+ driverParam: string | number;
38
+ notNull: true;
39
+ hasDefault: false;
40
+ isPrimaryKey: false;
41
+ isAutoincrement: false;
42
+ hasRuntimeDefault: false;
43
+ enumValues: undefined;
44
+ baseColumn: never;
45
+ identity: undefined;
46
+ generated: undefined;
47
+ }, {}, {}>;
48
+ version: import("drizzle-orm/pg-core").PgColumn<{
49
+ name: "version";
50
+ tableName: "label_values";
51
+ dataType: "number";
52
+ columnType: "PgInteger";
53
+ data: number;
54
+ driverParam: string | number;
55
+ notNull: true;
56
+ hasDefault: true;
57
+ isPrimaryKey: false;
58
+ isAutoincrement: false;
59
+ hasRuntimeDefault: false;
60
+ enumValues: undefined;
61
+ baseColumn: never;
62
+ identity: undefined;
63
+ generated: undefined;
64
+ }, {}, {}>;
65
+ locale: import("drizzle-orm/pg-core").PgColumn<{
66
+ name: "locale";
67
+ tableName: "label_values";
68
+ dataType: "string";
69
+ columnType: "PgText";
70
+ data: string;
71
+ driverParam: string;
72
+ notNull: true;
73
+ hasDefault: true;
74
+ isPrimaryKey: false;
75
+ isAutoincrement: false;
76
+ hasRuntimeDefault: false;
77
+ enumValues: [string, ...string[]];
78
+ baseColumn: never;
79
+ identity: undefined;
80
+ generated: undefined;
81
+ }, {}, {}>;
82
+ breakpoint: import("drizzle-orm/pg-core").PgColumn<{
83
+ name: "breakpoint";
84
+ tableName: "label_values";
85
+ dataType: "string";
86
+ columnType: "PgText";
87
+ data: string;
88
+ driverParam: string;
89
+ notNull: false;
90
+ hasDefault: false;
91
+ isPrimaryKey: false;
92
+ isAutoincrement: false;
93
+ hasRuntimeDefault: false;
94
+ enumValues: [string, ...string[]];
95
+ baseColumn: never;
96
+ identity: undefined;
97
+ generated: undefined;
98
+ }, {}, {}>;
99
+ value: import("drizzle-orm/pg-core").PgColumn<{
100
+ name: "value";
101
+ tableName: "label_values";
102
+ dataType: "json";
103
+ columnType: "PgJsonb";
104
+ data: unknown;
105
+ driverParam: unknown;
106
+ notNull: true;
107
+ hasDefault: false;
108
+ isPrimaryKey: false;
109
+ isAutoincrement: false;
110
+ hasRuntimeDefault: false;
111
+ enumValues: undefined;
112
+ baseColumn: never;
113
+ identity: undefined;
114
+ generated: undefined;
115
+ }, {}, {}>;
116
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
117
+ name: "created_at";
118
+ tableName: "label_values";
119
+ dataType: "date";
120
+ columnType: "PgTimestamp";
121
+ data: Date;
122
+ driverParam: string;
123
+ notNull: true;
124
+ hasDefault: true;
125
+ isPrimaryKey: false;
126
+ isAutoincrement: false;
127
+ hasRuntimeDefault: false;
128
+ enumValues: undefined;
129
+ baseColumn: never;
130
+ identity: undefined;
131
+ generated: undefined;
132
+ }, {}, {}>;
133
+ };
134
+ dialect: "pg";
135
+ }>;
136
+ export type CmsLabelValue = typeof cmsLabelValues.$inferSelect;
137
+ export type NewCmsLabelValue = typeof cmsLabelValues.$inferInsert;
138
+ /**
139
+ * 사용 예시:
140
+ *
141
+ * // 텍스트 값 저장
142
+ * await db.insert(cmsLabelValues).values({
143
+ * labelId: 1,
144
+ * version: 1,
145
+ * locale: 'ko',
146
+ * breakpoint: null,
147
+ * value: {
148
+ * type: 'text',
149
+ * content: '미래를 만드는 기업'
150
+ * }
151
+ * });
152
+ *
153
+ * // 반응형 이미지 저장 (모바일용)
154
+ * await db.insert(cmsLabelValues).values({
155
+ * labelId: 2,
156
+ * version: 1,
157
+ * locale: 'ko',
158
+ * breakpoint: 'sm',
159
+ * value: {
160
+ * type: 'image',
161
+ * url: '/uploads/hero-mobile.jpg',
162
+ * alt: 'Hero Image',
163
+ * width: 640,
164
+ * height: 480
165
+ * }
166
+ * });
167
+ *
168
+ * // 특정 버전의 한국어 값 조회
169
+ * const values = await db.select()
170
+ * .from(cmsLabelValues)
171
+ * .where(and(
172
+ * eq(cmsLabelValues.labelId, 1),
173
+ * eq(cmsLabelValues.version, 2),
174
+ * eq(cmsLabelValues.locale, 'ko')
175
+ * ));
176
+ *
177
+ * // Object 타입 값 저장 (재귀 구조)
178
+ * await db.insert(cmsLabelValues).values({
179
+ * labelId: 3,
180
+ * version: 1,
181
+ * locale: 'ko',
182
+ * value: {
183
+ * type: 'object',
184
+ * fields: {
185
+ * title: { type: 'text', content: '특징 1' },
186
+ * icon: { type: 'image', url: '/icons/feature1.svg', alt: 'Icon' },
187
+ * description: { type: 'text', content: '상세 설명...' }
188
+ * }
189
+ * }
190
+ * });
191
+ */
192
+ //# sourceMappingURL=cms-label-values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-label-values.d.ts","sourceRoot":"","sources":["../../src/entities/cms-label-values.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CzB,CAAC;AAGH,MAAM,MAAM,aAAa,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * CMS Label Values Entity
3
+ *
4
+ * 라벨의 실제 값을 저장합니다.
5
+ * - 다국어 지원 (locale)
6
+ * - 반응형 지원 (breakpoint)
7
+ * - 버전 관리 (version)
8
+ * - JSONB로 유연한 값 저장
9
+ */
10
+ import { serial, integer, text, jsonb, timestamp, index, unique } from 'drizzle-orm/pg-core';
11
+ import { createFunctionSchema } from '@spfn/core/db';
12
+ import { cmsLabels } from './cms-labels';
13
+ // Create isolated schema for @spfn/cms
14
+ const schema = createFunctionSchema('@spfn/cms');
15
+ export const cmsLabelValues = schema.table('label_values', {
16
+ // Primary Key
17
+ id: serial('id').primaryKey(),
18
+ // Foreign Key: cms_labels
19
+ labelId: integer('label_id')
20
+ .notNull()
21
+ .references(() => cmsLabels.id, { onDelete: 'cascade' }),
22
+ // 버전 번호
23
+ version: integer('version').notNull().default(1),
24
+ // 언어 코드
25
+ locale: text('locale').notNull().default('ko'),
26
+ // "ko" | "en" | "ja"
27
+ // 반응형 브레이크포인트
28
+ breakpoint: text('breakpoint'),
29
+ // null = 기본값 (모든 화면 크기)
30
+ // "sm" | "md" | "lg" | "xl" | "2xl"
31
+ // 실제 값 (JSONB)
32
+ value: jsonb('value').notNull(),
33
+ // LabelValue 타입:
34
+ // - TextValue: { type: "text", content: string }
35
+ // - ImageValue: { type: "image", url: string, alt?: string, width?: number, height?: number }
36
+ // - VideoValue: { type: "video", url: string, thumbnail?: string, duration?: number }
37
+ // - FileValue: { type: "file", url: string, filename: string, size?: number }
38
+ // - ObjectValue: { type: "object", fields: Record<string, LabelValue> }
39
+ // 생성 시각
40
+ createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
41
+ }, (table) => [
42
+ // UNIQUE 제약: 같은 버전에서 locale + breakpoint 조합은 유일
43
+ unique('cms_label_values_locale_breakpoint_unique')
44
+ .on(table.labelId, table.version, table.locale, table.breakpoint),
45
+ // 인덱스: labelId + version 복합 조회 최적화
46
+ index('cms_label_values_label_version_idx')
47
+ .on(table.labelId, table.version),
48
+ // 인덱스: locale 필터링 최적화
49
+ index('cms_label_values_locale_idx').on(table.locale),
50
+ ]);
51
+ /**
52
+ * 사용 예시:
53
+ *
54
+ * // 텍스트 값 저장
55
+ * await db.insert(cmsLabelValues).values({
56
+ * labelId: 1,
57
+ * version: 1,
58
+ * locale: 'ko',
59
+ * breakpoint: null,
60
+ * value: {
61
+ * type: 'text',
62
+ * content: '미래를 만드는 기업'
63
+ * }
64
+ * });
65
+ *
66
+ * // 반응형 이미지 저장 (모바일용)
67
+ * await db.insert(cmsLabelValues).values({
68
+ * labelId: 2,
69
+ * version: 1,
70
+ * locale: 'ko',
71
+ * breakpoint: 'sm',
72
+ * value: {
73
+ * type: 'image',
74
+ * url: '/uploads/hero-mobile.jpg',
75
+ * alt: 'Hero Image',
76
+ * width: 640,
77
+ * height: 480
78
+ * }
79
+ * });
80
+ *
81
+ * // 특정 버전의 한국어 값 조회
82
+ * const values = await db.select()
83
+ * .from(cmsLabelValues)
84
+ * .where(and(
85
+ * eq(cmsLabelValues.labelId, 1),
86
+ * eq(cmsLabelValues.version, 2),
87
+ * eq(cmsLabelValues.locale, 'ko')
88
+ * ));
89
+ *
90
+ * // Object 타입 값 저장 (재귀 구조)
91
+ * await db.insert(cmsLabelValues).values({
92
+ * labelId: 3,
93
+ * version: 1,
94
+ * locale: 'ko',
95
+ * value: {
96
+ * type: 'object',
97
+ * fields: {
98
+ * title: { type: 'text', content: '특징 1' },
99
+ * icon: { type: 'image', url: '/icons/feature1.svg', alt: 'Icon' },
100
+ * description: { type: 'text', content: '상세 설명...' }
101
+ * }
102
+ * }
103
+ * });
104
+ */
105
+ //# sourceMappingURL=cms-label-values.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-label-values.js","sourceRoot":"","sources":["../../src/entities/cms-label-values.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,uCAAuC;AACvC,MAAM,MAAM,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;AAEjD,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE;IACvD,cAAc;IACd,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE;IAE7B,0BAA0B;IAC1B,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC;SACvB,OAAO,EAAE;SACT,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IAE5D,QAAQ;IACR,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEhD,QAAQ;IACR,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9C,qBAAqB;IAErB,cAAc;IACd,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC;IAC9B,wBAAwB;IACxB,oCAAoC;IAEpC,eAAe;IACf,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE;IAC/B,iBAAiB;IACjB,iDAAiD;IACjD,8FAA8F;IAC9F,sFAAsF;IACtF,8EAA8E;IAC9E,wEAAwE;IAExE,QAAQ;IACR,SAAS,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE;CACpF,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;IACV,gDAAgD;IAChD,MAAM,CAAC,2CAA2C,CAAC;SAC9C,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC;IAErE,mCAAmC;IACnC,KAAK,CAAC,oCAAoC,CAAC;SACtC,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;IAErC,sBAAsB;IACtB,KAAK,CAAC,6BAA6B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;CACxD,CAAC,CAAC;AAMH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG"}