@spfn/cms 0.1.0-alpha.7 → 0.1.0-alpha.70
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.
- package/README.md +28 -416
- package/dist/{helpers/locale.actions.d.ts → actions-BpTAYuBA.d.ts} +70 -7
- package/dist/actions.d.ts +2 -9
- package/dist/actions.js +97 -10
- package/dist/actions.js.map +1 -1
- package/dist/api.d.ts +214 -0
- package/dist/api.js +353 -0
- package/dist/api.js.map +1 -0
- package/dist/client.d.ts +136 -127
- package/dist/client.js +1199 -59
- package/dist/client.js.map +1 -1
- package/dist/{types.d.ts → index-Dh5FjWzR.d.ts} +45 -7
- package/dist/index.d.ts +108 -16
- package/dist/index.js +610 -23
- package/dist/index.js.map +1 -1
- package/dist/label-sync-generator-B0EmvtWM.d.ts +32 -0
- package/dist/lib/contracts/labels.d.ts +151 -0
- package/dist/lib/contracts/labels.js +168 -0
- package/dist/lib/contracts/labels.js.map +1 -0
- package/dist/lib/contracts/published-cache.d.ts +48 -0
- package/dist/lib/contracts/published-cache.js +49 -0
- package/dist/lib/contracts/published-cache.js.map +1 -0
- package/dist/lib/contracts/values.d.ts +71 -0
- package/dist/lib/contracts/values.js +103 -0
- package/dist/lib/contracts/values.js.map +1 -0
- package/dist/locale.constants-BMBK70YM.d.ts +104 -0
- package/dist/{entities → server/entities}/cms-audit-logs.d.ts +15 -70
- package/dist/server/entities/cms-audit-logs.js +78 -0
- package/dist/server/entities/cms-audit-logs.js.map +1 -0
- package/dist/{entities → server/entities}/cms-draft-cache.d.ts +13 -73
- package/dist/server/entities/cms-draft-cache.js +38 -0
- package/dist/server/entities/cms-draft-cache.js.map +1 -0
- package/dist/{entities → server/entities}/cms-label-values.d.ts +16 -67
- package/dist/server/entities/cms-label-values.js +81 -0
- package/dist/server/entities/cms-label-values.js.map +1 -0
- package/dist/{entities → server/entities}/cms-label-versions.d.ts +16 -49
- package/dist/server/entities/cms-label-versions.js +76 -0
- package/dist/server/entities/cms-label-versions.js.map +1 -0
- package/dist/{entities → server/entities}/cms-labels.d.ts +17 -14
- package/dist/server/entities/cms-labels.js +42 -0
- package/dist/server/entities/cms-labels.js.map +1 -0
- package/dist/{entities → server/entities}/cms-published-cache.d.ts +14 -69
- package/dist/server/entities/cms-published-cache.js +36 -0
- package/dist/server/entities/cms-published-cache.js.map +1 -0
- package/dist/server/entities/index.d.ts +7 -0
- package/dist/server/entities/index.js +218 -0
- package/dist/server/entities/index.js.map +1 -0
- package/dist/server/generators/index.d.ts +19 -0
- package/dist/server/generators/index.js +753 -0
- package/dist/server/generators/index.js.map +1 -0
- package/dist/server/labels/index.d.ts +1 -0
- package/dist/server/labels/index.js +32 -0
- package/dist/server/labels/index.js.map +1 -0
- package/dist/server/repositories/index.d.ts +209 -0
- package/dist/server/repositories/index.js +441 -0
- package/dist/server/repositories/index.js.map +1 -0
- package/dist/server/routes/labels/[id]/index.js +508 -0
- package/dist/server/routes/labels/[id]/index.js.map +1 -0
- package/dist/{routes/labels/[id] → server/routes/labels/_id_}/index.d.ts +5 -3
- package/dist/server/routes/labels/by-key/[key]/index.js +458 -0
- package/dist/server/routes/labels/by-key/[key]/index.js.map +1 -0
- package/dist/server/routes/labels/by-key/_key_/index.d.ts +10 -0
- package/dist/server/routes/labels/index.d.ts +12 -0
- package/dist/server/routes/labels/index.js +617 -0
- package/dist/server/routes/labels/index.js.map +1 -0
- package/dist/server/routes/published-cache/index.d.ts +11 -0
- package/dist/server/routes/published-cache/index.js +369 -0
- package/dist/server/routes/published-cache/index.js.map +1 -0
- package/dist/server/routes/values/[labelId]/[version]/index.js +479 -0
- package/dist/server/routes/values/[labelId]/[version]/index.js.map +1 -0
- package/dist/server/routes/values/[labelId]/index.js +474 -0
- package/dist/server/routes/values/[labelId]/index.js.map +1 -0
- package/dist/server/routes/values/_labelId_/_version_/index.d.ts +10 -0
- package/dist/server/routes/values/_labelId_/index.d.ts +10 -0
- package/dist/server.d.ts +78 -7
- package/dist/server.js +1752 -247
- package/dist/server.js.map +1 -1
- package/migrations/0000_init.sql +3 -0
- package/migrations/0001_far_lady_vermin.sql +86 -0
- package/migrations/0002_heavy_the_enforcers.sql +2 -0
- package/migrations/meta/0000_snapshot.json +15 -0
- package/migrations/meta/0001_snapshot.json +687 -0
- package/migrations/meta/0002_snapshot.json +686 -0
- package/migrations/meta/_journal.json +27 -0
- package/package.json +55 -36
- package/dist/actions.d.ts.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/cms.config.d.ts +0 -77
- package/dist/cms.config.d.ts.map +0 -1
- package/dist/cms.config.js +0 -111
- package/dist/cms.config.js.map +0 -1
- package/dist/entities/cms-audit-logs.d.ts.map +0 -1
- package/dist/entities/cms-audit-logs.js +0 -103
- package/dist/entities/cms-audit-logs.js.map +0 -1
- package/dist/entities/cms-draft-cache.d.ts.map +0 -1
- package/dist/entities/cms-draft-cache.js +0 -112
- package/dist/entities/cms-draft-cache.js.map +0 -1
- package/dist/entities/cms-label-values.d.ts.map +0 -1
- package/dist/entities/cms-label-values.js +0 -105
- package/dist/entities/cms-label-values.js.map +0 -1
- package/dist/entities/cms-label-versions.d.ts.map +0 -1
- package/dist/entities/cms-label-versions.js +0 -80
- package/dist/entities/cms-label-versions.js.map +0 -1
- package/dist/entities/cms-labels.d.ts.map +0 -1
- package/dist/entities/cms-labels.js +0 -48
- package/dist/entities/cms-labels.js.map +0 -1
- package/dist/entities/cms-published-cache.d.ts.map +0 -1
- package/dist/entities/cms-published-cache.js +0 -103
- package/dist/entities/cms-published-cache.js.map +0 -1
- package/dist/entities/index.d.ts +0 -10
- package/dist/entities/index.d.ts.map +0 -1
- package/dist/entities/index.js +0 -10
- package/dist/entities/index.js.map +0 -1
- package/dist/generators/index.d.ts +0 -19
- package/dist/generators/index.d.ts.map +0 -1
- package/dist/generators/index.js +0 -19
- package/dist/generators/index.js.map +0 -1
- package/dist/generators/label-sync-generator.d.ts +0 -33
- package/dist/generators/label-sync-generator.d.ts.map +0 -1
- package/dist/generators/label-sync-generator.js +0 -87
- package/dist/generators/label-sync-generator.js.map +0 -1
- package/dist/helpers/locale.actions.d.ts.map +0 -1
- package/dist/helpers/locale.actions.js +0 -210
- package/dist/helpers/locale.actions.js.map +0 -1
- package/dist/helpers/locale.constants.d.ts +0 -10
- package/dist/helpers/locale.constants.d.ts.map +0 -1
- package/dist/helpers/locale.constants.js +0 -10
- package/dist/helpers/locale.constants.js.map +0 -1
- package/dist/helpers/locale.d.ts +0 -17
- package/dist/helpers/locale.d.ts.map +0 -1
- package/dist/helpers/locale.js +0 -20
- package/dist/helpers/locale.js.map +0 -1
- package/dist/helpers/sync.d.ts +0 -41
- package/dist/helpers/sync.d.ts.map +0 -1
- package/dist/helpers/sync.js +0 -309
- package/dist/helpers/sync.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/init.d.ts +0 -31
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -36
- package/dist/init.js.map +0 -1
- package/dist/labels/helpers.d.ts +0 -31
- package/dist/labels/helpers.d.ts.map +0 -1
- package/dist/labels/helpers.js +0 -60
- package/dist/labels/helpers.js.map +0 -1
- package/dist/labels/index.d.ts +0 -7
- package/dist/labels/index.d.ts.map +0 -1
- package/dist/labels/index.js +0 -7
- package/dist/labels/index.js.map +0 -1
- package/dist/repositories/cms-draft-cache.repository.d.ts +0 -62
- package/dist/repositories/cms-draft-cache.repository.d.ts.map +0 -1
- package/dist/repositories/cms-draft-cache.repository.js +0 -56
- package/dist/repositories/cms-draft-cache.repository.js.map +0 -1
- package/dist/repositories/cms-label-values.repository.d.ts +0 -32
- package/dist/repositories/cms-label-values.repository.d.ts.map +0 -1
- package/dist/repositories/cms-label-values.repository.js +0 -72
- package/dist/repositories/cms-label-values.repository.js.map +0 -1
- package/dist/repositories/cms-labels.repository.d.ts +0 -53
- package/dist/repositories/cms-labels.repository.d.ts.map +0 -1
- package/dist/repositories/cms-labels.repository.js +0 -77
- package/dist/repositories/cms-labels.repository.js.map +0 -1
- package/dist/repositories/cms-published-cache.repository.d.ts +0 -53
- package/dist/repositories/cms-published-cache.repository.d.ts.map +0 -1
- package/dist/repositories/cms-published-cache.repository.js +0 -54
- package/dist/repositories/cms-published-cache.repository.js.map +0 -1
- package/dist/repositories/index.d.ts +0 -8
- package/dist/repositories/index.d.ts.map +0 -1
- package/dist/repositories/index.js +0 -9
- package/dist/repositories/index.js.map +0 -1
- package/dist/routes/labels/[id]/contract.d.ts +0 -68
- package/dist/routes/labels/[id]/contract.d.ts.map +0 -1
- package/dist/routes/labels/[id]/contract.js +0 -84
- package/dist/routes/labels/[id]/contract.js.map +0 -1
- package/dist/routes/labels/[id]/index.d.ts.map +0 -1
- package/dist/routes/labels/[id]/index.js +0 -96
- package/dist/routes/labels/[id]/index.js.map +0 -1
- package/dist/routes/labels/by-key/[key]/contract.d.ts +0 -24
- package/dist/routes/labels/by-key/[key]/contract.d.ts.map +0 -1
- package/dist/routes/labels/by-key/[key]/contract.js +0 -28
- package/dist/routes/labels/by-key/[key]/contract.js.map +0 -1
- package/dist/routes/labels/by-key/[key]/index.d.ts +0 -8
- package/dist/routes/labels/by-key/[key]/index.d.ts.map +0 -1
- package/dist/routes/labels/by-key/[key]/index.js +0 -32
- package/dist/routes/labels/by-key/[key]/index.js.map +0 -1
- package/dist/routes/labels/contract.d.ts +0 -59
- package/dist/routes/labels/contract.d.ts.map +0 -1
- package/dist/routes/labels/contract.js +0 -75
- package/dist/routes/labels/contract.js.map +0 -1
- package/dist/routes/labels/index.d.ts +0 -10
- package/dist/routes/labels/index.d.ts.map +0 -1
- package/dist/routes/labels/index.js +0 -73
- package/dist/routes/labels/index.js.map +0 -1
- package/dist/routes/published-cache/contract.d.ts +0 -25
- package/dist/routes/published-cache/contract.d.ts.map +0 -1
- package/dist/routes/published-cache/contract.js +0 -35
- package/dist/routes/published-cache/contract.js.map +0 -1
- package/dist/routes/published-cache/index.d.ts +0 -8
- package/dist/routes/published-cache/index.d.ts.map +0 -1
- package/dist/routes/published-cache/index.js +0 -33
- package/dist/routes/published-cache/index.js.map +0 -1
- package/dist/routes/values/[labelId]/[version]/contract.d.ts +0 -29
- package/dist/routes/values/[labelId]/[version]/contract.d.ts.map +0 -1
- package/dist/routes/values/[labelId]/[version]/contract.js +0 -33
- package/dist/routes/values/[labelId]/[version]/contract.js.map +0 -1
- package/dist/routes/values/[labelId]/[version]/index.d.ts +0 -8
- package/dist/routes/values/[labelId]/[version]/index.d.ts.map +0 -1
- package/dist/routes/values/[labelId]/[version]/index.js +0 -45
- package/dist/routes/values/[labelId]/[version]/index.js.map +0 -1
- package/dist/routes/values/[labelId]/contract.d.ts +0 -38
- package/dist/routes/values/[labelId]/contract.d.ts.map +0 -1
- package/dist/routes/values/[labelId]/contract.js +0 -59
- package/dist/routes/values/[labelId]/contract.js.map +0 -1
- package/dist/routes/values/[labelId]/index.d.ts +0 -8
- package/dist/routes/values/[labelId]/index.d.ts.map +0 -1
- package/dist/routes/values/[labelId]/index.js +0 -42
- package/dist/routes/values/[labelId]/index.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/store.d.ts +0 -87
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -205
- package/dist/store.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -7
- package/dist/types.js.map +0 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// src/lib/contracts/values.ts
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
var LabelValueSchema = Type.Object({
|
|
4
|
+
type: Type.Union([
|
|
5
|
+
Type.Literal("text"),
|
|
6
|
+
Type.Literal("image"),
|
|
7
|
+
Type.Literal("video"),
|
|
8
|
+
Type.Literal("file"),
|
|
9
|
+
Type.Literal("object")
|
|
10
|
+
]),
|
|
11
|
+
content: Type.Optional(Type.String()),
|
|
12
|
+
// text type
|
|
13
|
+
url: Type.Optional(Type.String()),
|
|
14
|
+
// image, video, file types
|
|
15
|
+
alt: Type.Optional(Type.String()),
|
|
16
|
+
// image type
|
|
17
|
+
width: Type.Optional(Type.Number()),
|
|
18
|
+
// image type
|
|
19
|
+
height: Type.Optional(Type.Number()),
|
|
20
|
+
// image type
|
|
21
|
+
thumbnail: Type.Optional(Type.String()),
|
|
22
|
+
// video type
|
|
23
|
+
duration: Type.Optional(Type.Number()),
|
|
24
|
+
// video type
|
|
25
|
+
filename: Type.Optional(Type.String()),
|
|
26
|
+
// file type
|
|
27
|
+
size: Type.Optional(Type.Number()),
|
|
28
|
+
// file type
|
|
29
|
+
fields: Type.Optional(Type.Any())
|
|
30
|
+
// object type - recursive structure
|
|
31
|
+
});
|
|
32
|
+
var saveValuesContract = {
|
|
33
|
+
method: "POST",
|
|
34
|
+
path: "/_cms/values/:labelId",
|
|
35
|
+
params: Type.Object({
|
|
36
|
+
labelId: Type.String({ description: "\uB77C\uBCA8 ID" })
|
|
37
|
+
}),
|
|
38
|
+
body: Type.Object({
|
|
39
|
+
version: Type.Union([
|
|
40
|
+
Type.Null({ description: "Draft \uC800\uC7A5 (\uB36E\uC5B4\uC4F0\uAE30)" }),
|
|
41
|
+
Type.Number({ description: "\uBC84\uC804 \uBC88\uD638 (\uBD88\uBCC0)", minimum: 1 })
|
|
42
|
+
]),
|
|
43
|
+
values: Type.Array(
|
|
44
|
+
Type.Object({
|
|
45
|
+
locale: Type.String({ description: "\uC5B8\uC5B4 \uCF54\uB4DC (ko, en, ja)", default: "ko" }),
|
|
46
|
+
breakpoint: Type.Optional(Type.Union([
|
|
47
|
+
Type.Literal("sm"),
|
|
48
|
+
Type.Literal("md"),
|
|
49
|
+
Type.Literal("lg"),
|
|
50
|
+
Type.Literal("xl"),
|
|
51
|
+
Type.Literal("2xl"),
|
|
52
|
+
Type.Null()
|
|
53
|
+
], { description: "\uBC18\uC751\uD615 \uBE0C\uB808\uC774\uD06C\uD3EC\uC778\uD2B8" })),
|
|
54
|
+
value: LabelValueSchema
|
|
55
|
+
})
|
|
56
|
+
)
|
|
57
|
+
}),
|
|
58
|
+
response: Type.Union([
|
|
59
|
+
Type.Object({
|
|
60
|
+
success: Type.Boolean(),
|
|
61
|
+
saved: Type.Number(),
|
|
62
|
+
version: Type.Union([Type.Null(), Type.Number()])
|
|
63
|
+
}),
|
|
64
|
+
Type.Object({
|
|
65
|
+
error: Type.String()
|
|
66
|
+
})
|
|
67
|
+
])
|
|
68
|
+
};
|
|
69
|
+
var getValuesContract = {
|
|
70
|
+
method: "GET",
|
|
71
|
+
path: "/_cms/values/:labelId/:version",
|
|
72
|
+
params: Type.Object({
|
|
73
|
+
labelId: Type.String({ description: "\uB77C\uBCA8 ID" }),
|
|
74
|
+
version: Type.String({ description: "\uBC84\uC804 \uBC88\uD638" })
|
|
75
|
+
}),
|
|
76
|
+
query: Type.Object({
|
|
77
|
+
locale: Type.Optional(Type.String({ description: "\uC5B8\uC5B4 \uCF54\uB4DC (ko, en, ja)" })),
|
|
78
|
+
breakpoint: Type.Optional(Type.String({ description: "\uBC18\uC751\uD615 \uBE0C\uB808\uC774\uD06C\uD3EC\uC778\uD2B8" }))
|
|
79
|
+
}),
|
|
80
|
+
response: Type.Union([
|
|
81
|
+
Type.Object({
|
|
82
|
+
labelId: Type.Number(),
|
|
83
|
+
version: Type.Number(),
|
|
84
|
+
values: Type.Array(
|
|
85
|
+
Type.Object({
|
|
86
|
+
id: Type.Number(),
|
|
87
|
+
locale: Type.String(),
|
|
88
|
+
breakpoint: Type.Union([Type.String(), Type.Null()]),
|
|
89
|
+
value: Type.Any(),
|
|
90
|
+
createdAt: Type.String()
|
|
91
|
+
})
|
|
92
|
+
)
|
|
93
|
+
}),
|
|
94
|
+
Type.Object({
|
|
95
|
+
error: Type.String()
|
|
96
|
+
})
|
|
97
|
+
])
|
|
98
|
+
};
|
|
99
|
+
export {
|
|
100
|
+
getValuesContract,
|
|
101
|
+
saveValuesContract
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/contracts/values.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { RouteContract } from '@spfn/core/route';\n\n/**\n * Label Value 타입 정의\n */\nconst LabelValueSchema = Type.Object({\n type: Type.Union([\n Type.Literal('text'),\n Type.Literal('image'),\n Type.Literal('video'),\n Type.Literal('file'),\n Type.Literal('object')\n ]),\n content: Type.Optional(Type.String()), // text type\n url: Type.Optional(Type.String()), // image, video, file types\n alt: Type.Optional(Type.String()), // image type\n width: Type.Optional(Type.Number()), // image type\n height: Type.Optional(Type.Number()), // image type\n thumbnail: Type.Optional(Type.String()), // video type\n duration: Type.Optional(Type.Number()), // video type\n filename: Type.Optional(Type.String()), // file type\n size: Type.Optional(Type.Number()), // file type\n fields: Type.Optional(Type.Any()) // object type - recursive structure\n});\n\n/**\n * POST /_cms/values/:labelId - 라벨 값 저장\n * - version: null → Draft 저장 (덮어쓰기)\n * - version: number → Published 버전 생성 (불변)\n */\nexport const saveValuesContract = {\n method: 'POST' as const,\n path: '/_cms/values/:labelId',\n params: Type.Object({\n labelId: Type.String({ description: '라벨 ID' })\n }),\n body: Type.Object({\n version: Type.Union([\n Type.Null({ description: 'Draft 저장 (덮어쓰기)' }),\n Type.Number({ description: '버전 번호 (불변)', minimum: 1 })\n ]),\n values: Type.Array(\n Type.Object({\n locale: Type.String({ description: '언어 코드 (ko, en, ja)', default: 'ko' }),\n breakpoint: Type.Optional(Type.Union([\n Type.Literal('sm'),\n Type.Literal('md'),\n Type.Literal('lg'),\n Type.Literal('xl'),\n Type.Literal('2xl'),\n Type.Null()\n ], { description: '반응형 브레이크포인트' })),\n value: LabelValueSchema\n })\n )\n }),\n response: Type.Union([\n Type.Object({\n success: Type.Boolean(),\n saved: Type.Number(),\n version: Type.Union([Type.Null(), Type.Number()])\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;\n\n/**\n * GET /_cms/values/:labelId/:version - 특정 버전의 값 조회\n */\nexport const getValuesContract = {\n method: 'GET' as const,\n path: '/_cms/values/:labelId/:version',\n params: Type.Object({\n labelId: Type.String({ description: '라벨 ID' }),\n version: Type.String({ description: '버전 번호' })\n }),\n query: Type.Object({\n locale: Type.Optional(Type.String({ description: '언어 코드 (ko, en, ja)' })),\n breakpoint: Type.Optional(Type.String({ description: '반응형 브레이크포인트' }))\n }),\n response: Type.Union([\n Type.Object({\n labelId: Type.Number(),\n version: Type.Number(),\n values: Type.Array(\n Type.Object({\n id: Type.Number(),\n locale: Type.String(),\n breakpoint: Type.Union([Type.String(), Type.Null()]),\n value: Type.Any(),\n createdAt: Type.String()\n })\n )\n }),\n Type.Object({\n error: Type.String()\n })\n ])\n} as const satisfies RouteContract;"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locale Constants
|
|
3
|
+
*
|
|
4
|
+
* Server/Client 양쪽에서 사용 가능한 locale 관련 상수
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Locale 쿠키 키
|
|
8
|
+
*/
|
|
9
|
+
declare const LOCALE_COOKIE_KEY = "spfn-locale";
|
|
10
|
+
/**
|
|
11
|
+
* 지원하는 Locale 타입 (Type-safe)
|
|
12
|
+
*/
|
|
13
|
+
type SupportedLocale = 'ko' | 'ja' | 'zh' | 'zh-TW' | 'zh-HK' | 'hi' | 'th' | 'vi' | 'id' | 'ms' | 'en' | 'en-GB' | 'en-CA' | 'en-AU' | 'en-NZ' | 'es' | 'es-MX' | 'es-AR' | 'es-CO' | 'fr' | 'de' | 'it' | 'pt' | 'nl' | 'sv' | 'no' | 'da' | 'fi' | 'ru' | 'pl' | 'uk' | 'cs' | 'hu' | 'ro' | 'bg' | 'hr' | 'sr' | 'sk' | 'sl' | 'lt' | 'lv' | 'et' | 'el' | 'tr' | 'ar' | 'fa' | 'he' | 'sw';
|
|
14
|
+
/**
|
|
15
|
+
* 국가/지역 정보 타입
|
|
16
|
+
*/
|
|
17
|
+
interface LocaleInfo {
|
|
18
|
+
/** Locale 코드 (ISO 639-1) */
|
|
19
|
+
locale: SupportedLocale;
|
|
20
|
+
/** 국가 코드 (ISO 3166-1 alpha-2) */
|
|
21
|
+
countryCode: string;
|
|
22
|
+
/** 국기 이모지 (HTML/React용) */
|
|
23
|
+
flag: string;
|
|
24
|
+
/** 전화번호 국가 코드 */
|
|
25
|
+
dialCode: string;
|
|
26
|
+
/** 네이티브 이름 (현지어) */
|
|
27
|
+
nativeName: string;
|
|
28
|
+
/** 영어 이름 */
|
|
29
|
+
englishName: string;
|
|
30
|
+
/** RTL (Right-to-Left) 여부 */
|
|
31
|
+
rtl?: boolean;
|
|
32
|
+
/** 통화 코드 (ISO 4217) */
|
|
33
|
+
currencyCode?: string;
|
|
34
|
+
/** 날짜 형식 예시 */
|
|
35
|
+
dateFormat?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 사전 정의된 Locale 정보 맵
|
|
39
|
+
*
|
|
40
|
+
* 주요 언어/국가 정보를 포함합니다.
|
|
41
|
+
* 프로젝트에 맞게 추가/수정 가능합니다.
|
|
42
|
+
*/
|
|
43
|
+
declare const LOCALE_INFO_MAP: Record<SupportedLocale, LocaleInfo>;
|
|
44
|
+
/**
|
|
45
|
+
* Locale 정보 가져오기
|
|
46
|
+
*
|
|
47
|
+
* @param locale - Locale 코드 (예: 'ko', 'en', 'ja')
|
|
48
|
+
* @returns LocaleInfo 또는 undefined
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const koInfo = getLocaleInfo('ko');
|
|
53
|
+
* console.log(koInfo.flag); // 🇰🇷
|
|
54
|
+
* console.log(koInfo.dialCode); // +82
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
declare function getLocaleInfo(locale: string): LocaleInfo | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* 지원하는 모든 Locale 목록 가져오기
|
|
60
|
+
*
|
|
61
|
+
* @returns Locale 코드 배열
|
|
62
|
+
*/
|
|
63
|
+
declare function getSupportedLocales(): SupportedLocale[];
|
|
64
|
+
/**
|
|
65
|
+
* 국기 이모지만 가져오기
|
|
66
|
+
*
|
|
67
|
+
* @param locale - Locale 코드
|
|
68
|
+
* @returns 국기 이모지 또는 빈 문자열
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* getFlag('ko'); // 🇰🇷
|
|
73
|
+
* getFlag('en'); // 🇺🇸
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
declare function getFlag(locale: string): string;
|
|
77
|
+
/**
|
|
78
|
+
* 전화번호 국가 코드 가져오기
|
|
79
|
+
*
|
|
80
|
+
* @param locale - Locale 코드
|
|
81
|
+
* @returns 전화번호 코드 또는 빈 문자열
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* getDialCode('ko'); // +82
|
|
86
|
+
* getDialCode('en'); // +1
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare function getDialCode(locale: string): string;
|
|
90
|
+
/**
|
|
91
|
+
* RTL (Right-to-Left) 여부 확인
|
|
92
|
+
*
|
|
93
|
+
* @param locale - Locale 코드
|
|
94
|
+
* @returns RTL 여부
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* isRTL('ar'); // true (Arabic)
|
|
99
|
+
* isRTL('ko'); // false (Korean)
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
declare function isRTL(locale: string): boolean;
|
|
103
|
+
|
|
104
|
+
export { LOCALE_COOKIE_KEY as L, type SupportedLocale as S, getSupportedLocales as a, getFlag as b, getDialCode as c, LOCALE_INFO_MAP as d, type LocaleInfo as e, getLocaleInfo as g, isRTL as i };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* CMS Audit Logs Entity
|
|
3
5
|
*
|
|
@@ -7,11 +9,11 @@
|
|
|
7
9
|
* - 무엇을 (action, changes)
|
|
8
10
|
* - 왜 (metadata)
|
|
9
11
|
*/
|
|
10
|
-
|
|
12
|
+
declare const cmsAuditLogs: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
11
13
|
name: "audit_logs";
|
|
12
14
|
schema: string;
|
|
13
15
|
columns: {
|
|
14
|
-
id:
|
|
16
|
+
id: drizzle_orm_pg_core.PgColumn<{
|
|
15
17
|
name: "id";
|
|
16
18
|
tableName: "audit_logs";
|
|
17
19
|
dataType: "number";
|
|
@@ -28,7 +30,7 @@ export declare const cmsAuditLogs: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
28
30
|
identity: undefined;
|
|
29
31
|
generated: undefined;
|
|
30
32
|
}, {}, {}>;
|
|
31
|
-
labelId:
|
|
33
|
+
labelId: drizzle_orm_pg_core.PgColumn<{
|
|
32
34
|
name: "label_id";
|
|
33
35
|
tableName: "audit_logs";
|
|
34
36
|
dataType: "number";
|
|
@@ -45,7 +47,7 @@ export declare const cmsAuditLogs: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
45
47
|
identity: undefined;
|
|
46
48
|
generated: undefined;
|
|
47
49
|
}, {}, {}>;
|
|
48
|
-
action:
|
|
50
|
+
action: drizzle_orm_pg_core.PgColumn<{
|
|
49
51
|
name: "action";
|
|
50
52
|
tableName: "audit_logs";
|
|
51
53
|
dataType: "string";
|
|
@@ -62,7 +64,7 @@ export declare const cmsAuditLogs: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
62
64
|
identity: undefined;
|
|
63
65
|
generated: undefined;
|
|
64
66
|
}, {}, {}>;
|
|
65
|
-
userId:
|
|
67
|
+
userId: drizzle_orm_pg_core.PgColumn<{
|
|
66
68
|
name: "user_id";
|
|
67
69
|
tableName: "audit_logs";
|
|
68
70
|
dataType: "string";
|
|
@@ -79,7 +81,7 @@ export declare const cmsAuditLogs: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
79
81
|
identity: undefined;
|
|
80
82
|
generated: undefined;
|
|
81
83
|
}, {}, {}>;
|
|
82
|
-
userName:
|
|
84
|
+
userName: drizzle_orm_pg_core.PgColumn<{
|
|
83
85
|
name: "user_name";
|
|
84
86
|
tableName: "audit_logs";
|
|
85
87
|
dataType: "string";
|
|
@@ -96,7 +98,7 @@ export declare const cmsAuditLogs: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
96
98
|
identity: undefined;
|
|
97
99
|
generated: undefined;
|
|
98
100
|
}, {}, {}>;
|
|
99
|
-
changes:
|
|
101
|
+
changes: drizzle_orm_pg_core.PgColumn<{
|
|
100
102
|
name: "changes";
|
|
101
103
|
tableName: "audit_logs";
|
|
102
104
|
dataType: "json";
|
|
@@ -113,7 +115,7 @@ export declare const cmsAuditLogs: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
113
115
|
identity: undefined;
|
|
114
116
|
generated: undefined;
|
|
115
117
|
}, {}, {}>;
|
|
116
|
-
metadata:
|
|
118
|
+
metadata: drizzle_orm_pg_core.PgColumn<{
|
|
117
119
|
name: "metadata";
|
|
118
120
|
tableName: "audit_logs";
|
|
119
121
|
dataType: "json";
|
|
@@ -130,7 +132,7 @@ export declare const cmsAuditLogs: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
130
132
|
identity: undefined;
|
|
131
133
|
generated: undefined;
|
|
132
134
|
}, {}, {}>;
|
|
133
|
-
createdAt:
|
|
135
|
+
createdAt: drizzle_orm_pg_core.PgColumn<{
|
|
134
136
|
name: "created_at";
|
|
135
137
|
tableName: "audit_logs";
|
|
136
138
|
dataType: "date";
|
|
@@ -150,64 +152,7 @@ export declare const cmsAuditLogs: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
150
152
|
};
|
|
151
153
|
dialect: "pg";
|
|
152
154
|
}>;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
*
|
|
158
|
-
* // 라벨 생성 로그
|
|
159
|
-
* await db.insert(cmsAuditLogs).values({
|
|
160
|
-
* labelId: 1,
|
|
161
|
-
* action: 'create',
|
|
162
|
-
* userId: 'user123',
|
|
163
|
-
* userName: '김철수',
|
|
164
|
-
* changes: {
|
|
165
|
-
* before: null,
|
|
166
|
-
* after: {
|
|
167
|
-
* key: 'home.hero.title',
|
|
168
|
-
* section: 'home',
|
|
169
|
-
* type: 'text'
|
|
170
|
-
* }
|
|
171
|
-
* },
|
|
172
|
-
* metadata: {
|
|
173
|
-
* ip: '192.168.1.1',
|
|
174
|
-
* userAgent: 'Mozilla/5.0...'
|
|
175
|
-
* }
|
|
176
|
-
* });
|
|
177
|
-
*
|
|
178
|
-
* // 발행 로그
|
|
179
|
-
* await db.insert(cmsAuditLogs).values({
|
|
180
|
-
* labelId: 1,
|
|
181
|
-
* action: 'publish',
|
|
182
|
-
* userId: 'admin123',
|
|
183
|
-
* userName: '관리자',
|
|
184
|
-
* changes: {
|
|
185
|
-
* before: { status: 'draft', publishedVersion: null },
|
|
186
|
-
* after: { status: 'published', publishedVersion: 2 }
|
|
187
|
-
* },
|
|
188
|
-
* metadata: {
|
|
189
|
-
* version: 2,
|
|
190
|
-
* notes: '신규 브랜딩 적용'
|
|
191
|
-
* }
|
|
192
|
-
* });
|
|
193
|
-
*
|
|
194
|
-
* // 라벨별 이력 조회
|
|
195
|
-
* const logs = await db.select()
|
|
196
|
-
* .from(cmsAuditLogs)
|
|
197
|
-
* .where(eq(cmsAuditLogs.labelId, 1))
|
|
198
|
-
* .orderBy(desc(cmsAuditLogs.createdAt))
|
|
199
|
-
* .limit(20);
|
|
200
|
-
*
|
|
201
|
-
* // 사용자별 활동 조회
|
|
202
|
-
* const userActivity = await db.select()
|
|
203
|
-
* .from(cmsAuditLogs)
|
|
204
|
-
* .where(eq(cmsAuditLogs.userId, 'user123'))
|
|
205
|
-
* .orderBy(desc(cmsAuditLogs.createdAt));
|
|
206
|
-
*
|
|
207
|
-
* // 최근 24시간 변경 이력
|
|
208
|
-
* const recent = await db.select()
|
|
209
|
-
* .from(cmsAuditLogs)
|
|
210
|
-
* .where(gte(cmsAuditLogs.createdAt, new Date(Date.now() - 24 * 60 * 60 * 1000)))
|
|
211
|
-
* .orderBy(desc(cmsAuditLogs.createdAt));
|
|
212
|
-
*/
|
|
213
|
-
//# sourceMappingURL=cms-audit-logs.d.ts.map
|
|
155
|
+
type CmsAuditLog = typeof cmsAuditLogs.$inferSelect;
|
|
156
|
+
type NewCmsAuditLog = typeof cmsAuditLogs.$inferInsert;
|
|
157
|
+
|
|
158
|
+
export { type CmsAuditLog, type NewCmsAuditLog, cmsAuditLogs };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// src/server/entities/cms-audit-logs.ts
|
|
2
|
+
import { serial as serial2, integer as integer2, text as text2, jsonb, timestamp as timestamp2, index as index2 } from "drizzle-orm/pg-core";
|
|
3
|
+
import { createFunctionSchema as createFunctionSchema2 } from "@spfn/core/db";
|
|
4
|
+
|
|
5
|
+
// src/server/entities/cms-labels.ts
|
|
6
|
+
import { index, integer, serial, text, timestamp } from "drizzle-orm/pg-core";
|
|
7
|
+
import { createFunctionSchema } from "@spfn/core/db";
|
|
8
|
+
var schema = createFunctionSchema("@spfn/cms");
|
|
9
|
+
var cmsLabels = schema.table("labels", {
|
|
10
|
+
// Primary Key
|
|
11
|
+
id: serial("id").primaryKey(),
|
|
12
|
+
// 라벨 식별자
|
|
13
|
+
key: text("key").notNull().unique(),
|
|
14
|
+
// 예: "home.hero.title", "why-futureplay.hero.subtitle"
|
|
15
|
+
// 구조: {section}.{component}.{property}
|
|
16
|
+
// 섹션 분류 (페이지 단위)
|
|
17
|
+
section: text("section").notNull(),
|
|
18
|
+
// 예: "home", "why-futureplay", "team"
|
|
19
|
+
// 값 타입
|
|
20
|
+
type: text("type").notNull(),
|
|
21
|
+
// "text" | "image" | "video" | "file" | "object"
|
|
22
|
+
// 기본값
|
|
23
|
+
defaultValue: text("default_value"),
|
|
24
|
+
// 라벨의 기본값 (sync 시 설정)
|
|
25
|
+
// 설명
|
|
26
|
+
description: text("description"),
|
|
27
|
+
// 라벨에 대한 설명 (optional)
|
|
28
|
+
// 현재 발행된 버전 번호
|
|
29
|
+
publishedVersion: integer("published_version"),
|
|
30
|
+
// null = 미발행 상태
|
|
31
|
+
// 1, 2, 3... = 발행된 버전 번호
|
|
32
|
+
// 생성자 추적
|
|
33
|
+
createdBy: text("created_by"),
|
|
34
|
+
// 타임스탬프
|
|
35
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
36
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
37
|
+
}, (table) => [
|
|
38
|
+
// 인덱스: 섹션별 조회 최적화
|
|
39
|
+
index("cms_labels_section_idx").on(table.section),
|
|
40
|
+
// 인덱스: key로 조회 최적화 (unique 제약으로 자동 생성되지만 명시)
|
|
41
|
+
index("cms_labels_key_idx").on(table.key)
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
// src/server/entities/cms-audit-logs.ts
|
|
45
|
+
var schema2 = createFunctionSchema2("@spfn/cms");
|
|
46
|
+
var cmsAuditLogs = schema2.table("audit_logs", {
|
|
47
|
+
// Primary Key
|
|
48
|
+
id: serial2("id").primaryKey(),
|
|
49
|
+
// Foreign Key: cms_labels (nullable - 라벨 삭제 시 로그는 유지)
|
|
50
|
+
labelId: integer2("label_id").references(() => cmsLabels.id, { onDelete: "set null" }),
|
|
51
|
+
// 작업 유형
|
|
52
|
+
action: text2("action").notNull(),
|
|
53
|
+
// "create" | "update" | "publish" | "unpublish" | "archive" | "delete" | "rollback" | "duplicate"
|
|
54
|
+
// 사용자 정보
|
|
55
|
+
userId: text2("user_id").notNull(),
|
|
56
|
+
userName: text2("user_name"),
|
|
57
|
+
// 변경 내용 (before/after)
|
|
58
|
+
changes: jsonb("changes"),
|
|
59
|
+
// { before: {...}, after: {...} }
|
|
60
|
+
// 추가 메타데이터
|
|
61
|
+
metadata: jsonb("metadata"),
|
|
62
|
+
// { version: number, ip: string, userAgent: string, ... }
|
|
63
|
+
// 작업 시각
|
|
64
|
+
createdAt: timestamp2("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
65
|
+
}, (table) => [
|
|
66
|
+
// 인덱스: labelId로 이력 조회 최적화
|
|
67
|
+
index2("cms_audit_logs_label_id_idx").on(table.labelId),
|
|
68
|
+
// 인덱스: userId로 사용자 활동 조회 최적화
|
|
69
|
+
index2("cms_audit_logs_user_id_idx").on(table.userId),
|
|
70
|
+
// 인덱스: action 필터링 최적화
|
|
71
|
+
index2("cms_audit_logs_action_idx").on(table.action),
|
|
72
|
+
// 인덱스: 시간순 조회 최적화
|
|
73
|
+
index2("cms_audit_logs_created_at_idx").on(table.createdAt)
|
|
74
|
+
]);
|
|
75
|
+
export {
|
|
76
|
+
cmsAuditLogs
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=cms-audit-logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/server/entities/cms-audit-logs.ts","../../../src/server/entities/cms-labels.ts"],"sourcesContent":["/**\n * CMS Audit Logs Entity\n *\n * CMS의 모든 변경사항을 추적합니다.\n * - 누가 (userId, userName)\n * - 언제 (createdAt)\n * - 무엇을 (action, changes)\n * - 왜 (metadata)\n */\n\nimport { serial, integer, text, jsonb, timestamp, index } from 'drizzle-orm/pg-core';\nimport { createFunctionSchema } from '@spfn/core/db';\nimport { cmsLabels } from '@/server/entities/cms-labels';\n\n// Create isolated schema for @spfn/cms\nconst schema = createFunctionSchema('@spfn/cms');\n\nexport const cmsAuditLogs = schema.table('audit_logs', {\n // Primary Key\n id: serial('id').primaryKey(),\n\n // Foreign Key: cms_labels (nullable - 라벨 삭제 시 로그는 유지)\n labelId: integer('label_id')\n .references(() => cmsLabels.id, { onDelete: 'set null' }),\n\n // 작업 유형\n action: text('action').notNull(),\n // \"create\" | \"update\" | \"publish\" | \"unpublish\" | \"archive\" | \"delete\" | \"rollback\" | \"duplicate\"\n\n // 사용자 정보\n userId: text('user_id').notNull(),\n userName: text('user_name'),\n\n // 변경 내용 (before/after)\n changes: jsonb('changes'),\n // { before: {...}, after: {...} }\n\n // 추가 메타데이터\n metadata: jsonb('metadata'),\n // { version: number, ip: string, userAgent: string, ... }\n\n // 작업 시각\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n // 인덱스: labelId로 이력 조회 최적화\n index('cms_audit_logs_label_id_idx').on(table.labelId),\n\n // 인덱스: userId로 사용자 활동 조회 최적화\n index('cms_audit_logs_user_id_idx').on(table.userId),\n\n // 인덱스: action 필터링 최적화\n index('cms_audit_logs_action_idx').on(table.action),\n\n // 인덱스: 시간순 조회 최적화\n index('cms_audit_logs_created_at_idx').on(table.createdAt),\n]);\n\n// 타입 추론\nexport type CmsAuditLog = typeof cmsAuditLogs.$inferSelect;\nexport type NewCmsAuditLog = typeof cmsAuditLogs.$inferInsert;\n\n/**\n * 사용 예시:\n *\n * // 라벨 생성 로그\n * await db.insert(cmsAuditLogs).values({\n * labelId: 1,\n * action: 'create',\n * userId: 'user123',\n * userName: '김철수',\n * changes: {\n * before: null,\n * after: {\n * key: 'home.hero.title',\n * section: 'home',\n * type: 'text'\n * }\n * },\n * metadata: {\n * ip: '192.168.1.1',\n * userAgent: 'Mozilla/5.0...'\n * }\n * });\n *\n * // 발행 로그\n * await db.insert(cmsAuditLogs).values({\n * labelId: 1,\n * action: 'publish',\n * userId: 'admin123',\n * userName: '관리자',\n * changes: {\n * before: { status: 'draft', publishedVersion: null },\n * after: { status: 'published', publishedVersion: 2 }\n * },\n * metadata: {\n * version: 2,\n * notes: '신규 브랜딩 적용'\n * }\n * });\n *\n * // 라벨별 이력 조회\n * const logs = await db.select()\n * .from(cmsAuditLogs)\n * .where(eq(cmsAuditLogs.labelId, 1))\n * .orderBy(desc(cmsAuditLogs.createdAt))\n * .limit(20);\n *\n * // 사용자별 활동 조회\n * const userActivity = await db.select()\n * .from(cmsAuditLogs)\n * .where(eq(cmsAuditLogs.userId, 'user123'))\n * .orderBy(desc(cmsAuditLogs.createdAt));\n *\n * // 최근 24시간 변경 이력\n * const recent = await db.select()\n * .from(cmsAuditLogs)\n * .where(gte(cmsAuditLogs.createdAt, new Date(Date.now() - 24 * 60 * 60 * 1000)))\n * .orderBy(desc(cmsAuditLogs.createdAt));\n */","/**\n * CMS Labels Entity\n *\n * 라벨의 메타데이터와 현재 발행 상태를 관리합니다.\n * - 라벨 식별 (id, key)\n * - 섹션 분류 (section)\n * - 타입 정의 (type)\n * - 발행 상태 (publishedVersion)\n */\n\nimport { index, integer, serial, text, timestamp } from 'drizzle-orm/pg-core';\nimport { createFunctionSchema } from '@spfn/core/db';\n\n// Create isolated schema for @spfn/cms\nconst schema = createFunctionSchema('@spfn/cms');\n\nexport const cmsLabels = schema.table('labels', {\n // Primary Key\n id: serial('id').primaryKey(),\n\n // 라벨 식별자\n key: text('key').notNull().unique(),\n // 예: \"home.hero.title\", \"why-futureplay.hero.subtitle\"\n // 구조: {section}.{component}.{property}\n\n // 섹션 분류 (페이지 단위)\n section: text('section').notNull(),\n // 예: \"home\", \"why-futureplay\", \"team\"\n\n // 값 타입\n type: text('type').notNull(),\n // \"text\" | \"image\" | \"video\" | \"file\" | \"object\"\n\n // 기본값\n defaultValue: text('default_value'),\n // 라벨의 기본값 (sync 시 설정)\n\n // 설명\n description: text('description'),\n // 라벨에 대한 설명 (optional)\n\n // 현재 발행된 버전 번호\n publishedVersion: integer('published_version'),\n // null = 미발행 상태\n // 1, 2, 3... = 발행된 버전 번호\n\n // 생성자 추적\n createdBy: text('created_by'),\n\n // 타임스탬프\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n // 인덱스: 섹션별 조회 최적화\n index('cms_labels_section_idx').on(table.section),\n\n // 인덱스: key로 조회 최적화 (unique 제약으로 자동 생성되지만 명시)\n index('cms_labels_key_idx').on(table.key),\n]);\n\n// 타입 추론\nexport type CmsLabel = typeof cmsLabels.$inferSelect;\nexport type NewCmsLabel = typeof cmsLabels.$inferInsert;"],"mappings":";AAUA,SAAS,UAAAA,SAAQ,WAAAC,UAAS,QAAAC,OAAM,OAAO,aAAAC,YAAW,SAAAC,cAAa;AAC/D,SAAS,wBAAAC,6BAA4B;;;ACDrC,SAAS,OAAO,SAAS,QAAQ,MAAM,iBAAiB;AACxD,SAAS,4BAA4B;AAGrC,IAAM,SAAS,qBAAqB,WAAW;AAExC,IAAM,YAAY,OAAO,MAAM,UAAU;AAAA;AAAA,EAE5C,IAAI,OAAO,IAAI,EAAE,WAAW;AAAA;AAAA,EAG5B,KAAK,KAAK,KAAK,EAAE,QAAQ,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA,EAKlC,SAAS,KAAK,SAAS,EAAE,QAAQ;AAAA;AAAA;AAAA,EAIjC,MAAM,KAAK,MAAM,EAAE,QAAQ;AAAA;AAAA;AAAA,EAI3B,cAAc,KAAK,eAAe;AAAA;AAAA;AAAA,EAIlC,aAAa,KAAK,aAAa;AAAA;AAAA;AAAA,EAI/B,kBAAkB,QAAQ,mBAAmB;AAAA;AAAA;AAAA;AAAA,EAK7C,WAAW,KAAK,YAAY;AAAA;AAAA,EAG5B,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,EAAE,QAAQ,EAAE,WAAW;AAAA,EAChF,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,EAAE,QAAQ,EAAE,WAAW;AACpF,GAAG,CAAC,UAAU;AAAA;AAAA,EAEV,MAAM,wBAAwB,EAAE,GAAG,MAAM,OAAO;AAAA;AAAA,EAGhD,MAAM,oBAAoB,EAAE,GAAG,MAAM,GAAG;AAC5C,CAAC;;;AD3CD,IAAMC,UAASC,sBAAqB,WAAW;AAExC,IAAM,eAAeD,QAAO,MAAM,cAAc;AAAA;AAAA,EAEnD,IAAIE,QAAO,IAAI,EAAE,WAAW;AAAA;AAAA,EAG5B,SAASC,SAAQ,UAAU,EAC1B,WAAW,MAAM,UAAU,IAAI,EAAE,UAAU,WAAW,CAAC;AAAA;AAAA,EAGxD,QAAQC,MAAK,QAAQ,EAAE,QAAQ;AAAA;AAAA;AAAA,EAI/B,QAAQA,MAAK,SAAS,EAAE,QAAQ;AAAA,EAChC,UAAUA,MAAK,WAAW;AAAA;AAAA,EAG1B,SAAS,MAAM,SAAS;AAAA;AAAA;AAAA,EAIxB,UAAU,MAAM,UAAU;AAAA;AAAA;AAAA,EAI1B,WAAWC,WAAU,cAAc,EAAE,cAAc,KAAK,CAAC,EAAE,QAAQ,EAAE,WAAW;AACpF,GAAG,CAAC,UAAU;AAAA;AAAA,EAEVC,OAAM,6BAA6B,EAAE,GAAG,MAAM,OAAO;AAAA;AAAA,EAGrDA,OAAM,4BAA4B,EAAE,GAAG,MAAM,MAAM;AAAA;AAAA,EAGnDA,OAAM,2BAA2B,EAAE,GAAG,MAAM,MAAM;AAAA;AAAA,EAGlDA,OAAM,+BAA+B,EAAE,GAAG,MAAM,SAAS;AAC7D,CAAC;","names":["serial","integer","text","timestamp","index","createFunctionSchema","schema","createFunctionSchema","serial","integer","text","timestamp","index"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* CMS Draft Cache Entity
|
|
3
5
|
*
|
|
@@ -11,11 +13,11 @@
|
|
|
11
13
|
* - 각자의 변경사항은 자신의 미리보기에만 표시
|
|
12
14
|
* - 충돌 없이 안전하게 작업
|
|
13
15
|
*/
|
|
14
|
-
|
|
16
|
+
declare const cmsDraftCache: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
15
17
|
name: "draft_cache";
|
|
16
18
|
schema: string;
|
|
17
19
|
columns: {
|
|
18
|
-
id:
|
|
20
|
+
id: drizzle_orm_pg_core.PgColumn<{
|
|
19
21
|
name: "id";
|
|
20
22
|
tableName: "draft_cache";
|
|
21
23
|
dataType: "number";
|
|
@@ -32,7 +34,7 @@ export declare const cmsDraftCache: import("drizzle-orm/pg-core").PgTableWithCol
|
|
|
32
34
|
identity: undefined;
|
|
33
35
|
generated: undefined;
|
|
34
36
|
}, {}, {}>;
|
|
35
|
-
section:
|
|
37
|
+
section: drizzle_orm_pg_core.PgColumn<{
|
|
36
38
|
name: "section";
|
|
37
39
|
tableName: "draft_cache";
|
|
38
40
|
dataType: "string";
|
|
@@ -49,7 +51,7 @@ export declare const cmsDraftCache: import("drizzle-orm/pg-core").PgTableWithCol
|
|
|
49
51
|
identity: undefined;
|
|
50
52
|
generated: undefined;
|
|
51
53
|
}, {}, {}>;
|
|
52
|
-
locale:
|
|
54
|
+
locale: drizzle_orm_pg_core.PgColumn<{
|
|
53
55
|
name: "locale";
|
|
54
56
|
tableName: "draft_cache";
|
|
55
57
|
dataType: "string";
|
|
@@ -66,7 +68,7 @@ export declare const cmsDraftCache: import("drizzle-orm/pg-core").PgTableWithCol
|
|
|
66
68
|
identity: undefined;
|
|
67
69
|
generated: undefined;
|
|
68
70
|
}, {}, {}>;
|
|
69
|
-
userId:
|
|
71
|
+
userId: drizzle_orm_pg_core.PgColumn<{
|
|
70
72
|
name: "user_id";
|
|
71
73
|
tableName: "draft_cache";
|
|
72
74
|
dataType: "string";
|
|
@@ -83,7 +85,7 @@ export declare const cmsDraftCache: import("drizzle-orm/pg-core").PgTableWithCol
|
|
|
83
85
|
identity: undefined;
|
|
84
86
|
generated: undefined;
|
|
85
87
|
}, {}, {}>;
|
|
86
|
-
content:
|
|
88
|
+
content: drizzle_orm_pg_core.PgColumn<{
|
|
87
89
|
name: "content";
|
|
88
90
|
tableName: "draft_cache";
|
|
89
91
|
dataType: "json";
|
|
@@ -100,7 +102,7 @@ export declare const cmsDraftCache: import("drizzle-orm/pg-core").PgTableWithCol
|
|
|
100
102
|
identity: undefined;
|
|
101
103
|
generated: undefined;
|
|
102
104
|
}, {}, {}>;
|
|
103
|
-
updatedAt:
|
|
105
|
+
updatedAt: drizzle_orm_pg_core.PgColumn<{
|
|
104
106
|
name: "updated_at";
|
|
105
107
|
tableName: "draft_cache";
|
|
106
108
|
dataType: "date";
|
|
@@ -120,69 +122,7 @@ export declare const cmsDraftCache: import("drizzle-orm/pg-core").PgTableWithCol
|
|
|
120
122
|
};
|
|
121
123
|
dialect: "pg";
|
|
122
124
|
}>;
|
|
123
|
-
|
|
124
|
-
|
|
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
|
|
125
|
+
type CmsDraftCache = typeof cmsDraftCache.$inferSelect;
|
|
126
|
+
type NewCmsDraftCache = typeof cmsDraftCache.$inferInsert;
|
|
127
|
+
|
|
128
|
+
export { type CmsDraftCache, type NewCmsDraftCache, cmsDraftCache };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/server/entities/cms-draft-cache.ts
|
|
2
|
+
import { serial, text, jsonb, timestamp, index, unique } from "drizzle-orm/pg-core";
|
|
3
|
+
import { createFunctionSchema } from "@spfn/core/db";
|
|
4
|
+
var schema = createFunctionSchema("@spfn/cms");
|
|
5
|
+
var cmsDraftCache = schema.table("draft_cache", {
|
|
6
|
+
// Primary Key
|
|
7
|
+
id: serial("id").primaryKey(),
|
|
8
|
+
// 섹션 (페이지 단위)
|
|
9
|
+
section: text("section").notNull(),
|
|
10
|
+
// "home" | "why-futureplay" | "team" | "our-companies" | "apply"
|
|
11
|
+
// 언어
|
|
12
|
+
locale: text("locale").notNull(),
|
|
13
|
+
// "ko" | "en" | "ja"
|
|
14
|
+
// 사용자 ID (핵심 필드!)
|
|
15
|
+
userId: text("user_id").notNull(),
|
|
16
|
+
// 각 관리자의 독립적인 작업 공간
|
|
17
|
+
// Draft 콘텐츠 (JSONB)
|
|
18
|
+
content: jsonb("content").notNull(),
|
|
19
|
+
// Record<string, LabelValue>
|
|
20
|
+
// {
|
|
21
|
+
// "home.hero.title": { type: "text", content: "수정 중..." },
|
|
22
|
+
// "home.hero.subtitle": { type: "text", content: "새로운 문구" },
|
|
23
|
+
// ...
|
|
24
|
+
// }
|
|
25
|
+
// 최종 수정 시각
|
|
26
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
27
|
+
}, (table) => [
|
|
28
|
+
// UNIQUE 제약: section + locale + userId 조합은 유일
|
|
29
|
+
unique("cms_draft_cache_unique").on(table.section, table.locale, table.userId),
|
|
30
|
+
// 인덱스: section으로 조회 최적화
|
|
31
|
+
index("cms_draft_cache_section_idx").on(table.section),
|
|
32
|
+
// 인덱스: userId로 사용자의 모든 draft 조회 최적화
|
|
33
|
+
index("cms_draft_cache_user_idx").on(table.userId)
|
|
34
|
+
]);
|
|
35
|
+
export {
|
|
36
|
+
cmsDraftCache
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=cms-draft-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/server/entities/cms-draft-cache.ts"],"sourcesContent":["/**\n * CMS Draft Cache Entity\n *\n * 관리자별 Draft 콘텐츠를 캐싱합니다.\n * - 사용자별 격리 (userId)\n * - 실시간 미리보기 지원\n * - 동시 편집 가능\n *\n * 핵심 기능:\n * - 여러 관리자가 같은 섹션을 동시에 편집\n * - 각자의 변경사항은 자신의 미리보기에만 표시\n * - 충돌 없이 안전하게 작업\n */\n\nimport { serial, text, jsonb, timestamp, index, unique } from 'drizzle-orm/pg-core';\nimport { createFunctionSchema } from '@spfn/core/db';\n\n// Create isolated schema for @spfn/cms\nconst schema = createFunctionSchema('@spfn/cms');\n\nexport const cmsDraftCache = schema.table('draft_cache', {\n // Primary Key\n id: serial('id').primaryKey(),\n\n // 섹션 (페이지 단위)\n section: text('section').notNull(),\n // \"home\" | \"why-futureplay\" | \"team\" | \"our-companies\" | \"apply\"\n\n // 언어\n locale: text('locale').notNull(),\n // \"ko\" | \"en\" | \"ja\"\n\n // 사용자 ID (핵심 필드!)\n userId: text('user_id').notNull(),\n // 각 관리자의 독립적인 작업 공간\n\n // Draft 콘텐츠 (JSONB)\n content: jsonb('content').notNull(),\n // Record<string, LabelValue>\n // {\n // \"home.hero.title\": { type: \"text\", content: \"수정 중...\" },\n // \"home.hero.subtitle\": { type: \"text\", content: \"새로운 문구\" },\n // ...\n // }\n\n // 최종 수정 시각\n updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n // UNIQUE 제약: section + locale + userId 조합은 유일\n unique('cms_draft_cache_unique')\n .on(table.section, table.locale, table.userId),\n\n // 인덱스: section으로 조회 최적화\n index('cms_draft_cache_section_idx').on(table.section),\n\n // 인덱스: userId로 사용자의 모든 draft 조회 최적화\n index('cms_draft_cache_user_idx').on(table.userId),\n]);\n\n// 타입 추론\nexport type CmsDraftCache = typeof cmsDraftCache.$inferSelect;\nexport type NewCmsDraftCache = typeof cmsDraftCache.$inferInsert;\n\n/**\n * 사용 예시:\n *\n * // Draft 초기화 (편집 시작)\n * await db.insert(cmsDraftCache)\n * .values({\n * section: 'home',\n * locale: 'ko',\n * userId: 'user-a@futureplay.com',\n * content: publishedContent // 발행 버전 복사\n * });\n *\n * // Draft 업데이트 (값 수정 시)\n * const cache = await db.select()\n * .from(cmsDraftCache)\n * .where(and(\n * eq(cmsDraftCache.section, 'home'),\n * eq(cmsDraftCache.locale, 'ko'),\n * eq(cmsDraftCache.userId, userId)\n * ))\n * .limit(1);\n *\n * const updatedContent = {\n * ...cache[0].content,\n * 'home.hero.title': newValue // 부분 업데이트\n * };\n *\n * await db.update(cmsDraftCache)\n * .set({ content: updatedContent, updatedAt: new Date() })\n * .where(eq(cmsDraftCache.id, cache[0].id));\n *\n * // Draft 조회 (미리보기)\n * const draft = await db.select()\n * .from(cmsDraftCache)\n * .where(and(\n * eq(cmsDraftCache.section, 'home'),\n * eq(cmsDraftCache.locale, 'ko'),\n * eq(cmsDraftCache.userId, session.user.id)\n * ))\n * .limit(1);\n *\n * // 사용자의 모든 작업 중인 섹션 조회\n * const userDrafts = await db.select()\n * .from(cmsDraftCache)\n * .where(eq(cmsDraftCache.userId, userId))\n * .orderBy(desc(cmsDraftCache.updatedAt));\n *\n * // 오래된 Draft 정리 (30일 이상)\n * const stale = await db.delete(cmsDraftCache)\n * .where(lt(\n * cmsDraftCache.updatedAt,\n * new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)\n * ))\n * .returning();\n *\n * // Draft 폐기 (변경사항 버리기)\n * await db.delete(cmsDraftCache)\n * .where(and(\n * eq(cmsDraftCache.section, 'home'),\n * eq(cmsDraftCache.locale, 'ko'),\n * eq(cmsDraftCache.userId, userId)\n * ));\n */"],"mappings":";AAcA,SAAS,QAAQ,MAAM,OAAO,WAAW,OAAO,cAAc;AAC9D,SAAS,4BAA4B;AAGrC,IAAM,SAAS,qBAAqB,WAAW;AAExC,IAAM,gBAAgB,OAAO,MAAM,eAAe;AAAA;AAAA,EAErD,IAAI,OAAO,IAAI,EAAE,WAAW;AAAA;AAAA,EAG5B,SAAS,KAAK,SAAS,EAAE,QAAQ;AAAA;AAAA;AAAA,EAIjC,QAAQ,KAAK,QAAQ,EAAE,QAAQ;AAAA;AAAA;AAAA,EAI/B,QAAQ,KAAK,SAAS,EAAE,QAAQ;AAAA;AAAA;AAAA,EAIhC,SAAS,MAAM,SAAS,EAAE,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASlC,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,EAAE,QAAQ,EAAE,WAAW;AACpF,GAAG,CAAC,UAAU;AAAA;AAAA,EAEV,OAAO,wBAAwB,EAC9B,GAAG,MAAM,SAAS,MAAM,QAAQ,MAAM,MAAM;AAAA;AAAA,EAG7C,MAAM,6BAA6B,EAAE,GAAG,MAAM,OAAO;AAAA;AAAA,EAGrD,MAAM,0BAA0B,EAAE,GAAG,MAAM,MAAM;AACrD,CAAC;","names":[]}
|